Platform: get addresses of memory regions based on linker symbols

Replaces the defines to linker symbols to get memory region's address:
  - Linking TF-M to two different partitions requires this change,
    because memory config is not static anymore, instead it is just
    finalized during linking time.
  - New load regions were added to linker config file to cover
    non-secure partition and secondary image partition.
  - Addresses of memory regions can be set only at linking time.
  - Linker symbols are used during HW configuration.

Change-Id: I05645120a3a48ced578d1aec685d82a3a27823d3
Signed-off-by: Tamas Ban <tamas.ban@arm.com>
diff --git a/cmake/Common/CompilerGNUARMCommon.cmake b/cmake/Common/CompilerGNUARMCommon.cmake
index b3662f9..6a06781 100644
--- a/cmake/Common/CompilerGNUARMCommon.cmake
+++ b/cmake/Common/CompilerGNUARMCommon.cmake
@@ -92,8 +92,7 @@
 	#Create additional target if linker script needs to be pre-processed.
 	if (_MY_PARAMS_DEFINES OR _MY_PARAMS_INCLUDES)
 		#Name of pre-processed linker script file.
-		get_filename_component(FINAL_LD_FILE_NAME ${_MY_PARAMS_PATH} NAME)
-		set(FINAL_LD_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/${FINAL_LD_FILE_NAME}.i")
+		set(FINAL_LD_FILE_NAME "${CMAKE_CURRENT_BINARY_DIR}/${_MY_PARAMS_TARGET}.ld.i")
 		#Name of the target doing the pre-processing
 		set(LD_PP_TARGET_NAME "${_MY_PARAMS_TARGET}_ldpp")
 		#The target definition.
diff --git a/platform/ext/target/mps2/an519/armclang/mps2_an519_s.sct b/platform/ext/target/mps2/an519/armclang/mps2_an519_s.sct
index 529fc28..f34926c 100644
--- a/platform/ext/target/mps2/an519/armclang/mps2_an519_s.sct
+++ b/platform/ext/target/mps2/an519/armclang/mps2_an519_s.sct
@@ -154,3 +154,24 @@
         *(Veneer$$CMSE)
     }
 }
+
+LR_NS_PARTITION NS_PARTITION_START {
+    /* Reserved place for NS application.
+     * No code will be placed here, just address of this region is used in the
+     * secure code to configure certain HW components.
+     */
+    ER_NS_PARTITION NS_PARTITION_START EMPTY NS_PARTITION_SIZE {
+    }
+}
+
+#ifdef BL2
+LR_SECONDARY_PARTITION SECONDARY_PARTITION_START {
+    /* Reserved place for new image in case of firmware upgrade.
+     * No code will be placed here, just address of this region is used in the
+     * secure code to configure certain HW components.
+     */
+    ER_SECONDARY_PARTITION SECONDARY_PARTITION_START \
+        EMPTY SECONDARY_PARTITION_SIZE {
+    }
+}
+#endif /* BL2 */
diff --git a/platform/ext/target/mps2/an519/partition/region_defs.h b/platform/ext/target/mps2/an519/partition/region_defs.h
index 91ba42b..ab08f11 100644
--- a/platform/ext/target/mps2/an519/partition/region_defs.h
+++ b/platform/ext/target/mps2/an519/partition/region_defs.h
@@ -28,12 +28,22 @@
  */
 
 #ifdef BL2
-#define  S_IMAGE_PRIMARY_PARTITION_OFFSET (FLASH_AREA_IMAGE_0_OFFSET)
+#ifndef LINK_TO_SECONDARY_PARTITION
+#define  S_IMAGE_PRIMARY_PARTITION_OFFSET   (FLASH_AREA_IMAGE_0_OFFSET)
+#define  S_IMAGE_SECONDARY_PARTITION_OFFSET (FLASH_AREA_IMAGE_1_OFFSET)
+#else
+#define  S_IMAGE_PRIMARY_PARTITION_OFFSET   (FLASH_AREA_IMAGE_1_OFFSET)
+#define  S_IMAGE_SECONDARY_PARTITION_OFFSET (FLASH_AREA_IMAGE_0_OFFSET)
+#endif /* !LINK_TO_SECONDARY_PARTITION */
 #else
 #define  S_IMAGE_PRIMARY_PARTITION_OFFSET (0x0)
 #endif /* BL2 */
 
+#ifndef LINK_TO_SECONDARY_PARTITION
 #define NS_IMAGE_PRIMARY_PARTITION_OFFSET (0x100000)
+#else
+#define NS_IMAGE_PRIMARY_PARTITION_OFFSET (0x200000)
+#endif /* !LINK_TO_SECONDARY_PARTITION */
 
 /*
  * Boot partition structure if MCUBoot is used:
@@ -43,7 +53,8 @@
  */
 /* IMAGE_CODE_SIZE is the space available for the software binary image.
  * It is less than the FLASH_PARTITION_SIZE because we reserve space
- * for the image header and trailer introduced by the bootloader. */
+ * for the image header and trailer introduced by the bootloader.
+ */
 #ifdef BL2
 #define BL2_HEADER_SIZE      (0x400)
 #define BL2_TRAILER_SIZE     (0x10000)
@@ -75,7 +86,7 @@
 
 /* Secure regions */
 #define  S_IMAGE_PRIMARY_AREA_OFFSET \
-            (S_IMAGE_PRIMARY_PARTITION_OFFSET + BL2_HEADER_SIZE)
+             (S_IMAGE_PRIMARY_PARTITION_OFFSET + BL2_HEADER_SIZE)
 #define S_CODE_START    (S_ROM_ALIAS(S_IMAGE_PRIMARY_AREA_OFFSET))
 #define S_CODE_SIZE     (IMAGE_CODE_SIZE - CMSE_VENEER_REGION_SIZE)
 #define S_CODE_LIMIT    (S_CODE_START + S_CODE_SIZE - 1)
@@ -86,32 +97,29 @@
 
 /* CMSE Veneers region */
 #define CMSE_VENEER_REGION_START  (S_CODE_LIMIT + 1)
-#define CMSE_VENEER_REGION_LIMIT  (CMSE_VENEER_REGION_START + \
-                                   CMSE_VENEER_REGION_SIZE - 1)
 
 /* Non-secure regions */
 #define NS_IMAGE_PRIMARY_AREA_OFFSET \
-                        (NS_IMAGE_PRIMARY_PARTITION_OFFSET + BL2_HEADER_SIZE)
+            (NS_IMAGE_PRIMARY_PARTITION_OFFSET + BL2_HEADER_SIZE)
 #define NS_CODE_START   (NS_ROM_ALIAS(NS_IMAGE_PRIMARY_AREA_OFFSET))
 #define NS_CODE_SIZE    (IMAGE_CODE_SIZE)
 #define NS_CODE_LIMIT   (NS_CODE_START + NS_CODE_SIZE - 1)
 
-/* NS partition information is used for MPC configuration */
+#define NS_DATA_START   (NS_RAM_ALIAS(TOTAL_RAM_SIZE/2))
+#define NS_DATA_SIZE    (TOTAL_RAM_SIZE/2)
+#define NS_DATA_LIMIT   (NS_DATA_START + NS_DATA_SIZE - 1)
+
+/* NS partition information is used for MPC and SAU configuration */
 #define NS_PARTITION_START \
             (NS_ROM_ALIAS(NS_IMAGE_PRIMARY_PARTITION_OFFSET))
 
