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. The parameter
39  *                owner identifies the owner of the PSA client call.
40  */
41 struct tfm_rpc_ops_t {
42     void (*handle_req)(void);
43     void (*reply)(const void *owner, int32_t ret);
44 };
45 
46 /**
47  * \brief RPC handler for \ref psa_framework_version.
48  *
49  * \return version              The version of the PSA Framework implementation
50  *                              that is providing the runtime services.
51  */
52 uint32_t tfm_rpc_psa_framework_version(void);
53 
54 /**
55  * \brief RPC handler for \ref psa_version.
56  *
57  * \param[in] sid               RoT Service identity.
58  *
59  * \retval PSA_VERSION_NONE     The RoT Service is not implemented, or the
60  *                              caller is not permitted to access the service.
61  * \retval > 0                  The version of the implemented RoT Service.
62  */
63 uint32_t tfm_rpc_psa_version(uint32_t sid);
64 
65 /**
66  * \brief RPC handler for \ref psa_connect.
67  *
68  * \param[in] sid               RoT Service identity.
69  * \param[in] version           The version of the RoT Service.
70  * \param[in] ns_client_id      Agent representing NS client's identifier.
71  * \param[in] client_data       Client data, treated as opaque by SPM.
72  *
73  * \retval PSA_SUCCESS          Success.
74  * \retval PSA_CONNECTION_BUSY  The SPM cannot make the connection
75  *                              at the moment.
76  * \retval "Does not return"    The RoT Service ID and version are not
77  *                              supported, or the caller is not permitted to
78  *                              access the service.
79  */
80 psa_status_t tfm_rpc_psa_connect(uint32_t sid,
81                                  uint32_t version,
82                                  int32_t ns_client_id,
83                                  const void *client_data);
84 
85 /**
86  * \brief RPC handler for \ref psa_call.
87  *
88  * \param[in] handle                 Handle to the service being accessed.
89  * \param[in] control                A composited uint32_t value for controlling purpose,
90  *                                   containing call types, numbers of in/out vectors and
91  *                                   attributes of vectors.
92  * \param[in] params                 Combines the psa_invec and psa_outvec params
93  *                                   for the psa_call() to be made, as well as
94  *                                   NS agent's client identifier, which is ignored
95  *                                   for connection-based services.
96  * \param[in] client_data_stateless  Client data, treated as opaque by SPM.
97  *
98  * \retval PSA_SUCCESS               Success.
99  * \retval "Does not return"         The call is invalid, one or more of the
100  *                                   following are true:
101  * \arg                                An invalid handle was passed.
102  * \arg                                The connection is already handling a request.
103  * \arg                                An invalid memory reference was provided.
104  * \arg                                in_num + out_num > PSA_MAX_IOVEC.
105  * \arg                                The message is unrecognized by the RoT
106  *                                     Service or incorrectly formatted.
107  */
108 psa_status_t tfm_rpc_psa_call(psa_handle_t handle, uint32_t control,
109                               const struct client_params_t *params,
110                               const void *client_data_stateless);
111 
112 /**
113  * \brief RPC handler for \ref psa_close.
114  *
115  * \param[in] handle            A handle to an established connection, or the null handle.
116  * \param[in] ns_client_id      NS client's identifier.
117  *
118  * \retval PSA_SUCCESS          Success.
119  * \retval "PROGRAMMER ERROR"   The call is a PROGRAMMER ERROR if one or more
120  *                              of the following are true:
121  * \arg                           An invalid handle was provided that is not
122  *                                the null handle.
123  * \arg                           The connection is currently handling a
124  *                                request.
125  */
126 psa_status_t tfm_rpc_psa_close(psa_handle_t handle, int32_t ns_client_id);
127 
128 /**
129  * \brief Register underlying mailbox communication operations.
130  *
131  * \param[in] ops_ptr           Pointer to the specific operation structure.
132  *
133  * \retval TFM_RPC_SUCCESS      Mailbox operations are successfully registered.
134  * \retval Other error code     Fail to register mailbox operations.
135  */
136 int32_t tfm_rpc_register_ops(const struct tfm_rpc_ops_t *ops_ptr);
137 
138 /**
139  * \brief Unregister underlying mailbox communication operations.
140  *
141  * Currently one and only one underlying mailbox communication implementation is
142  * allowed in runtime. Thus it is unnecessary to specify the mailbox
143  * communication operation callbacks to be unregistered.
144  *
145  * \param[in] void
146  */
147 void tfm_rpc_unregister_ops(void);
148 
149 /**
150  * \brief Handling PSA client call request
151  *
152  * \param void
153  */
154 void tfm_rpc_client_call_handler(void);
155 
156 #if CONFIG_TFM_SPM_BACKEND_IPC == 1
157 /**
158  * \brief Reply PSA client call return result
159  *
160  * \param[in] void
161  */
162 void tfm_rpc_client_call_reply(void);
163 #endif /* CONFIG_TFM_SPM_BACKEND_IPC == 1 */
164 
165 #endif /* TFM_PARTITION_NS_AGENT_MAILBOX */
166 #endif /* __TFM_RPC_H__ */
167