1 /* 2 * Copyright (c) 2019-2022, Arm Limited. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 */ 7 8 #ifndef __PSA_API_H__ 9 #define __PSA_API_H__ 10 11 #include <stdint.h> 12 #include <stdbool.h> 13 #include "config_spm.h" 14 #include "psa/client.h" 15 #include "psa/service.h" 16 17 /** 18 * \brief This function handles the specific programmer error cases. 19 * 20 * \param[in] status Standard error codes for the SPM. 21 * 22 * \retval void Status will not cause SPM panic 23 * \retval "SPM panic" Following programmer errors are triggered by SP: 24 * \arg PSA_ERROR_PROGRAMMER_ERROR 25 * \arg PSA_ERROR_CONNECTION_REFUSED 26 * \arg PSA_ERROR_CONNECTION_BUSY 27 */ 28 void spm_handle_programmer_errors(psa_status_t status); 29 30 /** 31 * \brief This function get the current PSA RoT lifecycle state. 32 * 33 * \return state The current security lifecycle state of the PSA 34 * RoT. The PSA state and implementation state are 35 * encoded as follows: 36 * \arg state[15:8] – PSA lifecycle state 37 * \arg state[7:0] – IMPLEMENTATION DEFINED state 38 */ 39 uint32_t tfm_spm_get_lifecycle_state(void); 40 41 /* PSA Client API function body, for privileged use only. */ 42 43 /** 44 * \brief handler for \ref psa_framework_version. 45 * 46 * \return version The version of the PSA Framework implementation 47 * that is providing the runtime services. 48 */ 49 uint32_t tfm_spm_client_psa_framework_version(void); 50 51 /** 52 * \brief handler for \ref psa_version. 53 * 54 * \param[in] sid RoT Service identity. 55 * 56 * \retval PSA_VERSION_NONE The RoT Service is not implemented, or the 57 * caller is not permitted to access the service. 58 * \retval > 0 The version of the implemented RoT Service. 59 */ 60 uint32_t tfm_spm_client_psa_version(uint32_t sid); 61 62 /** 63 * \brief handler for \ref psa_call. 64 * 65 * \param[in] handle Service handle to the established connection, 66 * \ref psa_handle_t 67 * \param[in] ctrl_param Parameters combined in uint32_t, 68 * includes request type, in_num and out_num. 69 * \param[in] inptr Array of input psa_invec structures. 70 * \ref psa_invec 71 * \param[in] outptr Array of output psa_outvec structures. 72 * \ref psa_outvec 73 * 74 * \retval PSA_SUCCESS Success. 75 * \retval "Does not return" The call is invalid, one or more of the 76 * following are true: 77 * \arg An invalid handle was passed. 78 * \arg The connection is already handling a request. 79 * \arg An invalid memory reference was provided. 80 * \arg in_num + out_num > PSA_MAX_IOVEC. 81 * \arg The message is unrecognized by the RoT 82 * Service or incorrectly formatted. 83 */ 84 psa_status_t tfm_spm_client_psa_call(psa_handle_t handle, 85 uint32_t ctrl_param, 86 const psa_invec *inptr, 87 psa_outvec *outptr); 88 89 /* Following PSA APIs are only needed by connection-based services */ 90 #if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1 91 92 /** 93 * \brief handler for \ref psa_connect. 94 * 95 * \param[in] sid RoT Service identity. 96 * \param[in] version The version of the RoT Service. 97 * 98 * \retval PSA_SUCCESS Success. 99 * \retval PSA_ERROR_CONNECTION_REFUSED The SPM or RoT Service has refused the 100 * connection. 101 * \retval PSA_ERROR_CONNECTION_BUSY The SPM or RoT Service cannot make the 102 * connection at the moment. 103 * \retval "Does not return" The RoT Service ID and version are not 104 * supported, or the caller is not permitted to 105 * access the service. 106 */ 107 psa_status_t tfm_spm_client_psa_connect(uint32_t sid, uint32_t version); 108 109 /** 110 * \brief handler for \ref psa_close. 111 * 112 * \param[in] handle Service handle to the connection to be closed, 113 * \ref psa_handle_t 114 * 115 * \retval PSA_SUCCESS Success. 116 * \retval PSA_ERROR_PROGRAMMER_ERROR The call is invalid, one or more of the 117 * following are true: 118 * \arg Called with a stateless handle. 119 * \arg An invalid handle was provided that is not 120 * the null handle. 121 * \arg The connection is handling a request. 122 */ 123 psa_status_t tfm_spm_client_psa_close(psa_handle_t handle); 124 125 #endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API */ 126 127 /* PSA Partition API function body, for privileged use only. */ 128 129 #if CONFIG_TFM_SPM_BACKEND_IPC == 1 \ 130 || CONFIG_TFM_FLIH_API == 1 || CONFIG_TFM_SLIH_API == 1 131 /** 132 * \brief Function body of \ref psa_wait. 133 * 134 * \param[in] signal_mask A set of signals to query. Signals that are not 135 * in this set will be ignored. 136 * \param[in] timeout Specify either blocking \ref PSA_BLOCK or 137 * polling \ref PSA_POLL operation. 138 * 139 * \retval >0 At least one signal is asserted. 140 * \retval 0 No signals are asserted. This is only seen when 141 * a polling timeout is used. 142 */ 143 psa_signal_t tfm_spm_partition_psa_wait(psa_signal_t signal_mask, 144 uint32_t timeout); 145 #endif 146 147 /* This API is only used in IPC backend. */ 148 #if CONFIG_TFM_SPM_BACKEND_IPC == 1 149 /** 150 * \brief Function body of \ref psa_get. 151 * 152 * \param[in] signal The signal value for an asserted RoT Service. 153 * \param[out] msg Pointer to \ref psa_msg_t object for receiving 154 * the message. 155 * 156 * \retval PSA_SUCCESS Success, *msg will contain the delivered 157 * message. 158 * \retval PSA_ERROR_DOES_NOT_EXIST Message could not be delivered. 159 * \retval "PROGRAMMER ERROR" The call is invalid because one or more of the 160 * following are true: 161 * \arg signal has more than a single bit set. 162 * \arg signal does not correspond to an RoT Service. 163 * \arg The RoT Service signal is not currently 164 * asserted. 165 * \arg The msg pointer provided is not a valid memory 166 * reference. 167 */ 168 psa_status_t tfm_spm_partition_psa_get(psa_signal_t signal, psa_msg_t *msg); 169 #endif /* CONFIG_TFM_SPM_BACKEND_IPC == 1 */ 170 171 /** 172 * \brief Function body of \ref psa_read. 173 * 174 * \param[in] msg_handle Handle for the client's message. 175 * \param[in] invec_idx Index of the input vector to read from. Must be 176 * less than \ref PSA_MAX_IOVEC. 177 * \param[out] buffer Buffer in the Secure Partition to copy the 178 * requested data to. 179 * \param[in] num_bytes Maximum number of bytes to be read from the 180 * client input vector. 181 * 182 * \retval >0 Number of bytes copied. 183 * \retval 0 There was no remaining data in this input 184 * vector. 185 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the 186 * following are true: 187 * \arg msg_handle is invalid. 188 * \arg msg_handle does not refer to a 189 * \ref PSA_IPC_CALL message. 190 * \arg invec_idx is equal to or greater than 191 * \ref PSA_MAX_IOVEC. 192 * \arg the memory reference for buffer is invalid or 193 * not writable. 194 */ 195 size_t tfm_spm_partition_psa_read(psa_handle_t msg_handle, uint32_t invec_idx, 196 void *buffer, size_t num_bytes); 197 198 /** 199 * \brief Function body of psa_skip. 200 * 201 * \param[in] msg_handle Handle for the client's message. 202 * \param[in] invec_idx Index of input vector to skip from. Must be 203 * less than \ref PSA_MAX_IOVEC. 204 * \param[in] num_bytes Maximum number of bytes to skip in the client 205 * input vector. 206 * 207 * \retval >0 Number of bytes skipped. 208 * \retval 0 There was no remaining data in this input 209 * vector. 210 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the 211 * following are true: 212 * \arg msg_handle is invalid. 213 * \arg msg_handle does not refer to a request 214 * message. 215 * \arg invec_idx is equal to or greater than 216 * \ref PSA_MAX_IOVEC. 217 */ 218 size_t tfm_spm_partition_psa_skip(psa_handle_t msg_handle, uint32_t invec_idx, 219 size_t num_bytes); 220 221 /** 222 * \brief Function body of \ref psa_write. 223 * 224 * \param[in] msg_handle Handle for the client's message. 225 * \param[out] outvec_idx Index of output vector in message to write to. 226 * Must be less than \ref PSA_MAX_IOVEC. 227 * \param[in] buffer Buffer with the data to write. 228 * \param[in] num_bytes Number of bytes to write to the client output 229 * vector. 230 * 231 * \retval void Success 232 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the 233 * following are true: 234 * \arg msg_handle is invalid. 235 * \arg msg_handle does not refer to a request 236 * message. 237 * \arg outvec_idx is equal to or greater than 238 * \ref PSA_MAX_IOVEC. 239 * \arg The memory reference for buffer is invalid. 240 * \arg The call attempts to write data past the end 241 * of the client output vector. 242 */ 243 void tfm_spm_partition_psa_write(psa_handle_t msg_handle, uint32_t outvec_idx, 244 const void *buffer, size_t num_bytes); 245 246 /** 247 * \brief Function body of \ref psa_reply. 248 * 249 * \param[in] msg_handle Handle for the client's message. 250 * \param[in] status Message result value to be reported to the 251 * client. 252 * 253 * \retval Positive integer Success, the connection handle. 254 * \retval PSA_SUCCESS Success 255 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the 256 * following are true: 257 * \arg msg_handle is invalid. 258 * \arg An invalid status code is specified for the 259 * type of message. 260 */ 261 int32_t tfm_spm_partition_psa_reply(psa_handle_t msg_handle, 262 psa_status_t status); 263 264 #if CONFIG_TFM_DOORBELL_API == 1 265 /** 266 * \brief Function body of \ref psa_norify. 267 * 268 * \param[in] partition_id Secure Partition ID of the target partition. 269 * 270 * \retval void Success. 271 * \retval "PROGRAMMER ERROR" partition_id does not correspond to a Secure 272 * Partition. 273 */ 274 void tfm_spm_partition_psa_notify(int32_t partition_id); 275 276 /** 277 * \brief Function body of \ref psa_clear. 278 * 279 * \retval void Success. 280 * \retval "PROGRAMMER ERROR" The Secure Partition's doorbell signal is not 281 * currently asserted. 282 */ 283 void tfm_spm_partition_psa_clear(void); 284 #endif /* CONFIG_TFM_DOORBELL_API == 1 */ 285 286 /** 287 * \brief Function body of \ref psa_panic. 288 * 289 * \retval "Does not return" 290 */ 291 void tfm_spm_partition_psa_panic(void); 292 293 /* psa_set_rhandle is only needed by connection-based services */ 294 #if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1 295 296 /** 297 * \brief Function body of \ref psa_set_rhandle. 298 * 299 * \param[in] msg_handle Handle for the client's message. 300 * \param[in] rhandle Reverse handle allocated by the RoT Service. 301 * 302 * \retval void Success, rhandle will be provided with all 303 * subsequent messages delivered on this 304 * connection. 305 * \retval "PROGRAMMER ERROR" msg_handle is invalid. 306 */ 307 void tfm_spm_partition_psa_set_rhandle(psa_handle_t msg_handle, void *rhandle); 308 309 #endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API */ 310 311 #if CONFIG_TFM_FLIH_API == 1 || CONFIG_TFM_SLIH_API == 1 312 /** 313 * \brief Function body of \ref psa_irq_enable. 314 * 315 * \param[in] irq_signal The signal for the interrupt to be enabled. 316 * This must have a single bit set, which must be the 317 * signal value for an interrupt in the calling Secure 318 * Partition. 319 * 320 * \retval void 321 * \retval "PROGRAMMER ERROR" If one or more of the following are true: 322 * \arg \a irq_signal is not an interrupt signal. 323 * \arg \a irq_signal indicates more than one signal. 324 */ 325 void tfm_spm_partition_psa_irq_enable(psa_signal_t irq_signal); 326 327 /** 328 * \brief Function body of psa_irq_disable. 329 * 330 * \param[in] irq_signal The signal for the interrupt to be disabled. 331 * This must have a single bit set, which must be the 332 * signal value for an interrupt in the calling Secure 333 * Partition. 334 * 335 * \retval 0 The interrupt was disabled prior to this call. 336 * 1 The interrupt was enabled prior to this call. 337 * \retval "PROGRAMMER ERROR" If one or more of the following are true: 338 * \arg \a irq_signal is not an interrupt signal. 339 * \arg \a irq_signal indicates more than one signal. 340 * 341 * \note The current implementation always return 1. Do not use the return. 342 */ 343 psa_irq_status_t tfm_spm_partition_psa_irq_disable(psa_signal_t irq_signal); 344 345 /* This API is only used for FLIH. */ 346 #if CONFIG_TFM_FLIH_API == 1 347 /** 348 * \brief Function body of \ref psa_reset_signal. 349 * 350 * \param[in] irq_signal The interrupt signal to be reset. 351 * This must have a single bit set, corresponding to a 352 * currently asserted signal for an interrupt that is 353 * defined to use FLIH handling. 354 * 355 * \retval void 356 * \retval "Programmer Error" if one or more of the following are true: 357 * \arg \a irq_signal is not a signal for an interrupt 358 * that is specified with FLIH handling in the Secure 359 * Partition manifest. 360 * \arg \a irq_signal indicates more than one signal. 361 * \arg \a irq_signal is not currently asserted. 362 */ 363 void tfm_spm_partition_psa_reset_signal(psa_signal_t irq_signal); 364 #endif 365 366 /* This API is only used for SLIH. */ 367 #if CONFIG_TFM_SLIH_API == 1 368 /** 369 * \brief Function body of \ref psa_eoi. 370 * 371 * \param[in] irq_signal The interrupt signal that has been processed. 372 * 373 * \retval void Success. 374 * \retval "PROGRAMMER ERROR" The call is invalid, one or more of the 375 * following are true: 376 * \arg irq_signal is not an interrupt signal. 377 * \arg irq_signal indicates more than one signal. 378 * \arg irq_signal is not currently asserted. 379 * \arg The interrupt is not using SLIH. 380 */ 381 void tfm_spm_partition_psa_eoi(psa_signal_t irq_signal); 382 #endif 383 #endif /* CONFIG_TFM_FLIH_API == 1 || CONFIG_TFM_SLIH_API == 1 */ 384 385 #if PSA_FRAMEWORK_HAS_MM_IOVEC 386 387 /** 388 * \brief Function body of psa_map_invec. 389 */ 390 const void *tfm_spm_partition_psa_map_invec(psa_handle_t msg_handle, 391 uint32_t invec_idx); 392 393 /** 394 * \brief Function body of psa_unmap_invec. 395 */ 396 void tfm_spm_partition_psa_unmap_invec(psa_handle_t msg_handle, 397 uint32_t invec_idx); 398 399 /** 400 * \brief Function body of psa_map_outvet. 401 */ 402 void *tfm_spm_partition_psa_map_outvec(psa_handle_t msg_handle, 403 uint32_t outvec_idx); 404 405 /** 406 * \brief Function body of psa_unmap_outvec. 407 */ 408 void tfm_spm_partition_psa_unmap_outvec(psa_handle_t msg_handle, 409 uint32_t outvec_idx, size_t len); 410 411 #endif /* PSA_FRAMEWORK_HAS_MM_IOVEC */ 412 413 #endif /* __PSA_API_H__ */ 414