-#ifdef BL2
-/* Cover: non-secure primary + secure secondary + non-secure secondary area */
-#define NS_PARTITION_LIMIT \
-            (NS_PARTITION_START + 3 * FLASH_PARTITION_SIZE - 1)
-#else
-#define NS_PARTITION_LIMIT \
-            (NS_PARTITION_START + FLASH_PARTITION_SIZE - 1)
-#endif /* BL2 */
+#define NS_PARTITION_SIZE (FLASH_PARTITION_SIZE)
 
-#define NS_DATA_START   (NS_RAM_ALIAS(TOTAL_RAM_SIZE/2))
-#define NS_DATA_SIZE    (TOTAL_RAM_SIZE/2)
-#define NS_DATA_LIMIT   (NS_DATA_START + NS_DATA_SIZE -1)
+/* Secondary partition for new images in case of firmware upgrade */
+#define SECONDARY_PARTITION_START \
+            (NS_ROM_ALIAS(S_IMAGE_SECONDARY_PARTITION_OFFSET))
+
+#define SECONDARY_PARTITION_SIZE (2 * FLASH_PARTITION_SIZE)
 
 #ifdef BL2
 /* Bootloader regions */
diff --git a/platform/ext/target/mps2/an519/spm_hal.c b/platform/ext/target/mps2/an519/spm_hal.c
index a520043..94336aa 100644
--- a/platform/ext/target/mps2/an519/spm_hal.c
+++ b/platform/ext/target/mps2/an519/spm_hal.c
@@ -19,6 +19,9 @@
 /* Import MPC driver */

 extern ARM_DRIVER_MPC Driver_SRAM1_MPC;

 

+/* Get address of memory regions to configure MPU */

+extern const struct memory_region_limits memory_regions;

+

 struct mpu_armv8m_dev_t dev_mpu_s = { MPU_BASE };

 

 void tfm_spm_hal_init_isolation_hw(void)

@@ -64,8 +67,8 @@
 

     /* Veneer region */

     region_cfg.region_nr = MPU_REGION_VENEERS;

-    region_cfg.region_base = CMSE_VENEER_REGION_START;

-    region_cfg.region_limit = CMSE_VENEER_REGION_LIMIT;

+    region_cfg.region_base = memory_regions.veneer_base;

+    region_cfg.region_limit = memory_regions.veneer_limit;

     region_cfg.attr_access = MPU_ARMV8M_AP_RO_PRIV_UNPRIV;

     region_cfg.attr_sh = MPU_ARMV8M_SH_NONE;

     region_cfg.attr_exec = MPU_ARMV8M_XN_EXEC_OK;

@@ -235,8 +238,8 @@
             res = SPM_ERR_OK;

             break;

         case TFM_BUFFER_SHARE_NS_CODE:

-            region_cfg.region_base = NS_CODE_START;

-            region_cfg.region_limit = NS_CODE_LIMIT;

+            region_cfg.region_base = memory_regions.non_secure_partition_base;

+            region_cfg.region_limit = memory_regions.non_secure_partition_limit;

             /* Only allow read access to NS code region and keep

              * exec.never attribute

              */

@@ -303,3 +306,17 @@
     tfm_access_violation_handler();

 }

 

+uint32_t tfm_spm_hal_get_ns_VTOR(void)

+{

+    return memory_regions.non_secure_code_start;

+}

+

+uint32_t tfm_spm_hal_get_ns_MSP(void)

+{

+    return *((uint32_t *)memory_regions.non_secure_code_start);

+}

+

+uint32_t tfm_spm_hal_get_ns_entry_point(void)

+{

+    return *((uint32_t *)(memory_regions.non_secure_code_start+ 4));

+}

diff --git a/platform/ext/target/mps2/an519/target_cfg.c b/platform/ext/target/mps2/an519/target_cfg.c
index edc9bb3..da7a744 100644
--- a/platform/ext/target/mps2/an519/target_cfg.c
+++ b/platform/ext/target/mps2/an519/target_cfg.c
@@ -21,6 +21,48 @@
 #include "region_defs.h"
 #include "tfm_secure_api.h"
 
+/* Macros to pick linker symbols */
+#define REGION(a, b, c) a##b##c
+#define REGION_NAME(a, b, c) REGION(a, b, c)
+#define REGION_DECLARE(a, b, c) extern uint32_t REGION_NAME(a, b, c)
+
+/* The section names come from the scatter file */
+REGION_DECLARE(Load$$LR$$, LR_NS_PARTITION, $$Base);
+REGION_DECLARE(Load$$LR$$, LR_VENEER, $$Base);
+REGION_DECLARE(Load$$LR$$, LR_VENEER, $$Limit);
+#ifdef BL2
+REGION_DECLARE(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base);
+#endif /* BL2 */
+
+const struct memory_region_limits memory_regions = {
+    .non_secure_code_start =
+        (uint32_t)&REGION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) +
+        BL2_HEADER_SIZE,
+
+    .non_secure_partition_base =
+        (uint32_t)&REGION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base),
+
+    .non_secure_partition_limit =
+        (uint32_t)&REGION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) +
+        NS_PARTITION_SIZE - 1,
+
+    .veneer_base =
+        (uint32_t)&REGION_NAME(Load$$LR$$, LR_VENEER, $$Base),
+
+    .veneer_limit =
+        (uint32_t)&REGION_NAME(Load$$LR$$, LR_VENEER, $$Limit),
+
+#ifdef BL2
+    .secondary_partition_base =
+        (uint32_t)&REGION_NAME(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base),
+
+    .secondary_partition_limit =
+        (uint32_t)&REGION_NAME(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base) +
+        SECONDARY_PARTITION_SIZE - 1,
+#endif /* BL2 */
+};
+
+
 /* Allows software, via SAU, to define the code region as a NSC */
 #define NSCCFG_CODENSC  1
 
@@ -110,8 +152,12 @@
 
     /* Configures SAU regions to be non-secure */
     SAU->RNR  = TFM_NS_REGION_CODE;
-    SAU->RBAR = (NS_PARTITION_START & SAU_RBAR_BADDR_Msk);
-    SAU->RLAR = (NS_PARTITION_LIMIT & SAU_RLAR_LADDR_Msk) | SAU_RLAR_ENABLE_Msk;
+    SAU->RBAR = (memory_regions.non_secure_partition_base
+                & SAU_RBAR_BADDR_Msk);
+    SAU->RLAR = (memory_regions.non_secure_partition_limit
+                & SAU_RLAR_LADDR_Msk)
+                | SAU_RLAR_ENABLE_Msk;
+
 
     SAU->RNR  = TFM_NS_REGION_DATA;
     SAU->RBAR = (NS_DATA_START & SAU_RBAR_BADDR_Msk);
@@ -119,8 +165,8 @@
 
     /* Configures veneers region to be non-secure callable */
     SAU->RNR  = TFM_NS_REGION_VENEER;
