Add TZ shim layer from NS side
RTOS defines an API to standardize the context memory system.
Implement a shim layer in the TZ API functions
to have the RTOS context manager call TF-M NSID API.
Signed-off-by: Xinyu Zhang <xinyu.zhang@arm.com>
Change-Id: I77327ae463ebb47579d406c510c071cfd5d31d1e
diff --git a/CMSIS/RTOS2/RTX/Include/tz_context.h b/CMSIS/RTOS2/RTX/Include/tz_context.h
new file mode 100644
index 0000000..cd6d8ab
--- /dev/null
+++ b/CMSIS/RTOS2/RTX/Include/tz_context.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2015-2016 ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * $Date: 21. September 2016
+ * $Revision: V1.0
+ *
+ * Project: TrustZone for ARMv8-M
+ * Title: Context Management for ARMv8-M TrustZone
+ *
+ * Version 1.0
+ * Initial Release
+ *---------------------------------------------------------------------------*/
+
+#ifndef TZ_CONTEXT_H
+#define TZ_CONTEXT_H
+
+#include <stdint.h>
+
+#ifndef TZ_MODULEID_T
+#define TZ_MODULEID_T
+/// \details Data type that identifies secure software modules called by a process.
+typedef uint32_t TZ_ModuleId_t;
+#endif
+
+/// \details TZ Memory ID identifies an allocated memory slot.
+typedef uint32_t TZ_MemoryId_t;
+
+/// Initialize secure context memory system
+/// \return execution status (1: success, 0: error)
+uint32_t TZ_InitContextSystem_S (void);
+
+/// Allocate context memory for calling secure software modules in TrustZone
+/// \param[in] module identifies software modules called from non-secure mode
+/// \return value != 0 id TrustZone memory slot identifier
+/// \return value 0 no memory available or internal error
+TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module);
+
+/// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S
+/// \param[in] id TrustZone memory slot identifier
+/// \return execution status (1: success, 0: error)
+uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id);
+
+/// Load secure context (called on RTOS thread context switch)
+/// \param[in] id TrustZone memory slot identifier
+/// \return execution status (1: success, 0: error)
+uint32_t TZ_LoadContext_S (TZ_MemoryId_t id);
+
+/// Store secure context (called on RTOS thread context switch)
+/// \param[in] id TrustZone memory slot identifier
+/// \return execution status (1: success, 0: error)
+uint32_t TZ_StoreContext_S (TZ_MemoryId_t id);
+
+#endif // TZ_CONTEXT_H
diff --git a/ns_interface/ns_client_ext/tz_shim_layer.c b/ns_interface/ns_client_ext/tz_shim_layer.c
new file mode 100755
index 0000000..ed959ea
--- /dev/null
+++ b/ns_interface/ns_client_ext/tz_shim_layer.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/*
+ * This is a simple example implementaton for reference
+ * to make TZ APIs co-work with TF-M NSCE module.
+ *
+ * Developers can implement according to different RTOS and usage scenarios.
+ */
+
+#include "tz_context.h"
+
+#include "tfm_ns_client_ext.h"
+#include "tfm_nsid_manager.h"
+
+#ifdef TFM_NS_MANAGE_NSID
+#define NSID_MGR_THREAD_ID_MAX 0xFF
+#define NSID_MGR_GROUP_ID_DEFAULT 0X00
+/*
+ * 0 is reserved for thread ID in NSID manager to avoid token being set as 0.
+ * TZ_MemoryID_t is used to record the token value.
+ * Scheduler of the RTOS would be disabled if TZ_MemoryID_t is 0.
+ */
+static uint8_t nsid_mgr_thread_id = 1;
+#endif
+
+/*
+ * TF-M shim layer of the CMSIS TZ RTOS thread context management API
+ */
+
+/*
+ * Initialize token-nsid map table in tfm nsid manager
+ * Return execution status (1: success, 0: error)
+ */
+uint32_t TZ_InitContextSystem_S(void)
+{
+#ifdef TFM_NS_MANAGE_NSID
+ /* Initialize the ns client ext */
+ if (tfm_nsce_init(0) == 0) {
+ return 0U; /* Error */
+ }
+
+ /* Initialize the nsid manager */
+ if (nsid_mgr_init() == NSID_MGR_ERR_SUCCESS) {
+ return 1U; /* Success */
+ } else {
+ return 0U; /* Error */
+ }
+#else /* TFM_NS_MANAGE_NSID */
+ return 1U; /* Success */
+#endif /* TFM_NS_MANAGE_NSID */
+}
+
+/*
+ * Allocate context memory from Secure side
+ * Param: TZ_ModuleId_t (NSID if TFM_NS_MANAGE_NSID is enabled)
+ * Return token if TFM_NS_MANAGE_NSID is enabled
+ * Return 0 if no memory available or internal error
+ */
+TZ_MemoryId_t TZ_AllocModuleContext_S(TZ_ModuleId_t module)
+{
+#ifdef TFM_NS_MANAGE_NSID
+ int32_t nsid;
+ uint32_t token;
+
+ /* TZ_ModuleID_t is used to record NSID */
+ nsid = (int32_t)module;
+
+ /* New thread ID not available, return error */
+ if (nsid_mgr_thread_id >= NSID_MGR_THREAD_ID_MAX) {
+ return 0U; /* Error */
+ }
+
+ token = tfm_nsce_acquire_ctx(NSID_MGR_GROUP_ID_DEFAULT, nsid_mgr_thread_id++);
+
+ if (nsid_mgr_add_entry(nsid, token) == NSID_MGR_ERR_SUCCESS) {
+ return token; /* Success: return token as TZ_MemoryId_t */
+ } else {
+ return 0U; /* Error */
+ }
+#else /* TFM_NS_MANAGE_NSID */
+ return 1U; /* Success */
+#endif /* TFM_NS_MANAGE_NSID */
+}
+
+/*
+ * Free context memory that was previously allocated with TZ_AllocModuleContext_S
+ * Param: TZ_MemoryId_t (token if TFM_NS_MANAGE_NSID is enabled)
+ * Return execution status (1: success, 0: error)
+ */
+uint32_t TZ_FreeModuleContext_S(TZ_MemoryId_t id)
+{
+#ifdef TFM_NS_MANAGE_NSID
+ uint32_t token;
+
+ /* TZ_MemoryId_t is used to record token */
+ token = (uint32_t)id;
+
+ if (nsid_mgr_remove_entry(token) != NSID_MGR_ERR_SUCCESS) {
+ return 0U; /* Error */
+ }
+
+ if (tfm_nsce_release_ctx(token) == TFM_NS_CLIENT_ERR_SUCCESS) {
+ return 1U; /* Success */
+ } else {
+ return 0U; /* Error */
+ }
+#else /* TFM_NS_MANAGE_NSID */
+ return 1U; /* Success */
+#endif /* TFM_NS_MANAGE_NSID */
+}
+
+/*
+ * Load secure context (called on RTOS thread context switch)
+ * Param: TZ_MemoryId_t (token if TFM_NS_MANAGE_NSID is enabled)
+ * Return execution status (1: success, 0: error)
+ */
+uint32_t TZ_LoadContext_S(TZ_MemoryId_t id)
+{
+#ifdef TFM_NS_MANAGE_NSID
+ int32_t nsid;
+ uint32_t token;
+
+ /* TZ_MemoryId_t is used to record token */
+ token = (uint32_t)id;
+
+ nsid = nsid_mgr_query_nsid(token);
+
+ if (nsid >= TFM_INVALID_NSID_MIN) {
+ return 0U; /* Error */
+ }
+
+ if (tfm_nsce_load_ctx(token, nsid) == TFM_NS_CLIENT_ERR_SUCCESS) {
+ return 1U; /* Success */
+ } else {
+ return 0U; /* Error */
+ }
+#else /* TFM_NS_MANAGE_NSID */
+ return 1U; /* Success */
+#endif /* TFM_NS_MANAGE_NSID */
+}
+
+/*
+ * Store secure context (called on RTOS thread context switch)
+ * Param: TZ_MemoryId_t (token if TFM_NS_MANAGE_NSID is enabled)
+ * Return execution status (1: success, 0: error)
+ */
+uint32_t TZ_StoreContext_S(TZ_MemoryId_t id)
+{
+#ifdef TFM_NS_MANAGE_NSID
+ uint32_t token;
+
+ /* TZ_MemoryId_t is used to record token */
+ token = (uint32_t)id;
+
+ if (tfm_nsce_save_ctx(token) == TFM_NS_CLIENT_ERR_SUCCESS) {
+ return 1U; /* Success */
+ } else {
+ return 0U; /* Error */
+ }
+#else /* TFM_NS_MANAGE_NSID */
+ return 1U; /* Success */
+#endif /* TFM_NS_MANAGE_NSID */
+}