Platform: Support isolation level 2 for MUSCA_B1

- Add MUSCA_B1 TARGET_PLATFORM in ConfigCoreIPCTfmLevel2.cmake.
- Re-arrange the placement of secure partition in ARMCLANG linker file.
- Add start and end address for PSA and App RoT in ARMCLANG linker file.
- Add MPU config for App RoT.

Change-Id: I2c7c3f04e6183e986502d142397658d373948260
Signed-off-by: Edison Ai <edison.ai@arm.com>
diff --git a/ConfigCoreIPCTfmLevel2.cmake b/ConfigCoreIPCTfmLevel2.cmake
index 5a74dea..835d630 100644
--- a/ConfigCoreIPCTfmLevel2.cmake
+++ b/ConfigCoreIPCTfmLevel2.cmake
@@ -15,6 +15,8 @@
 	set(PLATFORM_CMAKE_FILE "${CMAKE_CURRENT_LIST_DIR}/platform/ext/Mps2AN521.cmake")
 elseif(${TARGET_PLATFORM} STREQUAL "MUSCA_A")
 	set(PLATFORM_CMAKE_FILE "${CMAKE_CURRENT_LIST_DIR}/platform/ext/musca_a.cmake")
+elseif(${TARGET_PLATFORM} STREQUAL "MUSCA_B1")
+	set(PLATFORM_CMAKE_FILE "${CMAKE_CURRENT_LIST_DIR}/platform/ext/musca_b1.cmake")
 else()
 	message(FATAL_ERROR "ERROR: Target \"${TARGET_PLATFORM}\" is not supported.")
 endif()
diff --git a/platform/ext/target/musca_b1/Device/Source/armclang/musca_s.sct b/platform/ext/target/musca_b1/Device/Source/armclang/musca_s.sct
index ac2b0f8..55fe48f 100644
--- a/platform/ext/target/musca_b1/Device/Source/armclang/musca_s.sct
+++ b/platform/ext/target/musca_b1/Device/Source/armclang/musca_s.sct
@@ -69,6 +69,14 @@
         *armlib*
     }
 
+    /**** PSA RoT RO part (CODE + RODATA) start here */
+    /*
+     * This empty, zero long execution region is here to mark the start address
+     * of PSA RoT code.
+     */
+    TFM_PSA_CODE_START +0 ALIGN 32 EMPTY 0x0 {
+    }
+
     TFM_SP_STORAGE +0 ALIGN 32 {
         *tfm_storage* (+RO)
         *(TFM_SP_STORAGE_ATTR_FN)
@@ -94,20 +102,6 @@
         *(TFM_SP_INITIAL_ATTESTATION_ATTR_FN)
     }
 
-#ifdef TFM_PARTITION_TEST_CORE
-    TFM_SP_CORE_TEST +0 ALIGN 32 {
-        *tfm_ss_core_test.* (+RO)
-        *(TFM_SP_CORE_TEST_ATTR_FN)
-    }
-#endif /* TFM_PARTITION_TEST_CORE */
-
-#ifdef TFM_PARTITION_TEST_CORE
-    TFM_SP_CORE_TEST_2 +0 ALIGN 32 {
-        *tfm_ss_core_test_2.* (+RO)
-        *(TFM_SP_CORE_TEST_2_ATTR_FN)
-    }
-#endif /* TFM_PARTITION_TEST_CORE */
-
 #ifdef TFM_PARTITION_TEST_SECURE_SERVICES
     TFM_SP_SECURE_TEST_PARTITION +0 ALIGN 32 {
         *tfm_secure_client_service.* (+RO)
@@ -129,6 +123,35 @@
     }
 #endif /* TFM_PSA_API */
 
