Skip to content

More MPU work #9061

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Dec 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 68 additions & 61 deletions hal/mpu/mbed_mpu_v7m.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
*/
#include "hal/mpu_api.h"
#include "platform/mbed_assert.h"
#include "platform/mbed_error.h"
#include "cmsis.h"

#if ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_6M__ == 1U)) && \
Expand All @@ -26,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)
Expand All @@ -45,12 +46,17 @@ MBED_STATIC_ASSERT(
void mbed_mpu_init()
{
// Flush memory writes before configuring the MPU.
__DSB();
__DMB();

const uint32_t regions = (MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos;
if (regions < 4) {
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_HAL, MBED_ERROR_CODE_EINVAL), "Device is not capable of supporting an MPU - remove DEVICE_MPU for 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;
Expand All @@ -74,13 +80,12 @@ void mbed_mpu_init()
* 0xE0000000 - 0xFFFFFFFF System No
*/

// Select region 1 and used it for the WT rom region
// - RAM 0x00000000 to MBED_MPU_ROM_END
MPU->RNR = 0;
// Set address to 0
MPU->RBAR = 0;
// Configure and enable region
MPU->RASR =
// Select region 0 and use it for the WT read-only rom region
// - Code 0x00000000 to MBED_MPU_ROM_END
ARM_MPU_SetRegion(
ARM_MPU_RBAR(
0, // Region
0x00000000), // Base
ARM_MPU_RASR(
0, // DisableExec
ARM_MPU_AP_RO, // AccessPermission
Expand All @@ -97,16 +102,16 @@ void mbed_mpu_init()
((MBED_MPU_ROM_END >= 0x14000000) ? 0 : (1 << 5)) |
((MBED_MPU_ROM_END >= 0x18000000) ? 0 : (1 << 6)) |
((MBED_MPU_ROM_END >= 0x1C000000) ? 0 : (1 << 7)),
ARM_MPU_REGION_SIZE_512MB // Size
);

// Select region 1 and used it for the WT rom region
// - RAM MBED_MPU_ROM_END + 1 to 0x1FFFFFFF
MPU->RNR = 1;
// Set address to 0
MPU->RBAR = 0;
// Configure and enable region
MPU->RASR =
ARM_MPU_REGION_SIZE_512MB) // Size
);

#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(
3, // Region
0x00000000), // Base
ARM_MPU_RASR(
1, // DisableExec
ARM_MPU_AP_FULL, // AccessPermission
Expand All @@ -123,17 +128,20 @@ void mbed_mpu_init()
((MBED_MPU_RAM_START <= 0x18000000) ? 0 : (1 << 5)) |
((MBED_MPU_RAM_START <= 0x1C000000) ? 0 : (1 << 6)) |
((MBED_MPU_RAM_START <= 0x20000000) ? 0 : (1 << 7)),
ARM_MPU_REGION_SIZE_512MB // Size
);
ARM_MPU_REGION_SIZE_512MB) // Size
);
#define LAST_RAM_REGION 3
#else
#define LAST_RAM_REGION 2
#endif

// Select region 2 and used it for WBWA ram regions
// Select region 1 and use it for WBWA ram regions
// - SRAM 0x20000000 to 0x3FFFFFFF
// - RAM 0x60000000 to 0x7FFFFFFF
MPU->RNR = 2;
// Set address to 0
MPU->RBAR = 0;
// Configure and enable region
MPU->RASR =
ARM_MPU_SetRegion(
ARM_MPU_RBAR(
1, // Region
0x00000000), // Base
ARM_MPU_RASR(
1, // DisableExec
ARM_MPU_AP_FULL, // AccessPermission
Expand All @@ -150,26 +158,25 @@ void mbed_mpu_init()
(1 << 5) | // Disable Sub-region
(1 << 6) | // Disable Sub-region
(1 << 7), // Disable Sub-region
ARM_MPU_REGION_SIZE_4GB // Size
);

// Select region 3 and used it for the WT ram region
// - RAM RAM 0x80000000 to 0x9FFFFFFF
MPU->RNR = 3;
// Set address
MPU->RBAR = 0x80000000;
// Configure and enable region
MPU->RASR =
ARM_MPU_REGION_SIZE_4GB) // Size
);

// Select region 2 and use it for the WT ram region
// - RAM 0x80000000 to 0x9FFFFFFF
ARM_MPU_SetRegion(
ARM_MPU_RBAR(
2, // Region
0x80000000), // Base
ARM_MPU_RASR(
1, // DisableExec
ARM_MPU_AP_FULL, // AccessPermission
0, // TypeExtField
0, // IsShareable
1, // IsCacheable
0, // IsBufferable
~0U, // SubRegionDisable
ARM_MPU_REGION_SIZE_512MB // Size
);
0U, // SubRegionDisable
ARM_MPU_REGION_SIZE_512MB) // Size
);

// Enable the MPU
MPU->CTRL =
Expand All @@ -178,53 +185,53 @@ void mbed_mpu_init()
(1 << MPU_CTRL_ENABLE_Pos); // Enable MPU

// Ensure changes take effect
__ISB();
__DSB();
__ISB();
}

void mbed_mpu_free()
{
// Flush memory writes before configuring the MPU.
__DSB();
__DMB();

// Disable the MPU
MPU->CTRL = 0;

// Ensure changes take effect
__ISB();
__DSB();
__ISB();
}

static void enable_region(bool enable, uint32_t region)
{
MPU->RNR = region;
MPU->RASR = (MPU->RASR & ~MPU_RASR_ENABLE_Msk) | (enable << MPU_RASR_ENABLE_Pos);
}

void mbed_mpu_enable_rom_wn(bool enable)
{
// Flush memory writes before configuring the MPU.
__DSB();
__DMB();

MPU->RNR = 0;
MPU->RASR = (MPU->RASR & ~MPU_RASR_ENABLE_Msk) | (enable ? MPU_RASR_ENABLE_Msk : 0);
enable_region(enable, 0);

// Ensure changes take effect
__ISB();
__DSB();
__ISB();
}

void mbed_mpu_enable_ram_xn(bool enable)
{
// Flush memory writes before configuring the MPU.
__DSB();
__DMB();

MPU->RNR = 1;
MPU->RASR = (MPU->RASR & ~MPU_RASR_ENABLE_Msk) | (enable ? MPU_RASR_ENABLE_Msk : 0);

MPU->RNR = 2;
MPU->RASR = (MPU->RASR & ~MPU_RASR_ENABLE_Msk) | (enable ? MPU_RASR_ENABLE_Msk : 0);

MPU->RNR = 3;
MPU->RASR = (MPU->RASR & ~MPU_RASR_ENABLE_Msk) | (enable ? MPU_RASR_ENABLE_Msk : 0);
for (uint32_t region = 1; region <= LAST_RAM_REGION; region++) {
enable_region(enable, region);
}

// Ensure changes take effect
__ISB();
__DSB();
__ISB();
}

#endif
Loading