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