+    /*
+     * This empty, zero long execution region is here to mark the end address
+     * of PSA RoT code.
+     */
+    TFM_PSA_CODE_END +0 ALIGN 32 EMPTY 0x0 {
+    }
+
+    /**** APPLICATION RoT RO part (CODE + RODATA) start here */
+    /*
+     * This empty, zero long execution region is here to mark the start address
+     * of APP RoT code.
+     */
+    TFM_APP_CODE_START +0 ALIGN 32 EMPTY 0x0 {
+    }
+
+#ifdef TFM_PARTITION_TEST_CORE
+    TFM_SP_CORE_TEST +0 ALIGN 32 {
+        *tfm_ss_core_test.* (+RO)
+        *(TFM_SP_CORE_TEST_ATTR_FN)
+    }
+#endif /* TFM_PARTITION_TEST_CORE */
+
+#ifdef TFM_PARTITION_TEST_CORE
+    TFM_SP_CORE_TEST_2 +0 ALIGN 32 {
+        *tfm_ss_core_test_2.* (+RO)
+        *(TFM_SP_CORE_TEST_2_ATTR_FN)
+    }
+#endif /* TFM_PARTITION_TEST_CORE */
+
 #ifdef TFM_PSA_API
     TFM_SP_IPC_CLIENT_TEST +0 ALIGN 32 {
         *ipc_client_test* (+RO)
@@ -136,6 +159,13 @@
     }
 #endif /* TFM_PSA_API */
 
+    /*
+     * This empty, zero long execution region is here to mark the end address
+     * of APP RoT code.
+     */
+    TFM_APP_CODE_END +0 ALIGN 32 EMPTY 0x0 {
+    }
+
     /* Shared area between BL2 and runtime to exchange data */
     TFM_SHARED_DATA S_DATA_START ALIGN 32 OVERLAY EMPTY BOOT_TFM_SHARED_DATA_SIZE {
     }
@@ -167,6 +197,14 @@
     TFM_UNPRIV_SCRATCH +0 ALIGN 32 EMPTY 0x400 {
     }
 
+    /**** PSA RoT DATA start here */
+    /*
+     * This empty, zero long execution region is here to mark the start address
+     * of PSA RoT RW and Stack.
+     */
+    TFM_PSA_RW_STACK_START +0 ALIGN 32 EMPTY 0x0 {
+    }
+
     TFM_SP_STORAGE_DATA +0 ALIGN 32 {
         *tfm_storage* (+RW +ZI)
     }
@@ -202,24 +240,6 @@
     TFM_SP_INITIAL_ATTESTATION_STACK +0 ALIGN 128 EMPTY 0x0400 {
     }
 
-#ifdef TFM_PARTITION_TEST_CORE
-    TFM_SP_CORE_TEST_DATA +0 ALIGN 32 {
-        *tfm_ss_core_test.* (+RW +ZI)
-    }
-
-    TFM_SP_CORE_TEST_STACK +0 ALIGN 128 EMPTY 0x0300 {
-    }
-#endif /* TFM_PARTITION_TEST_CORE */
-
-#ifdef TFM_PARTITION_TEST_CORE
-    TFM_SP_CORE_TEST_2_DATA +0 ALIGN 32 {
-        *tfm_ss_core_test_2.* (+RW +ZI)
-    }
-
-    TFM_SP_CORE_TEST_2_STACK +0 ALIGN 128 EMPTY 0x0200 {
-    }
-#endif /* TFM_PARTITION_TEST_CORE */
-
 #ifdef TFM_PARTITION_TEST_SECURE_SERVICES
     TFM_SP_SECURE_TEST_PARTITION_DATA +0 ALIGN 32 {
         *tfm_secure_client_service.* (+RW +ZI)
@@ -245,6 +265,39 @@
     }
 #endif /* TFM_PSA_API */
 
+    /*
+     * This empty, zero long execution region is here to mark the end address
+     * of PSA RoT RW and Stack.
+     */
+    TFM_PSA_RW_STACK_END +0 ALIGN 32 EMPTY 0x0 {
+    }
+
+    /**** APP RoT DATA start here */
+    /*
+     * This empty, zero long execution region is here to mark the start address
+     * of APP RoT RW and Stack.
+     */
+    TFM_APP_RW_STACK_START +0 ALIGN 32 EMPTY 0x0 {
+    }
+
+#ifdef TFM_PARTITION_TEST_CORE
+    TFM_SP_CORE_TEST_DATA +0 ALIGN 32 {
+        *tfm_ss_core_test.* (+RW +ZI)
+    }
+
+    TFM_SP_CORE_TEST_STACK +0 ALIGN 128 EMPTY 0x0300 {
+    }
+#endif /* TFM_PARTITION_TEST_CORE */
+
+#ifdef TFM_PARTITION_TEST_CORE
+    TFM_SP_CORE_TEST_2_DATA +0 ALIGN 32 {
+        *tfm_ss_core_test_2.* (+RW +ZI)
+    }
+
+    TFM_SP_CORE_TEST_2_STACK +0 ALIGN 128 EMPTY 0x0200 {
+    }
+#endif /* TFM_PARTITION_TEST_CORE */
+
 #ifdef TFM_PSA_API
     TFM_SP_IPC_CLIENT_TEST_DATA +0 ALIGN 32 {
         *ipc_client_test* (+RW +ZI)
@@ -254,6 +307,12 @@
     }
 #endif /* TFM_PSA_API */
 
