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