1 /* 2 * Copyright (c) 2019-2024, Arm Limited. All rights reserved. 3 * Copyright (c) 2022-2023 Cypress Semiconductor Corporation (an Infineon company) 4 * or an affiliate of Cypress Semiconductor Corporation. All rights reserved. 5 * 6 * SPDX-License-Identifier: BSD-3-Clause 7 * 8 */ 9 10 /* 11 * Definitions of Remote Procedure Call (RPC) functionalities in TF-M, which 12 * sits between upper TF-M SPM and underlying mailbox implementation. 13 */ 14 15 #ifndef __TFM_RPC_H__ 16 #define __TFM_RPC_H__ 17 18 #ifdef TFM_PARTITION_NS_AGENT_MAILBOX 19 20 #include <stdint.h> 21 #include "cmsis_compiler.h" 22 #include "psa/client.h" 23 #include "psa/service.h" 24 #include "thread.h" 25 #include "spm.h" 26 #include "ffm/mailbox_agent_api.h" 27 28 #define TFM_RPC_SUCCESS (0) 29 #define TFM_RPC_INVAL_PARAM (INT32_MIN + 1) 30 #define TFM_RPC_CONFLICT_CALLBACK (INT32_MIN + 2) 31 32 /* 33 * The underlying mailbox communication implementation should provide 34 * the specific operations to complete the RPC functionalities. 35 * 36 * It includes the following operations: 37 * handle_req() - Handle PSA client call request from NSPE 38 * reply() - Reply PSA client call return result to NSPE. 39 * The parameter owner identifies the owner of the PSA 40 * client call. 41 * handle_req_irq_src() - Handle PSA client call request from NSPE and identify 42 * mailbox message source according to irq_src. 43 * process_new_msg() - OPTIONAL: Process a message awaiting in the mailbox. 44 * Returns the number messages that have been processed. 45 * If the platform does not use support for Hybrid 46 * Platform, then this handler must be set to NULL. 47 */ 48 struct tfm_rpc_ops_t { 49 void (*handle_req)(void); 50 void (*reply)(const void *owner, int32_t ret); 51 void (*handle_req_irq_src)(uint32_t irq_src); 52 int32_t (*process_new_msg)(uint32_t *nr_msg); 53 }; 54 55 /** 56 * \brief RPC handler for \ref psa_framework_version. 57 * 58 * \return version The version of the PSA Framework implementation 59 * that is providing the runtime services. 60 */ 61 uint32_t tfm_rpc_psa_framework_version(void); 62 63 /** 64 * \brief RPC handler for \ref psa_version. 65 * 66 * \param[in] sid RoT Service identity. 67 * 68 * \retval PSA_VERSION_NONE The RoT Service is not implemented, or the 69 * caller is not permitted to access the service. 70 * \retval > 0 The version of the implemented RoT Service. 71 */ 72 uint32_t tfm_rpc_psa_version(uint32_t sid); 73 74 /** 75 * \brief RPC handler for \ref psa_connect. 76 * 77 * \param[in] sid RoT Service identity. 78 * \param[in] version The version of the RoT Service. 79 * \param[in] ns_client_id Agent representing NS client's identifier. 80 * \param[in] client_data Client data, treated as opaque by SPM. 81 * 82 * \retval PSA_SUCCESS Success. 83 * \retval PSA_CONNECTION_BUSY The SPM cannot make the connection 84 * at the moment. 85 * \retval "Does not return" The RoT Service ID and version are not 86 * supported, or the caller is not permitted to 87 * access the service. 88 */ 89 psa_status_t tfm_rpc_psa_connect(uint32_t sid, 90 uint32_t version, 91 int32_t ns_client_id, 92 const void *client_data); 93 94 /** 95 * \brief RPC handler for \ref psa_call. 96 * 97 * \param[in] handle Handle to the service being accessed. 98 * \param[in] control A composited uint32_t value for controlling purpose, 99 * containing call types, numbers of in/out vectors and 100 * attributes of vectors. 101 * \param[in] params Combines the psa_invec and psa_outvec params 102 * for the psa_call() to be made, as well as 103 * NS agent's client identifier, which is ignored 104 * for connection-based services. 105 * \param[in] client_data_stateless Client data, treated as opaque by SPM. 106 * 107 * \retval PSA_SUCCESS Success. 108 * \retval "Does not return" The call is invalid, one or more of the 109 * following are true: 110 * \arg An invalid handle was passed. 111 * \arg The connection is already handling a request. 112 * \arg An invalid memory reference was provided. 113 * \arg in_num + out_num > PSA_MAX_IOVEC. 114 * \arg The message is unrecognized by the RoT 115 * Service or incorrectly formatted. 116 */ 117 psa_status_t tfm_rpc_psa_call(psa_handle_t handle, uint32_t control, 118 const struct client_params_t *params, 119 const void *client_data_stateless); 120 121 /** 122 * \brief RPC handler for \ref psa_close. 123 * 124 * \param[in] handle A handle to an established connection, or the null handle. 125 * \param[in] ns_client_id NS client's identifier. 126 * 127 * \retval PSA_SUCCESS Success. 128 * \retval "PROGRAMMER ERROR" The call is a PROGRAMMER ERROR if one or more 129 * of the following are true: 130 * \arg An invalid handle was provided that is not 131 * the null handle. 132 * \arg The connection is currently handling a 133 * request. 134 */ 135 psa_status_t tfm_rpc_psa_close(psa_handle_t handle, int32_t ns_client_id); 136 137 /** 138 * \brief Register underlying mailbox communication operations. 139 * 140 * \note Register callbacks handle_req() and reply() 141 * 142 * \param[in] ops_ptr Pointer to the specific operation structure. 143 * 144 * \retval TFM_RPC_SUCCESS Mailbox operations are successfully registered. 145 * \retval Other error code Fail to register mailbox operations. 146 */ 147 int32_t tfm_rpc_register_ops(const struct tfm_rpc_ops_t *ops_ptr); 148 149 /** 150 * \brief Unregister underlying mailbox communication operations. 151 * 152 * Currently one and only one underlying mailbox communication implementation is 153 * allowed in runtime. Thus it is unnecessary to specify the mailbox 154 * communication operation callbacks to be unregistered. 155 * 156 * \param[in] void 157 */ 158 void tfm_rpc_unregister_ops(void); 159 160 /** 161 * \brief Register underlying mailbox communication operations when multiple 162 * mailbox message sources require diverse mailbox message handlings. 163 * 164 * \note Register callbacks handle_req_irq_src() and reply() 165 * 166 * \param[in] ops_ptr Pointer to the specific operation structure. 167 * 168 * \retval TFM_RPC_SUCCESS Mailbox operations are successfully registered. 169 * \retval Other error code Fail to register mailbox operations. 170 */ 171 int32_t tfm_rpc_register_ops_multi_srcs(const struct tfm_rpc_ops_t *ops_ptr); 172 173 /** 174 * \brief Handling PSA client call request 175 * 176 * \param[in] signal The received signal indicating the incoming PSA client 177 * call request 178 */ 179 void tfm_rpc_client_call_handler(psa_signal_t signal); 180 181 #if CONFIG_TFM_SPM_BACKEND_IPC == 1 182 /** 183 * \brief Reply PSA client call return result 184 * 185 * \param[in] void 186 */ 187 void tfm_rpc_client_call_reply(void); 188 #endif /* CONFIG_TFM_SPM_BACKEND_IPC == 1 */ 189 190 /** 191 * \brief Handling PSA client request to process new messages 192 * 193 * \param[out] nr_msg The number of messages processed 194 * 195 * \return The number of messages processed or an error 196 * \retval PSA_SUCCESS The handler processed successfully the request 197 * \retval Other error code The request failed 198 */ 199 int32_t tfm_rpc_client_process_new_msg(uint32_t *nr_msg); 200 201 #endif /* TFM_PARTITION_NS_AGENT_MAILBOX */ 202 #endif /* __TFM_RPC_H__ */ 203