From 342eed5f29c0223af9cd8d8305b25faf93771121 Mon Sep 17 00:00:00 2001 From: Kevin Bracey Date: Wed, 12 Dec 2018 15:03:40 +0200 Subject: [PATCH] Fix target.mpu-rom-end setting, for ARMv8-M too targets.json was not specifying the same macro name as the code was checking for, so setting was ineffective. Making this work tripped up not-supported checks in ARMv8-M - rather than deal with making this work, support it instead. Both ARMv7-M and ARMv8-M slightly reduce code size and runtime impact if mpu-rom-end is 0x1fffffff, using one fewer region. This means default setup for ARMv8-M now requires 5 regions, with mpu-rom-end set to default 0x0fffffff, but this can be put back to 4 by changing the setting. --- hal/mpu/mbed_mpu_v7m.c | 31 +++++++++++++++++++++---------- hal/mpu/mbed_mpu_v8m.c | 40 +++++++++++++++++++++++++++++++++------- targets/targets.json | 3 +-- 3 files changed, 55 insertions(+), 19 deletions(-) diff --git a/hal/mpu/mbed_mpu_v7m.c b/hal/mpu/mbed_mpu_v7m.c index 63bdc32b1c..7b7a7c7259 100644 --- a/hal/mpu/mbed_mpu_v7m.c +++ b/hal/mpu/mbed_mpu_v7m.c @@ -25,7 +25,9 @@ #error "Device has v7m MPU but it is not enabled. Add 'MPU' to device_has in targets.json" #endif -#if !defined(MBED_MPU_ROM_END) +#ifdef MBED_CONF_TARGET_MPU_ROM_END +#define MBED_MPU_ROM_END MBED_CONF_TARGET_MPU_ROM_END +#else #define MBED_MPU_ROM_END (0x10000000 - 1) #endif #define MBED_MPU_RAM_START (MBED_MPU_ROM_END + 1) @@ -48,9 +50,13 @@ void mbed_mpu_init() const uint32_t regions = (MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos; - // Our MPU setup requires 4 regions - if this assert is hit, remove - // DEVICE_MPU from device_has + // Our MPU setup requires 3 or 4 regions - if this assert is hit, remove + // a region by setting MPU_ROM_END to 0x1fffffff, or remove MPU from device_has +#if MBED_MPU_RAM_START == 0x20000000 + MBED_ASSERT(regions >= 3); +#else MBED_ASSERT(regions >= 4); +#endif // Disable the MCU MPU->CTRL = 0; @@ -99,11 +105,12 @@ void mbed_mpu_init() ARM_MPU_REGION_SIZE_512MB) // Size ); - // Select region 1 and use it for a WT ram region in the Code area +#if MBED_MPU_RAM_START < 0x20000000 + // Select region 3 and use it for a WT ram region in the Code area // - Code MBED_MPU_ROM_END + 1 to 0x1FFFFFFF ARM_MPU_SetRegion( ARM_MPU_RBAR( - 1, // Region + 3, // Region 0x00000000), // Base ARM_MPU_RASR( 1, // DisableExec @@ -123,13 +130,17 @@ void mbed_mpu_init() ((MBED_MPU_RAM_START <= 0x20000000) ? 0 : (1 << 7)), ARM_MPU_REGION_SIZE_512MB) // Size ); +#define LAST_RAM_REGION 3 +#else +#define LAST_RAM_REGION 2 +#endif - // Select region 2 and use it for WBWA ram regions + // Select region 1 and use it for WBWA ram regions // - SRAM 0x20000000 to 0x3FFFFFFF // - RAM 0x60000000 to 0x7FFFFFFF ARM_MPU_SetRegion( ARM_MPU_RBAR( - 2, // Region + 1, // Region 0x00000000), // Base ARM_MPU_RASR( 1, // DisableExec @@ -150,11 +161,11 @@ void mbed_mpu_init() ARM_MPU_REGION_SIZE_4GB) // Size ); - // Select region 3 and use it for the WT ram region + // Select region 2 and use it for the WT ram region // - RAM 0x80000000 to 0x9FFFFFFF ARM_MPU_SetRegion( ARM_MPU_RBAR( - 3, // Region + 2, // Region 0x80000000), // Base ARM_MPU_RASR( 1, // DisableExec @@ -214,7 +225,7 @@ void mbed_mpu_enable_ram_xn(bool enable) // Flush memory writes before configuring the MPU. __DMB(); - for (uint32_t region = 1; region <= 3; region++) { + for (uint32_t region = 1; region <= LAST_RAM_REGION; region++) { enable_region(enable, region); } diff --git a/hal/mpu/mbed_mpu_v8m.c b/hal/mpu/mbed_mpu_v8m.c index e9a4cdfa81..4b992f543d 100644 --- a/hal/mpu/mbed_mpu_v8m.c +++ b/hal/mpu/mbed_mpu_v8m.c @@ -25,11 +25,15 @@ #error "Device has v8m MPU but it is not enabled. Add 'MPU' to device_has in targets.json" #endif -#if !defined(MBED_MPU_ROM_END) -#define MBED_MPU_ROM_END (0x20000000 - 1) +#ifdef MBED_CONF_TARGET_MPU_ROM_END +#define MBED_MPU_ROM_END MBED_CONF_TARGET_MPU_ROM_END +#else +#define MBED_MPU_ROM_END (0x10000000 - 1) #endif +#define MBED_MPU_RAM_START (MBED_MPU_ROM_END + 1) -MBED_STATIC_ASSERT(MBED_MPU_ROM_END == 0x1fffffff, "Changing MBED_MPU_ROM_END for ARMv8-M is not supported."); +MBED_STATIC_ASSERT(MBED_MPU_ROM_END <= 0x20000000 - 1, + "Unsupported value for MBED_MPU_ROM_END"); void mbed_mpu_init() { @@ -38,9 +42,13 @@ void mbed_mpu_init() const uint32_t regions = (MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos; - // Our MPU setup requires 4 regions - if this assert is hit, remove - // DEVICE_MPU from device_has + // Our MPU setup requires 4 or 5 regions - if this assert is hit, remove + // a region by setting MPU_ROM_END to 0x1fffffff, or remove MPU from device_has +#if MBED_MPU_RAM_START == 0x20000000 MBED_ASSERT(regions >= 4); +#else + MBED_ASSERT(regions >= 5); +#endif // Disable the MCU MPU->CTRL = 0; @@ -54,7 +62,7 @@ void mbed_mpu_init() * ARMv8-M memory map: * * Start End Name Executable by default Default cache Mbed MPU protection - * 0x00000000 - 0x1FFFFFFF Code Yes WT, WA Write disabled + * 0x00000000 - 0x1FFFFFFF Code Yes WT, WA Write disabled for first portion and execute disabled for the rest * 0x20000000 - 0x3FFFFFFF SRAM Yes WB, WA, RA Execute disabled * 0x40000000 - 0x5FFFFFFF Peripheral No * 0x60000000 - 0x7FFFFFFF RAM Yes WB, WA, RA Execute disabled @@ -82,10 +90,28 @@ void mbed_mpu_init() 1, // Read-Only 1, // Non-Privileged 0), // Execute Never disabled + ARM_MPU_RLAR( + MBED_MPU_ROM_END, // Limit + AttrIndex_WTRA) // Attribute index - Write-Through, Read-allocate + ); + +#if MBED_MPU_RAM_START != 0x20000000 + ARM_MPU_SetRegion( + 4, // Region + ARM_MPU_RBAR( + MBED_MPU_RAM_START, // Base + ARM_MPU_SH_NON, // Non-shareable + 0, // Read-Write + 1, // Non-Privileged + 1), // Execute Never enabled ARM_MPU_RLAR( 0x1FFFFFFF, // Limit AttrIndex_WTRA) // Attribute index - Write-Through, Read-allocate ); +#define LAST_RAM_REGION 4 +#else +#define LAST_RAM_REGION 3 +#endif ARM_MPU_SetRegion( 1, // Region @@ -173,7 +199,7 @@ void mbed_mpu_enable_ram_xn(bool enable) // Flush memory writes before configuring the MPU. __DMB(); - for (uint32_t region = 1; region <= 3; region++) { + for (uint32_t region = 1; region <= LAST_RAM_REGION; region++) { enable_region(enable, region); } diff --git a/targets/targets.json b/targets/targets.json index 0e0882512e..de1e56d583 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -33,8 +33,7 @@ }, "mpu-rom-end": { "help": "Last address of ROM protected by the MPU", - "value": "0x0fffffff", - "macro_name": "MPU_ROM_END" + "value": "0x0fffffff" } } },