Core: Use the stack region in the linker file

Using array to store stack will consume lots of memory. To let all
platforms have enough RAM space, change to use every partition's own
stack from linker script.
 - Use tfm_spm_partition_memory_data_t to store memory information
   instead of unified stack size in level 1.
 - Initialize partition thread stack range with its own size.
 - Remove the unified stack size member from the spm_partition_desc_t
   structure for level 1.
 - Make tfm_spm_partition_get_stack_bottom() and
   tfm_spm_partition_get_stack_top() functions available for all levels.
 - Remove tfm_spm_partition_get_stack_base_ext() and
   tfm_spm_partition_get_stack_limit_ext() functions.

Change-Id: I2025a49957d60df47e693049fc04146a7ed97b62
Signed-off-by: Summer Qin <summer.qin@arm.com>
diff --git a/platform/include/tfm_spm_hal.h b/platform/include/tfm_spm_hal.h
index 509f153..f1a82a0 100644
--- a/platform/include/tfm_spm_hal.h
+++ b/platform/include/tfm_spm_hal.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -28,7 +28,6 @@
  */
 struct tfm_spm_partition_platform_data_t;
 
-#if TFM_LVL != 1
 /**
  * \brief Holds SPM db fields that define the memory regions used by a
  *        partition.
@@ -58,7 +57,6 @@
     uint32_t stack_bottom; /*!< The bottom of the stack for the partition. */
     uint32_t stack_top;    /*!< The top of the stack for the partition. */
 };
-#endif
 
 /**
  * \brief This function initialises the HW used for isolation, and sets the
diff --git a/secure_fw/core/ipc/tfm_spm.c b/secure_fw/core/ipc/tfm_spm.c
index 8d95ca5..6024369 100644
--- a/secure_fw/core/ipc/tfm_spm.c
+++ b/secure_fw/core/ipc/tfm_spm.c
@@ -431,19 +431,6 @@
     return &g_spm_partition_db.partitions[partition_idx].sp_thrd;
 }
 
-#if TFM_LVL == 1
-static uint32_t tfm_spm_partition_get_stack_base_ext(uint32_t partition_idx)
-{
-    return (uint32_t)&(g_spm_partition_db.partitions[partition_idx].
-                       stack[TFM_STACK_SIZE]);
-}
-
-static uint32_t tfm_spm_partition_get_stack_limit_ext(uint32_t partition_idx)
-{
-    return (uint32_t)&g_spm_partition_db.partitions[partition_idx].stack;
-}
-#endif
-
 static tfm_thrd_func_t
         tfm_spm_partition_get_init_func_ext(uint32_t partition_idx)
 {
@@ -541,13 +528,8 @@
         tfm_thrd_init(pth,
                       tfm_spm_partition_get_init_func_ext(i),
                       NULL,
-#if TFM_LVL == 1
-                      (uint8_t *)tfm_spm_partition_get_stack_base_ext(i),
-                      (uint8_t *)tfm_spm_partition_get_stack_limit_ext(i));
-#else
                       (uint8_t *)tfm_spm_partition_get_stack_top(i),
                       (uint8_t *)tfm_spm_partition_get_stack_bottom(i));
-#endif
 
         pth->prior = tfm_spm_partition_get_priority_ext(i);
 
diff --git a/secure_fw/spm/spm_api.c b/secure_fw/spm/spm_api.c
index 05d6c8d..5f10465 100644
--- a/secure_fw/spm/spm_api.c
+++ b/secure_fw/spm/spm_api.c
@@ -98,12 +98,10 @@
      */
 
     /* For the non secure Execution environment */
-#if TFM_LVL != 1
     extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Base[];
     extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit[];
     uint32_t psp_stack_bottom = (uint32_t)Image$$ARM_LIB_STACK$$ZI$$Base;
     uint32_t psp_stack_top    = (uint32_t)Image$$ARM_LIB_STACK$$ZI$$Limit;
-#endif
     if (g_spm_partition_db.partition_count >= SPM_MAX_PARTITIONS) {
         return SPM_ERR_INVALID_CONFIG;
     }
@@ -119,14 +117,12 @@
     part_ptr->static_data.partition_flags = 0;
 #endif
 
-#if TFM_LVL != 1
     part_ptr->memory_data.stack_bottom = psp_stack_bottom;
     part_ptr->memory_data.stack_top    = psp_stack_top;
     /* Since RW, ZI and stack are configured as one MPU region, configure
      * RW start address to psp_stack_bottom to get RW access to stack
      */
     part_ptr->memory_data.rw_start     = psp_stack_bottom;
-#endif
 
     part_ptr->runtime_data.partition_state = SPM_PARTITION_STATE_UNINIT;
     tfm_nspm_configure_clients();
@@ -202,6 +198,17 @@
     }
 }
 
+uint32_t tfm_spm_partition_get_stack_bottom(uint32_t partition_idx)
+{
+    return g_spm_partition_db.partitions[partition_idx].
+            memory_data.stack_bottom;
+}
+
+uint32_t tfm_spm_partition_get_stack_top(uint32_t partition_idx)
+{
+    return g_spm_partition_db.partitions[partition_idx].memory_data.stack_top;
+}
+
 #if TFM_LVL != 1
 enum spm_err_t tfm_spm_partition_sandbox_config(uint32_t partition_idx)
 {
@@ -231,17 +238,6 @@
                                                   part->platform_data);
 }
 