-    SAU->RBAR = (CMSE_VENEER_REGION_START & SAU_RBAR_BADDR_Msk);
-    SAU->RLAR = (CMSE_VENEER_REGION_LIMIT & SAU_RLAR_LADDR_Msk)
+    SAU->RBAR = (memory_regions.veneer_base  & SAU_RBAR_BADDR_Msk);
+    SAU->RLAR = (memory_regions.veneer_limit & SAU_RLAR_LADDR_Msk)
                 | SAU_RLAR_ENABLE_Msk
                 | SAU_RLAR_NSC_Msk;
 
@@ -143,7 +189,15 @@
     SAU->RLAR = (PERIPHERALS_BASE_NS_END & SAU_RLAR_LADDR_Msk)
                 | SAU_RLAR_ENABLE_Msk;
 
-    /* Allows SAU to define the code region as a NSC  */
+#ifdef BL2
+    /* Secondary image partition */
+    SAU->RNR  = TFM_NS_SECONDARY_IMAGE_REGION;
+    SAU->RBAR = (memory_regions.secondary_partition_base  & SAU_RBAR_BADDR_Msk);
+    SAU->RLAR = (memory_regions.secondary_partition_limit & SAU_RLAR_LADDR_Msk)
+                | SAU_RLAR_ENABLE_Msk;
+#endif /* BL2 */
+
+    /* Allows SAU to define the code region as a NSC */
     struct spctrl_def* spctrl = CMSDK_SPCTRL;
     spctrl->nsccfg |= NSCCFG_CODENSC;
 }
@@ -153,10 +207,17 @@
 void mpc_init_cfg(void)
 {
     Driver_SRAM1_MPC.Initialize();
-    Driver_SRAM1_MPC.ConfigRegion(NS_PARTITION_START,
-                                  NS_PARTITION_LIMIT,
+    Driver_SRAM1_MPC.ConfigRegion(memory_regions.non_secure_partition_base,
+                                  memory_regions.non_secure_partition_limit,
                                   ARM_MPC_ATTR_NONSECURE);
 
+#ifdef BL2
+    /* Secondary image region */
+    Driver_SRAM1_MPC.ConfigRegion(memory_regions.secondary_partition_base,
+                                  memory_regions.secondary_partition_limit,
+                                  ARM_MPC_ATTR_NONSECURE);
+#endif /* BL2 */
+
     Driver_SRAM2_MPC.Initialize();
     Driver_SRAM2_MPC.ConfigRegion(NS_DATA_START, NS_DATA_LIMIT,
                                   ARM_MPC_ATTR_NONSECURE);
@@ -166,7 +227,8 @@
     Driver_SRAM2_MPC.LockDown();
 
     /* Add barriers to assure the MPC configuration is done before continue
-     * the execution. */
+     * the execution.
+     */
     __DSB();
     __ISB();
 }
@@ -179,7 +241,8 @@
     struct nspctrl_def* nspctrl = CMSDK_NSPCTRL;
 
     /* Grant non-secure access to peripherals in the PPC0
-     * (timer0 and 1, dualtimer, watchdog, mhu 0 and 1) */
+     * (timer0 and 1, dualtimer, watchdog, mhu 0 and 1)
+     */
     spctrl->apbnsppc0 |= (1U << CMSDK_TIMER0_APB_PPC_POS);
     spctrl->apbnsppc0 |= (1U << CMSDK_TIMER1_APB_PPC_POS);
     spctrl->apbnsppc0 |= (1U << CMSDK_DTIMER_APB_PPC_POS);
@@ -235,7 +298,8 @@
     nspctrl->apbnspppcexp2 |= (1U << CMSDK_FPGA_IO_PPC_POS);
 
     /* Configure the response to a security violation as a
-     * bus error instead of RAZ/WI */
+     * bus error instead of RAZ/WI
+     */
     spctrl->secrespcfg |= 1U;
 }
 
@@ -268,6 +332,6 @@
 void ppc_clear_irq(void)
 {
     struct spctrl_def* spctrl = CMSDK_SPCTRL;
-    /* Clear APC PPC EXP2 IRQ */
+    /* Clear APB PPC EXP2 IRQ */
     spctrl->secppcintclr = CMSDK_APB_PPCEXP2_INT_POS_MASK;
 }
diff --git a/platform/ext/target/mps2/an519/target_cfg.h b/platform/ext/target/mps2/an519/target_cfg.h
index e60a866..c9c3cf1 100644
--- a/platform/ext/target/mps2/an519/target_cfg.h
+++ b/platform/ext/target/mps2/an519/target_cfg.h
@@ -44,7 +44,22 @@
 };
 
 /**
- * Holds the data necessary to do isolation for a specific peripheral.
+ * \brief Store the addresses of memory regions
+ */
+struct memory_region_limits {
+    uint32_t non_secure_code_start;
+    uint32_t non_secure_partition_base;
+    uint32_t non_secure_partition_limit;
+    uint32_t veneer_base;
+    uint32_t veneer_limit;
+#ifdef BL2
+    uint32_t secondary_partition_base;
+    uint32_t secondary_partition_limit;
+#endif /* BL2 */
+};
+
+/**
+ * \brief Holds the data necessary to do isolation for a specific peripheral.
  */
 struct tfm_spm_partition_platform_data_t
 {
diff --git a/platform/ext/target/mps2/an521/armclang/mps2_an521_s.sct b/platform/ext/target/mps2/an521/armclang/mps2_an521_s.sct
index 529fc28..10c665c 100644
--- a/platform/ext/target/mps2/an521/armclang/mps2_an521_s.sct
+++ b/platform/ext/target/mps2/an521/armclang/mps2_an521_s.sct
@@ -154,3 +154,24 @@
         *(Veneer$$CMSE)
     }
 }
+
+LR_NS_PARTITION NS_PARTITION_START {
+    /* Reserved place for NS application.
+     * No code will be placed here, just address of this region is used in the
+     * secure code to configure certain HW components.
+     */
+    ER_NS_PARTITION NS_PARTITION_START EMPTY NS_PARTITION_SIZE {
+    }
+}
+
+#ifdef BL2
+LR_SECONDARY_PARTITION SECONDARY_PARTITION_START {
+    /* Reserved place for new image in case of firmware upgrade.
+     * No code will be placed here, just address of this region is used in the
+     * secure code to configure certain HW components.
+     */
+    ER_SECONDARY_PARTITION SECONDARY_PARTITION_START \
+        EMPTY SECONDARY_PARTITION_SIZE {
+    }
+}
+#endif /* BL2 */
\ No newline at end of file
diff --git a/platform/ext/target/mps2/an521/gcc/mps2_an521_s.ld b/platform/ext/target/mps2/an521/gcc/mps2_an521_s.ld
index 2d8b2f6..16296fa 100644
--- a/platform/ext/target/mps2/an521/gcc/mps2_an521_s.ld
+++ b/platform/ext/target/mps2/an521/gcc/mps2_an521_s.ld
@@ -82,8 +82,11 @@
         . = ALIGN(4);
         *(.gnu.sgstubs*)
     } > VENEERS
