1From eb096e4c03b80f9f31e5d15ca06e5a38e4112664 Mon Sep 17 00:00:00 2001 2From: Bence Balogh <bence.balogh@arm.com> 3Date: Tue, 7 Nov 2023 20:25:49 +0100 4Subject: [PATCH 1/2] platform: corstone1000: Update MPU configuration 5 6In Armv6-M the MPU requires the regions to be aligned with 7region sizes. 8The commit aligns the different code/data sections using the 9alignment macros. The code/data sections can be covered by 10multiple MPU regions in order to save memory. 11 12Small adjustments had to be made in the memory layout in order to 13not overflow the flash: 14- Decreased TFM_PARTITION_SIZE 15- Increased S_UNPRIV_DATA_SIZE 16 17Added checks to the MPU configuration function for checking the 18MPU constraints: 19- Base address has to be aligned to the size 20- The minimum MPU region size is 0x100 21- The MPU can have 8 regions at most 22 23Change-Id: I059468e8aba0822bb354fd1cd4987ac2bb1f34d1 24Signed-off-by: Bence Balogh <bence.balogh@arm.com> 25Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/25393] 26 27--- 28 .../target/arm/corstone1000/CMakeLists.txt | 19 +++++ 29 .../arm/corstone1000/create-flash-image.sh | 8 +- 30 .../arm/corstone1000/partition/flash_layout.h | 2 +- 31 .../arm/corstone1000/partition/region_defs.h | 6 +- 32 .../arm/corstone1000/tfm_hal_isolation.c | 83 +++++++++++++++---- 33 5 files changed, 93 insertions(+), 25 deletions(-) 34 35diff --git a/platform/ext/target/arm/corstone1000/CMakeLists.txt b/platform/ext/target/arm/corstone1000/CMakeLists.txt 36index e6cf15b11..8817f514c 100644 37--- a/platform/ext/target/arm/corstone1000/CMakeLists.txt 38+++ b/platform/ext/target/arm/corstone1000/CMakeLists.txt 39@@ -22,6 +22,25 @@ target_compile_definitions(platform_region_defs 40 INTERFACE 41 $<$<BOOL:${TFM_S_REG_TEST}>:TFM_S_REG_TEST> 42 ) 43+ 44+# The Armv6-M MPU requires that the MPU regions be aligned to the region sizes. 45+# The minimal region size is 0x100 bytes. 46+# 47+# The alignments have to be a power of two and ideally bigger than the section size (which 48+# can be checked in the map file). 49+# In some cases the alignment value is smaller than the actual section 50+# size to save memory. In that case, multiple MPU region has to be configured to cover it. 51+# 52+# To save memory, the attributes are set to XN_EXEC_OK and AP_RO_PRIV_UNPRIV for 53+# the SRAM so the PSA_ROT_LINKER_CODE, TFM_UNPRIV_CODE and APP_ROT_LINKER_CODE don't have to 54+# be aligned. The higher-priority regions will overwrite these attributes if needed. 55+# The RAM is also located in the SRAM so it has to be configured to overwrite these default 56+# attributes. 57+target_compile_definitions(platform_region_defs 58+ INTERFACE 59+ TFM_LINKER_APP_ROT_LINKER_DATA_ALIGNMENT=0x2000 60+ TFM_LINKER_SP_META_PTR_ALIGNMENT=0x100 61+) 62 #========================= Platform common defs ===============================# 63 64 # Specify the location of platform specific build dependencies. 65diff --git a/platform/ext/target/arm/corstone1000/create-flash-image.sh b/platform/ext/target/arm/corstone1000/create-flash-image.sh 66index 2522d3674..a6be61384 100755 67--- a/platform/ext/target/arm/corstone1000/create-flash-image.sh 68+++ b/platform/ext/target/arm/corstone1000/create-flash-image.sh 69@@ -8,7 +8,7 @@ 70 71 ###################################################################### 72 # This script is to create a flash gpt image for corstone platform 73-# 74+# 75 # Flash image layout: 76 # |------------------------------| 77 # | Protective MBR | 78@@ -82,15 +82,15 @@ sgdisk --mbrtogpt \ 79 --new=4:56:+4K --typecode=4:$PRIVATE_METADATA_TYPE_UUID --partition-guid=4:$(uuidgen) --change-name=4:'private_metadata_replica_1' \ 80 --new=5:64:+4k --typecode=5:$PRIVATE_METADATA_TYPE_UUID --partition-guid=5:$(uuidgen) --change-name=5:'private_metadata_replica_2' \ 81 --new=6:72:+100k --typecode=6:$SE_BL2_TYPE_UUID --partition-guid=6:$(uuidgen) --change-name=6:'bl2_primary' \ 82- --new=7:272:+376K --typecode=7:$TFM_TYPE_UUID --partition-guid=7:$(uuidgen) --change-name=7:'tfm_primary' \ 83+ --new=7:272:+368K --typecode=7:$TFM_TYPE_UUID --partition-guid=7:$(uuidgen) --change-name=7:'tfm_primary' \ 84 --new=8:32784:+100k --typecode=8:$SE_BL2_TYPE_UUID --partition-guid=8:$(uuidgen) --change-name=8:'bl2_secondary' \ 85- --new=9:32984:+376K --typecode=9:$TFM_TYPE_UUID --partition-guid=9:$(uuidgen) --change-name=9:'tfm_secondary' \ 86+ --new=9:32984:+368K --typecode=9:$TFM_TYPE_UUID --partition-guid=9:$(uuidgen) --change-name=9:'tfm_secondary' \ 87 --new=10:65496:65501 --partition-guid=10:$(uuidgen) --change-name=10:'reserved_2' \ 88 $IMAGE 89 90 [ $? -ne 0 ] && echo "Error occurs while writing the GPT layout" && exit 1 91 92-# Write partitions 93+# Write partitions 94 # conv=notrunc avoids truncation to keep the geometry of the image. 95 dd if=$BIN_DIR/bl2_signed.bin of=${IMAGE} seek=72 conv=notrunc 96 dd if=$BIN_DIR/tfm_s_signed.bin of=${IMAGE} seek=272 conv=notrunc 97diff --git a/platform/ext/target/arm/corstone1000/partition/flash_layout.h b/platform/ext/target/arm/corstone1000/partition/flash_layout.h 98index 568c8de28..7fffd94c6 100644 99--- a/platform/ext/target/arm/corstone1000/partition/flash_layout.h 100+++ b/platform/ext/target/arm/corstone1000/partition/flash_layout.h 101@@ -134,7 +134,7 @@ 102 103 /* Bank configurations */ 104 #define BANK_PARTITION_SIZE (0xFE0000) /* 15.875 MB */ 105-#define TFM_PARTITION_SIZE (0x5E000) /* 376 KB */ 106+#define TFM_PARTITION_SIZE (0x5C000) /* 368 KB */ 107 108 /************************************************************/ 109 /* Bank : Images flash offsets are with respect to the bank */ 110diff --git a/platform/ext/target/arm/corstone1000/partition/region_defs.h b/platform/ext/target/arm/corstone1000/partition/region_defs.h 111index 99e822f51..64ab786e5 100644 112--- a/platform/ext/target/arm/corstone1000/partition/region_defs.h 113+++ b/platform/ext/target/arm/corstone1000/partition/region_defs.h 114@@ -1,8 +1,10 @@ 115 /* 116- * Copyright (c) 2017-2022 Arm Limited. All rights reserved. 117+ * Copyright (c) 2017-2023 Arm Limited. All rights reserved. 118 * Copyright (c) 2021-2023 Cypress Semiconductor Corporation (an Infineon company) 119 * or an affiliate of Cypress Semiconductor Corporation. All rights reserved. 120 * 121+ * SPDX-License-Identifier: Apache-2.0 122+ * 123 * Licensed under the Apache License, Version 2.0 (the "License"); 124 * you may not use this file except in compliance with the License. 125 * You may obtain a copy of the License at 126@@ -53,7 +55,7 @@ 127 128 #define S_DATA_START (SRAM_BASE + TFM_PARTITION_SIZE) 129 #define S_DATA_SIZE (SRAM_SIZE - TFM_PARTITION_SIZE) 130-#define S_UNPRIV_DATA_SIZE (0x2160) 131+#define S_UNPRIV_DATA_SIZE (0x4000) 132 #define S_DATA_LIMIT (S_DATA_START + S_DATA_SIZE - 1) 133 #define S_DATA_PRIV_START (S_DATA_START + S_UNPRIV_DATA_SIZE) 134 135diff --git a/platform/ext/target/arm/corstone1000/tfm_hal_isolation.c b/platform/ext/target/arm/corstone1000/tfm_hal_isolation.c 136index 01f7687bc..98e795dde 100644 137--- a/platform/ext/target/arm/corstone1000/tfm_hal_isolation.c 138+++ b/platform/ext/target/arm/corstone1000/tfm_hal_isolation.c 139@@ -1,5 +1,5 @@ 140 /* 141- * Copyright (c) 2020-2022, Arm Limited. All rights reserved. 142+ * Copyright (c) 2020-2023, Arm Limited. All rights reserved. 143 * Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon 144 * company) or an affiliate of Cypress Semiconductor Corporation. All rights 145 * reserved. 146@@ -14,9 +14,11 @@ 147 #include "tfm_hal_isolation.h" 148 #include "mpu_config.h" 149 #include "mmio_defs.h" 150+#include "flash_layout.h" 151 152 #define PROT_BOUNDARY_VAL \ 153 ((1U << HANDLE_ATTR_PRIV_POS) & HANDLE_ATTR_PRIV_MASK) 154+#define MPU_REGION_MIN_SIZE (0x100) 155 156 #ifdef CONFIG_TFM_ENABLE_MEMORY_PROTECT 157 158@@ -31,20 +33,38 @@ REGION_DECLARE(Image$$, TFM_SP_META_PTR, $$ZI$$Base); 159 REGION_DECLARE(Image$$, TFM_SP_META_PTR, $$ZI$$Limit); 160 #endif /* CONFIG_TFM_PARTITION_META */ 161 162-static void configure_mpu(uint32_t rnr, uint32_t base, uint32_t limit, 163- uint32_t is_xn_exec, uint32_t ap_permissions) 164+static enum tfm_hal_status_t configure_mpu(uint32_t rnr, uint32_t base, 165+ uint32_t limit, uint32_t is_xn_exec, uint32_t ap_permissions) 166 { 167- uint32_t size; /* region size */ 168+ uint32_t rbar_size_field; /* region size as it is used in the RBAR */ 169 uint32_t rasr; /* region attribute and size register */ 170 uint32_t rbar; /* region base address register */ 171 172- size = get_rbar_size_field(limit - base); 173+ rbar_size_field = get_rbar_size_field(limit - base); 174+ 175+ /* The MPU region's base address has to be aligned to the region 176+ * size for a valid MPU configuration */ 177+ if ((base % (1 << (rbar_size_field + 1))) != 0) { 178+ return TFM_HAL_ERROR_INVALID_INPUT; 179+ } 180+ 181+ /* The MPU supports only 8 memory regions */ 182+ if (rnr > 7) { 183+ return TFM_HAL_ERROR_INVALID_INPUT; 184+ } 185+ 186+ /* The minimum size for a region is 0x100 bytes */ 187+ if((limit - base) < MPU_REGION_MIN_SIZE) { 188+ return TFM_HAL_ERROR_INVALID_INPUT; 189+ } 190 191 rasr = ARM_MPU_RASR(is_xn_exec, ap_permissions, TEX, NOT_SHAREABLE, 192- NOT_CACHEABLE, NOT_BUFFERABLE, SUB_REGION_DISABLE, size); 193+ NOT_CACHEABLE, NOT_BUFFERABLE, SUB_REGION_DISABLE, rbar_size_field); 194 rbar = base & MPU_RBAR_ADDR_Msk; 195 196 ARM_MPU_SetRegionEx(rnr, rbar, rasr); 197+ 198+ return TFM_HAL_SUCCESS; 199 } 200 201 #endif /* CONFIG_TFM_ENABLE_MEMORY_PROTECT */ 202@@ -56,33 +76,60 @@ enum tfm_hal_status_t tfm_hal_set_up_static_boundaries( 203 uint32_t rnr = TFM_ISOLATION_REGION_START_NUMBER; /* current region number */ 204 uint32_t base; /* start address */ 205 uint32_t limit; /* end address */ 206+ enum tfm_hal_status_t ret; 207 208 ARM_MPU_Disable(); 209 210- /* TFM Core unprivileged code region */ 211- base = (uint32_t)®ION_NAME(Image$$, TFM_UNPRIV_CODE_START, $$RO$$Base); 212- limit = (uint32_t)®ION_NAME(Image$$, TFM_UNPRIV_CODE_END, $$RO$$Limit); 213- 214- configure_mpu(rnr++, base, limit, XN_EXEC_OK, AP_RO_PRIV_UNPRIV); 215- 216- /* RO region */ 217- base = (uint32_t)®ION_NAME(Image$$, TFM_APP_CODE_START, $$Base); 218- limit = (uint32_t)®ION_NAME(Image$$, TFM_APP_CODE_END, $$Base); 219+ /* Armv6-M MPU allows region overlapping. The region with the higher RNR 220+ * will decide the attributes. 221+ * 222+ * The default attributes are set to XN_EXEC_OK and AP_RO_PRIV_UNPRIV for the 223+ * whole SRAM so the PSA_ROT_LINKER_CODE, TFM_UNPRIV_CODE and APP_ROT_LINKER_CODE 224+ * don't have to be aligned and memory space can be saved. 225+ * This region has the lowest RNR so the next regions can overwrite these 226+ * attributes if it's needed. 227+ */ 228+ base = SRAM_BASE; 229+ limit = SRAM_BASE + SRAM_SIZE; 230+ 231+ ret = configure_mpu(rnr++, base, limit, 232+ XN_EXEC_OK, AP_RW_PRIV_UNPRIV); 233+ if (ret != TFM_HAL_SUCCESS) { 234+ return ret; 235+ } 236 237- configure_mpu(rnr++, base, limit, XN_EXEC_OK, AP_RO_PRIV_UNPRIV); 238 239 /* RW, ZI and stack as one region */ 240 base = (uint32_t)®ION_NAME(Image$$, TFM_APP_RW_STACK_START, $$Base); 241 limit = (uint32_t)®ION_NAME(Image$$, TFM_APP_RW_STACK_END, $$Base); 242 243- configure_mpu(rnr++, base, limit, XN_EXEC_NOT_OK, AP_RW_PRIV_UNPRIV); 244+ /* The section size can be bigger than the alignment size, else the code would 245+ * not fit into the memory. Because of this, the sections can use multiple MPU 246+ * regions. */ 247+ do { 248+ ret = configure_mpu(rnr++, base, base + TFM_LINKER_APP_ROT_LINKER_DATA_ALIGNMENT, 249+ XN_EXEC_NOT_OK, AP_RW_PRIV_UNPRIV); 250+ if (ret != TFM_HAL_SUCCESS) { 251+ return ret; 252+ } 253+ base += TFM_LINKER_APP_ROT_LINKER_DATA_ALIGNMENT; 254+ } while (base < limit); 255+ 256 257 #ifdef CONFIG_TFM_PARTITION_META 258 /* TFM partition metadata pointer region */ 259 base = (uint32_t)®ION_NAME(Image$$, TFM_SP_META_PTR, $$ZI$$Base); 260 limit = (uint32_t)®ION_NAME(Image$$, TFM_SP_META_PTR, $$ZI$$Limit); 261 262- configure_mpu(rnr++, base, limit, XN_EXEC_NOT_OK, AP_RW_PRIV_UNPRIV); 263+ do { 264+ ret = configure_mpu(rnr++, base, base + TFM_LINKER_SP_META_PTR_ALIGNMENT, 265+ XN_EXEC_NOT_OK, AP_RW_PRIV_UNPRIV); 266+ if (ret != TFM_HAL_SUCCESS) { 267+ return ret; 268+ } 269+ base += TFM_LINKER_SP_META_PTR_ALIGNMENT; 270+ } while (base < limit); 271+ 272 #endif 273 274 arm_mpu_enable(); 275