-uint32_t tfm_spm_partition_get_stack_bottom(uint32_t partition_idx)
-{
-    return g_spm_partition_db.partitions[partition_idx].
-            memory_data.stack_bottom;
-}
-
-uint32_t tfm_spm_partition_get_stack_top(uint32_t partition_idx)
-{
-    return g_spm_partition_db.partitions[partition_idx].memory_data.stack_top;
-}
-
 uint32_t tfm_spm_partition_get_zi_start(uint32_t partition_idx)
 {
     return g_spm_partition_db.partitions[partition_idx].
diff --git a/secure_fw/spm/spm_api.h b/secure_fw/spm/spm_api.h
index c78836d..c0122d6 100644
--- a/secure_fw/spm/spm_api.h
+++ b/secure_fw/spm/spm_api.h
@@ -87,6 +87,28 @@
  */
 uint32_t get_partition_idx(uint32_t partition_id);
 
+/**
+ * \brief Get bottom of stack region for a partition
+ *
+ * \param[in] partition_idx     Partition index
+ *
+ * \return Stack region bottom value
+ *
+ * \note This function doesn't check if partition_idx is valid.
+ */
+uint32_t tfm_spm_partition_get_stack_bottom(uint32_t partition_idx);
+
+/**
+ * \brief Get top of stack region for a partition
+ *
+ * \param[in] partition_idx     Partition index
+ *
+ * \return Stack region top value
+ *
+ * \note This function doesn't check if partition_idx is valid.
+ */
+uint32_t tfm_spm_partition_get_stack_top(uint32_t partition_idx);
+
 #if TFM_LVL != 1
 /**
  * \brief Configure isolated sandbox for a partition
@@ -111,28 +133,6 @@
 enum spm_err_t tfm_spm_partition_sandbox_deconfig(uint32_t partition_idx);
 
 /**
- * \brief Get bottom of stack region for a partition
- *
- * \param[in] partition_idx     Partition index
- *
- * \return Stack region bottom value
- *
- * \note This function doesn't check if partition_idx is valid.
- */
-uint32_t tfm_spm_partition_get_stack_bottom(uint32_t partition_idx);
-
-/**
- * \brief Get top of stack region for a partition
- *
- * \param[in] partition_idx     Partition index
- *
- * \return Stack region top value
- *
- * \note This function doesn't check if partition_idx is valid.
- */
-uint32_t tfm_spm_partition_get_stack_top(uint32_t partition_idx);
-
-/**
  * \brief Get the start of the zero-initialised region for a partition
  *
  * \param[in] partition_idx     Partition idx
diff --git a/secure_fw/spm/spm_db.h b/secure_fw/spm/spm_db.h
index 8a9568b..b8827b4 100644
--- a/secure_fw/spm/spm_db.h
+++ b/secure_fw/spm/spm_db.h
@@ -21,10 +21,6 @@
 #define TFM_PARTITION_TYPE_APP   "APPLICATION-ROT"
 #define TFM_PARTITION_TYPE_PSA   "PSA-ROT"
 
-#if TFM_LVL == 1
-#define TFM_STACK_SIZE           (1024 * 5)
-#endif
-
 #ifdef TFM_PSA_API
 enum tfm_partition_priority {
     TFM_PRIORITY_LOW = THRD_PRIOR_LOWEST,
@@ -61,31 +57,17 @@
     struct spm_partition_static_data_t static_data;
     struct spm_partition_runtime_data_t runtime_data;
     struct tfm_spm_partition_platform_data_t *platform_data;
-#if TFM_LVL != 1
     struct tfm_spm_partition_memory_data_t memory_data;
-#endif
 #ifdef TFM_PSA_API
     struct tfm_thrd_ctx sp_thrd;
-    /*
-     * FixMe: Hard code stack is not aligned with the definition in the
-     * manifest. It will use the partition stacks in the linker scripts/sct
-     * files include Level 1 to 3.
-     */
-#if TFM_LVL == 1
-    uint8_t stack[TFM_STACK_SIZE] __attribute__((aligned(8)));
-#endif
 #endif
 };
 
 /* Macros to pick linker symbols and allow to form the partition data base */
 #define REGION(a, b, c) a##b##c
 #define REGION_NAME(a, b, c) REGION(a, b, c)
-#if TFM_LVL == 1
-#define REGION_DECLARE(a, b, c)
-#else
 #define REGION_DECLARE(a, b, c) extern uint32_t REGION_NAME(a, b, c)
 #define PART_REGION_ADDR(partition, region) \
     (uint32_t)&REGION_NAME(Image$$, partition, region)
-#endif
 
 #endif /* __SPM_DB_H__ */
diff --git a/secure_fw/spm/spm_db_setup.h b/secure_fw/spm/spm_db_setup.h
index 57da372..1e91271 100644
--- a/secure_fw/spm/spm_db_setup.h
+++ b/secure_fw/spm/spm_db_setup.h
@@ -38,9 +38,6 @@
         data.partition_priority = TFM_PRIORITY(priority);                     \
     } while (0)
 
-#if TFM_LVL == 1
-#define PARTITION_INIT_MEMORY_DATA(data, partition)
-#else
 #define PARTITION_INIT_MEMORY_DATA(data, partition)                            \
     do {                                                                       \
         data.code_start      = PART_REGION_ADDR(partition, $$Base);            \
@@ -54,7 +51,6 @@
         data.stack_bottom    = PART_REGION_ADDR(partition, _STACK$$ZI$$Base);  \
         data.stack_top       = PART_REGION_ADDR(partition, _STACK$$ZI$$Limit); \
     } while (0)
-#endif
 
 
 #if TFM_LVL == 1