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