1 /*
2 * SPDX-License-Identifier: BSD-3-Clause
3 * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
4 *
5 */
6
7
8 #include <stdint.h>
9 #include <stdbool.h>
10
11 #include "psa/client.h"
12 #include "tfm_ns_interface.h"
13 #include "tfm_psa_call_pack.h"
14 #include "tfm_mailbox.h"
15 #include "tfm_ns_mailbox.h"
16
17 #include "hardware/structs/sio.h"
18
19 /*
20 * TODO
21 * Currently, force all the non-secure client to share the same ID.
22 *
23 * It requires a more clear mechanism to synchronize the non-secure client
24 * ID with SPE in dual core scenario.
25 * In current design, the value is transferred to SPE via mailbox message.
26 * A dedicated routine to receive the non-secure client information in
27 * TF-M core/SPM in dual core scenario should be added besides current
28 * implementation for single Armv8-M.
29 * The non-secure client identification is shared with SPE in
30 * single Armv8-M scenario via CMSIS TrustZone context management API,
31 * which may not work in dual core scenario.
32 */
33 #define NON_SECURE_CLIENT_ID (-1)
34
35 /*
36 * TODO
37 * Require a formal definition of errors related to mailbox in PSA client call.
38 */
39 #define PSA_INTER_CORE_COMM_ERR (INT32_MIN + 0xFF)
40
41 /**** TZ API functions ****/
42
tz_psa_framework_version(void)43 uint32_t tz_psa_framework_version(void)
44 {
45 return tfm_ns_interface_dispatch(
46 (veneer_fn)tfm_psa_framework_version_veneer,
47 0,
48 0,
49 0,
50 0);
51 }
52
tz_psa_version(uint32_t sid)53 uint32_t tz_psa_version(uint32_t sid)
54 {
55 return tfm_ns_interface_dispatch(
56 (veneer_fn)tfm_psa_version_veneer,
57 sid,
58 0,
59 0,
60 0);
61 }
62
tz_psa_call(psa_handle_t handle,int32_t type,const psa_invec * in_vec,size_t in_len,psa_outvec * out_vec,size_t out_len)63 psa_status_t tz_psa_call(psa_handle_t handle, int32_t type,
64 const psa_invec *in_vec,
65 size_t in_len,
66 psa_outvec *out_vec,
67 size_t out_len)
68 {
69 if ((type > PSA_CALL_TYPE_MAX) ||
70 (type < PSA_CALL_TYPE_MIN) ||
71 (in_len > PSA_MAX_IOVEC) ||
72 (out_len > PSA_MAX_IOVEC)) {
73 return PSA_ERROR_PROGRAMMER_ERROR;
74 }
75
76 return tfm_ns_interface_dispatch(
77 (veneer_fn)tfm_psa_call_veneer,
78 (uint32_t)handle,
79 PARAM_PACK(type, in_len, out_len),
80 (uint32_t)in_vec,
81 (uint32_t)out_vec);
82 }
83
tz_psa_connect(uint32_t sid,uint32_t version)84 psa_handle_t tz_psa_connect(uint32_t sid, uint32_t version)
85 {
86 return tfm_ns_interface_dispatch((veneer_fn)tfm_psa_connect_veneer, sid, version, 0, 0);
87 }
88
tz_psa_close(psa_handle_t handle)89 void tz_psa_close(psa_handle_t handle)
90 {
91 (void)tfm_ns_interface_dispatch((veneer_fn)tfm_psa_close_veneer, (uint32_t)handle, 0, 0, 0);
92 }
93
94 /**** Mailbox API functions ****/
95
mb_psa_framework_version(void)96 uint32_t mb_psa_framework_version(void)
97 {
98 struct psa_client_params_t params;
99 uint32_t version;
100 int32_t ret;
101
102 ret = tfm_ns_mailbox_client_call(MAILBOX_PSA_FRAMEWORK_VERSION,
103 ¶ms, NON_SECURE_CLIENT_ID,
104 (int32_t *)&version);
105 if (ret != MAILBOX_SUCCESS) {
106 version = PSA_VERSION_NONE;
107 }
108
109 return version;
110 }
111
mb_psa_version(uint32_t sid)112 uint32_t mb_psa_version(uint32_t sid)
113 {
114 struct psa_client_params_t params;
115 uint32_t version;
116 int32_t ret;
117
118 params.psa_version_params.sid = sid;
119
120 ret = tfm_ns_mailbox_client_call(MAILBOX_PSA_VERSION, ¶ms,
121 NON_SECURE_CLIENT_ID,
122 (int32_t *)&version);
123 if (ret != MAILBOX_SUCCESS) {
124 version = PSA_VERSION_NONE;
125 }
126
127 return version;
128 }
129
mb_psa_connect(uint32_t sid,uint32_t version)130 psa_handle_t mb_psa_connect(uint32_t sid, uint32_t version)
131 {
132 struct psa_client_params_t params;
133 psa_handle_t psa_handle;
134 int32_t ret;
135
136 params.psa_connect_params.sid = sid;
137 params.psa_connect_params.version = version;
138
139 ret = tfm_ns_mailbox_client_call(MAILBOX_PSA_CONNECT, ¶ms,
140 NON_SECURE_CLIENT_ID,
141 (int32_t *)&psa_handle);
142 if (ret != MAILBOX_SUCCESS) {
143 psa_handle = PSA_NULL_HANDLE;
144 }
145
146 return psa_handle;
147 }
148
mb_psa_call(psa_handle_t handle,int32_t type,const psa_invec * in_vec,size_t in_len,psa_outvec * out_vec,size_t out_len)149 psa_status_t mb_psa_call(psa_handle_t handle, int32_t type,
150 const psa_invec *in_vec, size_t in_len,
151 psa_outvec *out_vec, size_t out_len)
152 {
153 struct psa_client_params_t params;
154 int32_t ret;
155 psa_status_t status;
156
157 params.psa_call_params.handle = handle;
158 params.psa_call_params.type = type;
159 params.psa_call_params.in_vec = in_vec;
160 params.psa_call_params.in_len = in_len;
161 params.psa_call_params.out_vec = out_vec;
162 params.psa_call_params.out_len = out_len;
163
164 ret = tfm_ns_mailbox_client_call(MAILBOX_PSA_CALL, ¶ms,
165 NON_SECURE_CLIENT_ID,
166 (int32_t *)&status);
167 if (ret != MAILBOX_SUCCESS) {
168 status = PSA_INTER_CORE_COMM_ERR;
169 }
170
171 return status;
172 }
173
mb_psa_close(psa_handle_t handle)174 void mb_psa_close(psa_handle_t handle)
175 {
176 struct psa_client_params_t params;
177 int32_t reply;
178
179 params.psa_close_params.handle = handle;
180
181 (void)tfm_ns_mailbox_client_call(MAILBOX_PSA_CLOSE, ¶ms,
182 NON_SECURE_CLIENT_ID, &reply);
183 }
184
185 /**** API functions ****/
186
psa_framework_version(void)187 uint32_t psa_framework_version(void)
188 {
189 if(sio_hw->cpuid == 0) {
190 return tz_psa_framework_version();
191 } else {
192 return mb_psa_framework_version();
193 }
194 }
195
psa_version(uint32_t sid)196 uint32_t psa_version(uint32_t sid)
197 {
198 if(sio_hw->cpuid == 0) {
199 return tz_psa_version(sid);
200 } else {
201 return mb_psa_version(sid);
202 }
203 }
204
psa_call(psa_handle_t handle,int32_t type,const psa_invec * in_vec,size_t in_len,psa_outvec * out_vec,size_t out_len)205 psa_status_t psa_call(psa_handle_t handle, int32_t type,
206 const psa_invec *in_vec,
207 size_t in_len,
208 psa_outvec *out_vec,
209 size_t out_len)
210 {
211 if(sio_hw->cpuid == 0) {
212 return tz_psa_call(handle, type, in_vec, in_len, out_vec, out_len);
213 } else {
214 return mb_psa_call(handle, type, in_vec, in_len, out_vec, out_len);
215 }
216 }
217
psa_connect(uint32_t sid,uint32_t version)218 psa_handle_t psa_connect(uint32_t sid, uint32_t version)
219 {
220 if(sio_hw->cpuid == 0) {
221 return tz_psa_connect(sid, version);
222 } else {
223 return mb_psa_connect(sid, version);
224 }
225 }
226
psa_close(psa_handle_t handle)227 void psa_close(psa_handle_t handle)
228 {
229 if(sio_hw->cpuid == 0) {
230 return tz_psa_close(handle);
231 } else {
232 return mb_psa_close(handle);
233 }
234 }
235