-    Image$$ER_CODE_CMSE_VENEER$$Base = ADDR(.gnu.sgstubs);
-    Image$$ER_CODE_CMSE_VENEER$$Limit = ADDR(.gnu.sgstubs) + SIZEOF(.gnu.sgstubs);
+    Load$$LR$$LR_VENEER$$Base = ADDR(.gnu.sgstubs);
+    Load$$LR$$LR_VENEER$$Limit = ADDR(.gnu.sgstubs) + SIZEOF(.gnu.sgstubs);
+
+    Load$$LR$$LR_NS_PARTITION$$Base = NS_PARTITION_START;
+    Load$$LR$$LR_SECONDARY_PARTITION$$Base = SECONDARY_PARTITION_START;
 
     .ARM.extab :
     {
diff --git a/platform/ext/target/mps2/an521/partition/region_defs.h b/platform/ext/target/mps2/an521/partition/region_defs.h
index 5e1b260..768ac92 100644
--- a/platform/ext/target/mps2/an521/partition/region_defs.h
+++ b/platform/ext/target/mps2/an521/partition/region_defs.h
@@ -28,12 +28,22 @@
  */
 
 #ifdef BL2
-#define  S_IMAGE_PRIMARY_PARTITION_OFFSET (FLASH_AREA_IMAGE_0_OFFSET)
+#ifndef LINK_TO_SECONDARY_PARTITION
+#define  S_IMAGE_PRIMARY_PARTITION_OFFSET   (FLASH_AREA_IMAGE_0_OFFSET)
+#define  S_IMAGE_SECONDARY_PARTITION_OFFSET (FLASH_AREA_IMAGE_1_OFFSET)
+#else
+#define  S_IMAGE_PRIMARY_PARTITION_OFFSET   (FLASH_AREA_IMAGE_1_OFFSET)
+#define  S_IMAGE_SECONDARY_PARTITION_OFFSET (FLASH_AREA_IMAGE_0_OFFSET)
+#endif /* !LINK_TO_SECONDARY_PARTITION */
 #else
 #define  S_IMAGE_PRIMARY_PARTITION_OFFSET (0x0)
 #endif /* BL2 */
 
+#ifndef LINK_TO_SECONDARY_PARTITION
 #define NS_IMAGE_PRIMARY_PARTITION_OFFSET (0x100000)
+#else
+#define NS_IMAGE_PRIMARY_PARTITION_OFFSET (0x200000)
+#endif /* !LINK_TO_SECONDARY_PARTITION */
 
 /*
  * Boot partition structure if MCUBoot is used:
@@ -43,7 +53,8 @@
  */
 /* IMAGE_CODE_SIZE is the space available for the software binary image.
  * It is less than the FLASH_PARTITION_SIZE because we reserve space
- * for the image header and trailer introduced by the bootloader. */
+ * for the image header and trailer introduced by the bootloader.
+ */
 #ifdef BL2
 #define BL2_HEADER_SIZE      (0x400)
 #define BL2_TRAILER_SIZE     (0x10000)
@@ -75,7 +86,7 @@
 
 /* Secure regions */
 #define  S_IMAGE_PRIMARY_AREA_OFFSET \
-            (S_IMAGE_PRIMARY_PARTITION_OFFSET + BL2_HEADER_SIZE)
+             (S_IMAGE_PRIMARY_PARTITION_OFFSET + BL2_HEADER_SIZE)
 #define S_CODE_START    (S_ROM_ALIAS(S_IMAGE_PRIMARY_AREA_OFFSET))
 #define S_CODE_SIZE     (IMAGE_CODE_SIZE - CMSE_VENEER_REGION_SIZE)
 #define S_CODE_LIMIT    (S_CODE_START + S_CODE_SIZE - 1)
@@ -86,8 +97,6 @@
 
 /* CMSE Veneers region */
 #define CMSE_VENEER_REGION_START  (S_CODE_LIMIT + 1)
-#define CMSE_VENEER_REGION_LIMIT  (CMSE_VENEER_REGION_START + \
-                                   CMSE_VENEER_REGION_SIZE - 1)
 
 /* Non-secure regions */
 #define NS_IMAGE_PRIMARY_AREA_OFFSET \
@@ -96,22 +105,21 @@
 #define NS_CODE_SIZE    (IMAGE_CODE_SIZE)
 #define NS_CODE_LIMIT   (NS_CODE_START + NS_CODE_SIZE - 1)
 
-/* NS partition information is used for MPC configuration */
+#define NS_DATA_START   (NS_RAM_ALIAS(TOTAL_RAM_SIZE / 2))
+#define NS_DATA_SIZE    (TOTAL_RAM_SIZE / 2)
+#define NS_DATA_LIMIT   (NS_DATA_START + NS_DATA_SIZE - 1)
+
+/* NS partition information is used for MPC and SAU configuration */
 #define NS_PARTITION_START \
             (NS_ROM_ALIAS(NS_IMAGE_PRIMARY_PARTITION_OFFSET))
 
-#ifdef BL2
-/* Cover: non-secure primary + secure secondary + non-secure secondary area */
-#define NS_PARTITION_LIMIT \
-            (NS_PARTITION_START + 3 * FLASH_PARTITION_SIZE - 1)
-#else
-#define NS_PARTITION_LIMIT \
-            (NS_PARTITION_START + FLASH_PARTITION_SIZE - 1)
-#endif /* BL2 */
+#define NS_PARTITION_SIZE (FLASH_PARTITION_SIZE)
 
-#define NS_DATA_START   (NS_RAM_ALIAS(TOTAL_RAM_SIZE / 2))
-#define NS_DATA_SIZE    (TOTAL_RAM_SIZE / 2)
-#define NS_DATA_LIMIT   (NS_DATA_START + NS_DATA_SIZE -1)
+/* Secondary partition for new images in case of firmware upgrade */
+#define SECONDARY_PARTITION_START \
+            (NS_ROM_ALIAS(S_IMAGE_SECONDARY_PARTITION_OFFSET))
+
+#define SECONDARY_PARTITION_SIZE (2 * FLASH_PARTITION_SIZE)
 
 #ifdef BL2
 /* Bootloader regions */
diff --git a/platform/ext/target/mps2/an521/spm_hal.c b/platform/ext/target/mps2/an521/spm_hal.c
index e26496a..2f652eb 100644
--- a/platform/ext/target/mps2/an521/spm_hal.c
+++ b/platform/ext/target/mps2/an521/spm_hal.c
@@ -19,6 +19,9 @@
 /* Import MPC driver */

 extern ARM_DRIVER_MPC Driver_SRAM1_MPC;

 

+/* Get address of memory regions to configure MPU */

+extern const struct memory_region_limits memory_regions;

+

 struct mpu_armv8m_dev_t dev_mpu_s = { MPU_BASE };

 

 void tfm_spm_hal_init_isolation_hw(void)

@@ -64,8 +67,8 @@
 

     /* Veneer region */

     region_cfg.region_nr = MPU_REGION_VENEERS;

-    region_cfg.region_base = CMSE_VENEER_REGION_START;

-    region_cfg.region_limit = CMSE_VENEER_REGION_LIMIT;

+    region_cfg.region_base = memory_regions.veneer_base;

+    region_cfg.region_limit = memory_regions.veneer_limit;

     region_cfg.attr_access = MPU_ARMV8M_AP_RO_PRIV_UNPRIV;

     region_cfg.attr_sh = MPU_ARMV8M_SH_NONE;

     region_cfg.attr_exec = MPU_ARMV8M_XN_EXEC_OK;

