Isolation L3 for AN521 and Musca-B1
- Add Isolation L3 region configuration for AN521 and Musca-B1.
- Add level3-specific linker script/scatter load files for these
two platforms. The other platforms do not support L3 and do not
need specific load files at current stage.
- Implement level3-specific dynamic MPU region switching function
tfm_hal_mpu_update_partition_boundary() while isolation level3
is chosen.
Change-Id: Icc50683c8a9b32494b29948d1ebeedcb59c0bcaa
Signed-off-by: Kevin Peng <kevin.peng@arm.com>
Co-authored-by: Mingyang Sun <mingyang.sun@arm.com>
diff --git a/platform/ext/common/armclang/tfm_isolation_l3.sct.template b/platform/ext/common/armclang/tfm_isolation_l3.sct.template
new file mode 100644
index 0000000..f3d5f7e
--- /dev/null
+++ b/platform/ext/common/armclang/tfm_isolation_l3.sct.template
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2017-2020 Arm Limited. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+{{utilities.donotedit_warning}}
+
+/*
+ * Customized region name prefix abbreviation:
+ * LR : A Load region.
+ * ER : A typical execution region.
+ * PT : An empty execution region used as position-tag/address-alignment.
+ *
+ * No applying customzied prefixes on linker/system reserved/intentional
+ * names, such as 'ARM_LIB_STACK'.
+ */
+
+#include "region_defs.h"
+
+LR_CODE S_CODE_START {
+
+ PT_RO_START S_CODE_START ALIGN 32 EMPTY 0x0 {
+ /* Position tag: code + RO-data */
+ }
+
+ /**** This initial section contains mainly the SPM code and RO-data */
+ ER_TFM_CODE +0 ALIGN 32 {
+ *.o (RESET +First)
+ * (+RO)
+ }
+
+ /**** PSA RoT CODE + RO-data starts here */
+{% for manifest in manifests %}
+ {% if manifest.manifest.type == 'PSA-ROT' %}
+ {% if manifest.attr.conditional %}
+#ifdef {{manifest.attr.conditional}}
+ {% endif %}
+ ER_{{manifest.manifest.name}}_RO +0 ALIGN 32 {
+ {% if manifest.attr.linker_pattern.library_list %}
+ {% for pattern in manifest.attr.linker_pattern.library_list %}
+ {{pattern}} (+RO)
+ {% endfor %}
+ {% endif %}
+ {% if manifest.attr.linker_pattern.object_list %}
+ {% for pattern in manifest.attr.linker_pattern.object_list %}
+ {{pattern}} (+RO)
+ {% endfor %}
+ {% endif %}
+ *({{manifest.manifest.name}}_ATTR_FN)
+ }
+ {% if manifest.attr.conditional %}
+#endif /* {{manifest.attr.conditional}} */
+ {% endif %}
+
+ {% endif %}
+{% endfor %}
+ /**** PSA RoT CODE + RO-data ends here */
+
+ /**** APPLICATION RoT CODE + RO-data starts here */
+{% for manifest in manifests %}
+ {% if manifest.manifest.type == 'APPLICATION-ROT' %}
+ {% if manifest.attr.conditional %}
+#ifdef {{manifest.attr.conditional}}
+ {% endif %}
+ ER_{{manifest.manifest.name}}_RO +0 ALIGN 32 {
+ {% if manifest.attr.linker_pattern.library_list %}
+ {% for pattern in manifest.attr.linker_pattern.library_list %}
+ {{pattern}} (+RO)
+ {% endfor %}
+ {% endif %}
+ {% if manifest.attr.linker_pattern.object_list %}
+ {% for pattern in manifest.attr.linker_pattern.object_list %}
+ {{pattern}} (+RO)
+ {% endfor %}
+ {% endif %}
+ *({{manifest.manifest.name}}_ATTR_FN)
+ }
+ {% if manifest.attr.conditional %}
+#endif /* {{manifest.attr.conditional}} */
+ {% endif %}
+
+ {% endif %}
+{% endfor %}
+ /**** APPLICATION RoT CODE + RO-data ends here */
+
+ /**** Unprivileged Secure code + RO-data starts here */
+ TFM_UNPRIV_CODE +0 ALIGN 32 {
+ platform_retarget_dev.o (+RO)
+ device_definition.o (+RO)
+ *(SFN)
+ *armlib* (+RO)
+ *libtfmsprt.a (+RO)
+ *psa_client.* (+RO)
+ *psa_service.* (+RO)
+ *psa_lifecycle.* (+RO)
+ }
+
+ PT_RO_END +0 ALIGN 32 EMPTY 0x0 {
+ /* Position tag */
+ }
+
+ /**** Base address of secure data area */
+ PT_SECURE_DATA_START S_DATA_START EMPTY 0x0 {
+ /* Position tag */
+ }
+
+ PT_PRIV_RWZI_START +0 ALIGN 32 EMPTY 0x0 {
+ /* Position tag */
+ }
+
+ /* Shared area between BL2 and runtime to exchange data */
+ TFM_SHARED_DATA +0 ALIGN 32 OVERLAY EMPTY BOOT_TFM_SHARED_DATA_SIZE {
+ }
+
+ /* MSP */
+ ARM_LIB_STACK_MSP +0 ALIGN 32 OVERLAY EMPTY S_MSP_STACK_SIZE {
+ }
+
+ ARM_LIB_HEAP +0 ALIGN 8 EMPTY S_HEAP_SIZE {
+ }
+
+ ER_TFM_DATA +0 {
+ * (+RW +ZI)
+ }
+
+ /**** PSA RoT RWZI starts here */
+{% for manifest in manifests %}
+ {% if manifest.manifest.type == 'PSA-ROT' %}
+ {% if manifest.attr.conditional %}
+#ifdef {{manifest.attr.conditional}}
+ {% endif %}
+
+ PT_{{manifest.manifest.name}}_PRIVATE_DATA_START +0 ALIGN 32 {
+ /* Position tag */
+ }
+
+ ER_{{manifest.manifest.name}}_RWZI +0 ALIGN 32 {
+ {% if manifest.attr.linker_pattern.library_list %}
+ {% for pattern in manifest.attr.linker_pattern.library_list %}
+ {{pattern}} (+RW +ZI)
+ {% endfor %}
+ {% endif %}
+ {% if manifest.attr.linker_pattern.object_list %}
+ {% for pattern in manifest.attr.linker_pattern.object_list %}
+ {{pattern}} (+RW +ZI)
+ {% endfor %}
+ {% endif %}
+ *({{manifest.manifest.name}}_ATTR_RW)
+ *({{manifest.manifest.name}}_ATTR_ZI)
+ }
+
+ {% if manifest.attr.tfm_partition_ipc %}
+ {{manifest.manifest.name}}_LINKER_STACK +0 ALIGN 128 EMPTY {{manifest.manifest.stack_size}} {
+ }
+ {% else %}
+ {{manifest.manifest.name}}_LINKER_STACK +0 ALIGN 128 EMPTY 0 {
+ }
+ {% endif %}
+
+ PT_{{manifest.manifest.name}}_PRIVATE_DATA_END +0 ALIGN 32 {
+ /* Position tag */
+ }
+
+ {% if manifest.attr.conditional %}
+#endif /* {{manifest.attr.conditional}} */
+ {% endif %}
+
+ {% endif %}
+{% endfor %}
+
+ /**** PSA RoT RWZI ends here */
+ PT_PRIV_RWZI_END +0 ALIGN 32 EMPTY 0x0 {
+ /* Position tag */
+ }
+
+ /* PSP is unprivileged in single-core topology */
+ ARM_LIB_STACK +0 ALIGN 32 EMPTY S_PSP_STACK_SIZE {
+ }
+
+{% for manifest in manifests %}
+ {% if manifest.manifest.type == 'APPLICATION-ROT' %}
+ {% if manifest.attr.conditional %}
+#ifdef {{manifest.attr.conditional}}
+ {% endif %}
+
+ PT_{{manifest.manifest.name}}_PRIVATE_DATA_START +0 ALIGN 32 {
+ /* Position tag */
+ }
+
+ ER_{{manifest.manifest.name}}_RWZI +0 ALIGN 32 {
+ {% if manifest.attr.linker_pattern.library_list %}
+ {% for pattern in manifest.attr.linker_pattern.library_list %}
+ {{pattern}} (+RW +ZI)
+ {% endfor %}
+ {% endif %}
+ {% if manifest.attr.linker_pattern.object_list %}
+ {% for pattern in manifest.attr.linker_pattern.object_list %}
+ {{pattern}} (+RW +ZI)
+ {% endfor %}
+ {% endif %}
+ *({{manifest.manifest.name}}_ATTR_RW)
+ *({{manifest.manifest.name}}_ATTR_ZI)
+ }
+
+ {% if manifest.attr.tfm_partition_ipc %}
+ {{manifest.manifest.name}}_LINKER_STACK +0 ALIGN 128 EMPTY {{manifest.manifest.stack_size}} {
+ }
+ {% else %}
+ {{manifest.manifest.name}}_LINKER_STACK +0 ALIGN 128 EMPTY 0 {
+ }
+ {% endif %}
+
+ PT_{{manifest.manifest.name}}_PRIVATE_DATA_END +0 ALIGN 32 {
+ /* Position tag */
+ }
+
+ {% if manifest.attr.conditional %}
+#endif /* {{manifest.attr.conditional}} */
+ {% endif %}
+
+ {% endif %}
+{% endfor %}
+
+ PT_SRAM_WATERMARK +0 EMPTY 0x0 {
+ /* Position tag */
+ }
+
+ /* Make sure that the sections allocated in the SRAM does not exceed the
+ * size of the SRAM available.
+ */
+ ScatterAssert(ImageLimit(PT_SRAM_WATERMARK) <= S_DATA_START + S_DATA_SIZE)
+
+#if defined(S_CODE_SRAM_ALIAS_BASE)
+ /* eFlash driver code that gets copied from Flash to SRAM */
+ ER_EFLASH_DRIVER_RO S_CODE_SRAM_ALIAS_BASE ALIGN 32 {
+ Driver_GFC100_EFlash.o (+RO)
+ gfc100_eflash_drv.o (+RO)
+ musca_b1_eflash_drv.o (+RO)
+ }
+#endif
+}
+
+LR_VENEER CMSE_VENEER_REGION_START {
+ /*
+ * Place the CMSE Veneers (containing the SG instruction) in a separate
+ * 32 bytes aligned region so that the SAU can be programmed to
+ * just set this region as Non-Secure Callable.
+ */
+ ER_CODE_CMSE_VENEER CMSE_VENEER_REGION_START CMSE_VENEER_REGION_SIZE {
+ *(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. This generates an empty
+ * execution region description warning during linking.
+ */
+ ER_NS_PARTITION NS_PARTITION_START UNINIT 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. This generates an empty
+ * execution region description warning during linking.
+ */
+ ER_SECONDARY_PARTITION SECONDARY_PARTITION_START \
+ UNINIT SECONDARY_PARTITION_SIZE {
+ }
+}
+#endif /* BL2 */
diff --git a/platform/ext/common/gcc/tfm_isolation_l3.ld.template b/platform/ext/common/gcc/tfm_isolation_l3.ld.template
new file mode 100644
index 0000000..ca918f6
--- /dev/null
+++ b/platform/ext/common/gcc/tfm_isolation_l3.ld.template
@@ -0,0 +1,550 @@
+;/*
+; * Copyright (c) 2009-2020 Arm Limited
+; *
+; * Licensed under the Apache License, Version 2.0 (the "License");
+; * you may not use this file except in compliance with the License.
+; * You may obtain a copy of the License at
+; *
+; * http://www.apache.org/licenses/LICENSE-2.0
+; *
+; * Unless required by applicable law or agreed to in writing, software
+; * distributed under the License is distributed on an "AS IS" BASIS,
+; * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+; * See the License for the specific language governing permissions and
+; * limitations under the License.
+; *
+; *
+; * This file is derivative of CMSIS V5.00 gcc_arm.ld
+; */
+
+{{utilities.donotedit_warning}}
+
+/* Linker script to configure memory regions. */
+/* This file will be run trough the pre-processor. */
+
+#include "region_defs.h"
+
+MEMORY
+{
+ FLASH (rx) : ORIGIN = S_CODE_START, LENGTH = S_CODE_SIZE
+ RAM (rwx) : ORIGIN = S_DATA_START, LENGTH = S_DATA_SIZE
+#if defined(S_CODE_SRAM_ALIAS_BASE)
+ CODE_RAM (rwx) : ORIGIN = S_CODE_SRAM_ALIAS_BASE, LENGTH = TOTAL_CODE_SRAM_SIZE
+#endif
+ VENEERS (rx) : ORIGIN = CMSE_VENEER_REGION_START, LENGTH = CMSE_VENEER_REGION_SIZE
+}
+
+__heap_size__ = S_HEAP_SIZE;
+__psp_stack_size__ = S_PSP_STACK_SIZE;
+__msp_init_stack_size__ = S_MSP_STACK_SIZE_INIT;
+
+/* Library configurations */
+GROUP(libgcc.a libc.a libm.a libnosys.a libc_nano.a)
+
+ENTRY(Reset_Handler)
+
+SECTIONS
+{
+ .TFM_VECTORS : ALIGN(4)
+ {
+ __vectors_start__ = .;
+ KEEP(*(.vectors))
+ __vectors_end__ = .;
+ *startup*(.text*)
+ . = ALIGN(4);
+ } > FLASH
+
+ .copy.table : ALIGN(4)
+ {
+ __copy_table_start__ = .;
+ LONG (LOADADDR(.TFM_DATA))
+ LONG (ADDR(.TFM_DATA))
+ LONG (SIZEOF(.TFM_DATA))
+{% for manifest in manifests %}
+ {% if manifest.attr.conditional %}
+#ifdef {{manifest.attr.conditional}}
+ {% endif %}
+ LONG (LOADADDR(.ER_{{manifest.manifest.name}}_RWZI))
+ LONG (ADDR(.ER_{{manifest.manifest.name}}_RWZI))
+ LONG (SIZEOF(.ER_{{manifest.manifest.name}}_RWZI))
+ {% if manifest.attr.conditional %}
+#endif /* {{manifest.attr.conditional}} */
+ {% endif %}
+{% endfor %}
+#if defined(S_CODE_SRAM_ALIAS_BASE)
+ LONG (LOADADDR(.ER_EFLASH_DRIVER_RO))
+ LONG (ADDR(.ER_EFLASH_DRIVER_RO))
+ LONG (SIZEOF(.ER_EFLASH_DRIVER_RO))
+#endif
+ __copy_table_end__ = .;
+ } > FLASH
+
+ .zero.table : ALIGN(4)
+ {
+ __zero_table_start__ = .;
+ LONG (ADDR(.TFM_BSS))
+ LONG (SIZEOF(.TFM_BSS))
+{% for manifest in manifests %}
+ {% if manifest.attr.conditional %}
+#ifdef {{manifest.attr.conditional}}
+ {% endif %}
+ LONG (ADDR(.{{manifest.manifest.name}}_RWZI_BSS))
+ LONG (SIZEOF(.{{manifest.manifest.name}}_RWZI_BSS))
+ {% if manifest.attr.tfm_partition_ipc %}
+ LONG (ADDR(.{{manifest.manifest.name}}_LINKER_STACK))
+ LONG (SIZEOF(.{{manifest.manifest.name}}_LINKER_STACK))
+ {% endif %}
+ {% if manifest.attr.conditional %}
+#endif /* {{manifest.attr.conditional}} */
+ {% endif %}
+{% endfor %}
+ __zero_table_end__ = .;
+ } > FLASH
+
+ /* Position tag */
+ . = ALIGN(32);
+ Image$$PT_RO_START$$Base = .;
+
+ /**** PSA RoT RO CODE + RO-data starts here */
+{% for manifest in manifests %}
+ {% if manifest.manifest.type == 'PSA-ROT' %}
+ {% if manifest.attr.conditional %}
+#ifdef {{manifest.attr.conditional}}
+ {% endif %}
+ .{{manifest.manifest.name}}_RO : ALIGN(32)
+ {
+ {% if manifest.attr.linker_pattern.library_list %}
+ {% for pattern in manifest.attr.linker_pattern.library_list %}
+ {{pattern}}:*(.text*)
+ {{pattern}}:*(.rodata*)
+ {% endfor %}
+ {% endif %}
+ {% if manifest.attr.linker_pattern.object_list %}
+ {% for pattern in manifest.attr.linker_pattern.object_list %}
+ {{pattern}}(.text*)
+ {{pattern}}:*(.rodata*)
+ {% endfor %}
+ {% endif %}
+ *({{manifest.manifest.name}}_ATTR_FN)
+ . = ALIGN(32);
+ } > FLASH
+ Image$${{manifest.manifest.name}}_RO$$Base = ADDR(.{{manifest.manifest.name}}_RO);
+ Image$${{manifest.manifest.name}}_RO$$Limit = ADDR(.{{manifest.manifest.name}}_RO) + SIZEOF(.{{manifest.manifest.name}}_RO);
+ {% if manifest.attr.conditional %}
+#endif /* {{manifest.attr.conditional}} */
+ {% endif %}
+
+ {% endif %}
+{% endfor %}
+ /**** PSA RoT RO CODE + data ends here */
+
+ /**** APPLICATION RoT RO CODE + data starts here */
+{% for manifest in manifests %}
+ {% if manifest.manifest.type == 'APPLICATION-ROT' %}
+ {% if manifest.attr.conditional %}
+#ifdef {{manifest.attr.conditional}}
+ {% endif %}
+ .{{manifest.manifest.name}}_RO : ALIGN(32)
+ {
+ {% if manifest.attr.linker_pattern.library_list %}
+ {% for pattern in manifest.attr.linker_pattern.library_list %}
+ {{pattern}}:*(.text*)
+ {{pattern}}:*(.rodata*)
+ {% endfor %}
+ {% endif %}
+ {% if manifest.attr.linker_pattern.object_list %}
+ {% for pattern in manifest.attr.linker_pattern.object_list %}
+ {{pattern}}(.text*)
+ {{pattern}}:*(.rodata*)
+ {% endfor %}
+ {% endif %}
+ *({{manifest.manifest.name}}_ATTR_FN)
+ . = ALIGN(32);
+ } > FLASH
+ Image$${{manifest.manifest.name}}_CODE$$Base = ADDR(.{{manifest.manifest.name}}_RO);
+ Image$${{manifest.manifest.name}}_CODE$$Limit = ADDR(.{{manifest.manifest.name}}_RO) + SIZEOF(.{{manifest.manifest.name}}_RO);
+ {% if manifest.attr.conditional %}
+#endif /* {{manifest.attr.conditional}} */
+ {% endif %}
+
+ {% endif %}
+{% endfor %}
+ /**** APPLICATION RoT RO CODE + data ends here */
+
+ /**** Unprivileged Secure code starts here */
+ .ER_UNPRIV_CODE : ALIGN(32)
+ {
+ *platform_retarget_dev.*(.text*)
+ *platform_retarget_dev.*(.rodata*)
+ *device_definition.*(.text*)
+ *device_definition.*(.rodata*)
+ *(SFN)
+ *armlib*:*(.text*)
+ *armlib*:*(.rodata*)
+ *libtfmsprt*:*(.text*)
+ *libtfmsprt*:*(.rodata*)
+ *psa_client.*(.text*) /* NXP */
+ *psa_client.*(.rodata*)
+ *psa_service.*(.text*) /* NXP */
+ *psa_lifecycle.*(.text*) /* NXP */
+ *psa_lifecycle.*(.rodata*)
+ . = ALIGN(32);
+ } > FLASH
+ Image$$TFM_UNPRIV_CODE$$RO$$Base = ADDR(.ER_UNPRIV_CODE);
+ Image$$TFM_UNPRIV_CODE$$RO$$Limit = ADDR(.ER_UNPRIV_CODE) + SIZEOF(.ER_UNPRIV_CODE);
+
+ .ER_TFM_CODE : ALIGN(4)
+ {
+ *(.text*)
+
+ KEEP(*(.init))
+ KEEP(*(.fini))
+
+
+ /* .ctors */
+ *crtbegin.o(.ctors)
+ *crtbegin?.o(.ctors)
+ *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
+ *(SORT(.ctors.*))
+ *(.ctors)
+
+ /* .dtors */
+ *crtbegin.o(.dtors)
+ *crtbegin?.o(.dtors)
+ *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
+ *(SORT(.dtors.*))
+ *(.dtors)
+
+ *(.rodata*)
+
+ KEEP(*(.eh_frame*))
+ } > FLASH
+
+ /* Position tag */
+ . = ALIGN(32);
+ Image$$PT_RO_END$$Base = .;
+
+#if defined(S_CODE_SRAM_ALIAS_BASE)
+ .ER_EFLASH_DRIVER_RO : ALIGN(4)
+ {
+ *Driver_GFC100_EFlash.o(.text*)
+ *Driver_GFC100_EFlash.o(.rodata*)
+ *gfc100_eflash_drv.o(.text*)
+ *gfc100_eflash_drv.o(.rodata*)
+ *musca_b1_eflash_drv.o(.text*)
+ *musca_b1_eflash_drv.o(.rodata*)
+ . = ALIGN(4); /* This alignment is needed to make the section size 4 bytes aligned */
+ } > CODE_RAM AT > FLASH
+ Image$$ER_EFLASH_DRIVER_RO$$Base = ADDR(.ER_EFLASH_DRIVER_RO);
+ Image$$ER_EFLASH_DRIVER_RO$$Limit = ADDR(.ER_EFLASH_DRIVER_RO) + SIZEOF(.ER_EFLASH_DRIVER_RO);
+#endif
+
+ .ARM.extab :
+ {
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ } > FLASH
+
+ __exidx_start = .;
+ .ARM.exidx :
+ {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ } > FLASH
+ __exidx_end = .;
+
+ /**** Base address of secure data area */
+ .tfm_secure_data_start :
+ {
+ . = ABSOLUTE(S_DATA_START) ;
+ } > RAM
+
+ /* Position tag */
+ . = ALIGN(32);
+ Image$$PT_PRIV_RWZI_START$$Base = .;
+
+ /* shared_data and msp_stack are overlapping on purpose when
+ * msp_stack is extended until the beginning of RAM, when shared_date
+ * was read out by partitions
+ */
+ .tfm_bl2_shared_data : ALIGN(32)
+ {
+ . += BOOT_TFM_SHARED_DATA_SIZE;
+ } > RAM
+
+ .msp_stack : ALIGN(32)
+ {
+ . += __msp_init_stack_size__;
+ } > RAM
+ Image$$ARM_LIB_STACK_MSP$$ZI$$Base = ADDR(.msp_stack);
+ Image$$ARM_LIB_STACK_MSP$$ZI$$Limit = ADDR(.msp_stack) + SIZEOF(.msp_stack);
+
+ /**** PSA RoT DATA start here */
+{% for manifest in manifests %}
+ {% if manifest.manifest.type == 'PSA-ROT' %}
+ {% if manifest.attr.conditional %}
+#ifdef {{manifest.attr.conditional}}
+ {% endif %}
+
+ /* Position tag */
+ . = ALIGN(32);
+ Image$$PT_{{manifest.manifest.name}}_PRIVATE_DATA_START$$Base = .;
+
+ .ER_{{manifest.manifest.name}}_RWZI : ALIGN(32)
+ {
+ {% if manifest.attr.linker_pattern.library_list %}
+ {% for pattern in manifest.attr.linker_pattern.library_list %}
+ {{pattern}}:*(.data*)
+ {% endfor %}
+ {% endif %}
+ {% if manifest.attr.linker_pattern.object_list %}
+ {% for pattern in manifest.attr.linker_pattern.object_list %}
+ {{pattern}}(.data*)
+ {% endfor %}
+ {% endif %}
+ *({{manifest.manifest.name}}_ATTR_RW)
+ . = ALIGN(32);
+ } > RAM AT> FLASH
+ Image$$ER_{{manifest.manifest.name}}_RWZI$$RW$$Base = ADDR(.ER_{{manifest.manifest.name}}_RWZI);
+ Image$$ER_{{manifest.manifest.name}}_RWZI$$RW$$Limit = ADDR(.ER_{{manifest.manifest.name}}_RWZI) + SIZEOF(.ER_{{manifest.manifest.name}}_RWZI);
+
+ .{{manifest.manifest.name}}_RWZI_BSS : ALIGN(32)
+ {
+ start_of_{{manifest.manifest.name}}_RWZI = .;
+ {% if manifest.attr.linker_pattern.library_list %}
+ {% for pattern in manifest.attr.linker_pattern.library_list %}
+ {{pattern}}:*(.bss*)
+ {{pattern}}:*(COMMON)
+ {% endfor %}
+ {% endif %}
+ {% if manifest.attr.linker_pattern.object_list %}
+ {% for pattern in manifest.attr.linker_pattern.object_list %}
+ {{pattern}}(.bss*)
+ {{pattern}}(COMMON)
+ {% endfor %}
+ {% endif %}
+ *({{manifest.manifest.name}}_ATTR_ZI)
+ . += (. - start_of_{{manifest.manifest.name}}_RWZI) ? 0 : 4;
+ . = ALIGN(32);
+ } > RAM AT> RAM
+ Image$$ER_{{manifest.manifest.name}}_RWZI$$ZI$$Base = ADDR(.{{manifest.manifest.name}}_RWZI_BSS);
+ Image$$ER_{{manifest.manifest.name}}_RWZI$$ZI$$Limit = ADDR(.{{manifest.manifest.name}}_RWZI_BSS) + SIZEOF(.{{manifest.manifest.name}}_RWZI_BSS);
+
+ {% if manifest.attr.tfm_partition_ipc %}
+
+ .{{manifest.manifest.name}}_LINKER_STACK : ALIGN(128)
+ {
+ . += {{manifest.manifest.stack_size}};
+ } > RAM
+ Image$${{manifest.manifest.name}}_LINKER_STACK$$ZI$$Base = ADDR(.{{manifest.manifest.name}}_LINKER_STACK);
+ Image$${{manifest.manifest.name}}_LINKER_STACK$$ZI$$Limit = ADDR(.{{manifest.manifest.name}}_LINKER_STACK) + SIZEOF(.{{manifest.manifest.name}}_LINKER_STACK);
+
+ {% endif %}
+
+ /* Position tag */
+ . = ALIGN(32);
+ Image$$PT_{{manifest.manifest.name}}_PRIVATE_DATA_END$$Base = .;
+
+ {% if manifest.attr.conditional %}
+#endif /* {{manifest.attr.conditional}} */
+ {% endif %}
+
+ {% endif %}
+{% endfor %}
+ /**** PSA RoT DATA end here */
+ . = ALIGN(32);
+
+ /* Position tag */
+ Image$$PT_PRIV_RWZI_END$$Base = .;
+
+ /* PSP is unprivileged in single-core topology */
+ .psp_stack : ALIGN(32)
+ {
+ . += (__psp_stack_size__);
+ } > RAM
+ Image$$ARM_LIB_STACK$$ZI$$Base = ADDR(.psp_stack);
+ Image$$ARM_LIB_STACK$$ZI$$Limit = ADDR(.psp_stack) + SIZEOF(.psp_stack);
+
+ /**** APPLICATION RoT DATA start here */
+{% for manifest in manifests %}
+ {% if manifest.manifest.type == 'APPLICATION-ROT' %}
+ {% if manifest.attr.conditional %}
+#ifdef {{manifest.attr.conditional}}
+ {% endif %}
+
+ /* Position tag */
+ . = ALIGN(32);
+ Image$$PT_{{manifest.manifest.name}}_PRIVATE_DATA_START$$Base = .;
+
+ .ER_{{manifest.manifest.name}}_RWZI : ALIGN(32)
+ {
+ {% if manifest.attr.linker_pattern.library_list %}
+ {% for pattern in manifest.attr.linker_pattern.library_list %}
+ {{pattern}}:*(.data*)
+ {% endfor %}
+ {% endif %}
+ {% if manifest.attr.linker_pattern.object_list %}
+ {% for pattern in manifest.attr.linker_pattern.object_list %}
+ {{pattern}}(.data*)
+ {% endfor %}
+ {% endif %}
+ *({{manifest.manifest.name}}_ATTR_RW)
+ . = ALIGN(32);
+ } > RAM AT> FLASH
+ Image$$.ER_{{manifest.manifest.name}}_RWZI$$RW$$Base = ADDR(.ER_{{manifest.manifest.name}}_RWZI);
+ Image$$.ER_{{manifest.manifest.name}}_RWZI$$RW$$Limit = ADDR(.ER_{{manifest.manifest.name}}_RWZI) + SIZEOF(.ER_{{manifest.manifest.name}}_RWZI);
+
+ .{{manifest.manifest.name}}_RWZI_BSS : ALIGN(32)
+ {
+ start_of_{{manifest.manifest.name}}_RWZI = .;
+ {% if manifest.attr.linker_pattern.library_list %}
+ {% for pattern in manifest.attr.linker_pattern.library_list %}
+ {{pattern}}:*(.bss*)
+ {{pattern}}:*(COMMON)
+ {% endfor %}
+ {% endif %}
+ {% if manifest.attr.linker_pattern.object_list %}
+ {% for pattern in manifest.attr.linker_pattern.object_list %}
+ {{pattern}}(.bss*)
+ {{pattern}}(COMMON)
+ {% endfor %}
+ {% endif %}
+ *({{manifest.manifest.name}}_ATTR_ZI)
+ . += (. - start_of_{{manifest.manifest.name}}_RWZI) ? 0 : 4;
+ . = ALIGN(32);
+ } > RAM AT> RAM
+ Image$$ER_{{manifest.manifest.name}}_RWZI$$ZI$$Base = ADDR(.{{manifest.manifest.name}}_RWZI_BSS);
+ Image$$ER_{{manifest.manifest.name}}_RWZI$$ZI$$Limit = ADDR(.{{manifest.manifest.name}}_RWZI_BSS) + SIZEOF(.{{manifest.manifest.name}}_RWZI_BSS);
+
+ {% if manifest.attr.tfm_partition_ipc %}
+
+ .{{manifest.manifest.name}}_LINKER_STACK : ALIGN(128)
+ {
+ . += {{manifest.manifest.stack_size}};
+ } > RAM
+ Image$${{manifest.manifest.name}}_LINKER_STACK$$ZI$$Base = ADDR(.{{manifest.manifest.name}}_LINKER_STACK);
+ Image$${{manifest.manifest.name}}_LINKER_STACK$$ZI$$Limit = ADDR(.{{manifest.manifest.name}}_LINKER_STACK) + SIZEOF(.{{manifest.manifest.name}}_LINKER_STACK);
+
+ {% endif %}
+
+ /* Position tag */
+ . = ALIGN(32);
+ Image$$PT_{{manifest.manifest.name}}_PRIVATE_DATA_END$$Base = .;
+
+ {% if manifest.attr.conditional %}
+#endif /* {{manifest.attr.conditional}} */
+ {% endif %}
+
+ {% endif %}
+{% endfor %}
+ /**** APPLICATION RoT DATA end here */
+
+ /* Position tag */
+ . = ALIGN(32);
+ Image$$PT_APP_RWZI_END$$Base = .;
+
+#ifdef TFM_PARTITION_TEST_SECURE_SERVICES
+ .TFM_SP_SECURE_TEST_PARTITION_LINKER_DATA : ALIGN(32)
+ {
+ *libc_nano*:*(.data*)
+ . = ALIGN(32);
+ } > RAM AT> FLASH
+
+ .TFM_SP_SECURE_TEST_PARTITION_LINKER_BSS : ALIGN(32)
+ {
+ /* FixMe:
+ * Test framework use printf to print out test result. Implementation of
+ * printf in GCC libc use static data and heap as well. To be able to
+ * execute test suites with TFM_LVL=3 this workaround is needed to
+ * allocate libc static data and heap within the data section of secure
+ * test partition. This can be removed if test service will be executed
+ * in privileged mode.
+ */
+ *libc_nano*:*(.bss*)
+ *libc_nano*:*(COMMON)
+
+ __end__ = .;
+ PROVIDE(end = .);
+ __HeapBase = .;
+ . += __heap_size__;
+ __HeapLimit = .;
+ __heap_limit = .; /* Add for _sbrk */
+
+ . = ALIGN(32);
+ } > RAM AT> RAM
+#else /* TFM_PARTITION_TEST_SECURE_SERVICES */
+ .heap : ALIGN(8)
+ {
+ __end__ = .;
+ PROVIDE(end = .);
+ __HeapBase = .;
+ . += __heap_size__;
+ __HeapLimit = .;
+ __heap_limit = .; /* Add for _sbrk */
+ } > RAM AT> RAM
+#endif /* TFM_PARTITION_TEST_SECURE_SERVICES */
+
+ .TFM_DATA : ALIGN(4)
+ {
+ *(.data*)
+
+ . = ALIGN(4);
+ /* preinit data */
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP(*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+
+ . = ALIGN(4);
+ /* init data */
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP(*(SORT(.init_array.*)))
+ KEEP(*(.init_array))
+ PROVIDE_HIDDEN (__init_array_end = .);
+
+ . = ALIGN(4);
+ /* finit data */
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP(*(SORT(.fini_array.*)))
+ KEEP(*(.fini_array))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ KEEP(*(.jcr*))
+ . = ALIGN(4);
+
+ } > RAM AT> FLASH
+ Image$$ER_TFM_DATA$$RW$$Base = ADDR(.TFM_DATA);
+ Image$$ER_TFM_DATA$$RW$$Limit = ADDR(.TFM_DATA) + SIZEOF(.TFM_DATA);
+
+ .TFM_BSS : ALIGN(4)
+ {
+ __bss_start__ = .;
+ *(.bss*)
+ *(COMMON)
+ . = ALIGN(4);
+ __bss_end__ = .;
+ } > RAM AT> RAM
+ Image$$ER_TFM_DATA$$ZI$$Base = ADDR(.TFM_BSS);
+ Image$$ER_TFM_DATA$$ZI$$Limit = ADDR(.TFM_BSS) + SIZEOF(.TFM_BSS);
+
+ Image$$ER_TFM_DATA$$Base = ADDR(.TFM_DATA);
+ Image$$ER_TFM_DATA$$Limit = ADDR(.TFM_DATA) + SIZEOF(.TFM_DATA) + SIZEOF(.TFM_BSS);
+
+ /*
+ * Place the CMSE Veneers (containing the SG instruction) after the code, in a
+ * separate 32 bytes aligned region so that the SAU can programmed to just set
+ * this region as Non-Secure Callable.
+ */
+ .gnu.sgstubs : ALIGN(32)
+ {
+ *(.gnu.sgstubs*)
+ . = ALIGN(32);
+ } > VENEERS AT> VENEERS
+ 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;
+
+#ifdef BL2
+ Load$$LR$$LR_SECONDARY_PARTITION$$Base = SECONDARY_PARTITION_START;
+#endif /* BL2 */
+
+ PROVIDE(__stack = Image$$ARM_LIB_STACK$$ZI$$Limit);
+}
diff --git a/platform/ext/target/mps2/an521/CMakeLists.txt b/platform/ext/target/mps2/an521/CMakeLists.txt
index aabdbaf..d1bd199 100644
--- a/platform/ext/target/mps2/an521/CMakeLists.txt
+++ b/platform/ext/target/mps2/an521/CMakeLists.txt
@@ -24,10 +24,15 @@
$<$<C_COMPILER_ID:GNU>:${CMAKE_CURRENT_SOURCE_DIR}/gcc/startup_cmsdk_mps2_an521_s.S>
$<$<C_COMPILER_ID:IAR>:${CMAKE_CURRENT_SOURCE_DIR}/iar/startup_cmsdk_mps2_an521_s.s>
)
+
+# Use a common scatter file for Isolation L1 and L2, a dedicated one for Isolation L3
+# IAR is not supported for L3
target_add_scatter_file(tfm_s
- $<$<C_COMPILER_ID:ARMClang>:${CMAKE_BINARY_DIR}/generated/platform/ext/common/armclang/tfm_common_s.sct>
- $<$<C_COMPILER_ID:GNU>:${CMAKE_BINARY_DIR}/generated/platform/ext/common/gcc/tfm_common_s.ld>
- $<$<C_COMPILER_ID:IAR>:${CMAKE_BINARY_DIR}/generated/platform/ext/common/iar/tfm_common_s.icf>
+ $<$<AND:$<VERSION_LESS:${TFM_ISOLATION_LEVEL},3>,$<C_COMPILER_ID:ARMClang>>:${CMAKE_BINARY_DIR}/generated/platform/ext/common/armclang/tfm_common_s.sct>
+ $<$<AND:$<VERSION_LESS:${TFM_ISOLATION_LEVEL},3>,$<C_COMPILER_ID:GNU>>:${CMAKE_BINARY_DIR}/generated/platform/ext/common/gcc/tfm_common_s.ld>
+ $<$<AND:$<VERSION_LESS:${TFM_ISOLATION_LEVEL},3>,$<C_COMPILER_ID:IAR>>:${CMAKE_BINARY_DIR}/generated/platform/ext/common/iar/tfm_common_s.icf>
+ $<$<AND:$<VERSION_EQUAL:${TFM_ISOLATION_LEVEL},3>,$<C_COMPILER_ID:ARMClang>>:${CMAKE_BINARY_DIR}/generated/platform/ext/common/armclang/tfm_isolation_l3.sct>
+ $<$<AND:$<VERSION_EQUAL:${TFM_ISOLATION_LEVEL},3>,$<C_COMPILER_ID:GNU>>:${CMAKE_BINARY_DIR}/generated/platform/ext/common/gcc/tfm_isolation_l3.ld>
)
if(NS)
diff --git a/platform/ext/target/mps2/an521/config.cmake b/platform/ext/target/mps2/an521/config.cmake
index a81c8a1..367749a 100644
--- a/platform/ext/target/mps2/an521/config.cmake
+++ b/platform/ext/target/mps2/an521/config.cmake
@@ -4,3 +4,5 @@
# SPDX-License-Identifier: BSD-3-Clause
#
#-------------------------------------------------------------------------------
+
+set(TFM_EXTRA_GENERATED_FILE_LIST_PATH ${CMAKE_CURRENT_SOURCE_DIR}/platform/ext/target/mps2/an521/generated_file_list.yaml CACHE PATH "Path to extra generated file list. Appended to stardard TFM generated file list." FORCE)
diff --git a/platform/ext/target/mps2/an521/generated_file_list.yaml b/platform/ext/target/mps2/an521/generated_file_list.yaml
new file mode 100644
index 0000000..fc36ea2
--- /dev/null
+++ b/platform/ext/target/mps2/an521/generated_file_list.yaml
@@ -0,0 +1,31 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# The path of "template" can be relative path to TF-M root or absolute path
+# The path of "output" must be relative path to the root for generated files
+# Both can contain environment variables
+
+{
+ "name": "AN521 generated file list",
+ "type": "generated_file_list",
+ "version_major": 0,
+ "version_minor": 1,
+ "file_list": [
+ {
+ "name": "isolation l3 scatter file",
+ "short_name": "isolation_l3_sct",
+ "template": "platform/ext/common/armclang/tfm_isolation_l3.sct.template",
+ "output": "platform/ext/common/armclang/tfm_isolation_l3.sct"
+ },
+ {
+ "name": "isolation l3 linker script",
+ "short_name": "isolation_l3_ld",
+ "template": "platform/ext/common/gcc/tfm_isolation_l3.ld.template",
+ "output": "platform/ext/common/gcc/tfm_isolation_l3.ld"
+ }
+ ]
+}
diff --git a/platform/ext/target/mps2/an521/tfm_hal_isolation.c b/platform/ext/target/mps2/an521/tfm_hal_isolation.c
index d51ee58..ec8cf10 100644
--- a/platform/ext/target/mps2/an521/tfm_hal_isolation.c
+++ b/platform/ext/target/mps2/an521/tfm_hal_isolation.c
@@ -13,7 +13,49 @@
#include "tfm_hal_isolation.h"
#ifdef CONFIG_TFM_ENABLE_MEMORY_PROTECT
-#if TFM_LVL != 3
+#if TFM_LVL == 3
+REGION_DECLARE(Load$$LR$$, LR_VENEER, $$Base);
+REGION_DECLARE(Load$$LR$$, LR_VENEER, $$Limit);
+REGION_DECLARE(Image$$, PT_RO_START, $$Base);
+REGION_DECLARE(Image$$, PT_RO_END, $$Base);
+REGION_DECLARE(Image$$, PT_PRIV_RWZI_START, $$Base);
+REGION_DECLARE(Image$$, PT_PRIV_RWZI_END, $$Base);
+
+static uint32_t g_static_region_cnt;
+
+static struct mpu_armv8m_region_cfg_t isolation_regions[] = {
+ {
+ 0, /* will be updated before using */
+ (uint32_t)®ION_NAME(Load$$LR$$, LR_VENEER, $$Base),
+ (uint32_t)®ION_NAME(Load$$LR$$, LR_VENEER, $$Limit),
+ MPU_ARMV8M_MAIR_ATTR_CODE_IDX,
+ MPU_ARMV8M_XN_EXEC_OK,
+ MPU_ARMV8M_AP_RO_PRIV_UNPRIV,
+ MPU_ARMV8M_SH_NONE,
+ },
+ {
+ 0, /* will be updated before using */
+ (uint32_t)®ION_NAME(Image$$, PT_RO_START, $$Base),
+ (uint32_t)®ION_NAME(Image$$, PT_RO_END, $$Base),
+ MPU_ARMV8M_MAIR_ATTR_CODE_IDX,
+ MPU_ARMV8M_XN_EXEC_OK,
+ MPU_ARMV8M_AP_RO_PRIV_UNPRIV,
+ MPU_ARMV8M_SH_NONE,
+ },
+ /* For isolation Level 3, set up static isolation for privileged data.
+ * Unprivileged data is dynamically set during Partition sheduling.
+ */
+ {
+ 0, /* will be updated before using */
+ (uint32_t)®ION_NAME(Image$$, PT_PRIV_RWZI_START, $$Base),
+ (uint32_t)®ION_NAME(Image$$, PT_PRIV_RWZI_END, $$Base),
+ MPU_ARMV8M_MAIR_ATTR_DATA_IDX,
+ MPU_ARMV8M_XN_EXEC_NEVER,
+ MPU_ARMV8M_AP_RW_PRIV_ONLY,
+ MPU_ARMV8M_SH_NONE,
+ },
+};
+#else /* TFM_LVL == 3 */
#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
#define MPU_REGION_VENEERS 0
@@ -98,7 +140,7 @@
MPU_ARMV8M_SH_NONE
}
};
-#endif /* TFM_LVL != 3 */
+#endif /* TFM_LVL == 3 */
#endif /* CONFIG_TFM_ENABLE_MEMORY_PROTECT */
enum tfm_hal_status_t tfm_hal_set_up_static_boundaries(void)
@@ -112,12 +154,27 @@
/* Set up static isolation boundaries inside SPE */
#ifdef CONFIG_TFM_ENABLE_MEMORY_PROTECT
-#if TFM_LVL != 3
int32_t i;
struct mpu_armv8m_dev_t dev_mpu_s = { MPU_BASE };
mpu_armv8m_clean(&dev_mpu_s);
+#if TFM_LVL == 3
+ uint32_t cnt;
+
+ /* Update MPU region numbers. The numbers start from 0 and are continuous */
+ cnt = sizeof(isolation_regions) / sizeof(isolation_regions[0]);
+ g_static_region_cnt = cnt;
+ for (i = 0; i < cnt; i++) {
+ /* Update region number */
+ isolation_regions[i].region_nr = i;
+ /* Enable regions */
+ if (mpu_armv8m_region_enable(&dev_mpu_s, &isolation_regions[i])
+ != MPU_ARMV8M_OK) {
+ return TFM_HAL_ERROR_GENERIC;
+ }
+ }
+#else /* TFM_LVL == 3 */
for (i = 0; i < ARRAY_SIZE(region_cfg); i++) {
if (mpu_armv8m_region_enable(&dev_mpu_s,
(struct mpu_armv8m_region_cfg_t *)®ion_cfg[i])
@@ -125,11 +182,39 @@
return TFM_HAL_ERROR_GENERIC;
}
}
+#endif /* TFM_LVL == 3 */
- mpu_armv8m_enable(&dev_mpu_s, PRIVILEGED_DEFAULT_ENABLE,
- HARDFAULT_NMI_ENABLE);
-#endif /* TFM_LVL != 3 */
+ /* Enable MPU */
+ if (mpu_armv8m_enable(&dev_mpu_s,
+ PRIVILEGED_DEFAULT_ENABLE,
+ HARDFAULT_NMI_ENABLE) != MPU_ARMV8M_OK) {
+ return TFM_HAL_ERROR_GENERIC;
+ }
#endif /* CONFIG_TFM_ENABLE_MEMORY_PROTECT */
return TFM_HAL_SUCCESS;
}
+
+#if TFM_LVL == 3
+enum tfm_hal_status_t tfm_hal_mpu_update_partition_boundary(uintptr_t start,
+ uintptr_t end)
+{
+ struct mpu_armv8m_region_cfg_t cfg;
+ enum mpu_armv8m_error_t mpu_err;
+ struct mpu_armv8m_dev_t dev_mpu_s = { MPU_BASE };
+
+ /* Partition boundary regions is right after static regions */
+ cfg.region_nr = g_static_region_cnt;
+ cfg.region_base = start;
+ cfg.region_limit = end;
+ cfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_DATA_IDX;
+ cfg.attr_access = MPU_ARMV8M_AP_RW_PRIV_UNPRIV;
+ cfg.attr_exec = MPU_ARMV8M_XN_EXEC_NEVER;
+ cfg.attr_sh = MPU_ARMV8M_SH_NONE;
+ mpu_err = mpu_armv8m_region_enable(&dev_mpu_s, &cfg);
+ if (mpu_err != MPU_ARMV8M_OK) {
+ return TFM_HAL_ERROR_GENERIC;
+ }
+ return TFM_HAL_SUCCESS;
+}
+#endif /* TFM_LVL == 3 */
diff --git a/platform/ext/target/musca_b1/CMakeLists.txt b/platform/ext/target/musca_b1/CMakeLists.txt
index a1f9c5a..d2bb26f 100644
--- a/platform/ext/target/musca_b1/CMakeLists.txt
+++ b/platform/ext/target/musca_b1/CMakeLists.txt
@@ -23,9 +23,15 @@
$<$<C_COMPILER_ID:ARMClang>:${CMAKE_CURRENT_SOURCE_DIR}/Device/Source/armclang/startup_cmsdk_musca_s.s>
$<$<C_COMPILER_ID:GNU>:${CMAKE_CURRENT_SOURCE_DIR}/Device/Source/gcc/startup_cmsdk_musca_s.S>
)
+
+# Use a common scatter file for Isolation L1 and L2, a dedicated one for Isolation L3
+# IAR is not supported for L3
target_add_scatter_file(tfm_s
- $<$<C_COMPILER_ID:ARMClang>:${CMAKE_BINARY_DIR}/generated/platform/ext/common/armclang/tfm_common_s.sct>
- $<$<C_COMPILER_ID:GNU>:${CMAKE_BINARY_DIR}/generated/platform/ext/common/gcc/tfm_common_s.ld>
+ $<$<AND:$<VERSION_LESS:${TFM_ISOLATION_LEVEL},3>,$<C_COMPILER_ID:ARMClang>>:${CMAKE_BINARY_DIR}/generated/platform/ext/common/armclang/tfm_common_s.sct>
+ $<$<AND:$<VERSION_LESS:${TFM_ISOLATION_LEVEL},3>,$<C_COMPILER_ID:GNU>>:${CMAKE_BINARY_DIR}/generated/platform/ext/common/gcc/tfm_common_s.ld>
+ $<$<AND:$<VERSION_LESS:${TFM_ISOLATION_LEVEL},3>,$<C_COMPILER_ID:IAR>>:${CMAKE_BINARY_DIR}/generated/platform/ext/common/iar/tfm_common_s.icf>
+ $<$<AND:$<VERSION_EQUAL:${TFM_ISOLATION_LEVEL},3>,$<C_COMPILER_ID:ARMClang>>:${CMAKE_BINARY_DIR}/generated/platform/ext/common/armclang/tfm_isolation_l3.sct>
+ $<$<AND:$<VERSION_EQUAL:${TFM_ISOLATION_LEVEL},3>,$<C_COMPILER_ID:GNU>>:${CMAKE_BINARY_DIR}/generated/platform/ext/common/gcc/tfm_isolation_l3.ld>
)
if(NS)
diff --git a/platform/ext/target/musca_b1/config.cmake b/platform/ext/target/musca_b1/config.cmake
index a3bb018..b26e7a3 100644
--- a/platform/ext/target/musca_b1/config.cmake
+++ b/platform/ext/target/musca_b1/config.cmake
@@ -12,3 +12,5 @@
if(CRYPTO_HW_ACCELERATOR_OTP_STATE STREQUAL "ENABLED")
set(PLATFORM_DUMMY_CRYPTO_KEYS FALSE CACHE BOOL "Use dummy crypto keys. Should not be used in production.")
endif()
+
+set(TFM_EXTRA_GENERATED_FILE_LIST_PATH ${CMAKE_CURRENT_SOURCE_DIR}/platform/ext/target/musca_b1/generated_file_list.yaml CACHE PATH "Path to extra generated file list. Appended to stardard TFM generated file list." FORCE)
diff --git a/platform/ext/target/musca_b1/generated_file_list.yaml b/platform/ext/target/musca_b1/generated_file_list.yaml
new file mode 100644
index 0000000..ff01824
--- /dev/null
+++ b/platform/ext/target/musca_b1/generated_file_list.yaml
@@ -0,0 +1,31 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# The path of "template" can be relative path to TF-M root or absolute path
+# The path of "output" must be relative path to the root for generated files
+# Both can contain environment variables
+
+{
+ "name": "musca-b1 generated file list",
+ "type": "generated_file_list",
+ "version_major": 0,
+ "version_minor": 1,
+ "file_list": [
+ {
+ "name": "isolation l3 scatter file",
+ "short_name": "isolation_l3_sct",
+ "template": "platform/ext/common/armclang/tfm_isolation_l3.sct.template",
+ "output": "platform/ext/common/armclang/tfm_isolation_l3.sct"
+ },
+ {
+ "name": "isolation l3 linker script",
+ "short_name": "isolation_l3_ld",
+ "template": "platform/ext/common/gcc/tfm_isolation_l3.ld.template",
+ "output": "platform/ext/common/gcc/tfm_isolation_l3.ld"
+ }
+ ]
+}
diff --git a/platform/ext/target/musca_b1/tfm_hal_isolation.c b/platform/ext/target/musca_b1/tfm_hal_isolation.c
index 67ac95a..d4bc4e1 100644
--- a/platform/ext/target/musca_b1/tfm_hal_isolation.c
+++ b/platform/ext/target/musca_b1/tfm_hal_isolation.c
@@ -13,7 +13,49 @@
#include "tfm_hal_isolation.h"
#ifdef CONFIG_TFM_ENABLE_MEMORY_PROTECT
-#if TFM_LVL != 3
+#if TFM_LVL == 3
+REGION_DECLARE(Load$$LR$$, LR_VENEER, $$Base);
+REGION_DECLARE(Load$$LR$$, LR_VENEER, $$Limit);
+REGION_DECLARE(Image$$, PT_RO_START, $$Base);
+REGION_DECLARE(Image$$, PT_RO_END, $$Base);
+REGION_DECLARE(Image$$, PT_PRIV_RWZI_START, $$Base);
+REGION_DECLARE(Image$$, PT_PRIV_RWZI_END, $$Base);
+
+static uint32_t g_static_region_cnt;
+
+static struct mpu_armv8m_region_cfg_t isolation_regions[] = {
+ {
+ 0, /* will be updated before using */
+ (uint32_t)®ION_NAME(Load$$LR$$, LR_VENEER, $$Base),
+ (uint32_t)®ION_NAME(Load$$LR$$, LR_VENEER, $$Limit),
+ MPU_ARMV8M_MAIR_ATTR_CODE_IDX,
+ MPU_ARMV8M_XN_EXEC_OK,
+ MPU_ARMV8M_AP_RO_PRIV_UNPRIV,
+ MPU_ARMV8M_SH_NONE,
+ },
+ {
+ 0, /* will be updated before using */
+ (uint32_t)®ION_NAME(Image$$, PT_RO_START, $$Base),
+ (uint32_t)®ION_NAME(Image$$, PT_RO_END, $$Base),
+ MPU_ARMV8M_MAIR_ATTR_CODE_IDX,
+ MPU_ARMV8M_XN_EXEC_OK,
+ MPU_ARMV8M_AP_RO_PRIV_UNPRIV,
+ MPU_ARMV8M_SH_NONE,
+ },
+ /* For isolation Level 3, set up static isolation for privileged data.
+ * Unprivileged data is dynamically set during Partition sheduling.
+ */
+ {
+ 0, /* will be updated before using */
+ (uint32_t)®ION_NAME(Image$$, PT_PRIV_RWZI_START, $$Base),
+ (uint32_t)®ION_NAME(Image$$, PT_PRIV_RWZI_END, $$Base),
+ MPU_ARMV8M_MAIR_ATTR_DATA_IDX,
+ MPU_ARMV8M_XN_EXEC_NEVER,
+ MPU_ARMV8M_AP_RW_PRIV_ONLY,
+ MPU_ARMV8M_SH_NONE,
+ },
+};
+#else /* TFM_LVL == 3 */
#define MPU_REGION_VENEERS 0
#define MPU_REGION_TFM_UNPRIV_CODE 1
#define MPU_REGION_TFM_UNPRIV_DATA 2
@@ -33,7 +75,8 @@
REGION_DECLARE(Image$$, ARM_LIB_STACK, $$ZI$$Limit);
extern const struct memory_region_limits memory_regions;
-#endif /* TFM_LVL != 3 */
+
+#endif /* TFM_LVL == 3 */
#endif /* CONFIG_TFM_ENABLE_MEMORY_PROTECT */
enum tfm_hal_status_t tfm_hal_set_up_static_boundaries(void)
@@ -51,11 +94,27 @@
/* Set up static isolation boundaries inside SPE */
#ifdef CONFIG_TFM_ENABLE_MEMORY_PROTECT
-#if TFM_LVL != 3
- struct mpu_armv8m_region_cfg_t region_cfg;
+ int32_t i;
struct mpu_armv8m_dev_t dev_mpu_s = { MPU_BASE };
mpu_armv8m_clean(&dev_mpu_s);
+#if TFM_LVL == 3
+ uint32_t cnt;
+
+ /* Update MPU region numbers. The numbers start from 0 and are continuous */
+ cnt = sizeof(isolation_regions) / sizeof(isolation_regions[0]);
+ g_static_region_cnt = cnt;
+ for (i = 0; i < cnt; i++) {
+ /* Update region number */
+ isolation_regions[i].region_nr = i;
+ /* Enable regions */
+ if (mpu_armv8m_region_enable(&dev_mpu_s, &isolation_regions[i])
+ != MPU_ARMV8M_OK) {
+ return TFM_HAL_ERROR_GENERIC;
+ }
+ }
+#else /* TFM_LVL == 3 */
+ struct mpu_armv8m_region_cfg_t region_cfg;
/* Veneer region */
region_cfg.region_nr = MPU_REGION_VENEERS;
@@ -138,11 +197,39 @@
if (mpu_armv8m_region_enable(&dev_mpu_s, ®ion_cfg) != MPU_ARMV8M_OK) {
return TFM_HAL_ERROR_GENERIC;
}
+#endif /* TFM_LVL == 3 */
- mpu_armv8m_enable(&dev_mpu_s, PRIVILEGED_DEFAULT_ENABLE,
- HARDFAULT_NMI_ENABLE);
-#endif /* TFM_LVL != 3 */
-#endif /* CONFIG_TFM_ENABLE_MEMORY_PROTECT */
+ /* Enable MPU */
+ if (mpu_armv8m_enable(&dev_mpu_s,
+ PRIVILEGED_DEFAULT_ENABLE,
+ HARDFAULT_NMI_ENABLE) != MPU_ARMV8M_OK) {
+ return TFM_HAL_ERROR_GENERIC;
+ }
+#endif
return TFM_HAL_SUCCESS;
}
+
+#if TFM_LVL == 3
+enum tfm_hal_status_t tfm_hal_mpu_update_partition_boundary(uintptr_t start,
+ uintptr_t end)
+{
+ struct mpu_armv8m_region_cfg_t cfg;
+ enum mpu_armv8m_error_t mpu_err;
+ struct mpu_armv8m_dev_t dev_mpu_s = { MPU_BASE };
+
+ /* Partition boundary regions is right after static regions */
+ cfg.region_nr = g_static_region_cnt;
+ cfg.region_base = start;
+ cfg.region_limit = end;
+ cfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_DATA_IDX;
+ cfg.attr_access = MPU_ARMV8M_AP_RW_PRIV_UNPRIV;
+ cfg.attr_exec = MPU_ARMV8M_XN_EXEC_NEVER;
+ cfg.attr_sh = MPU_ARMV8M_SH_NONE;
+ mpu_err = mpu_armv8m_region_enable(&dev_mpu_s, &cfg);
+ if (mpu_err != MPU_ARMV8M_OK) {
+ return TFM_HAL_ERROR_GENERIC;
+ }
+ return TFM_HAL_SUCCESS;
+}
+#endif /* TFM_LVL == 3 */
diff --git a/platform/include/tfm_spm_hal.h b/platform/include/tfm_spm_hal.h
index fc2246a..0b49340 100644
--- a/platform/include/tfm_spm_hal.h
+++ b/platform/include/tfm_spm_hal.h
@@ -43,8 +43,17 @@
*/
struct tfm_spm_partition_memory_data_t
{
- uint32_t stack_bottom; /*!< The bottom of the stack for the partition. */
- uint32_t stack_top; /*!< The top of the stack for the partition. */
+#if TFM_LVL == 3
+ uint32_t data_start; /* Start of the private data region of current
+ * partition. Specifically, the private data
+ * includes RW, ZI and the partition stack below.
+ */
+ uint32_t data_limit; /* Address of the byte beyond the end of the data
+ * region of this partition.
+ */
+#endif
+ 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