SPM: Use Main Stack for initialization

On reset, the Main Stack is used by default.
TF-M changes the stack to Processor Stack.

This patch remove the change to PSP in startup.s and:
- Rename the ARM_LIB_STACK to ER_INITIAL_PSP
- Rename the ARM_LIB_STACK_MSP to ARM_LIB_STACK
The renaming is to align the __main function of ARMClang where the
ARM_LIB_STACK is set to the current SP (MSP)

For Library Mode, the stacks are set to back to use PSP before entering
c code to avoid massive corresponding changes.

For FF-M implementations, this patch also:
- Seal the Main Stack before entering c code
- Manually free the Main Stack usage after initialization as the init
  function does not return

Change-Id: Ie1b6f2fca1f774c4812a89fa45bb039b16fe5af0
Signed-off-by: Kevin Peng <kevin.peng@arm.com>
Co-authored-by: Summer Qin <summer.qin@arm.com>
diff --git a/secure_fw/spm/cmsis_psa/arch/tfm_arch.c b/secure_fw/spm/cmsis_psa/arch/tfm_arch.c
index 3d9f076..1d3e371 100644
--- a/secure_fw/spm/cmsis_psa/arch/tfm_arch.c
+++ b/secure_fw/spm/cmsis_psa/arch/tfm_arch.c
@@ -8,7 +8,23 @@
 #include "svc_num.h"
 #include "tfm_arch.h"
 #include "tfm_core_utils.h"
+#include "utilities.h"
 
+__attribute__((naked)) void tfm_arch_free_msp_and_exc_ret(uint32_t exc_return)
+{
+    __ASM volatile(
+#if !defined(__ICCARM__)
+        ".syntax unified                  \n"
+#endif
+        "MOV     lr, r0                   \n"
+        "LDR     r0, ="M2S(VTOR_BASE)"    \n" /* VTOR */
+        "LDR     r0, [r0]                 \n" /* MSP address */
+        "LDR     r0, [r0]                 \n" /* MSP */
+        "SUBS    r0, #8                   \n" /* Exclude stack seal */
+        "MSR     msp, r0                  \n" /* Free Main Stack space */
+        "BX      lr                       \n"
+    );
+}
 
 static void tfm_arch_init_state_ctx(struct tfm_state_context_t *p_stat_ctx,
                                     void *param, uintptr_t pfn)
diff --git a/secure_fw/spm/cmsis_psa/arch/tfm_arch_v6m_v7m.h b/secure_fw/spm/cmsis_psa/arch/tfm_arch_v6m_v7m.h
index b29af05..fca3fa0 100644
--- a/secure_fw/spm/cmsis_psa/arch/tfm_arch_v6m_v7m.h
+++ b/secure_fw/spm/cmsis_psa/arch/tfm_arch_v6m_v7m.h
@@ -35,6 +35,8 @@
 #define EXC_NUM_SVCALL                          (11)
 #define EXC_NUM_PENDSV                          (14)
 
+#define VTOR_BASE                       (0xE000ED08)
+
 struct tfm_arch_ctx_t {
     uint32_t    r8;
     uint32_t    r9;
@@ -110,6 +112,20 @@
 }
 
 /**
+ * \brief Set MSP limit value.
+ *
+ * \param[in] msplim        MSP limit value to be written.
+ */
+__STATIC_INLINE void tfm_arch_set_msplim(uint32_t msplim)
+{
+    /*
+     * Defined as an empty function now.
+     * The MSP limit value can be used in more strict memory check.
+     */
+    (void)msplim;
+}
+
+/**
  * \brief Seal the thread stack.
  *
  * \param[in] stk        Thread stack address.
diff --git a/secure_fw/spm/cmsis_psa/main.c b/secure_fw/spm/cmsis_psa/main.c
index 7d34578..30cae8b 100644
--- a/secure_fw/spm/cmsis_psa/main.c
+++ b/secure_fw/spm/cmsis_psa/main.c
@@ -31,7 +31,7 @@
 #error Invalid TFM_LVL value. Only TFM_LVL 1, 2 and 3 are supported in IPC model!
 #endif
 
-REGION_DECLARE(Image$$, ARM_LIB_STACK_MSP,  $$ZI$$Base);
+REGION_DECLARE(Image$$, ARM_LIB_STACK, $$ZI$$Base);
 
 static fih_int tfm_core_init(void)
 {
@@ -123,13 +123,24 @@
     FIH_RET(fih_int_encode(TFM_SUCCESS));
 }
 
+__attribute__((naked))
 int main(void)
 {
+    __ASM volatile(
+        "ldr    r0, =0xFEF5EDA5     \n" /* Seal Main Stack before using */
+        "ldr    r1, =0xFEF5EDA5     \n"
+        "push   {r0, r1}            \n"
+        "bl     c_main              \n"
+    );
+}
+
+int c_main(void)
+{
     fih_int fih_rc = FIH_FAILURE;
 
     /* set Main Stack Pointer limit */
-    tfm_arch_init_secure_msp((uint32_t)&REGION_NAME(Image$$, ARM_LIB_STACK_MSP,
-                                               $$ZI$$Base));
+    tfm_arch_set_msplim((uint32_t)&REGION_NAME(Image$$, ARM_LIB_STACK,
+                                                                   $$ZI$$Base));
 
     fih_delay_init();
 
@@ -152,4 +163,6 @@
 
     /* Move to handler mode for further SPM initialization. */
     tfm_core_handler_mode();
+
+    return 0;
 }
diff --git a/secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c b/secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c
index dd3c48c..0987f07 100644
--- a/secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c
+++ b/secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c
@@ -22,7 +22,7 @@
 #include "psa/client.h"
 
 /* MSP bottom (higher address) */
-REGION_DECLARE(Image$$, ARM_LIB_STACK_MSP, $$ZI$$Limit);
+REGION_DECLARE(Image$$, ARM_LIB_STACK, $$ZI$$Limit);
 
 #ifdef PLATFORM_SVC_HANDLERS
 extern int32_t platform_svc_handlers(uint8_t svc_num,
@@ -176,7 +176,7 @@
     struct partition_t *curr_sp, *prev_sp;
     struct tfm_svc_flih_ctx_t *flih_ctx;
     uint32_t msp_top =
-                (uint32_t)&REGION_NAME(Image$$, ARM_LIB_STACK_MSP, $$ZI$$Limit);
+                (uint32_t)&REGION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Limit);
 
     /* Skip one tfm_svc_flih_ctx_t + 8 words (R4- R11) + seals (2 words) */
     flih_ctx = (struct tfm_svc_flih_ctx_t *)
@@ -257,6 +257,8 @@
     case TFM_SVC_SPM_INIT:
         tfm_arch_clear_fp_status();
         exc_return = tfm_spm_init();
+        /* The following call does not return */
+        tfm_arch_free_msp_and_exc_ret(exc_return);
         break;
     case TFM_SVC_GET_BOOT_DATA:
         tfm_core_get_boot_data_handler(svc_args);
@@ -268,7 +270,7 @@
         exc_return = tfm_flih_return_to_isr(flih_ctx, svc_args[0]);
         break;
     default:
-        if (((uint32_t)&REGION_NAME(Image$$, ARM_LIB_STACK_MSP, $$ZI$$Limit)
+        if (((uint32_t)&REGION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Limit)
                                      - (uint32_t)msp) > TFM_STACK_SEALED_SIZE) {
             /* The Main Stack has contents, not calling from Partition thread */
             tfm_core_panic();