@@ -235,8 +238,8 @@
             res = SPM_ERR_OK;

             break;

         case TFM_BUFFER_SHARE_NS_CODE:

-            region_cfg.region_base = NS_CODE_START;

-            region_cfg.region_limit = NS_CODE_LIMIT;

+            region_cfg.region_base = memory_regions.non_secure_partition_base;

+            region_cfg.region_limit = memory_regions.non_secure_partition_limit;

             /* Only allow read access to NS code region and keep

              * exec.never attribute

              */

@@ -303,3 +306,17 @@
     tfm_access_violation_handler();

 }

 

+uint32_t tfm_spm_hal_get_ns_VTOR(void)

+{

+    return memory_regions.non_secure_code_start;

+}

+

+uint32_t tfm_spm_hal_get_ns_MSP(void)

+{

+    return *((uint32_t *)memory_regions.non_secure_code_start);

+}

+

+uint32_t tfm_spm_hal_get_ns_entry_point(void)

+{

+    return *((uint32_t *)(memory_regions.non_secure_code_start+ 4));

+}

diff --git a/platform/ext/target/mps2/an521/target_cfg.c b/platform/ext/target/mps2/an521/target_cfg.c
index 54ea719..3f44c91 100644
--- a/platform/ext/target/mps2/an521/target_cfg.c
+++ b/platform/ext/target/mps2/an521/target_cfg.c
@@ -21,6 +21,47 @@
 #include "region_defs.h"
 #include "tfm_secure_api.h"
 
+/* Macros to pick linker symbols */
+#define REGION(a, b, c) a##b##c
+#define REGION_NAME(a, b, c) REGION(a, b, c)
+#define REGION_DECLARE(a, b, c) extern uint32_t REGION_NAME(a, b, c)
+
+/* The section names come from the scatter file */
+REGION_DECLARE(Load$$LR$$, LR_NS_PARTITION, $$Base);
+REGION_DECLARE(Load$$LR$$, LR_VENEER, $$Base);
+REGION_DECLARE(Load$$LR$$, LR_VENEER, $$Limit);
+#ifdef BL2
+REGION_DECLARE(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base);
+#endif /* BL2 */
+
+const struct memory_region_limits memory_regions = {
+    .non_secure_code_start =
+        (uint32_t)&REGION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) +
+        BL2_HEADER_SIZE,
+
+    .non_secure_partition_base =
+        (uint32_t)&REGION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base),
+
+    .non_secure_partition_limit =
+        (uint32_t)&REGION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) +
+        NS_PARTITION_SIZE - 1,
+
+    .veneer_base =
+        (uint32_t)&REGION_NAME(Load$$LR$$, LR_VENEER, $$Base),
+
+    .veneer_limit =
+        (uint32_t)&REGION_NAME(Load$$LR$$, LR_VENEER, $$Limit),
+
+#ifdef BL2
+    .secondary_partition_base =
+        (uint32_t)&REGION_NAME(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base),
+
+    .secondary_partition_limit =
+        (uint32_t)&REGION_NAME(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base) +
+        SECONDARY_PARTITION_SIZE - 1,
+#endif /* BL2 */
+};
+
 /* Allows software, via SAU, to define the code region as a NSC */
 #define NSCCFG_CODENSC  1
 
@@ -112,8 +153,12 @@
 
     /* Configures SAU regions to be non-secure */
     SAU->RNR  = TFM_NS_REGION_CODE;
-    SAU->RBAR = (NS_PARTITION_START & SAU_RBAR_BADDR_Msk);
-    SAU->RLAR = (NS_PARTITION_LIMIT & SAU_RLAR_LADDR_Msk) | SAU_RLAR_ENABLE_Msk;
+    SAU->RBAR = (memory_regions.non_secure_partition_base
+                & SAU_RBAR_BADDR_Msk);
+    SAU->RLAR = (memory_regions.non_secure_partition_limit
+                & SAU_RLAR_LADDR_Msk)
+                | SAU_RLAR_ENABLE_Msk;
+
 
     SAU->RNR  = TFM_NS_REGION_DATA;
     SAU->RBAR = (NS_DATA_START & SAU_RBAR_BADDR_Msk);
@@ -121,8 +166,8 @@
 
     /* Configures veneers region to be non-secure callable */
     SAU->RNR  = TFM_NS_REGION_VENEER;
-    SAU->RBAR = (CMSE_VENEER_REGION_START & SAU_RBAR_BADDR_Msk);
-    SAU->RLAR = (CMSE_VENEER_REGION_LIMIT & SAU_RLAR_LADDR_Msk)
+    SAU->RBAR = (memory_regions.veneer_base  & SAU_RBAR_BADDR_Msk);
+    SAU->RLAR = (memory_regions.veneer_limit & SAU_RLAR_LADDR_Msk)
                 | SAU_RLAR_ENABLE_Msk
                 | SAU_RLAR_NSC_Msk;
 
@@ -145,7 +190,15 @@
     SAU->RLAR = (PERIPHERALS_BASE_NS_END & SAU_RLAR_LADDR_Msk)
                 | SAU_RLAR_ENABLE_Msk;
 
-    /* Allows SAU to define the code region as a NSC  */
+#ifdef BL2
+    /* Secondary image partition */
+    SAU->RNR  = TFM_NS_SECONDARY_IMAGE_REGION;
+    SAU->RBAR = (memory_regions.secondary_partition_base  & SAU_RBAR_BADDR_Msk);
+    SAU->RLAR = (memory_regions.secondary_partition_limit & SAU_RLAR_LADDR_Msk)
+                | SAU_RLAR_ENABLE_Msk;
+#endif /* BL2 */
+
+    /* Allows SAU to define the code region as a NSC */
     struct spctrl_def* spctrl = CMSDK_SPCTRL;
     spctrl->nsccfg |= NSCCFG_CODENSC;
 }
@@ -155,10 +208,17 @@
 void mpc_init_cfg(void)
 {
     Driver_SRAM1_MPC.Initialize();
-    Driver_SRAM1_MPC.ConfigRegion(NS_PARTITION_START,
-                                  NS_PARTITION_LIMIT,
+    Driver_SRAM1_MPC.ConfigRegion(memory_regions.non_secure_partition_base,
+                                  memory_regions.non_secure_partition_limit,
                                   ARM_MPC_ATTR_NONSECURE);
 
+#ifdef BL2
+    /* Secondary image region */
+    Driver_SRAM1_MPC.ConfigRegion(memory_regions.secondary_partition_base,
+                                  memory_regions.secondary_partition_limit,
+                                  ARM_MPC_ATTR_NONSECURE);
+#endif /* BL2 */
+
     Driver_SRAM2_MPC.Initialize();
     Driver_SRAM2_MPC.ConfigRegion(NS_DATA_START, NS_DATA_LIMIT,
                                   ARM_MPC_ATTR_NONSECURE);
@@ -168,7 +228,8 @@
     Driver_SRAM2_MPC.LockDown();
 
     /* Add barriers to assure the MPC configuration is done before continue
-     * the execution. */
+     * the execution.
+     */
     __DSB();
     __ISB();
 }
@@ -181,7 +242,8 @@
     struct nspctrl_def* nspctrl = CMSDK_NSPCTRL;
 
     /* Grant non-secure access to peripherals in the PPC0
-     * (timer0 and 1, dualtimer, watchdog, mhu 0 and 1) */
+     * (timer0 and 1, dualtimer, watchdog, mhu 0 and 1)
+     */
     spctrl->apbnsppc0 |= (1U << CMSDK_TIMER0_APB_PPC_POS);
     spctrl->apbnsppc0 |= (1U << CMSDK_TIMER1_APB_PPC_POS);
     spctrl->apbnsppc0 |= (1U << CMSDK_DTIMER_APB_PPC_POS);
@@ -237,7 +299,8 @@
     nspctrl->apbnspppcexp2 |= (1U << CMSDK_FPGA_IO_PPC_POS);
 
     /* Configure the response to a security violation as a
-     * bus error instead of RAZ/WI */
+     * bus error instead of RAZ/WI
+     */
     spctrl->secrespcfg |= 1U;
 }
 
