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