SPM: Use global variables as ns agent stack

Use global arrays as stack of the ns agent partition instead
of the ER_INITIAL_PSP. The stack size related settings are
added into the 'config_impl.h' template file.

Change-Id: If8443c6fe02d3f1547c637bd51f0a7352aead0c1
Signed-off-by: Mingyang Sun <mingyang.sun@arm.com>
diff --git a/interface/include/config_impl.h.template b/interface/include/config_impl.h.template
index 96ea631..5af682a 100644
--- a/interface/include/config_impl.h.template
+++ b/interface/include/config_impl.h.template
@@ -11,17 +11,26 @@
 #define __CONFIG_IMPL_H__
 
 {% if ipc_partition_num > 0 and sfn_partition_num == 0 %}
+/* IPC model */
 #define {{"%-56s"|format("CONFIG_TFM_SPM_BACKEND_IPC")}} 1
 
+/* Trustzone NS agent working stack size. */
+#define {{"%-56s"|format("CONFIG_TFM_NS_AGENT_TZ_STACK_SIZE")}} 1024
+
 #if TFM_LVL > 1
 #define {{"%-56s"|format("CONFIG_TFM_PSA_API_SUPERVISOR_CALL")}} 1
-#else
+#else /* TFM_LVL > 1 */
 #define {{"%-56s"|format("CONFIG_TFM_PSA_API_THREAD_CALL")}} 1
-#define {{"%-56s"|format("CONFIG_TFM_SPM_THREAD_STACK_SIZE")}} 1024
-#endif
+
+/* SPM re-uses Trustzone NS agent stack. */
+#define {{"%-56s"|format("CONFIG_TFM_SPM_THREAD_STACK_SIZE")}}     \
+            {{"%-56s"|format("CONFIG_TFM_NS_AGENT_TZ_STACK_SIZE")}}
+#endif /* TFM_LVL > 1 */
 
 {% elif sfn_partition_num > 0 and ipc_partition_num == 0 %}
+/* SFN model */
 #define {{"%-56s"|format("CONFIG_TFM_SPM_BACKEND_SFN")}} 1
+#define {{"%-56s"|format("CONFIG_TFM_PSA_API_SFN_CALL")}} 1
 
 #if TFM_LVL > 1
 #error "High isolation level SFN model is not supported."
@@ -35,7 +44,17 @@
             {% set total_stk.size = total_stk.size + partition.manifest.stack_size|int(base=10) %}
         {% endif %}
     {% endfor %}
-#define {{"%-36s"|format("SUM_OF_PARTITION_STACK_SIZES")}} ((({{"0x%x"|format(total_stk.size)}} >> 1) + 0x7) & (~0x7))
+/*
+ * In isolation level 1 SFN model, all subsequent components work on NS agent
+ * stack. It is observed that half of the sum of all partition stack sizes is
+ * enough for working. Define a divisor factor
+ * CONFIG_TFM_NS_AGENT_TZ_STK_SIZE_SHIFT_FACTOR for reference, and allow
+ * modification of the factor based on application situation. The stack size
+ * value is aligned to 8 bytes.
+ */
+#define CONFIG_TFM_NS_AGENT_TZ_STK_SIZE_SHIFT_FACTOR             1
+#define {{"%-56s"|format("CONFIG_TFM_NS_AGENT_TZ_STACK_SIZE")}} \
+    ((({{"0x%x"|format(total_stk.size)}} >> CONFIG_TFM_NS_AGENT_TZ_STK_SIZE_SHIFT_FACTOR) + 0x7) & (~0x7))
 
 {% elif sfn_partition_num > 0 and ipc_partition_num > 0 %}
 #error "IPC and SFN co-work not supported yet."
diff --git a/secure_fw/partitions/ns_agent/CMakeLists.txt b/secure_fw/partitions/ns_agent/CMakeLists.txt
index 0f5bfac..e9bfbb4 100644
--- a/secure_fw/partitions/ns_agent/CMakeLists.txt
+++ b/secure_fw/partitions/ns_agent/CMakeLists.txt
@@ -8,7 +8,24 @@
 cmake_minimum_required(VERSION 3.15)
 cmake_policy(SET CMP0079 NEW)
 