@@ -270,6 +333,6 @@
 void ppc_clear_irq(void)
 {
     struct spctrl_def* spctrl = CMSDK_SPCTRL;
-    /* Clear APC PPC EXP2 IRQ */
+    /* Clear APB PPC EXP2 IRQ */
     spctrl->secppcintclr = CMSDK_APB_PPCEXP2_INT_POS_MASK;
 }
diff --git a/platform/ext/target/mps2/an521/target_cfg.h b/platform/ext/target/mps2/an521/target_cfg.h
index 1b9e050..c9c3cf1 100644
--- a/platform/ext/target/mps2/an521/target_cfg.h
+++ b/platform/ext/target/mps2/an521/target_cfg.h
@@ -19,6 +19,10 @@
 
 #include "tfm_peripherals_def.h"
 
+/**
+ * \brief Defines the word offsets of Slave Peripheral Protection Controller
+ *        Registers
+ */
 enum ppc_bank_e
 {
     PPC_SP_AHB_PPC0 = 0,
@@ -40,7 +44,22 @@
 };
 
 /**
- * Holds the data necessary to do isolation for a specific peripheral.
+ * \brief Store the addresses of memory regions
+ */
+struct memory_region_limits {
+    uint32_t non_secure_code_start;
+    uint32_t non_secure_partition_base;
+    uint32_t non_secure_partition_limit;
+    uint32_t veneer_base;
+    uint32_t veneer_limit;
+#ifdef BL2
+    uint32_t secondary_partition_base;
+    uint32_t secondary_partition_limit;
+#endif /* BL2 */
+};
+
+/**
+ * \brief Holds the data necessary to do isolation for a specific peripheral.
  */
 struct tfm_spm_partition_platform_data_t
 {
diff --git a/platform/ext/target/musca_a/Device/Source/armclang/musca_s.sct b/platform/ext/target/musca_a/Device/Source/armclang/musca_s.sct
index 2b37e70..f717aed 100755
--- a/platform/ext/target/musca_a/Device/Source/armclang/musca_s.sct
+++ b/platform/ext/target/musca_a/Device/Source/armclang/musca_s.sct
@@ -139,3 +139,25 @@
         *(Veneer$$CMSE)
     }
 }
+
+LR_NS_PARTITION NS_PARTITION_START {
+    /* Reserved place for NS application.
+     * No code will be placed here, just address of this region is used in the
+     * secure code to configure certain HW components.
+     */
+    ER_NS_PARTITION NS_PARTITION_START EMPTY NS_PARTITION_SIZE {
+    }
+}
+
+#ifdef BL2
+LR_SECONDARY_PARTITION SECONDARY_PARTITION_START {
+    /* Reserved place for new image in case of firmware upgrade.
+     * No code will be placed here, just address of this region is used in the
+     * secure code to configure certain HW components.
+     */
+    ER_SECONDARY_PARTITION SECONDARY_PARTITION_START \
+        EMPTY SECONDARY_PARTITION_SIZE {
+    }
+}
+#endif /* BL2 */
+
diff --git a/platform/ext/target/musca_a/partition/region_defs.h b/platform/ext/target/musca_a/partition/region_defs.h
index 170dd11..f3aa9aa 100755
--- a/platform/ext/target/musca_a/partition/region_defs.h
+++ b/platform/ext/target/musca_a/partition/region_defs.h
@@ -27,7 +27,15 @@
  * of partitions is defined in accordance with this constraint.
  */
 
-#define  S_IMAGE_PRIMARY_PARTITION_OFFSET (FLASH_AREA_IMAGE_0_OFFSET)
+#ifndef LINK_TO_SECONDARY_PARTITION
+#define  S_IMAGE_PRIMARY_PARTITION_OFFSET   (FLASH_AREA_IMAGE_0_OFFSET)
+#define  S_IMAGE_SECONDARY_PARTITION_OFFSET (FLASH_AREA_IMAGE_1_OFFSET)
+#else
+#define  S_IMAGE_PRIMARY_PARTITION_OFFSET   (FLASH_AREA_IMAGE_1_OFFSET)
+#define  S_IMAGE_SECONDARY_PARTITION_OFFSET (FLASH_AREA_IMAGE_0_OFFSET)
+#endif /* !LINK_TO_SECONDARY_PARTITION */
+
+
 #define NS_IMAGE_PRIMARY_PARTITION_OFFSET (S_IMAGE_PRIMARY_PARTITION_OFFSET + \
                                            FLASH_PARTITION_SIZE)
 
@@ -71,7 +79,7 @@
 
 /* Secure regions */
 #define  S_IMAGE_PRIMARY_AREA_OFFSET \
-            (S_IMAGE_PRIMARY_PARTITION_OFFSET + BL2_HEADER_SIZE)
+             (S_IMAGE_PRIMARY_PARTITION_OFFSET + BL2_HEADER_SIZE)
 #define S_CODE_START    (S_ROM_ALIAS(S_IMAGE_PRIMARY_AREA_OFFSET))
 #define S_CODE_SIZE     (IMAGE_CODE_SIZE - CMSE_VENEER_REGION_SIZE)
 #define S_CODE_LIMIT    (S_CODE_START + S_CODE_SIZE - 1)
@@ -82,8 +90,6 @@
 
 /* CMSE Veneers region */
 #define CMSE_VENEER_REGION_START  (S_CODE_LIMIT + 1)
-#define CMSE_VENEER_REGION_LIMIT  (CMSE_VENEER_REGION_START + \
-                                   CMSE_VENEER_REGION_SIZE - 1)
 
 /* Non-secure regions */
 #define NS_IMAGE_PRIMARY_AREA_OFFSET \
@@ -92,22 +98,37 @@
 #define NS_CODE_SIZE    (IMAGE_CODE_SIZE - FLASH_AREA_BL2_SIZE)
 #define NS_CODE_LIMIT   (NS_CODE_START + NS_CODE_SIZE - 1)
 
-/* NS partition information is used for MPC configuration */
+#define NS_DATA_START   (NS_RAM_ALIAS(TOTAL_RAM_SIZE/2))
+#define NS_DATA_SIZE    (TOTAL_RAM_SIZE/2)
+#define NS_DATA_LIMIT   (NS_DATA_START + NS_DATA_SIZE - 1)
+
+/* NS partition information is used for MPC and SAU configuration */
 #define NS_PARTITION_START \
             (NS_ROM_ALIAS(NS_IMAGE_PRIMARY_PARTITION_OFFSET))
 
