SPM: Enable NSPE managing client_id

TFM_NS_MANAGE_NSID build flag is added to enable NSPE
managing client_id both in library model and IPC model.

Signed-off-by: Sherry Zhnag <sherry.zhang2@arm.com>
Change-Id: I4e8d1bf8967de442787f4989d2bb8e371f78bef6
diff --git a/secure_fw/spm/CMakeLists.txt b/secure_fw/spm/CMakeLists.txt
index c1ba547..8831f40 100755
--- a/secure_fw/spm/CMakeLists.txt
+++ b/secure_fw/spm/CMakeLists.txt
@@ -62,6 +62,8 @@
         $<$<NOT:$<BOOL:${TFM_PSA_API}>>:cmsis_func/spm_func.c>
         $<$<NOT:$<BOOL:${TFM_PSA_API}>>:cmsis_func/tfm_core_svcalls_func.c>
         $<$<NOT:$<BOOL:${TFM_PSA_API}>>:cmsis_func/tfm_nspm_func.c>
+        $<$<AND:$<NOT:$<BOOL:${TFM_MULTI_CORE_TOPOLOGY}>>,$<BOOL:${TFM_NS_MANAGE_NSID}>>:ns_client_ext/tfm_ns_ctx.c>
+        $<$<NOT:$<BOOL:${TFM_MULTI_CORE_TOPOLOGY}>>:ns_client_ext/tfm_spm_ns_ctx.c>
         $<$<NOT:$<BOOL:${TFM_PSA_API}>>:cmsis_func/tfm_secure_api.c>
         #TODO add other arches
         $<$<AND:$<BOOL:${TFM_PSA_API}>,$<STREQUAL:${CMAKE_SYSTEM_ARCHITECTURE},armv8.1-m.main>>:cmsis_psa/arch/tfm_arch_v8m_main.c>
@@ -113,14 +115,7 @@
         $<$<CONFIG:Debug>:TFM_CORE_DEBUG>
         $<$<AND:$<BOOL:${BL2}>,$<BOOL:${MCUBOOT_MEASURED_BOOT}>>:BOOT_DATA_AVAILABLE>
         $<$<BOOL:${TFM_EXCEPTION_INFO_DUMP}>:TFM_EXCEPTION_INFO_DUMP>
-)
-
-# With constant optimizations on tfm_nspc_func emits a symbol that the linker
-# doesn't like. It's unclear why this is, so I'll put a TODO here, but for the
-# moment this fixes it with mimimal impact.
-set_source_files_properties(tfm_nspm_func.c
-    PROPERTIES
-        COMPILE_FLAGS -fno-ipa-cp
+        $<$<BOOL:${TFM_NS_MANAGE_NSID}>:TFM_NS_MANAGE_NSID>
 )
 
 # The veneers give warnings about not being properly declared so they get hidden
@@ -186,5 +181,6 @@
         PRIVATE
             $<$<NOT:$<BOOL:${TFM_PSA_API}>>:${CMAKE_BINARY_DIR}/generated/secure_fw/spm/cmsis_func/tfm_veneers.c>
             $<$<BOOL:${TFM_PSA_API}>:${CMAKE_CURRENT_SOURCE_DIR}/cmsis_psa/tfm_psa_api_veneers.c>
+            $<$<BOOL:${TFM_NS_MANAGE_NSID}>:${CMAKE_CURRENT_SOURCE_DIR}/ns_client_ext/tfm_ns_client_ext.c>
     )
 endif()
diff --git a/secure_fw/spm/cmsis_func/spm_func.c b/secure_fw/spm/cmsis_func/spm_func.c
index 5326f94..9e1bb4f 100644
--- a/secure_fw/spm/cmsis_func/spm_func.c
+++ b/secure_fw/spm/cmsis_func/spm_func.c
@@ -1379,7 +1379,7 @@
     /* This function initialises partition db */
 
     /* For the non secure Execution environment */
