TF-M Reference Manual  1.2.0
TrustedFirmware-M
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
tfm_nspm_func.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include <stdbool.h>
9 #include "cmsis_compiler.h"
10 #include "spm_func.h"
11 #include "tfm_spm_hal.h"
12 #include "tfm_arch.h"
13 #include "tfm_api.h"
14 #include "tfm_nspm.h"
15 #include "ext/tz_context.h"
16 #include "arch.h"
17 
18 #ifndef TFM_MAX_NS_THREAD_COUNT
19 #define TFM_MAX_NS_THREAD_COUNT 8
20 #endif
21 #define INVALID_CLIENT_ID 0
22 
23 #define DEFAULT_NS_CLIENT_ID ((int32_t)-1)
24 
25 #define INVALID_NS_CLIENT_IDX (-1)
26 #define DEFAULT_NS_CLIENT_IDX 0
27 
28 #ifdef TFM_NS_CLIENT_IDENTIFICATION
29 static struct ns_client_list_t {
30  int32_t ns_client_id;
31  int32_t next_free_index;
32 } NsClientIdList[TFM_MAX_NS_THREAD_COUNT];
33 
34 static int32_t free_index = 0U;
35 static int32_t active_ns_client_idx = INVALID_NS_CLIENT_IDX;
36 
37 static int get_next_ns_client_id()
38 {
39  static int32_t next_ns_client_id = DEFAULT_NS_CLIENT_ID;
40 
41  if (next_ns_client_id > 0) {
42  next_ns_client_id = DEFAULT_NS_CLIENT_ID;
43  }
44  return next_ns_client_id--;
45 }
46 #endif /* TFM_NS_CLIENT_IDENTIFICATION */
47 
49 {
50 #ifdef TFM_NS_CLIENT_IDENTIFICATION
51  int32_t i;
52 
53  /* Default to one NS client */
54  free_index = 1;
55  NsClientIdList[0].ns_client_id = get_next_ns_client_id();
56  for (i = 1; i < TFM_MAX_NS_THREAD_COUNT; ++i) {
57  NsClientIdList[i].ns_client_id = INVALID_CLIENT_ID;
58  }
59  active_ns_client_idx = DEFAULT_NS_CLIENT_IDX;
60 #endif /* TFM_NS_CLIENT_IDENTIFICATION */
61 }
62 
64 {
65 #ifdef TFM_NS_CLIENT_IDENTIFICATION
66  if (active_ns_client_idx == INVALID_NS_CLIENT_IDX) {
67  return 0;
68  } else {
69  return NsClientIdList[active_ns_client_idx].ns_client_id;
70  }
71 #else /* TFM_NS_CLIENT_IDENTIFICATION */
72  return DEFAULT_NS_CLIENT_ID;
73 #endif /* TFM_NS_CLIENT_IDENTIFICATION */
74 }
75 
76 /*
77  * TF-M implementation of the CMSIS TZ RTOS thread context management API
78  * Currently the context management only contains the NS ID identification
79  */
80 
83 /* This veneer is TF-M internal, not a secure service */
85 uint32_t TZ_InitContextSystem_S(void)
86 {
87 #ifdef CONFIG_TFM_ENABLE_CTX_MGMT
88 #ifdef TFM_NS_CLIENT_IDENTIFICATION
89  int32_t i;
90 
92  /* This veneer should only be called by NS RTOS in handler mode */
93  return 0U;
94  }
95 
96  /* NS RTOS supports TZ context management, override defaults */
97  for (i = 1; i < TFM_MAX_NS_THREAD_COUNT; ++i) {
98  NsClientIdList[i].ns_client_id = INVALID_CLIENT_ID;
99  NsClientIdList[i].next_free_index = i + 1;
100  }
101 
102  /* Terminate list */
103  NsClientIdList[i - 1].next_free_index = INVALID_NS_CLIENT_IDX;
104 #endif /* TFM_NS_CLIENT_IDENTIFICATION */
105 #endif /* CONFIG_TFM_ENABLE_CTX_MGMT */
106 
107  /* Success */
108  return 1U;
109 }
110 
115 /* This veneer is TF-M internal, not a secure service */
118 {
119  TZ_MemoryId_t tz_id = 1;
120  (void) module; /* Currently unused */
121 
122 #ifdef CONFIG_TFM_ENABLE_CTX_MGMT
123 #ifdef TFM_NS_CLIENT_IDENTIFICATION
125  /* This veneer should only be called by NS RTOS in handler mode */
126  return 0U;
127  }
128 
129  if (free_index < 0) {
130  /* No more free slots */
131  return 0U;
132  }
133 
134  /* TZ_MemoryId_t must be a positive integer */
135  tz_id = (TZ_MemoryId_t)free_index + 1;
136  NsClientIdList[free_index].ns_client_id = get_next_ns_client_id();
137  free_index = NsClientIdList[free_index].next_free_index;
138 #endif /* TFM_NS_CLIENT_IDENTIFICATION */
139 #endif /* CONFIG_TFM_ENABLE_CTX_MGMT */
140 
141  return tz_id;
142 }
143 
147 /* This veneer is TF-M internal, not a secure service */
150 {
151 #ifdef CONFIG_TFM_ENABLE_CTX_MGMT
152 #ifdef TFM_NS_CLIENT_IDENTIFICATION
153  uint32_t index;
154 
156  /* This veneer should only be called by NS RTOS in handler mode */
157  return 0U;
158  }
159 
160  if ((id == 0U) || (id > TFM_MAX_NS_THREAD_COUNT)) {
161  /* Invalid TZ_MemoryId_t */
162  return 0U;
163  }
164 
165  index = id - 1;
166 
167  if (NsClientIdList[index].ns_client_id == INVALID_CLIENT_ID) {
168  /* Non-existent client */
169  return 0U;
170  }
171 
172  if (active_ns_client_idx == index) {
173  active_ns_client_idx = DEFAULT_NS_CLIENT_IDX;
174  }
175  NsClientIdList[index].ns_client_id = INVALID_CLIENT_ID;
176  NsClientIdList[index].next_free_index = free_index;
177 
178  free_index = index;
179 #else /* TFM_NS_CLIENT_IDENTIFICATION */
180  (void)id;
181 #endif /* TFM_NS_CLIENT_IDENTIFICATION */
182 #else /* CONFIG_TFM_ENABLE_CTX_MGMT */
183  (void)id;
184 #endif /* CONFIG_TFM_ENABLE_CTX_MGMT */
185 
186  return 1U; // Success
187 }
188 
192 /* This veneer is TF-M internal, not a secure service */
195 {
196 #ifdef CONFIG_TFM_ENABLE_CTX_MGMT
197 #ifdef TFM_NS_CLIENT_IDENTIFICATION
198  uint32_t index;
199 
201  /* This veneer should only be called by NS RTOS in handler mode */
202  return 0U;
203  }
204 
205  if ((id == 0U) || (id > TFM_MAX_NS_THREAD_COUNT)) {
206  /* Invalid TZ_MemoryId_t */
207  return 0U;
208  }
209 
210  index = id - 1;
211 
212  if (NsClientIdList[index].ns_client_id == INVALID_CLIENT_ID) {
213  /* Non-existent client */
214  return 0U;
215  }
216 
217  active_ns_client_idx = index;
218 #else /* TFM_NS_CLIENT_IDENTIFICATION */
219  (void)id;
220 #endif /* TFM_NS_CLIENT_IDENTIFICATION */
221 #else /* CONFIG_TFM_ENABLE_CTX_MGMT */
222  (void)id;
223 #endif /* CONFIG_TFM_ENABLE_CTX_MGMT */
224 
225  return 1U; // Success
226 }
227 
231 /* This veneer is TF-M internal, not a secure service */
234 {
235 #ifdef CONFIG_TFM_ENABLE_CTX_MGMT
236 #ifdef TFM_NS_CLIENT_IDENTIFICATION
237  uint32_t index;
238 
240  /* This veneer should only be called by NS RTOS in handler mode */
241  return 0U;
242  }
243 
244  /* id corresponds to context being swapped out on NS side */
245  if ((id == 0U) || (id > TFM_MAX_NS_THREAD_COUNT)) {
246  /* Invalid TZ_MemoryId_t */
247  return 0U;
248  }
249 
250  index = id - 1;
251 
252  if (NsClientIdList[index].ns_client_id == INVALID_CLIENT_ID) {
253  /* Non-existent client */
254  return 0U;
255  }
256 
257  if (active_ns_client_idx != index) {
258  return 0U;
259  }
260 
261  active_ns_client_idx = DEFAULT_NS_CLIENT_IDX;
262 #else /* TFM_NS_CLIENT_IDENTIFICATION */
263  (void)id;
264 #endif /* TFM_NS_CLIENT_IDENTIFICATION */
265 #else /* CONFIG_TFM_ENABLE_CTX_MGMT */
266  (void)id;
267 #endif /* CONFIG_TFM_ENABLE_CTX_MGMT */
268 
269  return 1U; // Success
270 }
271 
272 #ifdef TFM_NS_CLIENT_IDENTIFICATION
274 enum tfm_status_e tfm_register_client_id (int32_t ns_client_id)
275 {
276  int current_client_id;
277 
279  /* This veneer should only be called by NS RTOS in handler mode */
281  }
282 
283  if (ns_client_id >= 0) {
284  /* The client ID is invalid */
286  }
287 
288  if (active_ns_client_idx < 0) {
289  /* No client is active */
290  return TFM_ERROR_GENERIC;
291  }
292 
293  current_client_id = NsClientIdList[active_ns_client_idx].ns_client_id;
294  if (current_client_id >= 0 ) {
295  /* The client ID is invalid */
297  }
298 
299  NsClientIdList[active_ns_client_idx].ns_client_id = ns_client_id;
300 
301  return TFM_SUCCESS;
302 }
303 #endif
304 
306 {
307  /* SCB_NS.VTOR points to the Non-secure vector table base address */
308  SCB_NS->VTOR = tfm_spm_hal_get_ns_VTOR();
309 
310  /* Setups Main stack pointer of the non-secure code */
311  uint32_t ns_msp = tfm_spm_hal_get_ns_MSP();
312 
313  __TZ_set_MSP_NS(ns_msp);
314 
315  /* Get the address of non-secure code entry point to jump there */
316  uint32_t entry_ptr = tfm_spm_hal_get_ns_entry_point();
317 
318  /* Clears LSB of the function address to indicate the function-call
319  * will perform the switch from secure to non-secure
320  */
321  ns_entry = (nsfptr_t) cmse_nsfptr_create(entry_ptr);
322 }
#define INVALID_NS_CLIENT_IDX
Definition: tfm_nspm_func.c:25
tfm_status_e
Definition: tfm_api.h:45
#define TFM_MAX_NS_THREAD_COUNT
Definition: tfm_nspm_func.c:19
#define DEFAULT_NS_CLIENT_ID
Definition: tfm_nspm_func.c:23
#define __tfm_nspm_secure_gateway_attributes__
Attributes for secure gateway functions for NSPM.
Definition: tfm_nspm.h:33
void configure_ns_code(void)
#define cmse_nsfptr_create(p)
Definition: tfm_nspm.h:21
nsfptr_t ns_entry
Definition: arch.c:17
__STATIC_INLINE uint32_t __get_active_exc_num(void)
Definition: tfm_arch.h:65
uint32_t TZ_MemoryId_t
Definition: tz_context.h:42
void(* nsfptr_t)(void)
Definition: arch.h:18
int32_t tfm_nspm_get_current_client_id(void)
Get the client ID of the current NS client.
Definition: tfm_nspm_func.c:63
__tfm_nspm_secure_gateway_attributes__ uint32_t TZ_StoreContext_S(TZ_MemoryId_t id)
__tfm_nspm_secure_gateway_attributes__ uint32_t TZ_FreeModuleContext_S(TZ_MemoryId_t id)
__tfm_nspm_secure_gateway_attributes__ uint32_t TZ_LoadContext_S(TZ_MemoryId_t id)
__tfm_nspm_secure_gateway_attributes__ uint32_t TZ_InitContextSystem_S(void)
Definition: tfm_nspm_func.c:85
#define EXC_NUM_THREAD_MODE
Definition: spm_func.h:24
void tfm_nspm_configure_clients(void)
initialise the NS context database
Definition: tfm_nspm_func.c:48
__tfm_nspm_secure_gateway_attributes__ TZ_MemoryId_t TZ_AllocModuleContext_S(TZ_ModuleId_t module)
#define INVALID_CLIENT_ID
Definition: tfm_nspm_func.c:21
#define DEFAULT_NS_CLIENT_IDX
Definition: tfm_nspm_func.c:26
uint32_t TZ_ModuleId_t
Definition: tz_context.h:38
enum tfm_status_e tfm_register_client_id(int32_t ns_client_id)
Assign client ID to the current TZ context.