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 "current.h"
10 #include "tfm_psa_call_pack.h"
11 #include "ffm/backend.h"
12 #include "ffm/psa_api.h"
13 #include "psa/client.h"
14
psa_framework_version_sfn(void)15 uint32_t psa_framework_version_sfn(void)
16 {
17 if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
18 /* PSA APIs must be called from Thread mode */
19 tfm_core_panic();
20 }
21
22 return tfm_spm_client_psa_framework_version();
23 }
24
psa_version_sfn(uint32_t sid)25 uint32_t psa_version_sfn(uint32_t sid)
26 {
27 if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
28 /* PSA APIs must be called from Thread mode */
29 tfm_core_panic();
30 }
31
32 return tfm_spm_client_psa_version(sid);
33 }
34
psa_call_pack_sfn(psa_handle_t handle,uint32_t ctrl_param,const psa_invec * in_vec,psa_outvec * out_vec)35 psa_status_t psa_call_pack_sfn(psa_handle_t handle, uint32_t ctrl_param,
36 const psa_invec *in_vec, psa_outvec *out_vec)
37 {
38 struct partition_t *p_client, *p_target;
39 psa_status_t stat;
40
41 if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
42 /* PSA APIs must be called from Thread mode */
43 tfm_core_panic();
44 }
45
46 p_client = GET_CURRENT_COMPONENT();
47
48 stat = tfm_spm_client_psa_call(handle, ctrl_param, in_vec, out_vec);
49
50 p_target = GET_CURRENT_COMPONENT();
51 if (p_client != p_target) {
52 /* Execution is returned from RoT Service */
53 stat = tfm_spm_partition_psa_reply(p_target->p_handles->msg.handle,
54 stat);
55 } else {
56 /* Execution is returned from SPM */
57 spm_handle_programmer_errors(stat);
58 }
59
60 return (psa_status_t)stat;
61 }
62
psa_read_sfn(psa_handle_t msg_handle,uint32_t invec_idx,void * buffer,size_t num_bytes)63 size_t psa_read_sfn(psa_handle_t msg_handle, uint32_t invec_idx,
64 void *buffer, size_t num_bytes)
65 {
66 if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
67 /* PSA APIs must be called from Thread mode */
68 tfm_core_panic();
69 }
70
71 return tfm_spm_partition_psa_read(msg_handle, invec_idx,
72 buffer, num_bytes);
73 }
74
psa_skip_sfn(psa_handle_t msg_handle,uint32_t invec_idx,size_t num_bytes)75 size_t psa_skip_sfn(psa_handle_t msg_handle, uint32_t invec_idx,
76 size_t num_bytes)
77 {
78 if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
79 /* PSA APIs must be called from Thread mode */
80 tfm_core_panic();
81 }
82
83 return tfm_spm_partition_psa_skip(msg_handle, invec_idx, num_bytes);
84 }
85
psa_write_sfn(psa_handle_t msg_handle,uint32_t outvec_idx,const void * buffer,size_t num_bytes)86 void psa_write_sfn(psa_handle_t msg_handle, uint32_t outvec_idx,
87 const void *buffer, size_t num_bytes)
88 {
89 if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
90 /* PSA APIs must be called from Thread mode */
91 tfm_core_panic();
92 }
93
94 tfm_spm_partition_psa_write(msg_handle, outvec_idx, buffer, num_bytes);
95 }
96
psa_panic_sfn(void)97 void psa_panic_sfn(void)
98 {
99 if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
100 /* PSA APIs must be called from Thread mode */
101 tfm_core_panic();
102 }
103
104 tfm_spm_partition_psa_panic();
105 }
106
107 /* Following PSA APIs are only needed by connection-based services */
108 #if CONFIG_TFM_CONNECTION_BASED_SERVICE_API == 1
109
psa_connect_sfn(uint32_t sid,uint32_t version)110 psa_handle_t psa_connect_sfn(uint32_t sid, uint32_t version)
111 {
112 struct partition_t *p_client, *p_target;
113 psa_status_t stat;
114
115 if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
116 /* PSA APIs must be called from Thread mode */
117 tfm_core_panic();
118 }
119
120 p_client = GET_CURRENT_COMPONENT();
121
122 stat = tfm_spm_client_psa_connect(sid, version);
123
124 p_target = GET_CURRENT_COMPONENT();
125 if (p_client != p_target) {
126 /* Execution is returned from RoT Service */
127 stat = tfm_spm_partition_psa_reply(p_target->p_handles->msg.handle,
128 stat);
129 } else {
130 /* Execution is returned from SPM */
131 spm_handle_programmer_errors(stat);
132 }
133
134 return (psa_handle_t)stat;
135 }
136
psa_close_sfn(psa_handle_t handle)137 void psa_close_sfn(psa_handle_t handle)
138 {
139 struct partition_t *p_client, *p_target;
140 psa_status_t stat;
141
142 if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
143 /* PSA APIs must be called from Thread mode */
144 tfm_core_panic();
145 }
146
147 p_client = GET_CURRENT_COMPONENT();
148
149 stat = tfm_spm_client_psa_close(handle);
150
151 p_target = GET_CURRENT_COMPONENT();
152 if (p_client != p_target) {
153 /* Execution is returned from RoT Service */
154 stat = tfm_spm_partition_psa_reply(p_target->p_handles->msg.handle,
155 PSA_SUCCESS);
156 } else {
157 /* Execution is returned from SPM */
158 spm_handle_programmer_errors(stat);
159 }
160 }
161
162 #endif /* CONFIG_TFM_CONNECTION_BASED_SERVICE_API */
163
164 #if CONFIG_TFM_FLIH_API == 1 || CONFIG_TFM_SLIH_API == 1
psa_wait_sfn(psa_signal_t signal_mask,uint32_t timeout)165 psa_signal_t psa_wait_sfn(psa_signal_t signal_mask, uint32_t timeout)
166 {
167 if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
168 /* PSA APIs must be called from Thread mode */
169 tfm_core_panic();
170 }
171
172 return tfm_spm_partition_psa_wait(signal_mask, timeout);
173 }
174
psa_irq_enable_sfn(psa_signal_t irq_signal)175 void psa_irq_enable_sfn(psa_signal_t irq_signal)
176 {
177 if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
178 /* PSA APIs must be called from Thread mode */
179 tfm_core_panic();
180 }
181
182 tfm_spm_partition_psa_irq_enable(irq_signal);
183 }
184
psa_irq_disable_sfn(psa_signal_t irq_signal)185 psa_irq_status_t psa_irq_disable_sfn(psa_signal_t irq_signal)
186 {
187 if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
188 /* PSA APIs must be called from Thread mode */
189 tfm_core_panic();
190 }
191
192 return tfm_spm_partition_psa_irq_disable(irq_signal);
193 }
194 #endif
195
196 #if CONFIG_TFM_SLIH_API == 1
psa_eoi_sfn(psa_signal_t irq_signal)197 void psa_eoi_sfn(psa_signal_t irq_signal)
198 {
199 if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
200 /* PSA APIs must be called from Thread mode */
201 tfm_core_panic();
202 }
203
204 tfm_spm_partition_psa_eoi(irq_signal);
205 }
206 #endif
207
208 #if CONFIG_TFM_FLIH_API == 1
psa_reset_signal_sfn(psa_signal_t irq_signal)209 void psa_reset_signal_sfn(psa_signal_t irq_signal)
210 {
211 if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
212 /* PSA APIs must be called from Thread mode */
213 tfm_core_panic();
214 }
215
216 tfm_spm_partition_psa_reset_signal(irq_signal);
217 }
218 #endif
219
220 #if PSA_FRAMEWORK_HAS_MM_IOVEC
221
psa_map_invec_sfn(psa_handle_t msg_handle,uint32_t invec_idx)222 const void *psa_map_invec_sfn(psa_handle_t msg_handle, uint32_t invec_idx)
223 {
224 if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
225 /* PSA APIs must be called from Thread mode */
226 tfm_core_panic();
227 }
228
229 return tfm_spm_partition_psa_map_invec(msg_handle, invec_idx);
230 }
231
psa_unmap_invec_sfn(psa_handle_t msg_handle,uint32_t invec_idx)232 void psa_unmap_invec_sfn(psa_handle_t msg_handle, uint32_t invec_idx)
233 {
234 if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
235 /* PSA APIs must be called from Thread mode */
236 tfm_core_panic();
237 }
238
239 tfm_spm_partition_psa_unmap_invec(msg_handle, invec_idx);
240 }
241
psa_map_outvec_sfn(psa_handle_t msg_handle,uint32_t outvec_idx)242 void *psa_map_outvec_sfn(psa_handle_t msg_handle, uint32_t outvec_idx)
243 {
244 if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
245 /* PSA APIs must be called from Thread mode */
246 tfm_core_panic();
247 }
248
249 return tfm_spm_partition_psa_map_outvec(msg_handle, outvec_idx);
250 }
251
psa_unmap_outvec_sfn(psa_handle_t msg_handle,uint32_t outvec_idx,size_t len)252 void psa_unmap_outvec_sfn(psa_handle_t msg_handle, uint32_t outvec_idx,
253 size_t len)
254 {
255 if (__get_active_exc_num() != EXC_NUM_THREAD_MODE) {
256 /* PSA APIs must be called from Thread mode */
257 tfm_core_panic();
258 }
259
260 tfm_spm_partition_psa_unmap_outvec(msg_handle, outvec_idx, len);
261 }
262
263 #endif /* PSA_FRAMEWORK_HAS_MM_IOVEC */
264