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