-#define NS_PARTITION_LIMIT \
-            (NS_PARTITION_START + FLASH_PARTITION_SIZE  \
-             - FLASH_AREA_BL2_SIZE - 1)
+#define NS_PARTITION_SIZE (FLASH_PARTITION_SIZE / 2)
+
+/* Secondary partition for new images in case of firmware upgrade */
+#define SECONDARY_PARTITION_START \
+            (NS_ROM_ALIAS(S_IMAGE_SECONDARY_PARTITION_OFFSET))
+
+#define SECONDARY_PARTITION_SIZE (FLASH_PARTITION_SIZE)
 
 /* Code SRAM area */
 #define TOTAL_CODE_SRAM_SIZE     (TOTAL_ROM_SIZE)
 #define S_CODE_SRAM_ALIAS_BASE   (0x10000000)
 #define NS_CODE_SRAM_ALIAS_BASE  (0x00000000)
 
-#define NS_DATA_START   (NS_RAM_ALIAS(TOTAL_RAM_SIZE/2))
-#define NS_DATA_SIZE    (TOTAL_RAM_SIZE/2)
-#define NS_DATA_LIMIT   (NS_DATA_START + NS_DATA_SIZE -1)
+#define BL2_CODE_SRAM_EXEC_BASE  (S_CODE_SRAM_ALIAS_BASE)
+#define S_CODE_SRAM_EXEC_BASE    (S_CODE_SRAM_ALIAS_BASE)
+#define S_CODE_SRAM_EXEC_LIMIT   (S_CODE_SRAM_EXEC_BASE + \
+                                 (TOTAL_CODE_SRAM_SIZE/2) - 1)
+#define NS_CODE_SRAM_EXEC_BASE   (NS_CODE_SRAM_ALIAS_BASE + \
+                                 (TOTAL_CODE_SRAM_SIZE/2))
+#define NS_CODE_SRAM_EXEC_LIMIT  (NS_CODE_SRAM_EXEC_BASE + \
+                                 (TOTAL_CODE_SRAM_SIZE/2) - 1)
+
+
 
 #ifdef BL2
 /* Bootloader regions */
diff --git a/platform/ext/target/musca_a/spm_hal.c b/platform/ext/target/musca_a/spm_hal.c
index a520043..94336aa 100644
--- a/platform/ext/target/musca_a/spm_hal.c
+++ b/platform/ext/target/musca_a/spm_hal.c
@@ -19,6 +19,9 @@
 /* Import MPC driver */

 extern ARM_DRIVER_MPC Driver_SRAM1_MPC;

 

+/* Get address of memory regions to configure MPU */

+extern const struct memory_region_limits memory_regions;

+

 struct mpu_armv8m_dev_t dev_mpu_s = { MPU_BASE };

 

 void tfm_spm_hal_init_isolation_hw(void)

@@ -64,8 +67,8 @@
 

     /* Veneer region */

     region_cfg.region_nr = MPU_REGION_VENEERS;

-    region_cfg.region_base = CMSE_VENEER_REGION_START;

-    region_cfg.region_limit = CMSE_VENEER_REGION_LIMIT;

+    region_cfg.region_base = memory_regions.veneer_base;

+    region_cfg.region_limit = memory_regions.veneer_limit;

     region_cfg.attr_access = MPU_ARMV8M_AP_RO_PRIV_UNPRIV;

     region_cfg.attr_sh = MPU_ARMV8M_SH_NONE;

     region_cfg.attr_exec = MPU_ARMV8M_XN_EXEC_OK;

@@ -235,8 +238,8 @@
             res = SPM_ERR_OK;

             break;

         case TFM_BUFFER_SHARE_NS_CODE:

-            region_cfg.region_base = NS_CODE_START;

-            region_cfg.region_limit = NS_CODE_LIMIT;

+            region_cfg.region_base = memory_regions.non_secure_partition_base;

+            region_cfg.region_limit = memory_regions.non_secure_partition_limit;

             /* Only allow read access to NS code region and keep

              * exec.never attribute

              */

@@ -303,3 +306,17 @@
     tfm_access_violation_handler();

 }

 

+uint32_t tfm_spm_hal_get_ns_VTOR(void)

+{

+    return memory_regions.non_secure_code_start;

+}

+

+uint32_t tfm_spm_hal_get_ns_MSP(void)

+{

+    return *((uint32_t *)memory_regions.non_secure_code_start);

+}

+

+uint32_t tfm_spm_hal_get_ns_entry_point(void)

+{

+    return *((uint32_t *)(memory_regions.non_secure_code_start+ 4));

+}

diff --git a/platform/ext/target/musca_a/target_cfg.c b/platform/ext/target/musca_a/target_cfg.c
index 462cae4..4f307d3 100755
--- a/platform/ext/target/musca_a/target_cfg.c
+++ b/platform/ext/target/musca_a/target_cfg.c
@@ -21,6 +21,47 @@
 #include "region_defs.h"
 #include "tfm_secure_api.h"
 
+/* Macros to pick linker symbols */
+#define REGION(a, b, c) a##b##c
+#define REGION_NAME(a, b, c) REGION(a, b, c)
+#define REGION_DECLARE(a, b, c) extern uint32_t REGION_NAME(a, b, c)
+
+/* The section names come from the scatter file */
+REGION_DECLARE(Load$$LR$$, LR_NS_PARTITION, $$Base);
+REGION_DECLARE(Load$$LR$$, LR_VENEER, $$Base);
+REGION_DECLARE(Load$$LR$$, LR_VENEER, $$Limit);
+#ifdef BL2
+REGION_DECLARE(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base);
+#endif /* BL2 */
+
+const struct memory_region_limits memory_regions = {
+    .non_secure_code_start =
+        (uint32_t)&REGION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) +
+        BL2_HEADER_SIZE,
+
+    .non_secure_partition_base =
+        (uint32_t)&REGION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base),
+
+    .non_secure_partition_limit =
+        (uint32_t)&REGION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) +
+        NS_PARTITION_SIZE - 1,
+
+    .veneer_base =
+        (uint32_t)&REGION_NAME(Load$$LR$$, LR_VENEER, $$Base),
+
+    .veneer_limit =
+        (uint32_t)&REGION_NAME(Load$$LR$$, LR_VENEER, $$Limit),
+
+#ifdef BL2
+    .secondary_partition_base =
+        (uint32_t)&REGION_NAME(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base),
+
+    .secondary_partition_limit =
+        (uint32_t)&REGION_NAME(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base) +
+        SECONDARY_PARTITION_SIZE - 1,
+#endif /* BL2 */
+};
+
 /* Allows software, via SAU, to define the code region as a NSC */
 #define NSCCFG_CODENSC  1
 
@@ -93,8 +134,11 @@
 
     /* Configures SAU regions to be non-secure */
     SAU->RNR  = TFM_NS_REGION_CODE;
