mbed-os5 only for TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Committer:
kenjiArai
Date:
Tue Dec 31 06:02:27 2019 +0000
Revision:
1:9db0e321a9f4
Parent:
0:5b88d5760320
updated based on mbed-os5.15.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 0:5b88d5760320 1 /*
kenjiArai 0:5b88d5760320 2 * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
kenjiArai 0:5b88d5760320 3 *
kenjiArai 0:5b88d5760320 4 * SPDX-License-Identifier: BSD-3-Clause
kenjiArai 0:5b88d5760320 5 *
kenjiArai 0:5b88d5760320 6 */
kenjiArai 0:5b88d5760320 7 #include <inttypes.h>
kenjiArai 0:5b88d5760320 8 #include <stdbool.h>
kenjiArai 0:5b88d5760320 9 #include <stdio.h>
kenjiArai 0:5b88d5760320 10 #include <stdlib.h>
kenjiArai 0:5b88d5760320 11 #include "psa_client.h"
kenjiArai 0:5b88d5760320 12 #include "psa_service.h"
kenjiArai 0:5b88d5760320 13 #include "tfm_svc.h"
kenjiArai 0:5b88d5760320 14 #include "tfm_svcalls.h"
kenjiArai 0:5b88d5760320 15 #include "tfm_thread.h"
kenjiArai 0:5b88d5760320 16 #include "tfm_wait.h"
kenjiArai 0:5b88d5760320 17 #include "tfm_utils.h"
kenjiArai 0:5b88d5760320 18 #include "tfm_internal_defines.h"
kenjiArai 0:5b88d5760320 19 #include "tfm_message_queue.h"
kenjiArai 0:5b88d5760320 20 #include "tfm_spm.h"
kenjiArai 0:5b88d5760320 21 #include "tfm_api.h"
kenjiArai 0:5b88d5760320 22 #include "tfm_secure_api.h"
kenjiArai 0:5b88d5760320 23 #include "tfm_memory_utils.h"
kenjiArai 0:5b88d5760320 24 #include "spm_api.h"
kenjiArai 0:5b88d5760320 25
kenjiArai 0:5b88d5760320 26 #define PSA_TIMEOUT_MASK PSA_BLOCK
kenjiArai 0:5b88d5760320 27
kenjiArai 0:5b88d5760320 28 /************************* SVC handler for PSA Client APIs *******************/
kenjiArai 0:5b88d5760320 29
kenjiArai 0:5b88d5760320 30 uint32_t tfm_svcall_psa_framework_version(void)
kenjiArai 0:5b88d5760320 31 {
kenjiArai 0:5b88d5760320 32 return PSA_FRAMEWORK_VERSION;
kenjiArai 0:5b88d5760320 33 }
kenjiArai 0:5b88d5760320 34
kenjiArai 0:5b88d5760320 35 uint32_t tfm_svcall_psa_version(uint32_t *args, int32_t ns_caller)
kenjiArai 0:5b88d5760320 36 {
kenjiArai 0:5b88d5760320 37 uint32_t sid;
kenjiArai 0:5b88d5760320 38 struct tfm_spm_service_t *service;
kenjiArai 0:5b88d5760320 39
kenjiArai 0:5b88d5760320 40 TFM_ASSERT(args != NULL);
kenjiArai 0:5b88d5760320 41 sid = (uint32_t)args[0];
kenjiArai 0:5b88d5760320 42 /*
kenjiArai 0:5b88d5760320 43 * It should return PSA_VERSION_NONE if the RoT Service is not
kenjiArai 0:5b88d5760320 44 * implemented.
kenjiArai 0:5b88d5760320 45 */
kenjiArai 0:5b88d5760320 46 service = tfm_spm_get_service_by_sid(sid);
kenjiArai 0:5b88d5760320 47 if (!service) {
kenjiArai 0:5b88d5760320 48 return PSA_VERSION_NONE;
kenjiArai 0:5b88d5760320 49 }
kenjiArai 0:5b88d5760320 50
kenjiArai 0:5b88d5760320 51 /*
kenjiArai 0:5b88d5760320 52 * It should return PSA_VERSION_NONE if the caller is not authorized
kenjiArai 0:5b88d5760320 53 * to access the RoT Service.
kenjiArai 0:5b88d5760320 54 */
kenjiArai 0:5b88d5760320 55 if (ns_caller && !service->service_db->non_secure_client) {
kenjiArai 0:5b88d5760320 56 return PSA_VERSION_NONE;
kenjiArai 0:5b88d5760320 57 }
kenjiArai 0:5b88d5760320 58
kenjiArai 0:5b88d5760320 59 return service->service_db->minor_version;
kenjiArai 0:5b88d5760320 60 }
kenjiArai 0:5b88d5760320 61
kenjiArai 0:5b88d5760320 62 psa_handle_t tfm_svcall_psa_connect(uint32_t *args, int32_t ns_caller)
kenjiArai 0:5b88d5760320 63 {
kenjiArai 0:5b88d5760320 64 uint32_t sid;
kenjiArai 0:5b88d5760320 65 uint32_t minor_version;
kenjiArai 0:5b88d5760320 66 struct tfm_spm_service_t *service;
kenjiArai 0:5b88d5760320 67 struct tfm_msg_body_t *msg;
kenjiArai 0:5b88d5760320 68
kenjiArai 0:5b88d5760320 69 TFM_ASSERT(args != NULL);
kenjiArai 0:5b88d5760320 70 sid = (uint32_t)args[0];
kenjiArai 0:5b88d5760320 71 minor_version = (uint32_t)args[1];
kenjiArai 0:5b88d5760320 72
kenjiArai 0:5b88d5760320 73 /* It is a fatal error if the RoT Service does not exist on the platform */
kenjiArai 0:5b88d5760320 74 service = tfm_spm_get_service_by_sid(sid);
kenjiArai 0:5b88d5760320 75 if (!service) {
kenjiArai 0:5b88d5760320 76 tfm_panic();
kenjiArai 0:5b88d5760320 77 }
kenjiArai 0:5b88d5760320 78
kenjiArai 0:5b88d5760320 79 /*
kenjiArai 0:5b88d5760320 80 * It is a fatal error if the caller is not authorized to access the RoT
kenjiArai 0:5b88d5760320 81 * Service.
kenjiArai 0:5b88d5760320 82 */
kenjiArai 0:5b88d5760320 83 if (ns_caller && !service->service_db->non_secure_client) {
kenjiArai 0:5b88d5760320 84 tfm_panic();
kenjiArai 0:5b88d5760320 85 }
kenjiArai 0:5b88d5760320 86
kenjiArai 0:5b88d5760320 87 /*
kenjiArai 0:5b88d5760320 88 * It is a fatal error if the version of the RoT Service requested is not
kenjiArai 0:5b88d5760320 89 * supported on the platform.
kenjiArai 0:5b88d5760320 90 */
kenjiArai 0:5b88d5760320 91 if (tfm_spm_check_client_version(service, minor_version) != IPC_SUCCESS) {
kenjiArai 0:5b88d5760320 92 tfm_panic();
kenjiArai 0:5b88d5760320 93 }
kenjiArai 0:5b88d5760320 94
kenjiArai 0:5b88d5760320 95 /* No input or output needed for connect message */
kenjiArai 0:5b88d5760320 96 msg = tfm_spm_create_msg(service, PSA_NULL_HANDLE, PSA_IPC_CONNECT,
kenjiArai 0:5b88d5760320 97 ns_caller, NULL, 0, NULL, 0, NULL);
kenjiArai 0:5b88d5760320 98 if (!msg) {
kenjiArai 0:5b88d5760320 99 return PSA_NULL_HANDLE;
kenjiArai 0:5b88d5760320 100 }
kenjiArai 0:5b88d5760320 101
kenjiArai 0:5b88d5760320 102 /*
kenjiArai 0:5b88d5760320 103 * Send message and wake up the SP who is waiting on message queue,
kenjiArai 0:5b88d5760320 104 * and scheduler triggered
kenjiArai 0:5b88d5760320 105 */
kenjiArai 0:5b88d5760320 106 tfm_spm_send_event(service, msg);
kenjiArai 0:5b88d5760320 107
kenjiArai 0:5b88d5760320 108 return PSA_NULL_HANDLE;
kenjiArai 0:5b88d5760320 109 }
kenjiArai 0:5b88d5760320 110
kenjiArai 0:5b88d5760320 111 psa_status_t tfm_svcall_psa_call(uint32_t *args, int32_t ns_caller, uint32_t lr)
kenjiArai 0:5b88d5760320 112 {
kenjiArai 0:5b88d5760320 113 psa_handle_t handle;
kenjiArai 0:5b88d5760320 114 psa_invec *inptr, invecs[PSA_MAX_IOVEC];
kenjiArai 0:5b88d5760320 115 psa_outvec *outptr, outvecs[PSA_MAX_IOVEC];
kenjiArai 0:5b88d5760320 116 size_t in_num, out_num;
kenjiArai 0:5b88d5760320 117 struct tfm_spm_service_t *service;
kenjiArai 0:5b88d5760320 118 struct tfm_msg_body_t *msg;
kenjiArai 0:5b88d5760320 119 int i;
kenjiArai 0:5b88d5760320 120 struct tfm_spm_ipc_partition_t *partition = NULL;
kenjiArai 0:5b88d5760320 121 uint32_t privileged;
kenjiArai 0:5b88d5760320 122
kenjiArai 0:5b88d5760320 123 TFM_ASSERT(args != NULL);
kenjiArai 0:5b88d5760320 124 handle = (psa_handle_t)args[0];
kenjiArai 0:5b88d5760320 125
kenjiArai 0:5b88d5760320 126 partition = tfm_spm_get_running_partition();
kenjiArai 0:5b88d5760320 127 if (!partition) {
kenjiArai 0:5b88d5760320 128 tfm_panic();
kenjiArai 0:5b88d5760320 129 }
kenjiArai 0:5b88d5760320 130 privileged = tfm_spm_partition_get_privileged_mode(partition->index);
kenjiArai 0:5b88d5760320 131
kenjiArai 0:5b88d5760320 132 if (!ns_caller) {
kenjiArai 0:5b88d5760320 133 inptr = (psa_invec *)args[1];
kenjiArai 0:5b88d5760320 134 in_num = (size_t)args[2];
kenjiArai 0:5b88d5760320 135 outptr = (psa_outvec *)args[3];
kenjiArai 0:5b88d5760320 136 /*
kenjiArai 0:5b88d5760320 137 * 5th parameter is pushed at stack top before SVC, then PE hardware
kenjiArai 0:5b88d5760320 138 * stacks the execution context. The size of the context depends on
kenjiArai 0:5b88d5760320 139 * various settings:
kenjiArai 0:5b88d5760320 140 * - if FP is not used, 5th parameter is at 8th position counting
kenjiArai 0:5b88d5760320 141 * from SP;
kenjiArai 0:5b88d5760320 142 * - if FP is used and FPCCR_S.TS is 0, 5th parameter is at 26th
kenjiArai 0:5b88d5760320 143 * position counting from SP;
kenjiArai 0:5b88d5760320 144 * - if FP is used and FPCCR_S.TS is 1, 5th parameter is at 42th
kenjiArai 0:5b88d5760320 145 * position counting from SP.
kenjiArai 0:5b88d5760320 146 */
kenjiArai 0:5b88d5760320 147 if (lr & EXC_RETURN_FPU_FRAME_BASIC) {
kenjiArai 0:5b88d5760320 148 out_num = (size_t)args[8];
kenjiArai 0:5b88d5760320 149 #if defined (__FPU_USED) && (__FPU_USED == 1U)
kenjiArai 0:5b88d5760320 150 } else if (FPU->FPCCR & FPU_FPCCR_TS_Msk) {
kenjiArai 0:5b88d5760320 151 out_num = (size_t)args[42];
kenjiArai 0:5b88d5760320 152 #endif
kenjiArai 0:5b88d5760320 153 } else {
kenjiArai 0:5b88d5760320 154 out_num = (size_t)args[26];
kenjiArai 0:5b88d5760320 155 }
kenjiArai 0:5b88d5760320 156 } else {
kenjiArai 0:5b88d5760320 157 /*
kenjiArai 0:5b88d5760320 158 * FixMe: From non-secure caller, vec and len are composed into a new
kenjiArai 0:5b88d5760320 159 * struct parameter. Need to extract them.
kenjiArai 0:5b88d5760320 160 */
kenjiArai 0:5b88d5760320 161 /*
kenjiArai 0:5b88d5760320 162 * Read parameters from the arguments. It is a fatal error if the
kenjiArai 0:5b88d5760320 163 * memory reference for buffer is invalid or not readable.
kenjiArai 0:5b88d5760320 164 */
kenjiArai 0:5b88d5760320 165 if (tfm_memory_check((void *)args[1], sizeof(uint32_t),
kenjiArai 0:5b88d5760320 166 ns_caller, TFM_MEMORY_ACCESS_RO, privileged) != IPC_SUCCESS) {
kenjiArai 0:5b88d5760320 167 tfm_panic();
kenjiArai 0:5b88d5760320 168 }
kenjiArai 0:5b88d5760320 169 if (tfm_memory_check((void *)args[2], sizeof(uint32_t),
kenjiArai 0:5b88d5760320 170 ns_caller, TFM_MEMORY_ACCESS_RO, privileged) != IPC_SUCCESS) {
kenjiArai 0:5b88d5760320 171 tfm_panic();
kenjiArai 0:5b88d5760320 172 }
kenjiArai 0:5b88d5760320 173
kenjiArai 0:5b88d5760320 174 inptr = (psa_invec *)((psa_invec *)args[1])->base;
kenjiArai 0:5b88d5760320 175 in_num = ((psa_invec *)args[1])->len;
kenjiArai 0:5b88d5760320 176 outptr = (psa_outvec *)((psa_invec *)args[2])->base;
kenjiArai 0:5b88d5760320 177 out_num = ((psa_invec *)args[2])->len;
kenjiArai 0:5b88d5760320 178 }
kenjiArai 0:5b88d5760320 179
kenjiArai 0:5b88d5760320 180 /* It is a fatal error if in_len + out_len > PSA_MAX_IOVEC. */
kenjiArai 0:5b88d5760320 181 if (in_num + out_num > PSA_MAX_IOVEC) {
kenjiArai 0:5b88d5760320 182 tfm_panic();
kenjiArai 0:5b88d5760320 183 }
kenjiArai 0:5b88d5760320 184
kenjiArai 0:5b88d5760320 185 /* It is a fatal error if an invalid handle was passed. */
kenjiArai 0:5b88d5760320 186 service = tfm_spm_get_service_by_handle(handle);
kenjiArai 0:5b88d5760320 187 if (!service) {
kenjiArai 0:5b88d5760320 188 /* FixMe: Need to implement one mechanism to resolve this failure. */
kenjiArai 0:5b88d5760320 189 tfm_panic();
kenjiArai 0:5b88d5760320 190 }
kenjiArai 0:5b88d5760320 191
kenjiArai 0:5b88d5760320 192 /*
kenjiArai 0:5b88d5760320 193 * Read client invecs from the wrap input vector. It is a fatal error
kenjiArai 0:5b88d5760320 194 * if the memory reference for the wrap input vector is invalid or not
kenjiArai 0:5b88d5760320 195 * readable.
kenjiArai 0:5b88d5760320 196 */
kenjiArai 0:5b88d5760320 197 if (tfm_memory_check((void *)inptr, in_num * sizeof(psa_invec),
kenjiArai 0:5b88d5760320 198 ns_caller, TFM_MEMORY_ACCESS_RO, privileged) != IPC_SUCCESS) {
kenjiArai 0:5b88d5760320 199 tfm_panic();
kenjiArai 0:5b88d5760320 200 }
kenjiArai 0:5b88d5760320 201 /*
kenjiArai 0:5b88d5760320 202 * Read client outvecs from the wrap output vector and will update the
kenjiArai 0:5b88d5760320 203 * actual length later. It is a fatal error if the memory reference for
kenjiArai 0:5b88d5760320 204 * the wrap output vector is invalid or not read-write.
kenjiArai 0:5b88d5760320 205 */
kenjiArai 0:5b88d5760320 206 if (tfm_memory_check((void *)outptr, out_num * sizeof(psa_outvec),
kenjiArai 0:5b88d5760320 207 ns_caller, TFM_MEMORY_ACCESS_RW, privileged) != IPC_SUCCESS) {
kenjiArai 0:5b88d5760320 208 tfm_panic();
kenjiArai 0:5b88d5760320 209 }
kenjiArai 0:5b88d5760320 210
kenjiArai 0:5b88d5760320 211 tfm_memset(invecs, 0, sizeof(invecs));
kenjiArai 0:5b88d5760320 212 tfm_memset(outvecs, 0, sizeof(outvecs));
kenjiArai 0:5b88d5760320 213
kenjiArai 0:5b88d5760320 214 /* Copy the address out to avoid TOCTOU attacks. */
kenjiArai 0:5b88d5760320 215 tfm_memcpy(invecs, inptr, in_num * sizeof(psa_invec));
kenjiArai 0:5b88d5760320 216 tfm_memcpy(outvecs, outptr, out_num * sizeof(psa_outvec));
kenjiArai 0:5b88d5760320 217
kenjiArai 0:5b88d5760320 218 /*
kenjiArai 0:5b88d5760320 219 * For client input vector, it is a fatal error if the provided payload
kenjiArai 0:5b88d5760320 220 * memory reference was invalid or not readable.
kenjiArai 0:5b88d5760320 221 */
kenjiArai 0:5b88d5760320 222 for (i = 0; i < in_num; i++) {
kenjiArai 0:5b88d5760320 223 if (tfm_memory_check((void *)invecs[i].base, invecs[i].len,
kenjiArai 0:5b88d5760320 224 ns_caller, TFM_MEMORY_ACCESS_RO, privileged) != IPC_SUCCESS) {
kenjiArai 0:5b88d5760320 225 tfm_panic();
kenjiArai 0:5b88d5760320 226 }
kenjiArai 0:5b88d5760320 227 }
kenjiArai 0:5b88d5760320 228 /*
kenjiArai 0:5b88d5760320 229 * For client output vector, it is a fatal error if the provided payload
kenjiArai 0:5b88d5760320 230 * memory reference was invalid or not read-write.
kenjiArai 0:5b88d5760320 231 */
kenjiArai 0:5b88d5760320 232 for (i = 0; i < out_num; i++) {
kenjiArai 0:5b88d5760320 233 if (tfm_memory_check(outvecs[i].base, outvecs[i].len,
kenjiArai 0:5b88d5760320 234 ns_caller, TFM_MEMORY_ACCESS_RW, privileged) != IPC_SUCCESS) {
kenjiArai 0:5b88d5760320 235 tfm_panic();
kenjiArai 0:5b88d5760320 236 }
kenjiArai 0:5b88d5760320 237 }
kenjiArai 0:5b88d5760320 238
kenjiArai 0:5b88d5760320 239 /*
kenjiArai 0:5b88d5760320 240 * FixMe: Need to check if the message is unrecognized by the RoT
kenjiArai 0:5b88d5760320 241 * Service or incorrectly formatted.
kenjiArai 0:5b88d5760320 242 */
kenjiArai 0:5b88d5760320 243 msg = tfm_spm_create_msg(service, handle, PSA_IPC_CALL, ns_caller, invecs,
kenjiArai 0:5b88d5760320 244 in_num, outvecs, out_num, outptr);
kenjiArai 0:5b88d5760320 245 if (!msg) {
kenjiArai 0:5b88d5760320 246 /* FixMe: Need to implement one mechanism to resolve this failure. */
kenjiArai 0:5b88d5760320 247 tfm_panic();
kenjiArai 0:5b88d5760320 248 }
kenjiArai 0:5b88d5760320 249
kenjiArai 0:5b88d5760320 250 /*
kenjiArai 0:5b88d5760320 251 * Send message and wake up the SP who is waiting on message queue,
kenjiArai 0:5b88d5760320 252 * and scheduler triggered
kenjiArai 0:5b88d5760320 253 */
kenjiArai 0:5b88d5760320 254 if (tfm_spm_send_event(service, msg) != IPC_SUCCESS) {
kenjiArai 0:5b88d5760320 255 /* FixMe: Need to refine failure process here. */
kenjiArai 0:5b88d5760320 256 tfm_panic();
kenjiArai 0:5b88d5760320 257 }
kenjiArai 0:5b88d5760320 258 return PSA_SUCCESS;
kenjiArai 0:5b88d5760320 259 }
kenjiArai 0:5b88d5760320 260
kenjiArai 0:5b88d5760320 261 void tfm_svcall_psa_close(uint32_t *args, int32_t ns_caller)
kenjiArai 0:5b88d5760320 262 {
kenjiArai 0:5b88d5760320 263 psa_handle_t handle;
kenjiArai 0:5b88d5760320 264 struct tfm_spm_service_t *service;
kenjiArai 0:5b88d5760320 265 struct tfm_msg_body_t *msg;
kenjiArai 0:5b88d5760320 266
kenjiArai 0:5b88d5760320 267 TFM_ASSERT(args != NULL);
kenjiArai 0:5b88d5760320 268 handle = args[0];
kenjiArai 0:5b88d5760320 269 /* It will have no effect if called with the NULL handle */
kenjiArai 0:5b88d5760320 270 if (handle == PSA_NULL_HANDLE) {
kenjiArai 0:5b88d5760320 271 return;
kenjiArai 0:5b88d5760320 272 }
kenjiArai 0:5b88d5760320 273
kenjiArai 0:5b88d5760320 274 /*
kenjiArai 0:5b88d5760320 275 * It is a fatal error if an invalid handle was provided that is not the
kenjiArai 0:5b88d5760320 276 * null handle..
kenjiArai 0:5b88d5760320 277 */
kenjiArai 0:5b88d5760320 278 service = tfm_spm_get_service_by_handle(handle);
kenjiArai 0:5b88d5760320 279 if (!service) {
kenjiArai 0:5b88d5760320 280 /* FixMe: Need to implement one mechanism to resolve this failure. */
kenjiArai 0:5b88d5760320 281 tfm_panic();
kenjiArai 0:5b88d5760320 282 }
kenjiArai 0:5b88d5760320 283
kenjiArai 0:5b88d5760320 284 /* No input or output needed for close message */
kenjiArai 0:5b88d5760320 285 msg = tfm_spm_create_msg(service, handle, PSA_IPC_DISCONNECT, ns_caller,
kenjiArai 0:5b88d5760320 286 NULL, 0, NULL, 0, NULL);
kenjiArai 0:5b88d5760320 287 if (!msg) {
kenjiArai 0:5b88d5760320 288 /* FixMe: Need to implement one mechanism to resolve this failure. */
kenjiArai 0:5b88d5760320 289 return;
kenjiArai 0:5b88d5760320 290 }
kenjiArai 0:5b88d5760320 291
kenjiArai 0:5b88d5760320 292 /*
kenjiArai 0:5b88d5760320 293 * Send message and wake up the SP who is waiting on message queue,
kenjiArai 0:5b88d5760320 294 * and scheduler triggered
kenjiArai 0:5b88d5760320 295 */
kenjiArai 0:5b88d5760320 296 tfm_spm_send_event(service, msg);
kenjiArai 0:5b88d5760320 297 }
kenjiArai 0:5b88d5760320 298
kenjiArai 0:5b88d5760320 299 /*********************** SVC handler for PSA Service APIs ********************/
kenjiArai 0:5b88d5760320 300
kenjiArai 0:5b88d5760320 301 /**
kenjiArai 0:5b88d5760320 302 * \brief SVC handler for \ref psa_wait.
kenjiArai 0:5b88d5760320 303 *
kenjiArai 0:5b88d5760320 304 * \param[in] args Include all input arguments:
kenjiArai 0:5b88d5760320 305 * signal_mask, timeout.
kenjiArai 0:5b88d5760320 306 *
kenjiArai 0:5b88d5760320 307 * \retval >0 At least one signal is asserted.
kenjiArai 0:5b88d5760320 308 * \retval 0 No signals are asserted. This is only seen when
kenjiArai 0:5b88d5760320 309 * a polling timeout is used.
kenjiArai 0:5b88d5760320 310 */
kenjiArai 0:5b88d5760320 311 static psa_signal_t tfm_svcall_psa_wait(uint32_t *args)
kenjiArai 0:5b88d5760320 312 {
kenjiArai 0:5b88d5760320 313 psa_signal_t signal_mask;
kenjiArai 0:5b88d5760320 314 uint32_t timeout;
kenjiArai 0:5b88d5760320 315 struct tfm_spm_ipc_partition_t *partition = NULL;
kenjiArai 0:5b88d5760320 316
kenjiArai 0:5b88d5760320 317 TFM_ASSERT(args != NULL);
kenjiArai 0:5b88d5760320 318 signal_mask = (psa_signal_t)args[0];
kenjiArai 0:5b88d5760320 319 timeout = args[1];
kenjiArai 0:5b88d5760320 320
kenjiArai 0:5b88d5760320 321 /*
kenjiArai 0:5b88d5760320 322 * Timeout[30:0] are reserved for future use.
kenjiArai 0:5b88d5760320 323 * SPM must ignore the value of RES.
kenjiArai 0:5b88d5760320 324 */
kenjiArai 0:5b88d5760320 325 timeout &= PSA_TIMEOUT_MASK;
kenjiArai 0:5b88d5760320 326
kenjiArai 0:5b88d5760320 327 partition = tfm_spm_get_running_partition();
kenjiArai 0:5b88d5760320 328 if (!partition) {
kenjiArai 0:5b88d5760320 329 tfm_panic();
kenjiArai 0:5b88d5760320 330 }
kenjiArai 0:5b88d5760320 331
kenjiArai 0:5b88d5760320 332 /*
kenjiArai 0:5b88d5760320 333 * Expected signals are included in signal wait mask, ignored signals
kenjiArai 0:5b88d5760320 334 * should not be set and affect caller thread status. Save this mask for
kenjiArai 0:5b88d5760320 335 * further checking while signals are ready to be set.
kenjiArai 0:5b88d5760320 336 */
kenjiArai 0:5b88d5760320 337 partition->signal_mask = signal_mask;
kenjiArai 0:5b88d5760320 338
kenjiArai 0:5b88d5760320 339 /*
kenjiArai 0:5b88d5760320 340 * tfm_event_wait() blocks the caller thread if no signals are available.
kenjiArai 0:5b88d5760320 341 * In this case, the return value of this function is temporary set into
kenjiArai 0:5b88d5760320 342 * runtime context. After new signal(s) are available, the return value
kenjiArai 0:5b88d5760320 343 * is updated with the available signal(s) and blocked thread gets to run.
kenjiArai 0:5b88d5760320 344 */
kenjiArai 0:5b88d5760320 345 if (timeout == PSA_BLOCK && (partition->signals & signal_mask) == 0) {
kenjiArai 0:5b88d5760320 346 tfm_event_wait(&partition->signal_evnt);
kenjiArai 0:5b88d5760320 347 }
kenjiArai 0:5b88d5760320 348
kenjiArai 0:5b88d5760320 349 return partition->signals & signal_mask;
kenjiArai 0:5b88d5760320 350 }
kenjiArai 0:5b88d5760320 351
kenjiArai 0:5b88d5760320 352 /**
kenjiArai 0:5b88d5760320 353 * \brief SVC handler for \ref psa_get.
kenjiArai 0:5b88d5760320 354 *
kenjiArai 0:5b88d5760320 355 * \param[in] args Include all input arguments: signal, msg.
kenjiArai 0:5b88d5760320 356 *
kenjiArai 0:5b88d5760320 357 * \retval PSA_SUCCESS Success, *msg will contain the delivered
kenjiArai 0:5b88d5760320 358 * message.
kenjiArai 0:5b88d5760320 359 * \retval PSA_ERR_NOMSG Message could not be delivered.
kenjiArai 0:5b88d5760320 360 * \retval "Does not return" The call is invalid because one or more of the
kenjiArai 0:5b88d5760320 361 * following are true:
kenjiArai 0:5b88d5760320 362 * \arg signal has more than a single bit set.
kenjiArai 0:5b88d5760320 363 * \arg signal does not correspond to a RoT Service.
kenjiArai 0:5b88d5760320 364 * \arg The RoT Service signal is not currently
kenjiArai 0:5b88d5760320 365 * asserted.
kenjiArai 0:5b88d5760320 366 * \arg The msg pointer provided is not a valid memory
kenjiArai 0:5b88d5760320 367 * reference.
kenjiArai 0:5b88d5760320 368 */
kenjiArai 0:5b88d5760320 369 static psa_status_t tfm_svcall_psa_get(uint32_t *args)
kenjiArai 0:5b88d5760320 370 {
kenjiArai 0:5b88d5760320 371 psa_signal_t signal;
kenjiArai 0:5b88d5760320 372 psa_msg_t *msg = NULL;
kenjiArai 0:5b88d5760320 373 struct tfm_spm_service_t *service = NULL;
kenjiArai 0:5b88d5760320 374 struct tfm_msg_body_t *tmp_msg = NULL;
kenjiArai 0:5b88d5760320 375 struct tfm_spm_ipc_partition_t *partition = NULL;
kenjiArai 0:5b88d5760320 376 uint32_t privileged;
kenjiArai 0:5b88d5760320 377
kenjiArai 0:5b88d5760320 378 TFM_ASSERT(args != NULL);
kenjiArai 0:5b88d5760320 379 signal = (psa_signal_t)args[0];
kenjiArai 0:5b88d5760320 380 msg = (psa_msg_t *)args[1];
kenjiArai 0:5b88d5760320 381
kenjiArai 0:5b88d5760320 382 /*
kenjiArai 0:5b88d5760320 383 * Only one message could be retrieved every time for psa_get(). It is a
kenjiArai 0:5b88d5760320 384 * fatal error if the input signal has more than a signal bit set.
kenjiArai 0:5b88d5760320 385 */
kenjiArai 0:5b88d5760320 386 if (tfm_bitcount(signal) != 1) {
kenjiArai 0:5b88d5760320 387 tfm_panic();
kenjiArai 0:5b88d5760320 388 }
kenjiArai 0:5b88d5760320 389
kenjiArai 0:5b88d5760320 390 partition = tfm_spm_get_running_partition();
kenjiArai 0:5b88d5760320 391 if (!partition) {
kenjiArai 0:5b88d5760320 392 tfm_panic();
kenjiArai 0:5b88d5760320 393 }
kenjiArai 0:5b88d5760320 394 privileged = tfm_spm_partition_get_privileged_mode(partition->index);
kenjiArai 0:5b88d5760320 395
kenjiArai 0:5b88d5760320 396 /*
kenjiArai 0:5b88d5760320 397 * Write the message to the service buffer. It is a fatal error if the
kenjiArai 0:5b88d5760320 398 * input msg pointer is not a valid memory reference or not read-write.
kenjiArai 0:5b88d5760320 399 */
kenjiArai 0:5b88d5760320 400 if (tfm_memory_check((void *)msg, sizeof(psa_msg_t),
kenjiArai 0:5b88d5760320 401 false, TFM_MEMORY_ACCESS_RW, privileged) != IPC_SUCCESS) {
kenjiArai 0:5b88d5760320 402 tfm_panic();
kenjiArai 0:5b88d5760320 403 }
kenjiArai 0:5b88d5760320 404
kenjiArai 0:5b88d5760320 405 /*
kenjiArai 0:5b88d5760320 406 * It is a fatal error if the caller call psa_get() when no message has
kenjiArai 0:5b88d5760320 407 * been set. The caller must call this function after a RoT Service signal
kenjiArai 0:5b88d5760320 408 * is returned by psa_wait().
kenjiArai 0:5b88d5760320 409 */
kenjiArai 0:5b88d5760320 410 if (partition->signals == 0) {
kenjiArai 0:5b88d5760320 411 tfm_panic();
kenjiArai 0:5b88d5760320 412 }
kenjiArai 0:5b88d5760320 413
kenjiArai 0:5b88d5760320 414 /*
kenjiArai 0:5b88d5760320 415 * It is a fatal error if the RoT Service signal is not currently asserted.
kenjiArai 0:5b88d5760320 416 */
kenjiArai 0:5b88d5760320 417 if ((partition->signals & signal) == 0) {
kenjiArai 0:5b88d5760320 418 tfm_panic();
kenjiArai 0:5b88d5760320 419 }
kenjiArai 0:5b88d5760320 420
kenjiArai 0:5b88d5760320 421 /*
kenjiArai 0:5b88d5760320 422 * Get Rot service by signal from partition. It is a fatal error if geting
kenjiArai 0:5b88d5760320 423 * failed which mean the input signal is not correspond to a RoT service.
kenjiArai 0:5b88d5760320 424 */
kenjiArai 0:5b88d5760320 425 service = tfm_spm_get_service_by_signal(partition, signal);
kenjiArai 0:5b88d5760320 426 if (!service) {
kenjiArai 0:5b88d5760320 427 tfm_panic();
kenjiArai 0:5b88d5760320 428 }
kenjiArai 0:5b88d5760320 429
kenjiArai 0:5b88d5760320 430 tmp_msg = tfm_msg_dequeue(&service->msg_queue);
kenjiArai 0:5b88d5760320 431 if (!tmp_msg) {
kenjiArai 0:5b88d5760320 432 return PSA_ERR_NOMSG;
kenjiArai 0:5b88d5760320 433 }
kenjiArai 0:5b88d5760320 434
kenjiArai 0:5b88d5760320 435 tfm_memcpy(msg, &tmp_msg->msg, sizeof(psa_msg_t));
kenjiArai 0:5b88d5760320 436
kenjiArai 0:5b88d5760320 437 /*
kenjiArai 0:5b88d5760320 438 * There may be mutiple messages for this RoT Service signal, do not clear
kenjiArai 0:5b88d5760320 439 * its mask until no remaining message.
kenjiArai 0:5b88d5760320 440 */
kenjiArai 0:5b88d5760320 441 if (tfm_msg_queue_is_empty(&service->msg_queue)) {
kenjiArai 0:5b88d5760320 442 partition->signals &= ~signal;
kenjiArai 0:5b88d5760320 443 }
kenjiArai 0:5b88d5760320 444
kenjiArai 0:5b88d5760320 445 return PSA_SUCCESS;
kenjiArai 0:5b88d5760320 446 }
kenjiArai 0:5b88d5760320 447
kenjiArai 0:5b88d5760320 448 /**
kenjiArai 0:5b88d5760320 449 * \brief SVC handler for \ref psa_set_rhandle.
kenjiArai 0:5b88d5760320 450 *
kenjiArai 0:5b88d5760320 451 * \param[in] args Include all input arguments:
kenjiArai 0:5b88d5760320 452 * msg_handle, rhandle.
kenjiArai 0:5b88d5760320 453 *
kenjiArai 0:5b88d5760320 454 * \retval void Success, rhandle will be provided with all
kenjiArai 0:5b88d5760320 455 * subsequent messages delivered on this
kenjiArai 0:5b88d5760320 456 * connection.
kenjiArai 0:5b88d5760320 457 * \retval "Does not return" msg_handle is invalid.
kenjiArai 0:5b88d5760320 458 */
kenjiArai 0:5b88d5760320 459 static void tfm_svcall_psa_set_rhandle(uint32_t *args)
kenjiArai 0:5b88d5760320 460 {
kenjiArai 0:5b88d5760320 461 psa_handle_t msg_handle;
kenjiArai 0:5b88d5760320 462 void *rhandle = NULL;
kenjiArai 0:5b88d5760320 463 struct tfm_msg_body_t *msg = NULL;
kenjiArai 0:5b88d5760320 464
kenjiArai 0:5b88d5760320 465 TFM_ASSERT(args != NULL);
kenjiArai 0:5b88d5760320 466 msg_handle = (psa_handle_t)args[0];
kenjiArai 0:5b88d5760320 467 rhandle = (void *)args[1];
kenjiArai 0:5b88d5760320 468
kenjiArai 0:5b88d5760320 469 /* It is a fatal error if message handle is invalid */
kenjiArai 0:5b88d5760320 470 msg = tfm_spm_get_msg_from_handle(msg_handle);
kenjiArai 0:5b88d5760320 471 if (!msg) {
kenjiArai 0:5b88d5760320 472 tfm_panic();
kenjiArai 0:5b88d5760320 473 }
kenjiArai 0:5b88d5760320 474
kenjiArai 0:5b88d5760320 475 /*
kenjiArai 0:5b88d5760320 476 * Connection handle is not created while SP is processing PSA_IPC_CONNECT
kenjiArai 0:5b88d5760320 477 * message. Store reverse handle temporarily and re-set it after the
kenjiArai 0:5b88d5760320 478 * connection created.
kenjiArai 0:5b88d5760320 479 */
kenjiArai 0:5b88d5760320 480 if (msg->handle != PSA_NULL_HANDLE) {
kenjiArai 0:5b88d5760320 481 tfm_spm_set_rhandle(msg->service, msg->handle, rhandle);
kenjiArai 0:5b88d5760320 482 } else {
kenjiArai 0:5b88d5760320 483 msg->msg.rhandle = rhandle;
kenjiArai 0:5b88d5760320 484 }
kenjiArai 0:5b88d5760320 485 }
kenjiArai 0:5b88d5760320 486
kenjiArai 0:5b88d5760320 487 /**
kenjiArai 0:5b88d5760320 488 * \brief SVC handler for \ref psa_read.
kenjiArai 0:5b88d5760320 489 *
kenjiArai 0:5b88d5760320 490 * \param[in] args Include all input arguments:
kenjiArai 0:5b88d5760320 491 * msg_handle, invec_idx, buffer, num_bytes.
kenjiArai 0:5b88d5760320 492 *
kenjiArai 0:5b88d5760320 493 * \retval >0 Number of bytes copied.
kenjiArai 0:5b88d5760320 494 * \retval 0 There was no remaining data in this input
kenjiArai 0:5b88d5760320 495 * vector.
kenjiArai 0:5b88d5760320 496 * \retval "Does not return" The call is invalid, one or more of the
kenjiArai 0:5b88d5760320 497 * following are true:
kenjiArai 0:5b88d5760320 498 * \arg msg_handle is invalid.
kenjiArai 0:5b88d5760320 499 * \arg msg_handle does not refer to a
kenjiArai 0:5b88d5760320 500 * \ref PSA_IPC_CALL message.
kenjiArai 0:5b88d5760320 501 * \arg invec_idx is equal to or greater than
kenjiArai 0:5b88d5760320 502 * \ref PSA_MAX_IOVEC.
kenjiArai 0:5b88d5760320 503 * \arg the memory reference for buffer is invalid or
kenjiArai 0:5b88d5760320 504 * not writable.
kenjiArai 0:5b88d5760320 505 */
kenjiArai 0:5b88d5760320 506 static size_t tfm_svcall_psa_read(uint32_t *args)
kenjiArai 0:5b88d5760320 507 {
kenjiArai 0:5b88d5760320 508 psa_handle_t msg_handle;
kenjiArai 0:5b88d5760320 509 uint32_t invec_idx;
kenjiArai 0:5b88d5760320 510 void *buffer = NULL;
kenjiArai 0:5b88d5760320 511 size_t num_bytes;
kenjiArai 0:5b88d5760320 512 size_t bytes;
kenjiArai 0:5b88d5760320 513 struct tfm_msg_body_t *msg = NULL;
kenjiArai 0:5b88d5760320 514 uint32_t privileged;
kenjiArai 0:5b88d5760320 515 struct tfm_spm_ipc_partition_t *partition = NULL;
kenjiArai 0:5b88d5760320 516
kenjiArai 0:5b88d5760320 517 TFM_ASSERT(args != NULL);
kenjiArai 0:5b88d5760320 518 msg_handle = (psa_handle_t)args[0];
kenjiArai 0:5b88d5760320 519 invec_idx = args[1];
kenjiArai 0:5b88d5760320 520 buffer = (void *)args[2];
kenjiArai 0:5b88d5760320 521 num_bytes = (size_t)args[3];
kenjiArai 0:5b88d5760320 522
kenjiArai 0:5b88d5760320 523 /* It is a fatal error if message handle is invalid */
kenjiArai 0:5b88d5760320 524 msg = tfm_spm_get_msg_from_handle(msg_handle);
kenjiArai 0:5b88d5760320 525 if (!msg) {
kenjiArai 0:5b88d5760320 526 tfm_panic();
kenjiArai 0:5b88d5760320 527 }
kenjiArai 0:5b88d5760320 528
kenjiArai 0:5b88d5760320 529 partition = msg->service->partition;
kenjiArai 0:5b88d5760320 530 privileged = tfm_spm_partition_get_privileged_mode(partition->index);
kenjiArai 0:5b88d5760320 531
kenjiArai 0:5b88d5760320 532 /*
kenjiArai 0:5b88d5760320 533 * It is a fatal error if message handle does not refer to a PSA_IPC_CALL
kenjiArai 0:5b88d5760320 534 * message
kenjiArai 0:5b88d5760320 535 */
kenjiArai 0:5b88d5760320 536 if (msg->msg.type != PSA_IPC_CALL) {
kenjiArai 0:5b88d5760320 537 tfm_panic();
kenjiArai 0:5b88d5760320 538 }
kenjiArai 0:5b88d5760320 539
kenjiArai 0:5b88d5760320 540 /*
kenjiArai 0:5b88d5760320 541 * It is a fatal error if invec_idx is equal to or greater than
kenjiArai 0:5b88d5760320 542 * PSA_MAX_IOVEC
kenjiArai 0:5b88d5760320 543 */
kenjiArai 0:5b88d5760320 544 if (invec_idx >= PSA_MAX_IOVEC) {
kenjiArai 0:5b88d5760320 545 tfm_panic();
kenjiArai 0:5b88d5760320 546 }
kenjiArai 0:5b88d5760320 547
kenjiArai 0:5b88d5760320 548 /* There was no remaining data in this input vector */
kenjiArai 0:5b88d5760320 549 if (msg->msg.in_size[invec_idx] == 0) {
kenjiArai 0:5b88d5760320 550 return 0;
kenjiArai 0:5b88d5760320 551 }
kenjiArai 0:5b88d5760320 552
kenjiArai 0:5b88d5760320 553 /*
kenjiArai 0:5b88d5760320 554 * Copy the client data to the service buffer. It is a fatal error
kenjiArai 0:5b88d5760320 555 * if the memory reference for buffer is invalid or not read-write.
kenjiArai 0:5b88d5760320 556 */
kenjiArai 0:5b88d5760320 557 if (tfm_memory_check(buffer, num_bytes, false,
kenjiArai 0:5b88d5760320 558 TFM_MEMORY_ACCESS_RW, privileged) != IPC_SUCCESS) {
kenjiArai 0:5b88d5760320 559 tfm_panic();
kenjiArai 0:5b88d5760320 560 }
kenjiArai 0:5b88d5760320 561
kenjiArai 0:5b88d5760320 562 bytes = num_bytes > msg->msg.in_size[invec_idx] ?
kenjiArai 0:5b88d5760320 563 msg->msg.in_size[invec_idx] : num_bytes;
kenjiArai 0:5b88d5760320 564
kenjiArai 0:5b88d5760320 565 tfm_memcpy(buffer, msg->invec[invec_idx].base, bytes);
kenjiArai 0:5b88d5760320 566
kenjiArai 0:5b88d5760320 567 /* There maybe some remaining data */
kenjiArai 0:5b88d5760320 568 msg->invec[invec_idx].base += bytes;
kenjiArai 0:5b88d5760320 569 msg->msg.in_size[invec_idx] -= bytes;
kenjiArai 0:5b88d5760320 570
kenjiArai 0:5b88d5760320 571 return bytes;
kenjiArai 0:5b88d5760320 572 }
kenjiArai 0:5b88d5760320 573
kenjiArai 0:5b88d5760320 574 /**
kenjiArai 0:5b88d5760320 575 * \brief SVC handler for \ref psa_skip.
kenjiArai 0:5b88d5760320 576 *
kenjiArai 0:5b88d5760320 577 * \param[in] args Include all input arguments:
kenjiArai 0:5b88d5760320 578 * msg_handle, invec_idx, num_bytes.
kenjiArai 0:5b88d5760320 579 *
kenjiArai 0:5b88d5760320 580 * \retval >0 Number of bytes skipped.
kenjiArai 0:5b88d5760320 581 * \retval 0 There was no remaining data in this input
kenjiArai 0:5b88d5760320 582 * vector.
kenjiArai 0:5b88d5760320 583 * \retval "Does not return" The call is invalid, one or more of the
kenjiArai 0:5b88d5760320 584 * following are true:
kenjiArai 0:5b88d5760320 585 * \arg msg_handle is invalid.
kenjiArai 0:5b88d5760320 586 * \arg msg_handle does not refer to a
kenjiArai 0:5b88d5760320 587 * \ref PSA_IPC_CALL message.
kenjiArai 0:5b88d5760320 588 * \arg invec_idx is equal to or greater than
kenjiArai 0:5b88d5760320 589 * \ref PSA_MAX_IOVEC.
kenjiArai 0:5b88d5760320 590 */
kenjiArai 0:5b88d5760320 591 static size_t tfm_svcall_psa_skip(uint32_t *args)
kenjiArai 0:5b88d5760320 592 {
kenjiArai 0:5b88d5760320 593 psa_handle_t msg_handle;
kenjiArai 0:5b88d5760320 594 uint32_t invec_idx;
kenjiArai 0:5b88d5760320 595 size_t num_bytes;
kenjiArai 0:5b88d5760320 596 struct tfm_msg_body_t *msg = NULL;
kenjiArai 0:5b88d5760320 597
kenjiArai 0:5b88d5760320 598 TFM_ASSERT(args != NULL);
kenjiArai 0:5b88d5760320 599 msg_handle = (psa_handle_t)args[0];
kenjiArai 0:5b88d5760320 600 invec_idx = args[1];
kenjiArai 0:5b88d5760320 601 num_bytes = (size_t)args[2];
kenjiArai 0:5b88d5760320 602
kenjiArai 0:5b88d5760320 603 /* It is a fatal error if message handle is invalid */
kenjiArai 0:5b88d5760320 604 msg = tfm_spm_get_msg_from_handle(msg_handle);
kenjiArai 0:5b88d5760320 605 if (!msg) {
kenjiArai 0:5b88d5760320 606 tfm_panic();
kenjiArai 0:5b88d5760320 607 }
kenjiArai 0:5b88d5760320 608
kenjiArai 0:5b88d5760320 609 /*
kenjiArai 0:5b88d5760320 610 * It is a fatal error if message handle does not refer to a PSA_IPC_CALL
kenjiArai 0:5b88d5760320 611 * message
kenjiArai 0:5b88d5760320 612 */
kenjiArai 0:5b88d5760320 613 if (msg->msg.type != PSA_IPC_CALL) {
kenjiArai 0:5b88d5760320 614 tfm_panic();
kenjiArai 0:5b88d5760320 615 }
kenjiArai 0:5b88d5760320 616
kenjiArai 0:5b88d5760320 617 /*
kenjiArai 0:5b88d5760320 618 * It is a fatal error if invec_idx is equal to or greater than
kenjiArai 0:5b88d5760320 619 * PSA_MAX_IOVEC
kenjiArai 0:5b88d5760320 620 */
kenjiArai 0:5b88d5760320 621 if (invec_idx >= PSA_MAX_IOVEC) {
kenjiArai 0:5b88d5760320 622 tfm_panic();
kenjiArai 0:5b88d5760320 623 }
kenjiArai 0:5b88d5760320 624
kenjiArai 0:5b88d5760320 625 /* There was no remaining data in this input vector */
kenjiArai 0:5b88d5760320 626 if (msg->msg.in_size[invec_idx] == 0) {
kenjiArai 0:5b88d5760320 627 return 0;
kenjiArai 0:5b88d5760320 628 }
kenjiArai 0:5b88d5760320 629
kenjiArai 0:5b88d5760320 630 /*
kenjiArai 0:5b88d5760320 631 * If num_bytes is greater than the remaining size of the input vector then
kenjiArai 0:5b88d5760320 632 * the remaining size of the input vector is used.
kenjiArai 0:5b88d5760320 633 */
kenjiArai 0:5b88d5760320 634 if (num_bytes > msg->msg.in_size[invec_idx]) {
kenjiArai 0:5b88d5760320 635 num_bytes = msg->msg.in_size[invec_idx];
kenjiArai 0:5b88d5760320 636 }
kenjiArai 0:5b88d5760320 637
kenjiArai 0:5b88d5760320 638 /* There maybe some remaining data */
kenjiArai 0:5b88d5760320 639 msg->invec[invec_idx].base += num_bytes;
kenjiArai 0:5b88d5760320 640 msg->msg.in_size[invec_idx] -= num_bytes;
kenjiArai 0:5b88d5760320 641
kenjiArai 0:5b88d5760320 642 return num_bytes;
kenjiArai 0:5b88d5760320 643 }
kenjiArai 0:5b88d5760320 644
kenjiArai 0:5b88d5760320 645 /**
kenjiArai 0:5b88d5760320 646 * \brief SVC handler for \ref psa_write.
kenjiArai 0:5b88d5760320 647 *
kenjiArai 0:5b88d5760320 648 * \param[in] args Include all input arguments:
kenjiArai 0:5b88d5760320 649 * msg_handle, outvec_idx, buffer, num_bytes.
kenjiArai 0:5b88d5760320 650 *
kenjiArai 0:5b88d5760320 651 * \retval void Success
kenjiArai 0:5b88d5760320 652 * \retval "Does not return" The call is invalid, one or more of the
kenjiArai 0:5b88d5760320 653 * following are true:
kenjiArai 0:5b88d5760320 654 * \arg msg_handle is invalid.
kenjiArai 0:5b88d5760320 655 * \arg msg_handle does not refer to a
kenjiArai 0:5b88d5760320 656 * \ref PSA_IPC_CALL message.
kenjiArai 0:5b88d5760320 657 * \arg outvec_idx is equal to or greater than
kenjiArai 0:5b88d5760320 658 * \ref PSA_MAX_IOVEC.
kenjiArai 0:5b88d5760320 659 * \arg The memory reference for buffer is invalid.
kenjiArai 0:5b88d5760320 660 * \arg The call attempts to write data past the end
kenjiArai 0:5b88d5760320 661 * of the client output vector.
kenjiArai 0:5b88d5760320 662 */
kenjiArai 0:5b88d5760320 663 static void tfm_svcall_psa_write(uint32_t *args)
kenjiArai 0:5b88d5760320 664 {
kenjiArai 0:5b88d5760320 665 psa_handle_t msg_handle;
kenjiArai 0:5b88d5760320 666 uint32_t outvec_idx;
kenjiArai 0:5b88d5760320 667 void *buffer = NULL;
kenjiArai 0:5b88d5760320 668 size_t num_bytes;
kenjiArai 0:5b88d5760320 669 struct tfm_msg_body_t *msg = NULL;
kenjiArai 0:5b88d5760320 670 uint32_t privileged;
kenjiArai 0:5b88d5760320 671 struct tfm_spm_ipc_partition_t *partition = NULL;
kenjiArai 0:5b88d5760320 672
kenjiArai 0:5b88d5760320 673 TFM_ASSERT(args != NULL);
kenjiArai 0:5b88d5760320 674 msg_handle = (psa_handle_t)args[0];
kenjiArai 0:5b88d5760320 675 outvec_idx = args[1];
kenjiArai 0:5b88d5760320 676 buffer = (void *)args[2];
kenjiArai 0:5b88d5760320 677 num_bytes = (size_t)args[3];
kenjiArai 0:5b88d5760320 678
kenjiArai 0:5b88d5760320 679 /* It is a fatal error if message handle is invalid */
kenjiArai 0:5b88d5760320 680 msg = tfm_spm_get_msg_from_handle(msg_handle);
kenjiArai 0:5b88d5760320 681 if (!msg) {
kenjiArai 0:5b88d5760320 682 tfm_panic();
kenjiArai 0:5b88d5760320 683 }
kenjiArai 0:5b88d5760320 684
kenjiArai 0:5b88d5760320 685 partition = msg->service->partition;
kenjiArai 0:5b88d5760320 686 privileged = tfm_spm_partition_get_privileged_mode(partition->index);
kenjiArai 0:5b88d5760320 687
kenjiArai 0:5b88d5760320 688 /*
kenjiArai 0:5b88d5760320 689 * It is a fatal error if message handle does not refer to a PSA_IPC_CALL
kenjiArai 0:5b88d5760320 690 * message
kenjiArai 0:5b88d5760320 691 */
kenjiArai 0:5b88d5760320 692 if (msg->msg.type != PSA_IPC_CALL) {
kenjiArai 0:5b88d5760320 693 tfm_panic();
kenjiArai 0:5b88d5760320 694 }
kenjiArai 0:5b88d5760320 695
kenjiArai 0:5b88d5760320 696 /*
kenjiArai 0:5b88d5760320 697 * It is a fatal error if outvec_idx is equal to or greater than
kenjiArai 0:5b88d5760320 698 * PSA_MAX_IOVEC
kenjiArai 0:5b88d5760320 699 */
kenjiArai 0:5b88d5760320 700 if (outvec_idx >= PSA_MAX_IOVEC) {
kenjiArai 0:5b88d5760320 701 tfm_panic();
kenjiArai 0:5b88d5760320 702 }
kenjiArai 0:5b88d5760320 703
kenjiArai 0:5b88d5760320 704 /*
kenjiArai 0:5b88d5760320 705 * It is a fatal error if the call attempts to write data past the end of
kenjiArai 0:5b88d5760320 706 * the client output vector
kenjiArai 0:5b88d5760320 707 */
kenjiArai 0:5b88d5760320 708 if (num_bytes > msg->msg.out_size[outvec_idx] -
kenjiArai 0:5b88d5760320 709 msg->outvec[outvec_idx].len) {
kenjiArai 0:5b88d5760320 710 tfm_panic();
kenjiArai 0:5b88d5760320 711 }
kenjiArai 0:5b88d5760320 712
kenjiArai 0:5b88d5760320 713 /*
kenjiArai 0:5b88d5760320 714 * Copy the service buffer to client outvecs. It is a fatal error
kenjiArai 0:5b88d5760320 715 * if the memory reference for buffer is invalid or not readable.
kenjiArai 0:5b88d5760320 716 */
kenjiArai 0:5b88d5760320 717 if (tfm_memory_check(buffer, num_bytes, false,
kenjiArai 0:5b88d5760320 718 TFM_MEMORY_ACCESS_RO, privileged) != IPC_SUCCESS) {
kenjiArai 0:5b88d5760320 719 tfm_panic();
kenjiArai 0:5b88d5760320 720 }
kenjiArai 0:5b88d5760320 721
kenjiArai 0:5b88d5760320 722 tfm_memcpy(msg->outvec[outvec_idx].base + msg->outvec[outvec_idx].len,
kenjiArai 0:5b88d5760320 723 buffer, num_bytes);
kenjiArai 0:5b88d5760320 724
kenjiArai 0:5b88d5760320 725 /* Update the write number */
kenjiArai 0:5b88d5760320 726 msg->outvec[outvec_idx].len += num_bytes;
kenjiArai 0:5b88d5760320 727 }
kenjiArai 0:5b88d5760320 728
kenjiArai 0:5b88d5760320 729 static void update_caller_outvec_len(struct tfm_msg_body_t *msg)
kenjiArai 0:5b88d5760320 730 {
kenjiArai 0:5b88d5760320 731 int32_t i = 0;
kenjiArai 0:5b88d5760320 732
kenjiArai 0:5b88d5760320 733 /*
kenjiArai 0:5b88d5760320 734 * FixeMe: abstract these part into dedicated functions to avoid
kenjiArai 0:5b88d5760320 735 * accessing thread context in psa layer
kenjiArai 0:5b88d5760320 736 */
kenjiArai 0:5b88d5760320 737 TFM_ASSERT(msg->ack_evnt.owner->status == THRD_STAT_BLOCK);
kenjiArai 0:5b88d5760320 738
kenjiArai 0:5b88d5760320 739 while (msg->msg.out_size[i] != 0) {
kenjiArai 0:5b88d5760320 740 TFM_ASSERT(msg->caller_outvec[i].base == msg->outvec[i].base);
kenjiArai 0:5b88d5760320 741 msg->caller_outvec[i].len = msg->outvec[i].len;
kenjiArai 0:5b88d5760320 742 i++;
kenjiArai 0:5b88d5760320 743 }
kenjiArai 0:5b88d5760320 744 }
kenjiArai 0:5b88d5760320 745 /**
kenjiArai 0:5b88d5760320 746 * \brief SVC handler for \ref psa_reply.
kenjiArai 0:5b88d5760320 747 *
kenjiArai 0:5b88d5760320 748 * \param[in] args Include all input arguments:
kenjiArai 0:5b88d5760320 749 * msg_handle, status.
kenjiArai 0:5b88d5760320 750 *
kenjiArai 0:5b88d5760320 751 * \retval void Success.
kenjiArai 0:5b88d5760320 752 * \retval "Does not return" The call is invalid, one or more of the
kenjiArai 0:5b88d5760320 753 * following are true:
kenjiArai 0:5b88d5760320 754 * \arg msg_handle is invalid.
kenjiArai 0:5b88d5760320 755 * \arg An invalid status code is specified for the
kenjiArai 0:5b88d5760320 756 * type of message.
kenjiArai 0:5b88d5760320 757 */
kenjiArai 0:5b88d5760320 758 static void tfm_svcall_psa_reply(uint32_t *args)
kenjiArai 0:5b88d5760320 759 {
kenjiArai 0:5b88d5760320 760 psa_handle_t msg_handle;
kenjiArai 0:5b88d5760320 761 psa_status_t status;
kenjiArai 0:5b88d5760320 762 struct tfm_spm_service_t *service = NULL;
kenjiArai 0:5b88d5760320 763 struct tfm_msg_body_t *msg = NULL;
kenjiArai 0:5b88d5760320 764 psa_handle_t connect_handle;
kenjiArai 0:5b88d5760320 765 int32_t ret = PSA_SUCCESS;
kenjiArai 0:5b88d5760320 766
kenjiArai 0:5b88d5760320 767 TFM_ASSERT(args != NULL);
kenjiArai 0:5b88d5760320 768 msg_handle = (psa_handle_t)args[0];
kenjiArai 0:5b88d5760320 769 status = (psa_status_t)args[1];
kenjiArai 0:5b88d5760320 770
kenjiArai 0:5b88d5760320 771 /* It is a fatal error if message handle is invalid */
kenjiArai 0:5b88d5760320 772 msg = tfm_spm_get_msg_from_handle(msg_handle);
kenjiArai 0:5b88d5760320 773 if (!msg) {
kenjiArai 0:5b88d5760320 774 tfm_panic();
kenjiArai 0:5b88d5760320 775 }
kenjiArai 0:5b88d5760320 776
kenjiArai 0:5b88d5760320 777 /*
kenjiArai 0:5b88d5760320 778 * RoT Service information is needed in this function, stored it in message
kenjiArai 0:5b88d5760320 779 * body structure. Only two parameters are passed in this function: handle
kenjiArai 0:5b88d5760320 780 * and status, so it is useful and simply to do like this.
kenjiArai 0:5b88d5760320 781 */
kenjiArai 0:5b88d5760320 782 service = msg->service;
kenjiArai 0:5b88d5760320 783 if (!service) {
kenjiArai 0:5b88d5760320 784 tfm_panic();
kenjiArai 0:5b88d5760320 785 }
kenjiArai 0:5b88d5760320 786
kenjiArai 0:5b88d5760320 787 /*
kenjiArai 0:5b88d5760320 788 * Three type of message are passed in this function: CONNECT, CALL,
kenjiArai 0:5b88d5760320 789 * DISCONNECT. It needs to process differently for each type.
kenjiArai 0:5b88d5760320 790 */
kenjiArai 0:5b88d5760320 791 switch (msg->msg.type) {
kenjiArai 0:5b88d5760320 792 case PSA_IPC_CONNECT:
kenjiArai 0:5b88d5760320 793 /*
kenjiArai 0:5b88d5760320 794 * Reply to PSA_IPC_CONNECT message. Connect handle is created if the
kenjiArai 0:5b88d5760320 795 * input status is PSA_SUCCESS. Others return values are based on the
kenjiArai 0:5b88d5760320 796 * input status.
kenjiArai 0:5b88d5760320 797 */
kenjiArai 0:5b88d5760320 798 if (status == PSA_SUCCESS) {
kenjiArai 0:5b88d5760320 799 connect_handle = tfm_spm_create_conn_handle(service);
kenjiArai 0:5b88d5760320 800 if (connect_handle == PSA_NULL_HANDLE) {
kenjiArai 0:5b88d5760320 801 tfm_panic();
kenjiArai 0:5b88d5760320 802 }
kenjiArai 0:5b88d5760320 803 ret = connect_handle;
kenjiArai 0:5b88d5760320 804
kenjiArai 0:5b88d5760320 805 /* Set reverse handle after connection created if needed. */
kenjiArai 0:5b88d5760320 806 if (msg->msg.rhandle) {
kenjiArai 0:5b88d5760320 807 tfm_spm_set_rhandle(service, connect_handle, msg->msg.rhandle);
kenjiArai 0:5b88d5760320 808 }
kenjiArai 0:5b88d5760320 809 } else if (status == PSA_CONNECTION_REFUSED) {
kenjiArai 0:5b88d5760320 810 ret = PSA_CONNECTION_REFUSED;
kenjiArai 0:5b88d5760320 811 } else if (status == PSA_CONNECTION_BUSY) {
kenjiArai 0:5b88d5760320 812 ret = PSA_CONNECTION_BUSY;
kenjiArai 0:5b88d5760320 813 } else {
kenjiArai 0:5b88d5760320 814 tfm_panic();
kenjiArai 0:5b88d5760320 815 }
kenjiArai 0:5b88d5760320 816 break;
kenjiArai 0:5b88d5760320 817 case PSA_IPC_CALL:
kenjiArai 0:5b88d5760320 818 /* Reply to PSA_IPC_CALL message. Return values are based on status */
kenjiArai 0:5b88d5760320 819 if (status == PSA_SUCCESS) {
kenjiArai 0:5b88d5760320 820 ret = PSA_SUCCESS;
kenjiArai 0:5b88d5760320 821 } else if (status == PSA_DROP_CONNECTION) {
kenjiArai 0:5b88d5760320 822 ret = PSA_DROP_CONNECTION;
kenjiArai 0:5b88d5760320 823 } else if ((status >= (INT32_MIN + 1)) &&
kenjiArai 0:5b88d5760320 824 (status <= (INT32_MIN + 127))) {
kenjiArai 0:5b88d5760320 825 tfm_panic();
kenjiArai 0:5b88d5760320 826 } else if ((status >= (INT32_MIN + 128)) && (status <= -1)) {
kenjiArai 0:5b88d5760320 827 ret = status;
kenjiArai 0:5b88d5760320 828 } else if ((status >= 1) && (status <= INT32_MAX)) {
kenjiArai 0:5b88d5760320 829 ret = status;
kenjiArai 0:5b88d5760320 830 } else {
kenjiArai 0:5b88d5760320 831 tfm_panic();
kenjiArai 0:5b88d5760320 832 }
kenjiArai 0:5b88d5760320 833
kenjiArai 0:5b88d5760320 834 /*
kenjiArai 0:5b88d5760320 835 * The total number of bytes written to a single parameter must be
kenjiArai 0:5b88d5760320 836 * reported to the client by updating the len member of the psa_outvec
kenjiArai 0:5b88d5760320 837 * structure for the parameter before returning from psa_call().
kenjiArai 0:5b88d5760320 838 */
kenjiArai 0:5b88d5760320 839 update_caller_outvec_len(msg);
kenjiArai 0:5b88d5760320 840 break;
kenjiArai 0:5b88d5760320 841 case PSA_IPC_DISCONNECT:
kenjiArai 0:5b88d5760320 842 /* Service handle is not used anymore */
kenjiArai 0:5b88d5760320 843 tfm_spm_free_conn_handle(service, msg->handle);
kenjiArai 0:5b88d5760320 844
kenjiArai 0:5b88d5760320 845 /*
kenjiArai 0:5b88d5760320 846 * If the message type is PSA_IPC_DISCONNECT, then the status code is
kenjiArai 0:5b88d5760320 847 * ignored
kenjiArai 0:5b88d5760320 848 */
kenjiArai 0:5b88d5760320 849 break;
kenjiArai 0:5b88d5760320 850 default:
kenjiArai 0:5b88d5760320 851 tfm_panic();
kenjiArai 0:5b88d5760320 852 }
kenjiArai 0:5b88d5760320 853
kenjiArai 0:5b88d5760320 854 tfm_event_wake(&msg->ack_evnt, ret);
kenjiArai 0:5b88d5760320 855
kenjiArai 0:5b88d5760320 856 /* Message should not be unsed anymore */
kenjiArai 0:5b88d5760320 857 tfm_spm_free_msg(msg);
kenjiArai 0:5b88d5760320 858 }
kenjiArai 0:5b88d5760320 859
kenjiArai 0:5b88d5760320 860 /**
kenjiArai 0:5b88d5760320 861 * \brief SVC handler for \ref psa_notify.
kenjiArai 0:5b88d5760320 862 *
kenjiArai 0:5b88d5760320 863 * \param[in] args Include all input arguments: partition_id.
kenjiArai 0:5b88d5760320 864 *
kenjiArai 0:5b88d5760320 865 * \retval void Success.
kenjiArai 0:5b88d5760320 866 * \retval "Does not return" partition_id does not correspond to a Secure
kenjiArai 0:5b88d5760320 867 * Partition.
kenjiArai 0:5b88d5760320 868 */
kenjiArai 0:5b88d5760320 869 static void tfm_svcall_psa_notify(uint32_t *args)
kenjiArai 0:5b88d5760320 870 {
kenjiArai 0:5b88d5760320 871 int32_t partition_id;
kenjiArai 0:5b88d5760320 872 struct tfm_spm_ipc_partition_t *partition = NULL;
kenjiArai 0:5b88d5760320 873
kenjiArai 0:5b88d5760320 874 TFM_ASSERT(args != NULL);
kenjiArai 0:5b88d5760320 875 partition_id = (int32_t)args[0];
kenjiArai 0:5b88d5760320 876
kenjiArai 0:5b88d5760320 877 /*
kenjiArai 0:5b88d5760320 878 * The value of partition_id must be greater than zero as the target of
kenjiArai 0:5b88d5760320 879 * notification must be a Secure Partition, providing a Non-secure
kenjiArai 0:5b88d5760320 880 * Partition ID is a fatal error.
kenjiArai 0:5b88d5760320 881 */
kenjiArai 0:5b88d5760320 882 if (!TFM_CLIENT_ID_IS_S(partition_id)) {
kenjiArai 0:5b88d5760320 883 tfm_panic();
kenjiArai 0:5b88d5760320 884 }
kenjiArai 0:5b88d5760320 885
kenjiArai 0:5b88d5760320 886 /*
kenjiArai 0:5b88d5760320 887 * It is a fatal error if partition_id does not correspond to a Secure
kenjiArai 0:5b88d5760320 888 * Partition.
kenjiArai 0:5b88d5760320 889 */
kenjiArai 0:5b88d5760320 890 partition = tfm_spm_get_partition_by_id(partition_id);
kenjiArai 0:5b88d5760320 891 if (!partition) {
kenjiArai 0:5b88d5760320 892 tfm_panic();
kenjiArai 0:5b88d5760320 893 }
kenjiArai 0:5b88d5760320 894
kenjiArai 0:5b88d5760320 895 partition->signals |= PSA_DOORBELL;
kenjiArai 0:5b88d5760320 896
kenjiArai 0:5b88d5760320 897 /*
kenjiArai 0:5b88d5760320 898 * The target partition may be blocked with waiting for signals after
kenjiArai 0:5b88d5760320 899 * called psa_wait(). Set the return value with the available signals
kenjiArai 0:5b88d5760320 900 * before wake it up with tfm_event_signal().
kenjiArai 0:5b88d5760320 901 */
kenjiArai 0:5b88d5760320 902 tfm_event_wake(&partition->signal_evnt,
kenjiArai 0:5b88d5760320 903 partition->signals & partition->signal_mask);
kenjiArai 0:5b88d5760320 904 }
kenjiArai 0:5b88d5760320 905
kenjiArai 0:5b88d5760320 906 /**
kenjiArai 0:5b88d5760320 907 * \brief SVC handler for \ref psa_clear.
kenjiArai 0:5b88d5760320 908 *
kenjiArai 0:5b88d5760320 909 * \retval void Success.
kenjiArai 0:5b88d5760320 910 * \retval "Does not return" The Secure Partition's doorbell signal is not
kenjiArai 0:5b88d5760320 911 * currently asserted.
kenjiArai 0:5b88d5760320 912 */
kenjiArai 0:5b88d5760320 913 static void tfm_svcall_psa_clear(uint32_t *args)
kenjiArai 0:5b88d5760320 914 {
kenjiArai 0:5b88d5760320 915 struct tfm_spm_ipc_partition_t *partition = NULL;
kenjiArai 0:5b88d5760320 916
kenjiArai 0:5b88d5760320 917 partition = tfm_spm_get_running_partition();
kenjiArai 0:5b88d5760320 918 if (!partition) {
kenjiArai 0:5b88d5760320 919 tfm_panic();
kenjiArai 0:5b88d5760320 920 }
kenjiArai 0:5b88d5760320 921
kenjiArai 0:5b88d5760320 922 /*
kenjiArai 0:5b88d5760320 923 * It is a fatal error if the Secure Partition's doorbell signal is not
kenjiArai 0:5b88d5760320 924 * currently asserted.
kenjiArai 0:5b88d5760320 925 */
kenjiArai 0:5b88d5760320 926 if ((partition->signals & PSA_DOORBELL) == 0) {
kenjiArai 0:5b88d5760320 927 tfm_panic();
kenjiArai 0:5b88d5760320 928 }
kenjiArai 0:5b88d5760320 929 partition->signals &= ~PSA_DOORBELL;
kenjiArai 0:5b88d5760320 930 }
kenjiArai 0:5b88d5760320 931
kenjiArai 0:5b88d5760320 932 /**
kenjiArai 0:5b88d5760320 933 * \brief SVC handler for \ref psa_eoi.
kenjiArai 0:5b88d5760320 934 *
kenjiArai 0:5b88d5760320 935 * \param[in] args Include all input arguments: irq_signal.
kenjiArai 0:5b88d5760320 936 *
kenjiArai 0:5b88d5760320 937 * \retval void Success.
kenjiArai 0:5b88d5760320 938 * \retval "Does not return" The call is invalid, one or more of the
kenjiArai 0:5b88d5760320 939 * following are true:
kenjiArai 0:5b88d5760320 940 * \arg irq_signal is not an interrupt signal.
kenjiArai 0:5b88d5760320 941 * \arg irq_signal indicates more than one signal.
kenjiArai 0:5b88d5760320 942 * \arg irq_signal is not currently asserted.
kenjiArai 0:5b88d5760320 943 */
kenjiArai 0:5b88d5760320 944 static void tfm_svcall_psa_eoi(uint32_t *args)
kenjiArai 0:5b88d5760320 945 {
kenjiArai 0:5b88d5760320 946 psa_signal_t irq_signal;
kenjiArai 0:5b88d5760320 947 struct tfm_spm_ipc_partition_t *partition = NULL;
kenjiArai 0:5b88d5760320 948
kenjiArai 0:5b88d5760320 949 TFM_ASSERT(args != NULL);
kenjiArai 0:5b88d5760320 950 irq_signal = (psa_signal_t)args[0];
kenjiArai 0:5b88d5760320 951
kenjiArai 0:5b88d5760320 952 partition = tfm_spm_get_running_partition();
kenjiArai 0:5b88d5760320 953 if (!partition) {
kenjiArai 0:5b88d5760320 954 tfm_panic();
kenjiArai 0:5b88d5760320 955 }
kenjiArai 0:5b88d5760320 956
kenjiArai 0:5b88d5760320 957 /*
kenjiArai 0:5b88d5760320 958 * FixMe: It is a fatal error if passed signal is not an interrupt signal.
kenjiArai 0:5b88d5760320 959 */
kenjiArai 0:5b88d5760320 960
kenjiArai 0:5b88d5760320 961 /* It is a fatal error if passed signal indicates more than one signals. */
kenjiArai 0:5b88d5760320 962 if (tfm_bitcount(partition->signals) != 1) {
kenjiArai 0:5b88d5760320 963 tfm_panic();
kenjiArai 0:5b88d5760320 964 }
kenjiArai 0:5b88d5760320 965
kenjiArai 0:5b88d5760320 966 /* It is a fatal error if passed signal is not currently asserted */
kenjiArai 0:5b88d5760320 967 if ((partition->signals & irq_signal) == 0) {
kenjiArai 0:5b88d5760320 968 tfm_panic();
kenjiArai 0:5b88d5760320 969 }
kenjiArai 0:5b88d5760320 970
kenjiArai 0:5b88d5760320 971 partition->signals &= ~irq_signal;
kenjiArai 0:5b88d5760320 972
kenjiArai 0:5b88d5760320 973 /* FixMe: re-enable interrupt */
kenjiArai 0:5b88d5760320 974 }
kenjiArai 0:5b88d5760320 975
kenjiArai 0:5b88d5760320 976 int32_t SVC_Handler_IPC(tfm_svc_number_t svc_num, uint32_t *ctx, uint32_t lr)
kenjiArai 0:5b88d5760320 977 {
kenjiArai 0:5b88d5760320 978 switch (svc_num) {
kenjiArai 0:5b88d5760320 979 case TFM_SVC_SCHEDULE:
kenjiArai 0:5b88d5760320 980 tfm_thrd_activate_schedule();
kenjiArai 0:5b88d5760320 981 break;
kenjiArai 0:5b88d5760320 982 case TFM_SVC_EXIT_THRD:
kenjiArai 0:5b88d5760320 983 tfm_svcall_thrd_exit();
kenjiArai 0:5b88d5760320 984 break;
kenjiArai 0:5b88d5760320 985 case TFM_SVC_PSA_FRAMEWORK_VERSION:
kenjiArai 0:5b88d5760320 986 return tfm_svcall_psa_framework_version();
kenjiArai 0:5b88d5760320 987 case TFM_SVC_PSA_VERSION:
kenjiArai 0:5b88d5760320 988 return tfm_svcall_psa_version(ctx, 0);
kenjiArai 0:5b88d5760320 989 case TFM_SVC_PSA_CONNECT:
kenjiArai 0:5b88d5760320 990 return tfm_svcall_psa_connect(ctx, 0);
kenjiArai 0:5b88d5760320 991 case TFM_SVC_PSA_CALL:
kenjiArai 0:5b88d5760320 992 return tfm_svcall_psa_call(ctx, 0, lr);
kenjiArai 0:5b88d5760320 993 case TFM_SVC_PSA_CLOSE:
kenjiArai 0:5b88d5760320 994 tfm_svcall_psa_close(ctx, 0);
kenjiArai 0:5b88d5760320 995 break;
kenjiArai 0:5b88d5760320 996 case TFM_SVC_PSA_WAIT:
kenjiArai 0:5b88d5760320 997 return tfm_svcall_psa_wait(ctx);
kenjiArai 0:5b88d5760320 998 case TFM_SVC_PSA_GET:
kenjiArai 0:5b88d5760320 999 return tfm_svcall_psa_get(ctx);
kenjiArai 0:5b88d5760320 1000 case TFM_SVC_PSA_SET_RHANDLE:
kenjiArai 0:5b88d5760320 1001 tfm_svcall_psa_set_rhandle(ctx);
kenjiArai 0:5b88d5760320 1002 break;
kenjiArai 0:5b88d5760320 1003 case TFM_SVC_PSA_READ:
kenjiArai 0:5b88d5760320 1004 return tfm_svcall_psa_read(ctx);
kenjiArai 0:5b88d5760320 1005 case TFM_SVC_PSA_SKIP:
kenjiArai 0:5b88d5760320 1006 return tfm_svcall_psa_skip(ctx);
kenjiArai 0:5b88d5760320 1007 case TFM_SVC_PSA_WRITE:
kenjiArai 0:5b88d5760320 1008 tfm_svcall_psa_write(ctx);
kenjiArai 0:5b88d5760320 1009 break;
kenjiArai 0:5b88d5760320 1010 case TFM_SVC_PSA_REPLY:
kenjiArai 0:5b88d5760320 1011 tfm_svcall_psa_reply(ctx);
kenjiArai 0:5b88d5760320 1012 break;
kenjiArai 0:5b88d5760320 1013 case TFM_SVC_PSA_NOTIFY:
kenjiArai 0:5b88d5760320 1014 tfm_svcall_psa_notify(ctx);
kenjiArai 0:5b88d5760320 1015 break;
kenjiArai 0:5b88d5760320 1016 case TFM_SVC_PSA_CLEAR:
kenjiArai 0:5b88d5760320 1017 tfm_svcall_psa_clear(ctx);
kenjiArai 0:5b88d5760320 1018 break;
kenjiArai 0:5b88d5760320 1019 case TFM_SVC_PSA_EOI:
kenjiArai 0:5b88d5760320 1020 tfm_svcall_psa_eoi(ctx);
kenjiArai 0:5b88d5760320 1021 break;
kenjiArai 0:5b88d5760320 1022 default:
kenjiArai 0:5b88d5760320 1023 break;
kenjiArai 0:5b88d5760320 1024 }
kenjiArai 0:5b88d5760320 1025 return PSA_SUCCESS;
kenjiArai 0:5b88d5760320 1026 }