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