+    /*
+     * This empty, zero long execution region is here to mark the end address
+     * of APP RoT RW and Stack.
+     */
+    TFM_APP_RW_STACK_END +0 ALIGN 32 EMPTY 0x0 {
+    }
 #endif /* TFM_LVL == 1 */
 
     /* This empty, zero long execution region is here to mark the limit address
diff --git a/platform/ext/target/musca_b1/Device/Source/armclang/musca_s.sct.template b/platform/ext/target/musca_b1/Device/Source/armclang/musca_s.sct.template
index 9a5d097..522cdea 100644
--- a/platform/ext/target/musca_b1/Device/Source/armclang/musca_s.sct.template
+++ b/platform/ext/target/musca_b1/Device/Source/armclang/musca_s.sct.template
@@ -69,7 +69,16 @@
         *armlib*
     }
 
+    /**** PSA RoT RO part (CODE + RODATA) start here */
+    /*
+     * This empty, zero long execution region is here to mark the start address
+     * of PSA RoT code.
+     */
+    TFM_PSA_CODE_START +0 ALIGN 32 EMPTY 0x0 {
+    }
+
 {% for manifest in manifests %}
+    {% if manifest.manifest.type == 'PSA-ROT' %}
     {% if manifest.attr.conditional %}
 #ifdef {{manifest.attr.conditional}}
     {% endif %}
@@ -90,7 +99,54 @@
 #endif /* {{manifest.attr.conditional}} */
     {% endif %}
 
+    {% endif %}
 {% endfor %}
+    /*
+     * This empty, zero long execution region is here to mark the end address
+     * of PSA RoT code.
+     */
+    TFM_PSA_CODE_END +0 ALIGN 32 EMPTY 0x0 {
+    }
+
+    /**** APPLICATION RoT RO part (CODE + RODATA) start here */
+    /*
+     * This empty, zero long execution region is here to mark the start address
+     * of APP RoT code.
+     */
+    TFM_APP_CODE_START +0 ALIGN 32 EMPTY 0x0 {
+    }
+
+{% for manifest in manifests %}
+    {% if manifest.manifest.type == 'APPLICATION-ROT' %}
+    {% if manifest.attr.conditional %}
+#ifdef {{manifest.attr.conditional}}
+    {% endif %}
+    {{manifest.manifest.name}} +0 ALIGN 32 {
+    {% if manifest.manifest.tfm_linker_pattern.library_list %}
+        {% for pattern in manifest.manifest.tfm_linker_pattern.library_list %}
+        {{pattern}} (+RO)
+        {% endfor %}
+    {% endif %}
+    {% if manifest.manifest.tfm_linker_pattern.object_list %}
+        {% for pattern in manifest.manifest.tfm_linker_pattern.object_list %}
+        {{pattern}} (+RO)
+        {% endfor %}
+    {% endif %}
+        *({{manifest.manifest.name}}_ATTR_FN)
+    }
+    {% if manifest.attr.conditional %}
+#endif /* {{manifest.attr.conditional}} */
+    {% endif %}
+
+    {% endif %}
+{% endfor %}
+    /*
+     * This empty, zero long execution region is here to mark the end address
+     * of APP RoT code.
+     */
+    TFM_APP_CODE_END +0 ALIGN 32 EMPTY 0x0 {
+    }
+
     /* Shared area between BL2 and runtime to exchange data */
     TFM_SHARED_DATA S_DATA_START ALIGN 32 OVERLAY EMPTY BOOT_TFM_SHARED_DATA_SIZE {
     }
