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