+if(NOT TFM_PSA_API)
+    return()
+endif()
+
+target_sources(tfm_spm
+    PRIVATE
+        $<$<NOT:$<BOOL:${TFM_MULTI_CORE_TOPOLOGY}>>:${CMAKE_CURRENT_SOURCE_DIR}/ns_agent.c>
+)
+
 target_sources(tfm_partitions
     INTERFACE
-        $<$<BOOL:${TFM_PSA_API}>:${CMAKE_CURRENT_SOURCE_DIR}/load_info_ns_agent.c>
+        ${CMAKE_CURRENT_SOURCE_DIR}/load_info_ns_agent.c
+)
+
+# If this is added to the spm, it is discarded as it is not used. Since the
+# spm is a static library it can't generate veneers under all compilers so
+# instead this single file is added to the tfm_s target.
+target_sources(tfm_s
+    PRIVATE
+        $<$<NOT:$<BOOL:${TFM_MULTI_CORE_TOPOLOGY}>>:${CMAKE_CURRENT_SOURCE_DIR}/tfm_psa_api_veneers.c>
 )
diff --git a/secure_fw/partitions/ns_agent/load_info_ns_agent.c b/secure_fw/partitions/ns_agent/load_info_ns_agent.c
index 94f7e4c..ebd854a 100644
--- a/secure_fw/partitions/ns_agent/load_info_ns_agent.c
+++ b/secure_fw/partitions/ns_agent/load_info_ns_agent.c
@@ -9,8 +9,8 @@
 
 #include <stdint.h>
 #include <stddef.h>
-#include "region.h"
-#include "region_defs.h"
+#include "compiler_ext_defs.h"
+#include "config_impl.h"
 #include "spm_ipc.h"
 #include "load/partition_defs.h"
 #include "load/service_defs.h"
@@ -22,13 +22,12 @@
 #define TFM_SP_NS_AGENT_NASSETS                                 (1)
 #endif
 
-/* Memory region declaration */
-REGION_DECLARE(Image$$, ER_INITIAL_PSP, $$ZI$$Base);
-REGION_DECLARE(Image$$, ER_INITIAL_PSP, $$ZI$$Limit);
-
 /* Entrypoint function declaration */
 extern void tfm_nspm_thread_entry(void);
 
+/* Stack */
+uint8_t ns_agent_tz_stack[CONFIG_TFM_NS_AGENT_TZ_STACK_SIZE] __aligned(0x20);
+
 struct partition_tfm_sp_ns_agent_load_info_t {
     /* common length load data */
     struct partition_load_info_t    load_info;
@@ -52,12 +51,9 @@
         .pid                        = TFM_SP_NON_SECURE_ID,
         .flags                      = (PARTITION_PRI_LOWEST - 1)
                                     | PARTITION_MODEL_IPC
-#if TFM_MULTI_CORE_TOPOLOGY
-                                    | PARTITION_MODEL_PSA_ROT
-#endif
-                                    ,
+                                    | PARTITION_MODEL_PSA_ROT,
         .entry                      = ENTRY_TO_POSITION(tfm_nspm_thread_entry),
-        .stack_size                 = S_PSP_STACK_SIZE,
+        .stack_size                 = CONFIG_TFM_NS_AGENT_TZ_STACK_SIZE,
         .heap_size                  = 0,
         .ndeps                      = TFM_SP_NS_AGENT_NDEPS,
         .nservices                  = TFM_SP_NS_AGENT_NSERVS,
@@ -65,16 +61,14 @@
         .nassets                    = TFM_SP_NS_AGENT_NASSETS,
 #endif
     },
-    .stack_addr                     = PART_REGION_ADDR(ER_INITIAL_PSP,
-                                                                    $$ZI$$Base),
+    .stack_addr                     = (uintptr_t)ns_agent_tz_stack,
     .heap_addr                      = 0,
 #if TFM_LVL == 3
     .assets                         = {
         {
-            .mem.start              = PART_REGION_ADDR(ER_INITIAL_PSP,
-                                                                    $$ZI$$Base),
-            .mem.limit              = PART_REGION_ADDR(ER_INITIAL_PSP,
-                                                                   $$ZI$$Limit),
+            .mem.start              = (uintptr_t)ns_agent_tz_stack,
+            .mem.limit              =
+               (uintptr_t)&ns_agent_tz_stack[CONFIG_TFM_NS_AGENT_TZ_STACK_SIZE],
             .attr                   = ASSET_ATTR_READ_WRITE,
         },
     },