-    tfm_nspm_configure_clients();
+    tfm_nspm_ctx_init();
 
     for (i = 0; i < g_spm_partition_db.partition_count; i++) {
         g_spm_partition_db.partitions[i].runtime_data.partition_state =
diff --git a/secure_fw/spm/cmsis_func/tfm_nspm_func.c b/secure_fw/spm/cmsis_func/tfm_nspm_func.c
old mode 100644
new mode 100755
index b27bb44..19075c7
--- a/secure_fw/spm/cmsis_func/tfm_nspm_func.c
+++ b/secure_fw/spm/cmsis_func/tfm_nspm_func.c
@@ -1,317 +1,14 @@
 /*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
  */
 
-#include <stdbool.h>
-#include "cmsis_compiler.h"
-#include "spm_func.h"
 #include "tfm_spm_hal.h"
 #include "tfm_arch.h"
-#include "tfm_api.h"
-#include "tfm_nspm.h"
-#include "ext/tz_context.h"
 #include "arch.h"
 
-#ifndef TFM_MAX_NS_THREAD_COUNT
-#define TFM_MAX_NS_THREAD_COUNT 8
-#endif
-#define INVALID_CLIENT_ID 0
-
-#define DEFAULT_NS_CLIENT_ID ((int32_t)-1)
-
-#define INVALID_NS_CLIENT_IDX (-1)
-#define DEFAULT_NS_CLIENT_IDX   0
-
-#ifdef TFM_NS_CLIENT_IDENTIFICATION
-static struct ns_client_list_t {
-    int32_t ns_client_id;
-    int32_t next_free_index;
-} NsClientIdList[TFM_MAX_NS_THREAD_COUNT];
-
-static int32_t free_index = 0U;
-static int32_t active_ns_client_idx = INVALID_NS_CLIENT_IDX;
-
-static int get_next_ns_client_id(void)
-{
-    static int32_t next_ns_client_id = DEFAULT_NS_CLIENT_ID;
-
-    if (next_ns_client_id > 0) {
-        next_ns_client_id = DEFAULT_NS_CLIENT_ID;
-    }
-    return next_ns_client_id--;
-}
-#endif /* TFM_NS_CLIENT_IDENTIFICATION */
-
-void tfm_nspm_configure_clients(void)
-{
-#ifdef TFM_NS_CLIENT_IDENTIFICATION
-    int32_t i;
-
-    /* Default to one NS client */
-    free_index = 1;
-    NsClientIdList[0].ns_client_id = get_next_ns_client_id();
-    for (i = 1; i < TFM_MAX_NS_THREAD_COUNT; ++i) {
-        NsClientIdList[i].ns_client_id = INVALID_CLIENT_ID;
-    }
-    active_ns_client_idx = DEFAULT_NS_CLIENT_IDX;
-#endif /* TFM_NS_CLIENT_IDENTIFICATION */
-}
-
-int32_t tfm_nspm_get_current_client_id(void)
-{
-#ifdef TFM_NS_CLIENT_IDENTIFICATION
-    if (active_ns_client_idx == INVALID_NS_CLIENT_IDX) {
-        return 0;
-    } else {
-        return NsClientIdList[active_ns_client_idx].ns_client_id;
-    }
-#else /* TFM_NS_CLIENT_IDENTIFICATION */
-    return DEFAULT_NS_CLIENT_ID;
-#endif /* TFM_NS_CLIENT_IDENTIFICATION */
-}
-
-/*
- * TF-M implementation of the CMSIS TZ RTOS thread context management API
- * Currently the context management only contains the NS ID identification
- */
-
-/**
- * Initialize secure context memory system
- * \return execution status (1: success, 0: error)
- */
-/* This veneer is TF-M internal, not a secure service */
-__tfm_nspm_secure_gateway_attributes__
-uint32_t TZ_InitContextSystem_S(void)
-{
-#ifdef CONFIG_TFM_ENABLE_CTX_MGMT
-#ifdef TFM_NS_CLIENT_IDENTIFICATION
-    int32_t i;
-
-    if (__get_active_exc_num() == EXC_NUM_THREAD_MODE) {
-        /* This veneer should only be called by NS RTOS in handler mode */
-        return 0U;
-    }
-
-    /* NS RTOS supports TZ context management, override defaults */
-    for (i = 1; i < TFM_MAX_NS_THREAD_COUNT; ++i) {
-        NsClientIdList[i].ns_client_id = INVALID_CLIENT_ID;
-        NsClientIdList[i].next_free_index = i + 1;
-    }
-
-    /* Terminate list */
-    NsClientIdList[i - 1].next_free_index = INVALID_NS_CLIENT_IDX;
-#endif /* TFM_NS_CLIENT_IDENTIFICATION */
-#endif /* CONFIG_TFM_ENABLE_CTX_MGMT */
-
-    /* Success */
-    return 1U;
-}
-
-/**
- * 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
- */
-/* This veneer is TF-M internal, not a secure service */
-__tfm_nspm_secure_gateway_attributes__
-TZ_MemoryId_t TZ_AllocModuleContext_S(TZ_ModuleId_t module)
-{
-    TZ_MemoryId_t tz_id = 1;
-    (void) module; /* Currently unused */
-
-#ifdef CONFIG_TFM_ENABLE_CTX_MGMT
-#ifdef TFM_NS_CLIENT_IDENTIFICATION
-    if (__get_active_exc_num() == EXC_NUM_THREAD_MODE) {
-        /* This veneer should only be called by NS RTOS in handler mode */
-        return 0U;
-    }
-
-    if (free_index < 0) {
-        /* No more free slots */
-        return 0U;
-    }
-
-    /* TZ_MemoryId_t must be a positive integer */
-    tz_id = (TZ_MemoryId_t)free_index + 1;
-    NsClientIdList[free_index].ns_client_id = get_next_ns_client_id();
-    free_index = NsClientIdList[free_index].next_free_index;
-#endif /* TFM_NS_CLIENT_IDENTIFICATION */
-#endif /* CONFIG_TFM_ENABLE_CTX_MGMT */
-
-    return tz_id;
-}
-
-/**
- * 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)
- */
-/* This veneer is TF-M internal, not a secure service */
-__tfm_nspm_secure_gateway_attributes__
-uint32_t TZ_FreeModuleContext_S(TZ_MemoryId_t id)
-{
-#ifdef CONFIG_TFM_ENABLE_CTX_MGMT
-#ifdef TFM_NS_CLIENT_IDENTIFICATION
-    uint32_t index;
-
-    if (__get_active_exc_num() == EXC_NUM_THREAD_MODE) {
-        /* This veneer should only be called by NS RTOS in handler mode */
-        return 0U;
-    }
-
-    if ((id == 0U) || (id > TFM_MAX_NS_THREAD_COUNT)) {
-        /* Invalid TZ_MemoryId_t */
-        return 0U;
-    }
-
-    index = id - 1;
-
-    if (NsClientIdList[index].ns_client_id == INVALID_CLIENT_ID) {
-        /* Non-existent client */
-        return 0U;
-    }
-
-    if (active_ns_client_idx == index) {
-        active_ns_client_idx = DEFAULT_NS_CLIENT_IDX;
-    }
-    NsClientIdList[index].ns_client_id = INVALID_CLIENT_ID;
-    NsClientIdList[index].next_free_index = free_index;
-
-    free_index = index;
-#else /* TFM_NS_CLIENT_IDENTIFICATION */
-    (void)id;
-#endif /* TFM_NS_CLIENT_IDENTIFICATION */
-#else /* CONFIG_TFM_ENABLE_CTX_MGMT */
-    (void)id;
-#endif /* CONFIG_TFM_ENABLE_CTX_MGMT */
-
-    return 1U;    /* Success */
-}
-
-/**
- * Load secure context (called on RTOS thread context switch)
- * \param[in]  id  TrustZone memory slot identifier
- * \return execution status (1: success, 0: error)
- */
-/* This veneer is TF-M internal, not a secure service */
-__tfm_nspm_secure_gateway_attributes__
-uint32_t TZ_LoadContext_S(TZ_MemoryId_t id)
-{
-#ifdef CONFIG_TFM_ENABLE_CTX_MGMT
-#ifdef TFM_NS_CLIENT_IDENTIFICATION
-    uint32_t index;
-
-    if (__get_active_exc_num() == EXC_NUM_THREAD_MODE) {
-        /* This veneer should only be called by NS RTOS in handler mode */
-        return 0U;
-    }
-
-    if ((id == 0U) || (id > TFM_MAX_NS_THREAD_COUNT)) {
-        /* Invalid TZ_MemoryId_t */
-        return 0U;
-    }
-
-    index = id - 1;
-
-    if (NsClientIdList[index].ns_client_id == INVALID_CLIENT_ID) {
-        /* Non-existent client */
-        return 0U;
-    }
-
-    active_ns_client_idx = index;
-#else /* TFM_NS_CLIENT_IDENTIFICATION */
-    (void)id;
-#endif /* TFM_NS_CLIENT_IDENTIFICATION */
-#else /* CONFIG_TFM_ENABLE_CTX_MGMT */
-    (void)id;
-#endif /* CONFIG_TFM_ENABLE_CTX_MGMT */
-
-    return 1U;    /* Success */
-}
-
-/**
- * Store secure context (called on RTOS thread context switch)
- * \param[in]  id  TrustZone memory slot identifier
- * \return execution status (1: success, 0: error)
- */
-/* This veneer is TF-M internal, not a secure service */
-__tfm_nspm_secure_gateway_attributes__
-uint32_t TZ_StoreContext_S(TZ_MemoryId_t id)
-{
-#ifdef CONFIG_TFM_ENABLE_CTX_MGMT
-#ifdef TFM_NS_CLIENT_IDENTIFICATION
-    uint32_t index;
-
-    if (__get_active_exc_num() == EXC_NUM_THREAD_MODE) {
-        /* This veneer should only be called by NS RTOS in handler mode */
-        return 0U;
-    }
-
-    /* id corresponds to context being swapped out on NS side */
-    if ((id == 0U) || (id > TFM_MAX_NS_THREAD_COUNT)) {
-        /* Invalid TZ_MemoryId_t */
-        return 0U;
-    }
-
-    index = id - 1;
-
-    if (NsClientIdList[index].ns_client_id == INVALID_CLIENT_ID) {
-        /* Non-existent client */
-        return 0U;
-    }
-
-    if (active_ns_client_idx != index) {
-        return 0U;
-    }
-
-    active_ns_client_idx = DEFAULT_NS_CLIENT_IDX;
-#else /* TFM_NS_CLIENT_IDENTIFICATION */
-    (void)id;
-#endif /* TFM_NS_CLIENT_IDENTIFICATION */
-#else /* CONFIG_TFM_ENABLE_CTX_MGMT */
-    (void)id;
-#endif /* CONFIG_TFM_ENABLE_CTX_MGMT */
-
-    return 1U;    /* Success */
-}
-
-#ifdef TFM_NS_CLIENT_IDENTIFICATION
-__tfm_nspm_secure_gateway_attributes__
-enum tfm_status_e tfm_register_client_id(int32_t ns_client_id)
-{
-    int current_client_id;
-
-    if (__get_active_exc_num() == EXC_NUM_THREAD_MODE) {
-        /* This veneer should only be called by NS RTOS in handler mode */
-        return TFM_ERROR_NS_THREAD_MODE_CALL;
-    }
-
-    if (ns_client_id >= 0) {
-        /* The client ID is invalid */
-        return TFM_ERROR_INVALID_PARAMETER;
-    }
-
-    if (active_ns_client_idx < 0) {
-        /* No client is active */
-        return TFM_ERROR_GENERIC;
-    }
-
-    current_client_id = NsClientIdList[active_ns_client_idx].ns_client_id;
-    if (current_client_id >= 0) {
-        /* The client ID is invalid */
-        return TFM_ERROR_INVALID_PARAMETER;
-    }
-
-    NsClientIdList[active_ns_client_idx].ns_client_id = ns_client_id;
-
-    return TFM_SUCCESS;
-}
-#endif
-
 void configure_ns_code(void)
 {
     /* SCB_NS.VTOR points to the Non-secure vector table base address */
diff --git a/secure_fw/spm/cmsis_psa/spm_ipc.c b/secure_fw/spm/cmsis_psa/spm_ipc.c
old mode 100644
new mode 100755
index d78c49c..bf4fd36
--- a/secure_fw/spm/cmsis_psa/spm_ipc.c
+++ b/secure_fw/spm/cmsis_psa/spm_ipc.c
@@ -35,6 +35,7 @@
 #include "load/service_defs.h"
 #include "load/asset_defs.h"
 #include "load/spm_load_api.h"
+#include "tfm_nspm.h"
 
 /* Partition and service runtime data list head/runtime data table */
 static struct service_head_t services_listhead;
@@ -602,6 +603,11 @@
     UNI_LISI_INIT_HEAD(PARTITION_LIST_ADDR);
     UNI_LISI_INIT_HEAD(&services_listhead);
 
+    /* Init the nonsecure context. */
+#ifndef TFM_MULTI_CORE_TOPOLOGY
+     tfm_nspm_ctx_init();
+#endif
+
     while (1) {
         partition = load_a_partition_assuredly(PARTITION_LIST_ADDR);
         if (partition == NO_MORE_PARTITION) {
diff --git a/secure_fw/spm/cmsis_psa/tfm_nspm_ipc.c b/secure_fw/spm/cmsis_psa/tfm_nspm_ipc.c
old mode 100644
new mode 100755
index 6cb3a0c..004ccfb
--- a/secure_fw/spm/cmsis_psa/tfm_nspm_ipc.c
+++ b/secure_fw/spm/cmsis_psa/tfm_nspm_ipc.c
@@ -1,91 +1,12 @@
 /*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
  */
 
-#include <stdbool.h>
 #include "compiler_ext_defs.h"
 #include "tfm_spm_hal.h"
-#include "psa/error.h"
-#include "tfm_nspm.h"
-#include "utilities.h"
-#include "ext/tz_context.h"
-
-#define DEFAULT_NS_CLIENT_ID ((int32_t)-1)
-
-int32_t tfm_nspm_get_current_client_id(void)
-{
-    return DEFAULT_NS_CLIENT_ID;
-}
-
-/* TF-M implementation of the CMSIS TZ RTOS thread context management API */
-
-/**
- * Initialize secure context memory system
- * \return execution status (1: success, 0: error)
- */
-/* This veneer is TF-M internal, not a secure service */
-__tfm_nspm_secure_gateway_attributes__
-uint32_t TZ_InitContextSystem_S(void)
-{
-    return 1U;
-}
-
-/**
- * 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
- */
-/* This veneer is TF-M internal, not a secure service */
-__tfm_nspm_secure_gateway_attributes__
-TZ_MemoryId_t TZ_AllocModuleContext_S(TZ_ModuleId_t module)
-{
-    /* add attribute 'noinline' to avoid a build error. */
-    (void)module;
-    return 1U;
-}
-
-/**
- * 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)
- */
-/* This veneer is TF-M internal, not a secure service */
-__tfm_nspm_secure_gateway_attributes__
-uint32_t TZ_FreeModuleContext_S(TZ_MemoryId_t id)
-{
-    (void)id;
-    return 1U;
-}
-
-/**
- * Load secure context (called on RTOS thread context switch)
- * \param[in]  id  TrustZone memory slot identifier
- * \return execution status (1: success, 0: error)
- */
-/* This veneer is TF-M internal, not a secure service */
-__tfm_nspm_secure_gateway_attributes__
-uint32_t TZ_LoadContext_S(TZ_MemoryId_t id)
-{
-    (void)id;
-    return 1U;
-}
-
-/**
- * Store secure context (called on RTOS thread context switch)
- * \param[in]  id  TrustZone memory slot identifier
- * \return execution status (1: success, 0: error)
- */
-/* This veneer is TF-M internal, not a secure service */
-__tfm_nspm_secure_gateway_attributes__
-uint32_t TZ_StoreContext_S(TZ_MemoryId_t id)
-{
-    (void)id;
-    return 1U;
-}
 
 /*
  * 'r0' impliedly holds the address of non-secure entry,
diff --git a/secure_fw/spm/include/tfm_nspm.h b/secure_fw/spm/include/tfm_nspm.h
index a458fba..8b27d6e 100644
--- a/secure_fw/spm/include/tfm_nspm.h
+++ b/secure_fw/spm/include/tfm_nspm.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -40,12 +40,10 @@
 #endif /* !__ARMCC_VERSION */
 #endif /* __GNUC__ && !TFM_MULTI_CORE_TOPOLOGY */
 
-#ifndef TFM_PSA_API
 /**
  * \brief initialise the NS context database
  */
-void tfm_nspm_configure_clients(void);
-#endif
+void tfm_nspm_ctx_init(void);
 
 /**
  * \brief Get the client ID of the current NS client
diff --git a/secure_fw/spm/ns_client_ext/tfm_spm_ns_ctx.c b/secure_fw/spm/ns_client_ext/tfm_spm_ns_ctx.c
new file mode 100755
index 0000000..313324b
--- /dev/null
+++ b/secure_fw/spm/ns_client_ext/tfm_spm_ns_ctx.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "tfm_nspm.h"
+#include "tfm_ns_ctx.h"
+#include "tfm_ns_client_ext.h"
+
+#define DEFAULT_NS_CLIENT_ID ((int32_t)-1)
+
+int32_t tfm_nspm_get_current_client_id(void)
+{
+#ifdef TFM_NS_MANAGE_NSID
+    int32_t client_id;
+    client_id = get_nsid_from_active_ns_ctx();
+    return (client_id < 0 ? client_id:TFM_NS_CLIENT_INVALID_ID);
+#else
+    return DEFAULT_NS_CLIENT_ID;
+#endif
+}
+
+void tfm_nspm_ctx_init(void)
+{
+#ifdef TFM_NS_MANAGE_NSID
+    if (!init_ns_ctx()) {
+        tfm_core_panic();
+    }
+#endif
+}