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
20 #if defined(__ICCARM__)
21
22 #pragma required = spm_interface_cross_dispatcher
23
24 #endif
25
26 /* Grab all functions here in one section to avoid fail in long jump */
27 __used
28 __naked
29 __section(".psa_interface_cross_call")
psa_interface_cross_unified_entry(uint32_t a0)30 static uint32_t psa_interface_cross_unified_entry(uint32_t a0)
31 {
32 __asm volatile(
33 #if !defined(__ICCARM__)
34 ".syntax unified \n"
35 #endif
36 "bl spm_interface_cross_dispatcher \n"
37 "pop {r0-r4, pc} \n"
38 );
39 }
40
41 __naked
42 __section(".psa_interface_cross_call")
psa_framework_version_cross(void)43 uint32_t psa_framework_version_cross(void)
44 {
45 __asm volatile(
46 #if !defined(__ICCARM__)
47 ".syntax unified \n"
48 #endif
49 "push {r0-r4, lr} \n"
50 "ldr r0, =tfm_spm_client_psa_framework_version \n"
51 "mov r1, sp \n"
52 "b psa_interface_cross_unified_entry \n"
53 );
54 }
55
56 __naked
57 __section(".psa_interface_cross_call")
psa_version_cross(uint32_t sid)58 uint32_t psa_version_cross(uint32_t sid)
59 {
60 __asm volatile(
61 #if !defined(__ICCARM__)
62 ".syntax unified \n"
63 #endif
64 "push {r0-r4, lr} \n"
65 "ldr r0, =tfm_spm_client_psa_version \n"
66 "mov r1, sp \n"
67 "b psa_interface_cross_unified_entry \n"
68 );
69 }
70
71 __naked
72 __section(".psa_interface_cross_call")
tfm_psa_call_pack_cross(psa_handle_t handle,uint32_t ctrl_param,const psa_invec * in_vec,psa_outvec * out_vec)73 psa_status_t tfm_psa_call_pack_cross(psa_handle_t handle,
74 uint32_t ctrl_param,
75 const psa_invec *in_vec,
76 psa_outvec *out_vec)
77 {
78 __asm volatile(
79 #if !defined(__ICCARM__)
80 ".syntax unified \n"
81 #endif
82 "push {r0-r4, lr} \n"
83 "ldr r0, =tfm_spm_client_psa_call \n"
84 "mov r1, sp \n"
85 "b psa_interface_cross_unified_entry \n"
86 );
87 }
88
89 __naked
90 __section(".psa_interface_cross_call")
psa_wait_cross(psa_signal_t signal_mask,uint32_t timeout)91 psa_signal_t psa_wait_cross(psa_signal_t signal_mask, uint32_t timeout)
92 {
93 __asm volatile(
94 #if !defined(__ICCARM__)
95 ".syntax unified \n"
96 #endif
97 "push {r0-r4, lr} \n"
98 "ldr r0, =tfm_spm_partition_psa_wait \n"
99 "mov r1, sp \n"
100 "b psa_interface_cross_unified_entry \n"
101 );
102 }
103
104 __naked
105 __section(".psa_interface_cross_call")
psa_get_cross(psa_signal_t signal,psa_msg_t * msg)106 psa_status_t psa_get_cross(psa_signal_t signal, psa_msg_t *msg)
107 {
108 __asm volatile(
109 #if !defined(__ICCARM__)
110 ".syntax unified \n"
111 #endif
112 "push {r0-r4, lr} \n"
113 "ldr r0, =tfm_spm_partition_psa_get \n"
114 "mov r1, sp \n"
115 "b psa_interface_cross_unified_entry \n"
116 );
117 }
118
119 __naked
120 __section(".psa_interface_cross_call")
psa_read_cross(psa_handle_t msg_handle,uint32_t invec_idx,void * buffer,size_t num_bytes)121 size_t psa_read_cross(psa_handle_t msg_handle, uint32_t invec_idx,
122 void *buffer, size_t num_bytes)
123 {
124 __asm volatile(
125 #if !defined(__ICCARM__)
126 ".syntax unified \n"
127 #endif
128 "push {r0-r4, lr} \n"
129 "ldr r0, =tfm_spm_partition_psa_read \n"
130 "mov r1, sp \n"
131 "b psa_interface_cross_unified_entry \n"
132 );
133 }
134
135 __naked
136 __section(".psa_interface_cross_call")
psa_skip_cross(psa_handle_t msg_handle,uint32_t invec_idx,size_t num_bytes)137 size_t psa_skip_cross(psa_handle_t msg_handle,
138 uint32_t invec_idx, size_t num_bytes)
139 {
140 __asm volatile(
141 #if !defined(__ICCARM__)
142 ".syntax unified \n"
143 #endif
144 "push {r0-r4, lr} \n"
145 "ldr r0, =tfm_spm_partition_psa_skip \n"
146 "mov r1, sp \n"
147 "b psa_interface_cross_unified_entry \n"
148 );
149 }
150
151 __naked
152 __section(".psa_interface_cross_call")
psa_write_cross(psa_handle_t msg_handle,uint32_t outvec_idx,const void * buffer,size_t num_bytes)153 void psa_write_cross(psa_handle_t msg_handle, uint32_t outvec_idx,
154 const void *buffer, size_t num_bytes)
155 {
156 __asm volatile(
157 #if !defined(__ICCARM__)
158 ".syntax unified \n"
159 #endif
160 "push {r0-r4, lr} \n"
161 "ldr r0, =tfm_spm_partition_psa_write \n"
162 "mov r1, sp \n"
163 "b psa_interface_cross_unified_entry \n"
164 );
165 }
166
167 __naked
168 __section(".psa_interface_cross_call")
psa_reply_cross(psa_handle_t msg_handle,psa_status_t status)169 void psa_reply_cross(psa_handle_t msg_handle, psa_status_t status)
170 {
171 __asm volatile(
172 #if !defined(__ICCARM__)
173 ".syntax unified \n"
174 #endif
175 "push {r0-r4, lr} \n"
176 "ldr r0, =tfm_spm_partition_psa_reply \n"
177 "mov r1, sp \n"
178 "b psa_interface_cross_unified_entry \n"
179 );
180 }
181
182 #if CONFIG_TFM_DOORBELL_API == 1
183 __naked
184 __section(".psa_interface_cross_call")
psa_notify_cross(int32_t partition_id)185 void psa_notify_cross(int32_t partition_id)
186 {
187 __asm volatile(
188 #if !defined(__ICCARM__)
189 ".syntax unified \n"
190 #endif
191 "push {r0-r4, lr} \n"
192 "ldr r0, =tfm_spm_partition_psa_notify \n"
193 "mov r1, sp \n"
194 "b psa_interface_cross_unified_entry \n"
195 );
196 }
197
198 __naked
199 __section(".psa_interface_cross_call")
psa_clear_cross(void)200 void psa_clear_cross(void)
201 {
202 __asm volatile(
203 #if !defined(__ICCARM__)
204 ".syntax unified \n"
205 #endif
206 "push {r0-r4, lr} \n"
207 "ldr r0, =tfm_spm_partition_psa_clear \n"
208 "mov r1, sp \n"
209 "b psa_interface_cross_unified_entry \n"
210 );
211 }
212 #endif /* CONFIG_TFM_DOORBELL_API == 1 */
213
214 __naked
215 __section(".psa_interface_cross_call")
psa_panic_cross(void)216 void psa_panic_cross(void)
217 {
218 __asm volatile(
219 #if !defined(__ICCARM__)
220 ".syntax unified \n"
221 #endif
222 "push {r0-r4, lr} \n"
223 "ldr r0, =tfm_spm_partition_psa_panic \n"
224 "mov r1, sp \n"
225 "b psa_interface_cross_unified_entry \n"
226 );
227 }
228
229 __naked
230 __section(".psa_interface_cross_call")
psa_rot_lifecycle_state_cross(void)231 uint32_t psa_rot_lifecycle_state_cross(void)
232 {
233 __asm volatile(
234 #if !defined(__ICCARM__)
235 ".syntax unified \n"
236 #endif
237 "push {r0-r4, lr} \n"
238 "ldr r0, =tfm_spm_get_lifecycle_state \n"
239 "mov r1, sp \n"
240 "b psa_interface_cross_unified_entry \n"
241 );
242 }
243
244 /* Following PSA APIs are only needed by connection-based services */
245 #if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
246
247 __naked
248 __section(".psa_interface_cross_call")
psa_connect_cross(uint32_t sid,uint32_t version)249 psa_handle_t psa_connect_cross(uint32_t sid, uint32_t version)
250 {
251 __asm volatile(
252 #if !defined(__ICCARM__)
253 ".syntax unified \n"
254 #endif
255 "push {r0-r4, lr} \n"
256 "ldr r0, =tfm_spm_client_psa_connect \n"
257 "mov r1, sp \n"
258 "b psa_interface_cross_unified_entry \n"
259 );
260 }
261
262 __naked
263 __section(".psa_interface_cross_call")
psa_close_cross(psa_handle_t handle)264 void psa_close_cross(psa_handle_t handle)
265 {
266 __asm volatile(
267 #if !defined(__ICCARM__)
268 ".syntax unified \n"
269 #endif
270 "push {r0-r4, lr} \n"
271 "ldr r0, =tfm_spm_client_psa_close \n"
272 "mov r1, sp \n"
273 "b psa_interface_cross_unified_entry \n"
274 );
275 }
276
277 __naked
278 __section(".psa_interface_cross_call")
psa_set_rhandle_cross(psa_handle_t msg_handle,void * rhandle)279 void psa_set_rhandle_cross(psa_handle_t msg_handle, void *rhandle)
280 {
281 __asm volatile(
282 #if !defined(__ICCARM__)
283 ".syntax unified \n"
284 #endif
285 "push {r0-r4, lr} \n"
286 "ldr r0, =tfm_spm_partition_psa_set_rhandle \n"
287 "mov r1, sp \n"
288 "b psa_interface_cross_unified_entry \n"
289 );
290 }
291
292 #endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API */
293
294 #if CONFIG_TFM_FLIH_API == 1 || CONFIG_TFM_SLIH_API == 1
295 __naked
296 __section(".psa_interface_cross_call")
psa_irq_enable_cross(psa_signal_t irq_signal)297 void psa_irq_enable_cross(psa_signal_t irq_signal)
298 {
299 __asm volatile(
300 #if !defined(__ICCARM__)
301 ".syntax unified \n"
302 #endif
303 "push {r0-r4, lr} \n"
304 "ldr r0, =tfm_spm_partition_psa_irq_enable \n"
305 "mov r1, sp \n"
306 "b psa_interface_cross_unified_entry \n"
307 );
308 }
309
310 __naked
311 __section(".psa_interface_cross_call")
psa_irq_disable_cross(psa_signal_t irq_signal)312 psa_irq_status_t psa_irq_disable_cross(psa_signal_t irq_signal)
313 {
314 __asm volatile(
315 #if !defined(__ICCARM__)
316 ".syntax unified \n"
317 #endif
318 "push {r0-r4, lr} \n"
319 "ldr r0, =tfm_spm_partition_psa_irq_disable \n"
320 "mov r1, sp \n"
321 "b psa_interface_cross_unified_entry \n"
322 );
323 }
324
325 /* This API is only used for FLIH. */
326 #if CONFIG_TFM_FLIH_API == 1
327 __naked
328 __section(".psa_interface_cross_call")
psa_reset_signal_cross(psa_signal_t irq_signal)329 void psa_reset_signal_cross(psa_signal_t irq_signal)
330 {
331 __asm volatile(
332 #if !defined(__ICCARM__)
333 ".syntax unified \n"
334 #endif
335 "push {r0-r4, lr} \n"
336 "ldr r0, =tfm_spm_partition_psa_reset_signal \n"
337 "mov r1, sp \n"
338 "b psa_interface_cross_unified_entry \n"
339 );
340 }
341 #endif /* CONFIG_TFM_FLIH_API == 1 */
342
343 /* This API is only used for SLIH. */
344 #if CONFIG_TFM_SLIH_API == 1
345 __naked
346 __section(".psa_interface_cross_call")
psa_eoi_cross(psa_signal_t irq_signal)347 void psa_eoi_cross(psa_signal_t irq_signal)
348 {
349 __asm volatile(
350 #if !defined(__ICCARM__)
351 ".syntax unified \n"
352 #endif
353 "push {r0-r4, lr} \n"
354 "ldr r0, =tfm_spm_partition_psa_eoi \n"
355 "mov r1, sp \n"
356 "b psa_interface_cross_unified_entry \n"
357 );
358 }
359 #endif /* CONFIG_TFM_SLIH_API */
360 #endif /* CONFIG_TFM_FLIH_API == 1 || CONFIG_TFM_SLIH_API == 1 */
361
362 #if PSA_FRAMEWORK_HAS_MM_IOVEC
363
364 __naked
365 __section(".psa_interface_cross_call")
psa_map_invec_cross(psa_handle_t msg_handle,uint32_t invec_idx)366 const void *psa_map_invec_cross(psa_handle_t msg_handle, uint32_t invec_idx)
367 {
368 __asm volatile(
369 #if !defined(__ICCARM__)
370 ".syntax unified \n"
371 #endif
372 "push {r0-r4, lr} \n"
373 "ldr r0, =tfm_spm_partition_psa_map_invec \n"
374 "mov r1, sp \n"
375 "b psa_interface_cross_unified_entry \n"
376 );
377 }
378
379 __naked
380 __section(".psa_interface_cross_call")
psa_unmap_invec_cross(psa_handle_t msg_handle,uint32_t invec_idx)381 void psa_unmap_invec_cross(psa_handle_t msg_handle, uint32_t invec_idx)
382 {
383 __asm volatile(
384 #if !defined(__ICCARM__)
385 ".syntax unified \n"
386 #endif
387 "push {r0-r4, lr} \n"
388 "ldr r0, =tfm_spm_partition_psa_unmap_invec \n"
389 "mov r1, sp \n"
390 "b psa_interface_cross_unified_entry \n"
391 );
392 }
393
394 __naked
395 __section(".psa_interface_cross_call")
psa_map_outvec_cross(psa_handle_t msg_handle,uint32_t outvec_idx)396 void *psa_map_outvec_cross(psa_handle_t msg_handle, uint32_t outvec_idx)
397 {
398 __asm volatile(
399 #if !defined(__ICCARM__)
400 ".syntax unified \n"
401 #endif
402 "push {r0-r4, lr} \n"
403 "ldr r0, =tfm_spm_partition_psa_map_outvec \n"
404 "mov r1, sp \n"
405 "b psa_interface_cross_unified_entry \n"
406 );
407 }
408
409 __naked
410 __section(".psa_interface_cross_call")
psa_unmap_outvec_cross(psa_handle_t msg_handle,uint32_t outvec_idx,size_t len)411 void psa_unmap_outvec_cross(psa_handle_t msg_handle, uint32_t outvec_idx,
412 size_t len)
413 {
414 __asm volatile(
415 #if !defined(__ICCARM__)
416 ".syntax unified \n"
417 #endif
418 "push {r0-r4, lr} \n"
419 "ldr r0, =tfm_spm_partition_psa_unmap_outvec \n"
420 "mov r1, sp \n"
421 "b psa_interface_cross_unified_entry \n"
422 );
423 }
424
425 #endif /* PSA_FRAMEWORK_HAS_MM_IOVEC */
426
427 const struct psa_api_tbl_t psa_api_cross = {
428 tfm_psa_call_pack_cross,
429 psa_version_cross,
430 psa_framework_version_cross,
431 psa_wait_cross,
432 psa_get_cross,
433 psa_read_cross,
434 psa_skip_cross,
435 psa_write_cross,
436 psa_reply_cross,
437 psa_panic_cross,
438 psa_rot_lifecycle_state_cross,
439 #if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
440 psa_connect_cross,
441 psa_close_cross,
442 psa_set_rhandle_cross,
443 #endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API */
444 #if CONFIG_TFM_DOORBELL_API == 1
445 psa_notify_cross,
446 psa_clear_cross,
447 #endif /* CONFIG_TFM_DOORBELL_API == 1 */
448 #if CONFIG_TFM_FLIH_API == 1 || CONFIG_TFM_SLIH_API == 1
449 psa_irq_enable_cross,
450 psa_irq_disable_cross,
451 #if CONFIG_TFM_FLIH_API == 1
452 psa_reset_signal_cross,
453 #endif /* CONFIG_TFM_FLIH_API == 1 */
454 #if CONFIG_TFM_SLIH_API == 1
455 psa_eoi_cross,
456 #endif /* CONFIG_TFM_SLIH_API == 1 */
457 #endif /* CONFIG_TFM_FLIH_API == 1 || CONFIG_TFM_SLIH_API == 1 */
458 #if PSA_FRAMEWORK_HAS_MM_IOVEC
459 psa_map_invec_cross,
460 psa_unmap_invec_cross,
461 psa_map_outvec_cross,
462 psa_unmap_outvec_cross,
463 #endif /* PSA_FRAMEWORK_HAS_MM_IOVEC */
464 };
465