@@ -122,7 +178,16 @@
     TFM_UNPRIV_SCRATCH +0 ALIGN 32 EMPTY 0x400 {
     }
 
-    {% for manifest in manifests %}
+    /**** PSA RoT DATA start here */
+    /*
+     * This empty, zero long execution region is here to mark the start address
+     * of PSA RoT RW and Stack.
+     */
+    TFM_PSA_RW_STACK_START +0 ALIGN 32 EMPTY 0x0 {
+    }
+
+{% for manifest in manifests %}
+    {% if manifest.manifest.type == 'PSA-ROT' %}
     {% if manifest.attr.conditional %}
 #ifdef {{manifest.attr.conditional}}
     {% endif %}
@@ -145,7 +210,55 @@
 #endif /* {{manifest.attr.conditional}} */
     {% endif %}
 
+    {% endif %}
 {% endfor %}
+    /*
+     * This empty, zero long execution region is here to mark the end address
+     * of PSA RoT RW and Stack.
+     */
+    TFM_PSA_RW_STACK_END +0 ALIGN 32 EMPTY 0x0 {
+    }
+
+    /**** APP RoT DATA start here */
+    /*
+     * This empty, zero long execution region is here to mark the start address
+     * of APP RoT RW and Stack.
+     */
+    TFM_APP_RW_STACK_START +0 ALIGN 32 EMPTY 0x0 {
+    }
+
+{% for manifest in manifests %}
+    {% if manifest.manifest.type == 'APPLICATION-ROT' %}
+    {% if manifest.attr.conditional %}
+#ifdef {{manifest.attr.conditional}}
+    {% endif %}
+    {{manifest.manifest.name}}_DATA +0 ALIGN 32 {
+    {% if manifest.manifest.tfm_linker_pattern.library_list %}
+        {% for pattern in manifest.manifest.tfm_linker_pattern.library_list %}
+        {{pattern}} (+RW +ZI)
+        {% endfor %}
+    {% endif %}
+    {% if manifest.manifest.tfm_linker_pattern.object_list %}
+        {% for pattern in manifest.manifest.tfm_linker_pattern.object_list %}
+        {{pattern}} (+RW +ZI)
+        {% endfor %}
+    {% endif %}
+    }
+
+    {{manifest.manifest.name}}_STACK +0 ALIGN 128 EMPTY {{manifest.manifest.stack_size}} {
+    }
+    {% if manifest.attr.conditional %}
+#endif /* {{manifest.attr.conditional}} */
+    {% endif %}
+
+    {% endif %}
+{% endfor %}
+    /*
+     * This empty, zero long execution region is here to mark the end address
+     * of APP RoT RW and Stack.
+     */
+    TFM_APP_RW_STACK_END +0 ALIGN 32 EMPTY 0x0 {
+    }
 #endif /* TFM_LVL == 1 */
 
     /* This empty, zero long execution region is here to mark the limit address
diff --git a/platform/ext/target/musca_b1/spm_hal.c b/platform/ext/target/musca_b1/spm_hal.c
index e6d62ee..2d8f678 100644
--- a/platform/ext/target/musca_b1/spm_hal.c
+++ b/platform/ext/target/musca_b1/spm_hal.c
@@ -48,18 +48,31 @@
 #define MPU_REGION_VENEERS           0
 #define MPU_REGION_TFM_UNPRIV_CODE   1
 #define MPU_REGION_TFM_UNPRIV_DATA   2
-#define MPU_REGION_NS_DATA           3
 #define PARTITION_REGION_RO          4
 #define PARTITION_REGION_RW_STACK    5
 #define PARTITION_REGION_PERIPH      6
 #define PARTITION_REGION_SHARE       7
 
+#if TFM_LVL == 2
+#define MPU_REGION_NS_STACK          3
+#elif TFM_LVL == 3
+#define MPU_REGION_NS_DATA           3
+#endif
+
 REGION_DECLARE(Image$$, TFM_UNPRIV_CODE, $$RO$$Base);
 REGION_DECLARE(Image$$, TFM_UNPRIV_CODE, $$RO$$Limit);
 REGION_DECLARE(Image$$, TFM_UNPRIV_DATA, $$RW$$Base);
 REGION_DECLARE(Image$$, TFM_UNPRIV_DATA, $$ZI$$Limit);
 REGION_DECLARE(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Base);
 REGION_DECLARE(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Limit);
+#if TFM_LVL == 2
+REGION_DECLARE(Image$$, TFM_APP_CODE_START, $$Base);
+REGION_DECLARE(Image$$, TFM_APP_CODE_END, $$Base);
+REGION_DECLARE(Image$$, TFM_APP_RW_STACK_START, $$Base);
+REGION_DECLARE(Image$$, TFM_APP_RW_STACK_END, $$Base);
+REGION_DECLARE(Image$$, ARM_LIB_STACK, $$ZI$$Base);
+REGION_DECLARE(Image$$, ARM_LIB_STACK, $$ZI$$Limit);
+#endif
 
 static enum spm_err_t tfm_spm_mpu_init(void)
 {
@@ -107,6 +120,7 @@
         return SPM_ERR_INVALID_CONFIG;
     }
 
+#if TFM_LVL == 3
     /* TFM Core unprivileged non-secure data region */
     region_cfg.region_nr = MPU_REGION_NS_DATA;
     region_cfg.region_base = NS_DATA_START;
