1 /*
2 * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include <stdint.h>
9 #include "compiler_ext_defs.h"
10 #include "config_spm.h"
11 #include "ffm/psa_api.h"
12 #include "spm.h"
13 #include "svc_num.h"
14 #include "tfm_psa_call_pack.h"
15 #include "psa/client.h"
16 #include "psa/lifecycle.h"
17 #include "psa/service.h"
18 #include "runtime_defs.h"
19 #include "tfm_arch.h"
20
21 #if defined(__ICCARM__)
22 #pragma required = tfm_arch_thread_fn_call
23 #endif
24
25 /*
26 * Restore target psa api to R12 and step to tfm_arch_thread_fn_call.
27 */
28 #define TFM_THREAD_FN_CALL_ENTRY(target_psa_api) \
29 __asm volatile( \
30 SYNTAX_UNIFIED \
31 "push {r4, lr} \n" \
32 "ldr r4, ="M2S(target_psa_api)" \n" \
33 "mov r12, r4 \n" \
34 "bl tfm_arch_thread_fn_call \n" \
35 "pop {r4, pc} \n" \
36 )
37
38 __naked
39 __section(".psa_interface_thread_fn_call")
psa_framework_version_thread_fn_call(void)40 uint32_t psa_framework_version_thread_fn_call(void)
41 {
42 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_client_psa_framework_version);
43 }
44
45 __naked
46 __section(".psa_interface_thread_fn_call")
psa_version_thread_fn_call(uint32_t sid)47 uint32_t psa_version_thread_fn_call(uint32_t sid)
48 {
49 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_client_psa_version);
50 }
51
52 __naked
53 __section(".psa_interface_thread_fn_call")
tfm_psa_call_pack_thread_fn_call(psa_handle_t handle,uint32_t ctrl_param,const psa_invec * in_vec,psa_outvec * out_vec)54 psa_status_t tfm_psa_call_pack_thread_fn_call(psa_handle_t handle,
55 uint32_t ctrl_param,
56 const psa_invec *in_vec,
57 psa_outvec *out_vec)
58 {
59 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_client_psa_call);
60 }
61
62 __naked
63 __section(".psa_interface_thread_fn_call")
psa_wait_thread_fn_call(psa_signal_t signal_mask,uint32_t timeout)64 psa_signal_t psa_wait_thread_fn_call(psa_signal_t signal_mask, uint32_t timeout)
65 {
66 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_wait);
67 }
68
69 __naked
70 __section(".psa_interface_thread_fn_call")
psa_get_thread_fn_call(psa_signal_t signal,psa_msg_t * msg)71 psa_status_t psa_get_thread_fn_call(psa_signal_t signal, psa_msg_t *msg)
72 {
73 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_get);
74 }
75
76 __naked
77 __section(".psa_interface_thread_fn_call")
psa_read_thread_fn_call(psa_handle_t msg_handle,uint32_t invec_idx,void * buffer,size_t num_bytes)78 size_t psa_read_thread_fn_call(psa_handle_t msg_handle, uint32_t invec_idx,
79 void *buffer, size_t num_bytes)
80 {
81 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_read);
82 }
83
84 __naked
85 __section(".psa_interface_thread_fn_call")
psa_skip_thread_fn_call(psa_handle_t msg_handle,uint32_t invec_idx,size_t num_bytes)86 size_t psa_skip_thread_fn_call(psa_handle_t msg_handle,
87 uint32_t invec_idx, size_t num_bytes)
88 {
89 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_skip);
90 }
91
92 __naked
93 __section(".psa_interface_thread_fn_call")
psa_write_thread_fn_call(psa_handle_t msg_handle,uint32_t outvec_idx,const void * buffer,size_t num_bytes)94 void psa_write_thread_fn_call(psa_handle_t msg_handle, uint32_t outvec_idx,
95 const void *buffer, size_t num_bytes)
96 {
97 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_write);
98 }
99
100 __naked
101 __section(".psa_interface_thread_fn_call")
psa_reply_thread_fn_call(psa_handle_t msg_handle,psa_status_t status)102 void psa_reply_thread_fn_call(psa_handle_t msg_handle, psa_status_t status)
103 {
104 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_reply);
105 }
106
107 #if CONFIG_TFM_DOORBELL_API == 1
108 __naked
109 __section(".psa_interface_thread_fn_call")
psa_notify_thread_fn_call(int32_t partition_id)110 void psa_notify_thread_fn_call(int32_t partition_id)
111 {
112 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_notify);
113 }
114
115 __naked
116 __section(".psa_interface_thread_fn_call")
psa_clear_thread_fn_call(void)117 void psa_clear_thread_fn_call(void)
118 {
119 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_clear);
120 }
121 #endif /* CONFIG_TFM_DOORBELL_API == 1 */
122
123 __naked
124 __section(".psa_interface_thread_fn_call")
psa_panic_thread_fn_call(void)125 void psa_panic_thread_fn_call(void)
126 {
127 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_panic);
128 }
129
130 __naked
131 __section(".psa_interface_thread_fn_call")
psa_rot_lifecycle_state_thread_fn_call(void)132 uint32_t psa_rot_lifecycle_state_thread_fn_call(void)
133 {
134 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_get_lifecycle_state);
135 }
136
137 /* Following PSA APIs are only needed by connection-based services */
138 #if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
139
140 __naked
141 __section(".psa_interface_thread_fn_call")
psa_connect_thread_fn_call(uint32_t sid,uint32_t version)142 psa_handle_t psa_connect_thread_fn_call(uint32_t sid, uint32_t version)
143 {
144 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_client_psa_connect);
145 }
146
147 __naked
148 __section(".psa_interface_thread_fn_call")
psa_close_thread_fn_call(psa_handle_t handle)149 void psa_close_thread_fn_call(psa_handle_t handle)
150 {
151 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_client_psa_close);
152 }
153
154 __naked
155 __section(".psa_interface_thread_fn_call")
psa_set_rhandle_thread_fn_call(psa_handle_t msg_handle,void * rhandle)156 void psa_set_rhandle_thread_fn_call(psa_handle_t msg_handle, void *rhandle)
157 {
158 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_set_rhandle);
159 }
160
161 #endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API */
162
163 #if CONFIG_TFM_FLIH_API == 1 || CONFIG_TFM_SLIH_API == 1
164 __naked
165 __section(".psa_interface_thread_fn_call")
psa_irq_enable_thread_fn_call(psa_signal_t irq_signal)166 void psa_irq_enable_thread_fn_call(psa_signal_t irq_signal)
167 {
168 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_irq_enable);
169 }
170
171 __naked
172 __section(".psa_interface_thread_fn_call")
psa_irq_disable_thread_fn_call(psa_signal_t irq_signal)173 psa_irq_status_t psa_irq_disable_thread_fn_call(psa_signal_t irq_signal)
174 {
175 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_irq_disable);
176 }
177
178 /* This API is only used for FLIH. */
179 #if CONFIG_TFM_FLIH_API == 1
180 __naked
181 __section(".psa_interface_thread_fn_call")
psa_reset_signal_thread_fn_call(psa_signal_t irq_signal)182 void psa_reset_signal_thread_fn_call(psa_signal_t irq_signal)
183 {
184 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_reset_signal);
185 }
186 #endif /* CONFIG_TFM_FLIH_API == 1 */
187
188 /* This API is only used for SLIH. */
189 #if CONFIG_TFM_SLIH_API == 1
190 __naked
191 __section(".psa_interface_thread_fn_call")
psa_eoi_thread_fn_call(psa_signal_t irq_signal)192 void psa_eoi_thread_fn_call(psa_signal_t irq_signal)
193 {
194 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_eoi);
195 }
196 #endif /* CONFIG_TFM_SLIH_API */
197 #endif /* CONFIG_TFM_FLIH_API == 1 || CONFIG_TFM_SLIH_API == 1 */
198
199 #if PSA_FRAMEWORK_HAS_MM_IOVEC
200
201 __naked
202 __section(".psa_interface_thread_fn_call")
psa_map_invec_thread_fn_call(psa_handle_t msg_handle,uint32_t invec_idx)203 const void *psa_map_invec_thread_fn_call(psa_handle_t msg_handle, uint32_t invec_idx)
204 {
205 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_map_invec);
206 }
207
208 __naked
209 __section(".psa_interface_thread_fn_call")
psa_unmap_invec_thread_fn_call(psa_handle_t msg_handle,uint32_t invec_idx)210 void psa_unmap_invec_thread_fn_call(psa_handle_t msg_handle, uint32_t invec_idx)
211 {
212 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_unmap_invec);
213 }
214
215 __naked
216 __section(".psa_interface_thread_fn_call")
psa_map_outvec_thread_fn_call(psa_handle_t msg_handle,uint32_t outvec_idx)217 void *psa_map_outvec_thread_fn_call(psa_handle_t msg_handle, uint32_t outvec_idx)
218 {
219 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_map_outvec);
220 }
221
222 __naked
223 __section(".psa_interface_thread_fn_call")
psa_unmap_outvec_thread_fn_call(psa_handle_t msg_handle,uint32_t outvec_idx,size_t len)224 void psa_unmap_outvec_thread_fn_call(psa_handle_t msg_handle, uint32_t outvec_idx,
225 size_t len)
226 {
227 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_unmap_outvec);
228 }
229
230 #endif /* PSA_FRAMEWORK_HAS_MM_IOVEC */
231
232 #ifdef TFM_PARTITION_NS_AGENT_MAILBOX
233 __naked
234 __section(".psa_interface_thread_fn_call")
agent_psa_call_thread_fn_call(psa_handle_t handle,uint32_t control,const struct client_params_t * params,const void * client_data_stateless)235 psa_status_t agent_psa_call_thread_fn_call(psa_handle_t handle,
236 uint32_t control,
237 const struct client_params_t *params,
238 const void *client_data_stateless)
239 {
240 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_agent_psa_call);
241 }
242
243 #if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
244 __naked
245 __section(".psa_interface_thread_fn_call")
agent_psa_connect_thread_fn_call(uint32_t sid,uint32_t version,int32_t ns_client_id,const void * client_data)246 psa_handle_t agent_psa_connect_thread_fn_call(uint32_t sid, uint32_t version,
247 int32_t ns_client_id,
248 const void *client_data)
249 {
250 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_agent_psa_connect);
251 }
252 #endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1 */
253 #endif /* TFM_PARTITION_NS_AGENT_MAILBOX */
254
255 const struct psa_api_tbl_t psa_api_thread_fn_call = {
256 tfm_psa_call_pack_thread_fn_call,
257 psa_version_thread_fn_call,
258 psa_framework_version_thread_fn_call,
259 psa_wait_thread_fn_call,
260 psa_get_thread_fn_call,
261 psa_read_thread_fn_call,
262 psa_skip_thread_fn_call,
263 psa_write_thread_fn_call,
264 psa_reply_thread_fn_call,
265 psa_panic_thread_fn_call,
266 psa_rot_lifecycle_state_thread_fn_call,
267 #if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
268 psa_connect_thread_fn_call,
269 psa_close_thread_fn_call,
270 psa_set_rhandle_thread_fn_call,
271 #endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API */
272 #if CONFIG_TFM_DOORBELL_API == 1
273 psa_notify_thread_fn_call,
274 psa_clear_thread_fn_call,
275 #endif /* CONFIG_TFM_DOORBELL_API == 1 */
276 #if CONFIG_TFM_FLIH_API == 1 || CONFIG_TFM_SLIH_API == 1
277 psa_irq_enable_thread_fn_call,
278 psa_irq_disable_thread_fn_call,
279 #if CONFIG_TFM_FLIH_API == 1
280 psa_reset_signal_thread_fn_call,
281 #endif /* CONFIG_TFM_FLIH_API == 1 */
282 #if CONFIG_TFM_SLIH_API == 1
283 psa_eoi_thread_fn_call,
284 #endif /* CONFIG_TFM_SLIH_API == 1 */
285 #endif /* CONFIG_TFM_FLIH_API == 1 || CONFIG_TFM_SLIH_API == 1 */
286 #if PSA_FRAMEWORK_HAS_MM_IOVEC
287 psa_map_invec_thread_fn_call,
288 psa_unmap_invec_thread_fn_call,
289 psa_map_outvec_thread_fn_call,
290 psa_unmap_outvec_thread_fn_call,
291 #endif /* PSA_FRAMEWORK_HAS_MM_IOVEC */
292 #ifdef TFM_PARTITION_NS_AGENT_MAILBOX
293 agent_psa_call_thread_fn_call,
294 #if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
295 agent_psa_connect_thread_fn_call,
296 #endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1 */
297 #endif /* TFM_PARTITION_NS_AGENT_MAILBOX */
298 };
299