blob: 74a12ecda25d18eaa45568bb2ec1960e107e2837 [file] [log] [blame]
Xinyu Zhang1a736562021-09-22 15:07:23 +08001/*
2 * Copyright (c) 2021, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8/*
9 * This is a simple example implementaton for reference
10 * to make TZ APIs co-work with TF-M NSCE module.
11 *
12 * Developers can implement according to different RTOS and usage scenarios.
13 */
14
15#include "tz_context.h"
16
17#include "tfm_ns_client_ext.h"
18#include "tfm_nsid_manager.h"
19
20#ifdef TFM_NS_MANAGE_NSID
21#define NSID_MGR_THREAD_ID_MAX 0xFF
22#define NSID_MGR_GROUP_ID_DEFAULT 0X00
23/*
24 * 0 is reserved for thread ID in NSID manager to avoid token being set as 0.
25 * TZ_MemoryID_t is used to record the token value.
26 * Scheduler of the RTOS would be disabled if TZ_MemoryID_t is 0.
27 */
28static uint8_t nsid_mgr_thread_id = 1;
29#endif
30
Xinyu Zhang21559372021-09-24 17:06:09 +080031#ifdef TEST_NS_MANAGE_NSID
32uint32_t current_active_token;
33#endif
34
Xinyu Zhang1a736562021-09-22 15:07:23 +080035/*
36 * TF-M shim layer of the CMSIS TZ RTOS thread context management API
37 */
38
39/*
40 * Initialize token-nsid map table in tfm nsid manager
41 * Return execution status (1: success, 0: error)
42 */
43uint32_t TZ_InitContextSystem_S(void)
44{
45#ifdef TFM_NS_MANAGE_NSID
46 /* Initialize the ns client ext */
47 if (tfm_nsce_init(0) == 0) {
48 return 0U; /* Error */
49 }
50
51 /* Initialize the nsid manager */
52 if (nsid_mgr_init() == NSID_MGR_ERR_SUCCESS) {
Xinyu Zhang21559372021-09-24 17:06:09 +080053#ifdef TEST_NS_MANAGE_NSID
54 current_active_token = TFM_NS_CLIENT_INVALID_TOKEN;
55#endif
Xinyu Zhang1a736562021-09-22 15:07:23 +080056 return 1U; /* Success */
57 } else {
58 return 0U; /* Error */
59 }
60#else /* TFM_NS_MANAGE_NSID */
61 return 1U; /* Success */
62#endif /* TFM_NS_MANAGE_NSID */
63}
64
65/*
66 * Allocate context memory from Secure side
67 * Param: TZ_ModuleId_t (NSID if TFM_NS_MANAGE_NSID is enabled)
68 * Return token if TFM_NS_MANAGE_NSID is enabled
69 * Return 0 if no memory available or internal error
70 */
71TZ_MemoryId_t TZ_AllocModuleContext_S(TZ_ModuleId_t module)
72{
73#ifdef TFM_NS_MANAGE_NSID
74 int32_t nsid;
75 uint32_t token;
76
77 /* TZ_ModuleID_t is used to record NSID */
78 nsid = (int32_t)module;
79
80 /* New thread ID not available, return error */
81 if (nsid_mgr_thread_id >= NSID_MGR_THREAD_ID_MAX) {
82 return 0U; /* Error */
83 }
84
85 token = tfm_nsce_acquire_ctx(NSID_MGR_GROUP_ID_DEFAULT, nsid_mgr_thread_id++);
86
87 if (nsid_mgr_add_entry(nsid, token) == NSID_MGR_ERR_SUCCESS) {
88 return token; /* Success: return token as TZ_MemoryId_t */
89 } else {
90 return 0U; /* Error */
91 }
92#else /* TFM_NS_MANAGE_NSID */
93 return 1U; /* Success */
94#endif /* TFM_NS_MANAGE_NSID */
95}
96
97/*
98 * Free context memory that was previously allocated with TZ_AllocModuleContext_S
99 * Param: TZ_MemoryId_t (token if TFM_NS_MANAGE_NSID is enabled)
100 * Return execution status (1: success, 0: error)
101 */
102uint32_t TZ_FreeModuleContext_S(TZ_MemoryId_t id)
103{
104#ifdef TFM_NS_MANAGE_NSID
105 uint32_t token;
106
107 /* TZ_MemoryId_t is used to record token */
108 token = (uint32_t)id;
109
110 if (nsid_mgr_remove_entry(token) != NSID_MGR_ERR_SUCCESS) {
111 return 0U; /* Error */
112 }
113
114 if (tfm_nsce_release_ctx(token) == TFM_NS_CLIENT_ERR_SUCCESS) {
Xinyu Zhang21559372021-09-24 17:06:09 +0800115#ifdef TEST_NS_MANAGE_NSID
116 if (current_active_token != TFM_NS_CLIENT_INVALID_TOKEN) {
117 current_active_token = TFM_NS_CLIENT_INVALID_TOKEN;
118 }
119#endif
Xinyu Zhang1a736562021-09-22 15:07:23 +0800120 return 1U; /* Success */
121 } else {
122 return 0U; /* Error */
123 }
124#else /* TFM_NS_MANAGE_NSID */
125 return 1U; /* Success */
126#endif /* TFM_NS_MANAGE_NSID */
127}
128
129/*
130 * Load secure context (called on RTOS thread context switch)
131 * Param: TZ_MemoryId_t (token if TFM_NS_MANAGE_NSID is enabled)
132 * Return execution status (1: success, 0: error)
133 */
134uint32_t TZ_LoadContext_S(TZ_MemoryId_t id)
135{
136#ifdef TFM_NS_MANAGE_NSID
137 int32_t nsid;
138 uint32_t token;
139
140 /* TZ_MemoryId_t is used to record token */
141 token = (uint32_t)id;
142
143 nsid = nsid_mgr_query_nsid(token);
144
145 if (nsid >= TFM_INVALID_NSID_MIN) {
146 return 0U; /* Error */
147 }
148
149 if (tfm_nsce_load_ctx(token, nsid) == TFM_NS_CLIENT_ERR_SUCCESS) {
Xinyu Zhang21559372021-09-24 17:06:09 +0800150#ifdef TEST_NS_MANAGE_NSID
151 current_active_token = token;
152#endif
Xinyu Zhang1a736562021-09-22 15:07:23 +0800153 return 1U; /* Success */
154 } else {
155 return 0U; /* Error */
156 }
157#else /* TFM_NS_MANAGE_NSID */
158 return 1U; /* Success */
159#endif /* TFM_NS_MANAGE_NSID */
160}
161
162/*
163 * Store secure context (called on RTOS thread context switch)
164 * Param: TZ_MemoryId_t (token if TFM_NS_MANAGE_NSID is enabled)
165 * Return execution status (1: success, 0: error)
166 */
167uint32_t TZ_StoreContext_S(TZ_MemoryId_t id)
168{
169#ifdef TFM_NS_MANAGE_NSID
170 uint32_t token;
171
172 /* TZ_MemoryId_t is used to record token */
173 token = (uint32_t)id;
174
175 if (tfm_nsce_save_ctx(token) == TFM_NS_CLIENT_ERR_SUCCESS) {
Xinyu Zhang21559372021-09-24 17:06:09 +0800176#ifdef TEST_NS_MANAGE_NSID
177 if (current_active_token != TFM_NS_CLIENT_INVALID_TOKEN) {
178 current_active_token = TFM_NS_CLIENT_INVALID_TOKEN;
179 }
180#endif
Xinyu Zhang1a736562021-09-22 15:07:23 +0800181 return 1U; /* Success */
182 } else {
183 return 0U; /* Error */
184 }
185#else /* TFM_NS_MANAGE_NSID */
186 return 1U; /* Success */
187#endif /* TFM_NS_MANAGE_NSID */
188}