@@ -118,6 +132,51 @@
     if (mpu_armv8m_region_enable(&dev_mpu_s, &region_cfg) != MPU_ARMV8M_OK) {
         return SPM_ERR_INVALID_CONFIG;
     }
+#endif
+
+#if TFM_LVL == 2
+    /* NSPM PSP */
+    region_cfg.region_nr = MPU_REGION_NS_STACK;
+    region_cfg.region_base =
+        (uint32_t)&REGION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Base);
+    region_cfg.region_limit =
+        (uint32_t)&REGION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Limit);
+    region_cfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_DATA_IDX;
+    region_cfg.attr_access = MPU_ARMV8M_AP_RW_PRIV_UNPRIV;
+    region_cfg.attr_sh = MPU_ARMV8M_SH_NONE;
+    region_cfg.attr_exec = MPU_ARMV8M_XN_EXEC_NEVER;
+    if (mpu_armv8m_region_enable(&dev_mpu_s, &region_cfg) != MPU_ARMV8M_OK) {
+        return SPM_ERR_INVALID_CONFIG;
+    }
+
+    /* RO region */
+    region_cfg.region_nr = PARTITION_REGION_RO;
+    region_cfg.region_base =
+        (uint32_t)&REGION_NAME(Image$$, TFM_APP_CODE_START, $$Base);
+    region_cfg.region_limit =
+        (uint32_t)&REGION_NAME(Image$$, TFM_APP_CODE_END, $$Base);
+    region_cfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_CODE_IDX;
+    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;
+    if (mpu_armv8m_region_enable(&dev_mpu_s, &region_cfg) != MPU_ARMV8M_OK) {
+        return SPM_ERR_INVALID_CONFIG;
+    }
+
+    /* RW, ZI and stack as one region */
+    region_cfg.region_nr = PARTITION_REGION_RW_STACK;
+    region_cfg.region_base =
+        (uint32_t)&REGION_NAME(Image$$, TFM_APP_RW_STACK_START, $$Base);
+    region_cfg.region_limit =
+        (uint32_t)&REGION_NAME(Image$$, TFM_APP_RW_STACK_END, $$Base);
+    region_cfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_DATA_IDX;
+    region_cfg.attr_access = MPU_ARMV8M_AP_RW_PRIV_UNPRIV;
+    region_cfg.attr_sh = MPU_ARMV8M_SH_NONE;
+    region_cfg.attr_exec = MPU_ARMV8M_XN_EXEC_NEVER;
+    if (mpu_armv8m_region_enable(&dev_mpu_s, &region_cfg) != MPU_ARMV8M_OK) {
+        return SPM_ERR_INVALID_CONFIG;
+    }
+#endif
 
     mpu_armv8m_enable(&dev_mpu_s, PRIVILEGED_DEFAULT_ENABLE,
                       HARDFAULT_NMI_ENABLE);