-    SAU->RBAR = (NS_PARTITION_START & SAU_RBAR_BADDR_Msk);
-    SAU->RLAR = (NS_PARTITION_LIMIT & SAU_RLAR_LADDR_Msk) | SAU_RLAR_ENABLE_Msk;
+    SAU->RBAR = (memory_regions.non_secure_partition_base
+                & SAU_RBAR_BADDR_Msk);
+    SAU->RLAR = (memory_regions.non_secure_partition_limit
+                & SAU_RLAR_LADDR_Msk)
+                | SAU_RLAR_ENABLE_Msk;
 
     SAU->RNR  = TFM_NS_REGION_DATA;
     SAU->RBAR = (NS_DATA_START & SAU_RBAR_BADDR_Msk);
@@ -102,8 +146,8 @@
 
     /* Configures veneers region to be non-secure callable */
     SAU->RNR  = TFM_NS_REGION_VENEER;
-    SAU->RBAR = (CMSE_VENEER_REGION_START & SAU_RBAR_BADDR_Msk);
-    SAU->RLAR = (CMSE_VENEER_REGION_LIMIT & SAU_RLAR_LADDR_Msk)
+    SAU->RBAR = (memory_regions.veneer_base  & SAU_RBAR_BADDR_Msk);
+    SAU->RLAR = (memory_regions.veneer_limit & SAU_RLAR_LADDR_Msk)
                 | SAU_RLAR_ENABLE_Msk
                 | SAU_RLAR_NSC_Msk;
 
@@ -113,7 +157,15 @@
     SAU->RLAR = (PERIPHERALS_BASE_NS_END & SAU_RLAR_LADDR_Msk)
                 | SAU_RLAR_ENABLE_Msk;
 
-    /* Allows SAU to define the code region as a NSC  */
+#ifdef BL2
+    /* Secondary image partition */
+    SAU->RNR  = TFM_NS_SECONDARY_IMAGE_REGION;
+    SAU->RBAR = (memory_regions.secondary_partition_base  & SAU_RBAR_BADDR_Msk);
+    SAU->RLAR = (memory_regions.secondary_partition_limit & SAU_RLAR_LADDR_Msk)
+                | SAU_RLAR_ENABLE_Msk;
+#endif /* BL2 */
+
+    /* Allows SAU to define the code region as a NSC */
     struct spctrl_def* spctrl = CMSDK_SPCTRL;
     spctrl->nsccfg |= NSCCFG_CODENSC;
 }
@@ -128,9 +180,15 @@
     ARM_DRIVER_MPC* mpc_data_region3 = &Driver_ISRAM3_MPC;
 
     Driver_QSPI_MPC.Initialize();
-    Driver_QSPI_MPC.ConfigRegion(NS_PARTITION_START,
-                                 NS_PARTITION_LIMIT,
+    Driver_QSPI_MPC.ConfigRegion(memory_regions.non_secure_partition_base,
+                                 memory_regions.non_secure_partition_limit,
                                  ARM_MPC_ATTR_NONSECURE);
+#ifdef BL2
+    /* Secondary image region */
+    Driver_QSPI_MPC.ConfigRegion(memory_regions.secondary_partition_base,
+                                 memory_regions.secondary_partition_limit,
+                                 ARM_MPC_ATTR_NONSECURE);
+#endif /* BL2 */
 
     mpc_data_region0->Initialize();
     mpc_data_region0->ConfigRegion(MPC_ISRAM0_RANGE_BASE_S,
@@ -160,12 +218,13 @@
     mpc_data_region3->LockDown();
 
     /* Add barriers to assure the MPC configuration is done before continue
-     * the execution. */
+     * the execution.
+     */
     __DSB();
     __ISB();
 }
 
-/*------------------- PPC configuration functions -------------------------*/
+/*---------------------- PPC configuration functions -------------------------*/
 
 void ppc_init_cfg(void)
 {
@@ -173,7 +232,8 @@
     struct nspctrl_def* nspctrl = CMSDK_NSPCTRL;
 
     /* Grant non-secure access to peripherals in the PPC0
-     * (timer0 and 1, dualtimer, watchdog, mhu 0 and 1) */
+     * (timer0 and 1, dualtimer, watchdog, mhu 0 and 1)
+     */
     spctrl->apbnsppc0 |= (1U << CMSDK_TIMER0_APB_PPC_POS);
     spctrl->apbnsppc0 |= (1U << CMSDK_TIMER1_APB_PPC_POS);
     spctrl->apbnsppc0 |= (1U << CMSDK_DTIMER_APB_PPC_POS);
@@ -189,7 +249,8 @@
     nspctrl->ahbnspppcexp0 = (1U << MUSCA_PERIPHS_AHB_PPC_POS);
 
     /* Configure the response to a security violation as a
-     * bus error instead of RAZ/WI */
+     * bus error instead of RAZ/WI
+     */
     spctrl->secrespcfg |= 1U;
 }
 
diff --git a/platform/ext/target/musca_a/target_cfg.h b/platform/ext/target/musca_a/target_cfg.h
index 3d59934..25bdeaf 100755
--- a/platform/ext/target/musca_a/target_cfg.h
+++ b/platform/ext/target/musca_a/target_cfg.h
@@ -40,7 +40,22 @@
 };
 
 /**
- * Holds the data necessary to do isolation for a specific peripheral.
+ * \brief Store the addresses of memory regions
+ */
+struct memory_region_limits {
+    uint32_t non_secure_code_start;
+    uint32_t non_secure_partition_base;
+    uint32_t non_secure_partition_limit;
+    uint32_t veneer_base;
+    uint32_t veneer_limit;
+#ifdef BL2
+    uint32_t secondary_partition_base;
+    uint32_t secondary_partition_limit;
+#endif /* BL2 */
+};
+
+/**
+ * \brief Holds the data necessary to do isolation for a specific peripheral.
  */
 struct tfm_spm_partition_platform_data_t
 {
diff --git a/platform/include/tfm_spm_hal.h b/platform/include/tfm_spm_hal.h
index 24e987b..7c6a1d1 100644
--- a/platform/include/tfm_spm_hal.h
+++ b/platform/include/tfm_spm_hal.h
@@ -107,6 +107,28 @@
  */

 void nvic_interrupt_enable(void);

 

+/**

+ * \brief Get the VTOR value of non-secure image

+ *

+ * \return Returns the address where the vector table of the non-secure image

+ *         is located

+ */

+uint32_t tfm_spm_hal_get_ns_VTOR(void);

+

+/**

+ * \brief Get the initial address of non-secure image main stack

+ *

+ * \return Returns the initial non-secure MSP

+ */

+uint32_t tfm_spm_hal_get_ns_MSP(void);

+

+/**

+ * \brief Get the entry point of the non-secure image

+ *

+ * \return Returns the address of the non-secure image entry point

+ */

+uint32_t tfm_spm_hal_get_ns_entry_point(void);

+

 

 #if TFM_LVL != 1

 /**

diff --git a/secure_fw/core/tfm_secure_api.h b/secure_fw/core/tfm_secure_api.h
index 02fda8d..03359aa 100644
--- a/secure_fw/core/tfm_secure_api.h
+++ b/secure_fw/core/tfm_secure_api.h
@@ -67,6 +67,7 @@
     TFM_NS_REGION_VENEER,
     TFM_NS_REGION_PERIPH_1,
     TFM_NS_REGION_PERIPH_2,
+    TFM_NS_SECONDARY_IMAGE_REGION,
 };
 
 enum tfm_memory_access_e {