diff --git a/secure_fw/partitions/ns_agent/ns_agent.c b/secure_fw/partitions/ns_agent/ns_agent.c
new file mode 100644
index 0000000..409641e
--- /dev/null
+++ b/secure_fw/partitions/ns_agent/ns_agent.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "compiler_ext_defs.h"
+#include "tfm_arch.h"
+
+/*
+ * 'r0' implicitly holds the address of non-secure entry,
+ * given during non-secure partition initialization.
+ */
+__naked void tfm_nspm_thread_entry(void)
+{
+    __ASM volatile(
+#ifndef __ICCARM__
+        ".syntax unified         \n"
+#endif
+        "mov      r4, r0         \n"
+        "movs     r2, #1         \n" /* Clear Bit[0] for S to NS transition */
+        "bics     r4, r2         \n"
+        "mov      r0, r4         \n"
+        "mov      r1, r4         \n"
+        "mov      r2, r4         \n"
+        "mov      r3, r4         \n"
+        "mov      r5, r4         \n"
+        "mov      r6, r4         \n"
+        "mov      r7, r4         \n"
+        "mov      r8, r4         \n"
+        "mov      r9, r4         \n"
+        "mov      r10, r4        \n"
+        "mov      r11, r4        \n"
+        "mov      r12, r4        \n"
+        "bxns     r0             \n"
+    );
+}
diff --git a/secure_fw/spm/cmsis_psa/tfm_psa_api_veneers.c b/secure_fw/partitions/ns_agent/tfm_psa_api_veneers.c
similarity index 99%
rename from secure_fw/spm/cmsis_psa/tfm_psa_api_veneers.c
rename to secure_fw/partitions/ns_agent/tfm_psa_api_veneers.c
index c400845..1de8b1d 100644
--- a/secure_fw/spm/cmsis_psa/tfm_psa_api_veneers.c
+++ b/secure_fw/partitions/ns_agent/tfm_psa_api_veneers.c
@@ -9,12 +9,11 @@
 #include <stdio.h>
 #include "config_impl.h"
 #include "security_defs.h"
-#include "tfm_psa_call_pack.h"
-#include "tfm_arch.h"
-#include "tfm_secure_api.h"
-#include "tfm_api.h"
-#include "tfm_svcalls.h"
+#include "svc_num.h"
 #include "utilities.h"
+#include "tfm_arch.h"
+#include "tfm_psa_call_pack.h"
+#include "tfm_secure_api.h"
 
 #ifdef CONFIG_TFM_PSA_API_THREAD_CALL
 #include "spm_ipc.h"
diff --git a/secure_fw/spm/CMakeLists.txt b/secure_fw/spm/CMakeLists.txt
index 6cc5540..2eed0af 100755
--- a/secure_fw/spm/CMakeLists.txt
+++ b/secure_fw/spm/CMakeLists.txt
@@ -181,7 +181,6 @@
     target_sources(tfm_s
         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_psa/tfm_nspm_ipc.c b/secure_fw/spm/cmsis_psa/tfm_nspm_ipc.c
index 004ccfb..6d6f325 100755
--- a/secure_fw/spm/cmsis_psa/tfm_nspm_ipc.c
+++ b/secure_fw/spm/cmsis_psa/tfm_nspm_ipc.c
@@ -8,36 +8,6 @@
 #include "compiler_ext_defs.h"
 #include "tfm_spm_hal.h"
 
-/*
- * 'r0' impliedly holds the address of non-secure entry,
- * given during non-secure partition initialization.
- */
-__section("SFN") __naked
-void tfm_nspm_thread_entry(void)
-{
-    __ASM volatile(
-#ifndef __ICCARM__
-        ".syntax unified         \n"
-#endif
-        "mov      r4, r0         \n"
-        "movs     r2, #1         \n" /* Clear Bit[0] for S to NS transition */
-        "bics     r4, r2         \n"
-        "mov      r0, r4         \n"
-        "mov      r1, r4         \n"
-        "mov      r2, r4         \n"
-        "mov      r3, r4         \n"
-        "mov      r5, r4         \n"
-        "mov      r6, r4         \n"
-        "mov      r7, r4         \n"
-        "mov      r8, r4         \n"
-        "mov      r9, r4         \n"
-        "mov      r10, r4        \n"
-        "mov      r11, r4        \n"
-        "mov      r12, r4        \n"
-        "bxns     r0             \n"
-    );
-}
-
 void configure_ns_code(void)
 {
     /* SCB_NS.VTOR points to the Non-secure vector table base address */