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.
pull/9061/head
Kevin Bracey 2018-12-12 15:03:40 +02:00
parent 170b73442b
commit 02330336f2
3 changed files with 55 additions and 19 deletions

View File

@ -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);
}

View File

@ -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);
}

View File

@ -32,8 +32,7 @@
},
"mpu-rom-end": {
"help": "Last address of ROM protected by the MPU",
"value": "0x0fffffff",
"macro_name": "MPU_ROM_END"
"value": "0x0fffffff"
}
}
},