1 /*
2 * Copyright (c) 2021-2024, 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
psa_framework_version_thread_fn_call(void)39 uint32_t psa_framework_version_thread_fn_call(void)
40 {
41 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_client_psa_framework_version);
42 }
43
44 __naked
psa_version_thread_fn_call(uint32_t sid)45 uint32_t psa_version_thread_fn_call(uint32_t sid)
46 {
47 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_client_psa_version);
48 }
49
50 __naked
tfm_psa_call_pack_thread_fn_call(psa_handle_t handle,uint32_t ctrl_param,const psa_invec * in_vec,psa_outvec * out_vec)51 psa_status_t tfm_psa_call_pack_thread_fn_call(psa_handle_t handle,
52 uint32_t ctrl_param,
53 const psa_invec *in_vec,
54 psa_outvec *out_vec)
55 {
56 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_client_psa_call);
57 }
58
59 __naked
psa_wait_thread_fn_call(psa_signal_t signal_mask,uint32_t timeout)60 psa_signal_t psa_wait_thread_fn_call(psa_signal_t signal_mask, uint32_t timeout)
61 {
62 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_wait);
63 }
64
65 __naked
psa_get_thread_fn_call(psa_signal_t signal,psa_msg_t * msg)66 psa_status_t psa_get_thread_fn_call(psa_signal_t signal, psa_msg_t *msg)
67 {
68 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_get);
69 }
70
71 __naked
psa_read_thread_fn_call(psa_handle_t msg_handle,uint32_t invec_idx,void * buffer,size_t num_bytes)72 size_t psa_read_thread_fn_call(psa_handle_t msg_handle, uint32_t invec_idx,
73 void *buffer, size_t num_bytes)
74 {
75 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_read);
76 }
77
78 __naked
psa_skip_thread_fn_call(psa_handle_t msg_handle,uint32_t invec_idx,size_t num_bytes)79 size_t psa_skip_thread_fn_call(psa_handle_t msg_handle,
80 uint32_t invec_idx, size_t num_bytes)
81 {
82 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_skip);
83 }
84
85 __naked
psa_write_thread_fn_call(psa_handle_t msg_handle,uint32_t outvec_idx,const void * buffer,size_t num_bytes)86 void psa_write_thread_fn_call(psa_handle_t msg_handle, uint32_t outvec_idx,
87 const void *buffer, size_t num_bytes)
88 {
89 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_write);
90 }
91
92 __naked
psa_reply_thread_fn_call(psa_handle_t msg_handle,psa_status_t status)93 void psa_reply_thread_fn_call(psa_handle_t msg_handle, psa_status_t status)
94 {
95 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_reply);
96 }
97
98 #if CONFIG_TFM_DOORBELL_API == 1
99 __naked
psa_notify_thread_fn_call(int32_t partition_id)100 void psa_notify_thread_fn_call(int32_t partition_id)
101 {
102 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_notify);
103 }
104
105 __naked
psa_clear_thread_fn_call(void)106 void psa_clear_thread_fn_call(void)
107 {
108 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_clear);
109 }
110 #endif /* CONFIG_TFM_DOORBELL_API == 1 */
111
112 __naked
psa_panic_thread_fn_call(void)113 void psa_panic_thread_fn_call(void)
114 {
115 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_panic);
116 }
117
118 __naked
psa_rot_lifecycle_state_thread_fn_call(void)119 uint32_t psa_rot_lifecycle_state_thread_fn_call(void)
120 {
121 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_get_lifecycle_state);
122 }
123
124 /* Following PSA APIs are only needed by connection-based services */
125 #if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
126
127 __naked
psa_connect_thread_fn_call(uint32_t sid,uint32_t version)128 psa_handle_t psa_connect_thread_fn_call(uint32_t sid, uint32_t version)
129 {
130 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_client_psa_connect);
131 }
132
133 __naked
psa_close_thread_fn_call(psa_handle_t handle)134 void psa_close_thread_fn_call(psa_handle_t handle)
135 {
136 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_client_psa_close);
137 }
138
139 __naked
psa_set_rhandle_thread_fn_call(psa_handle_t msg_handle,void * rhandle)140 void psa_set_rhandle_thread_fn_call(psa_handle_t msg_handle, void *rhandle)
141 {
142 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_set_rhandle);
143 }
144
145 #endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API */
146
147 #if (CONFIG_TFM_FLIH_API == 1) || (CONFIG_TFM_SLIH_API == 1)
148 __naked
psa_irq_enable_thread_fn_call(psa_signal_t irq_signal)149 void psa_irq_enable_thread_fn_call(psa_signal_t irq_signal)
150 {
151 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_irq_enable);
152 }
153
154 __naked
psa_irq_disable_thread_fn_call(psa_signal_t irq_signal)155 psa_irq_status_t psa_irq_disable_thread_fn_call(psa_signal_t irq_signal)
156 {
157 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_irq_disable);
158 }
159
160 /* This API is only used for FLIH. */
161 #if CONFIG_TFM_FLIH_API == 1
162 __naked
psa_reset_signal_thread_fn_call(psa_signal_t irq_signal)163 void psa_reset_signal_thread_fn_call(psa_signal_t irq_signal)
164 {
165 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_reset_signal);
166 }
167 #endif /* CONFIG_TFM_FLIH_API == 1 */
168
169 /* This API is only used for SLIH. */
170 #if CONFIG_TFM_SLIH_API == 1
171 __naked
psa_eoi_thread_fn_call(psa_signal_t irq_signal)172 void psa_eoi_thread_fn_call(psa_signal_t irq_signal)
173 {
174 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_eoi);
175 }
176 #endif /* CONFIG_TFM_SLIH_API */
177 #endif /* CONFIG_TFM_FLIH_API == 1 || CONFIG_TFM_SLIH_API == 1 */
178
179 #if PSA_FRAMEWORK_HAS_MM_IOVEC
180
181 __naked
psa_map_invec_thread_fn_call(psa_handle_t msg_handle,uint32_t invec_idx)182 const void *psa_map_invec_thread_fn_call(psa_handle_t msg_handle, uint32_t invec_idx)
183 {
184 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_map_invec);
185 }
186
187 __naked
psa_unmap_invec_thread_fn_call(psa_handle_t msg_handle,uint32_t invec_idx)188 void psa_unmap_invec_thread_fn_call(psa_handle_t msg_handle, uint32_t invec_idx)
189 {
190 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_unmap_invec);
191 }
192
193 __naked
psa_map_outvec_thread_fn_call(psa_handle_t msg_handle,uint32_t outvec_idx)194 void *psa_map_outvec_thread_fn_call(psa_handle_t msg_handle, uint32_t outvec_idx)
195 {
196 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_map_outvec);
197 }
198
199 __naked
psa_unmap_outvec_thread_fn_call(psa_handle_t msg_handle,uint32_t outvec_idx,size_t len)200 void psa_unmap_outvec_thread_fn_call(psa_handle_t msg_handle, uint32_t outvec_idx,
201 size_t len)
202 {
203 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_partition_psa_unmap_outvec);
204 }
205
206 #endif /* PSA_FRAMEWORK_HAS_MM_IOVEC */
207
208 #ifdef TFM_PARTITION_NS_AGENT_MAILBOX
209 __naked
agent_psa_call_thread_fn_call(psa_handle_t handle,uint32_t control,const struct client_params_t * params,const void * client_data_stateless)210 psa_status_t agent_psa_call_thread_fn_call(psa_handle_t handle,
211 uint32_t control,
212 const struct client_params_t *params,
213 const void *client_data_stateless)
214 {
215 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_agent_psa_call);
216 }
217
218 #if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
219 __naked
agent_psa_connect_thread_fn_call(uint32_t sid,uint32_t version,int32_t ns_client_id,const void * client_data)220 psa_handle_t agent_psa_connect_thread_fn_call(uint32_t sid, uint32_t version,
221 int32_t ns_client_id,
222 const void *client_data)
223 {
224 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_agent_psa_connect);
225 }
226
227 __naked
agent_psa_close_thread_fn_call(psa_handle_t handle,int32_t ns_client_id)228 psa_status_t agent_psa_close_thread_fn_call(psa_handle_t handle, int32_t ns_client_id)
229 {
230 TFM_THREAD_FN_CALL_ENTRY(tfm_spm_agent_psa_close);
231 }
232 #endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1 */
233 #endif /* TFM_PARTITION_NS_AGENT_MAILBOX */
234
235 const struct psa_api_tbl_t psa_api_thread_fn_call = {
236 tfm_psa_call_pack_thread_fn_call,
237 psa_version_thread_fn_call,
238 psa_framework_version_thread_fn_call,
239 psa_wait_thread_fn_call,
240 psa_get_thread_fn_call,
241 psa_read_thread_fn_call,
242 psa_skip_thread_fn_call,
243 psa_write_thread_fn_call,
244 psa_reply_thread_fn_call,
245 psa_panic_thread_fn_call,
246 psa_rot_lifecycle_state_thread_fn_call,
247 #if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
248 psa_connect_thread_fn_call,
249 psa_close_thread_fn_call,
250 psa_set_rhandle_thread_fn_call,
251 #endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API */
252 #if CONFIG_TFM_DOORBELL_API == 1
253 psa_notify_thread_fn_call,
254 psa_clear_thread_fn_call,
255 #endif /* CONFIG_TFM_DOORBELL_API == 1 */
256 #if (CONFIG_TFM_FLIH_API == 1) || (CONFIG_TFM_SLIH_API == 1)
257 psa_irq_enable_thread_fn_call,
258 psa_irq_disable_thread_fn_call,
259 #if CONFIG_TFM_FLIH_API == 1
260 psa_reset_signal_thread_fn_call,
261 #endif /* CONFIG_TFM_FLIH_API == 1 */
262 #if CONFIG_TFM_SLIH_API == 1
263 psa_eoi_thread_fn_call,
264 #endif /* CONFIG_TFM_SLIH_API == 1 */
265 #endif /* CONFIG_TFM_FLIH_API == 1 || CONFIG_TFM_SLIH_API == 1 */
266 #if PSA_FRAMEWORK_HAS_MM_IOVEC
267 psa_map_invec_thread_fn_call,
268 psa_unmap_invec_thread_fn_call,
269 psa_map_outvec_thread_fn_call,
270 psa_unmap_outvec_thread_fn_call,
271 #endif /* PSA_FRAMEWORK_HAS_MM_IOVEC */
272 #ifdef TFM_PARTITION_NS_AGENT_MAILBOX
273 agent_psa_call_thread_fn_call,
274 #if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
275 agent_psa_connect_thread_fn_call,
276 agent_psa_close_thread_fn_call,
277 #endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1 */
278 #endif /* TFM_PARTITION_NS_AGENT_MAILBOX */
279 };
280