TF-M Reference Manual  1.2.0
TrustedFirmware-M
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
tfm_multi_core_psa_ns_api.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include <stdint.h>
9 #include <stdbool.h>
10 
11 #include "os_wrapper/mutex.h"
12 
13 #include "psa/client.h"
14 #include "psa/error.h"
15 #include "tfm_api.h"
16 #include "tfm_multi_core_api.h"
17 #include "tfm_ns_mailbox.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 static void mailbox_wait_reply(mailbox_msg_handle_t handle)
42 {
43  /*
44  * If the system can support multiple outstanding NS PSA Client calls, call
45  * tfm_ns_mailbox_wait_reply() to sleep and wait for reply. The NS side
46  * should implement tfm_ns_mailbox_hal_wait_reply() and wake-up mechanism.
47  * Otherwise, by default, call tfm_ns_mailbox_is_msg_replied() to simply
48  * poll the reply status of the mailbox message of current thread.
49  */
50 #ifdef TFM_MULTI_CORE_MULTI_CLIENT_CALL
51  tfm_ns_mailbox_wait_reply(handle);
52 #else
53  while (!tfm_ns_mailbox_is_msg_replied(handle)) {
54  }
55 #endif
56 }
57 
58 /**** API functions ****/
59 
60 uint32_t psa_framework_version(void)
61 {
62  struct psa_client_params_t params;
64  uint32_t version;
65  int32_t ret;
66 
68  return PSA_VERSION_NONE;
69  }
70 
72  &params, NON_SECURE_CLIENT_ID);
73  if (handle < 0) {
75  return PSA_VERSION_NONE;
76  }
77 
78  mailbox_wait_reply(handle);
79 
80  ret = tfm_ns_mailbox_rx_client_reply(handle, (int32_t *)&version);
81  if (ret != MAILBOX_SUCCESS) {
82  version = PSA_VERSION_NONE;
83  }
84 
86  return PSA_VERSION_NONE;
87  }
88 
89  return version;
90 }
91 
92 uint32_t psa_version(uint32_t sid)
93 {
94  struct psa_client_params_t params;
96  uint32_t version;
97  int32_t ret;
98 
99  params.psa_version_params.sid = sid;
100 
102  return PSA_VERSION_NONE;
103  }
104 
107  if (handle < 0) {
109  return PSA_VERSION_NONE;
110  }
111 
112  mailbox_wait_reply(handle);
113 
114  ret = tfm_ns_mailbox_rx_client_reply(handle, (int32_t *)&version);
115  if (ret != MAILBOX_SUCCESS) {
116  version = PSA_VERSION_NONE;
117  }
118 
120  return PSA_VERSION_NONE;
121  }
122 
123  return version;
124 }
125 
126 psa_handle_t psa_connect(uint32_t sid, uint32_t version)
127 {
128  struct psa_client_params_t params;
130  psa_handle_t psa_handle;
131  int32_t ret;
132 
133  params.psa_connect_params.sid = sid;
134  params.psa_connect_params.version = version;
135 
137  return PSA_NULL_HANDLE;
138  }
139 
142  if (handle < 0) {
144  return PSA_NULL_HANDLE;
145  }
146 
147  mailbox_wait_reply(handle);
148 
149  ret = tfm_ns_mailbox_rx_client_reply(handle, (int32_t *)&psa_handle);
150  if (ret != MAILBOX_SUCCESS) {
151  psa_handle = PSA_NULL_HANDLE;
152  }
153 
155  return PSA_NULL_HANDLE;
156  }
157 
158  return psa_handle;
159 }
160 
162  const psa_invec *in_vec, size_t in_len,
163  psa_outvec *out_vec, size_t out_len)
164 {
165  struct psa_client_params_t params;
166  mailbox_msg_handle_t msg_handle;
167  int32_t ret;
168  psa_status_t status;
169 
170  params.psa_call_params.handle = handle;
171  params.psa_call_params.type = type;
172  params.psa_call_params.in_vec = in_vec;
173  params.psa_call_params.in_len = in_len;
174  params.psa_call_params.out_vec = out_vec;
175  params.psa_call_params.out_len = out_len;
176 
179  }
180 
181  msg_handle = tfm_ns_mailbox_tx_client_req(MAILBOX_PSA_CALL, &params,
183  if (msg_handle < 0) {
186  }
187 
188  mailbox_wait_reply(msg_handle);
189 
190  ret = tfm_ns_mailbox_rx_client_reply(msg_handle, (int32_t *)&status);
191  if (ret != MAILBOX_SUCCESS) {
192  status = PSA_INTER_CORE_COMM_ERR;
193  }
194 
197  }
198 
199  return status;
200 }
201 
203 {
204  struct psa_client_params_t params;
205  mailbox_msg_handle_t msg_handle;
206  int32_t reply;
207 
208  params.psa_close_params.handle = handle;
209 
211  return;
212  }
213 
214  msg_handle = tfm_ns_mailbox_tx_client_req(MAILBOX_PSA_CLOSE, &params,
216  if (msg_handle < 0) {
218  return;
219  }
220 
221  mailbox_wait_reply(msg_handle);
222 
223  (void)tfm_ns_mailbox_rx_client_reply(msg_handle, &reply);
224 
226 }
psa_handle_t psa_connect(uint32_t sid, uint32_t version)
Connect to an RoT Service by its SID.
psa_handle_t handle
Definition: tfm_mailbox.h:92
psa_outvec * out_vec
Definition: tfm_mailbox.h:96
struct psa_client_params_t::@2::@7 psa_close_params
#define NON_SECURE_CLIENT_ID
struct psa_client_params_t::@2::@6 psa_call_params
psa_status_t 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)
Call an RoT Service on an established connection.
#define MAILBOX_PSA_CALL
Definition: tfm_mailbox.h:64
uint32_t tfm_ns_multi_core_lock_acquire(void)
Acquire the multi-core lock for synchronizing PSA client call(s) The actual implementation depends on...
#define MAILBOX_SUCCESS
Definition: tfm_mailbox.h:68
uint32_t psa_framework_version(void)
Retrieve the version of the PSA Framework API that is implemented.
#define MAILBOX_PSA_CLOSE
Definition: tfm_mailbox.h:65
Standard error codes for the SPM and RoT Services.
uint32_t psa_version(uint32_t sid)
Retrieve the version of an RoT Service or indicate that it is not present on this system...
#define MAILBOX_PSA_CONNECT
Definition: tfm_mailbox.h:63
#define PSA_ERROR_GENERIC_ERROR
Definition: crypto_values.h:43
#define PSA_INTER_CORE_COMM_ERR
int32_t mailbox_msg_handle_t
Definition: tfm_mailbox.h:122
int32_t tfm_ns_mailbox_rx_client_reply(mailbox_msg_handle_t handle, int32_t *reply)
Fetch PSA client return result.
#define PSA_VERSION_NONE
Definition: client.h:32
uint32_t tfm_ns_multi_core_lock_release(void)
Release the multi-core lock for synchronizing PSA client call(s) The actual implementation depends on...
const psa_invec * in_vec
Definition: tfm_mailbox.h:94
#define PSA_NULL_HANDLE
Definition: client.h:38
#define OS_WRAPPER_SUCCESS
Definition: common.h:17
int32_t psa_handle_t
Definition: client.h:61
void psa_close(psa_handle_t handle)
Close a connection to an RoT Service.
struct psa_client_params_t::@2::@5 psa_connect_params
#define MAILBOX_PSA_FRAMEWORK_VERSION
Definition: tfm_mailbox.h:61
mailbox_msg_handle_t tfm_ns_mailbox_tx_client_req(uint32_t call_type, const struct psa_client_params_t *params, int32_t client_id)
Prepare and send PSA client request to SPE via mailbox.
int32_t psa_status_t
Function return status.
Definition: crypto_types.h:43
bool tfm_ns_mailbox_is_msg_replied(mailbox_msg_handle_t handle)
Check whether a specific mailbox message has been replied.
#define MAILBOX_PSA_VERSION
Definition: tfm_mailbox.h:62
struct psa_client_params_t::@2::@4 psa_version_params