Fix MPU synchronisation

Synchronisation instructions were not quite right - too strict on entry,
and not quite correctly synchronising the instruction stream on exit.

References:

* https://static.docs.arm.com/dai0321/a/DAI0321A_programming_guide_memory_barriers_for_m_profile.pdf
* https://static.docs.arm.com/100699/0100/armv8m_architecture_memory_protection_unit_100699_0100_00_en.pdf
pull/9061/head
Kevin Bracey 2018-12-11 16:01:34 +02:00
parent cdc61c5954
commit e585eac31b
2 changed files with 16 additions and 16 deletions

View File

@ -45,7 +45,7 @@ MBED_STATIC_ASSERT(
void mbed_mpu_init() void mbed_mpu_init()
{ {
// Flush memory writes before configuring the MPU. // Flush memory writes before configuring the MPU.
__DSB(); __DMB();
const uint32_t regions = (MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos; const uint32_t regions = (MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos;
if (regions < 4) { if (regions < 4) {
@ -178,40 +178,40 @@ void mbed_mpu_init()
(1 << MPU_CTRL_ENABLE_Pos); // Enable MPU (1 << MPU_CTRL_ENABLE_Pos); // Enable MPU
// Ensure changes take effect // Ensure changes take effect
__ISB();
__DSB(); __DSB();
__ISB();
} }
void mbed_mpu_free() void mbed_mpu_free()
{ {
// Flush memory writes before configuring the MPU. // Flush memory writes before configuring the MPU.
__DSB(); __DMB();
// Disable the MPU // Disable the MPU
MPU->CTRL = 0; MPU->CTRL = 0;
// Ensure changes take effect // Ensure changes take effect
__ISB();
__DSB(); __DSB();
__ISB();
} }
void mbed_mpu_enable_rom_wn(bool enable) void mbed_mpu_enable_rom_wn(bool enable)
{ {
// Flush memory writes before configuring the MPU. // Flush memory writes before configuring the MPU.
__DSB(); __DMB();
MPU->RNR = 0; MPU->RNR = 0;
MPU->RASR = (MPU->RASR & ~MPU_RASR_ENABLE_Msk) | (enable ? MPU_RASR_ENABLE_Msk : 0); MPU->RASR = (MPU->RASR & ~MPU_RASR_ENABLE_Msk) | (enable ? MPU_RASR_ENABLE_Msk : 0);
// Ensure changes take effect // Ensure changes take effect
__ISB();
__DSB(); __DSB();
__ISB();
} }
void mbed_mpu_enable_ram_xn(bool enable) void mbed_mpu_enable_ram_xn(bool enable)
{ {
// Flush memory writes before configuring the MPU. // Flush memory writes before configuring the MPU.
__DSB(); __DMB();
MPU->RNR = 1; MPU->RNR = 1;
MPU->RASR = (MPU->RASR & ~MPU_RASR_ENABLE_Msk) | (enable ? MPU_RASR_ENABLE_Msk : 0); MPU->RASR = (MPU->RASR & ~MPU_RASR_ENABLE_Msk) | (enable ? MPU_RASR_ENABLE_Msk : 0);
@ -223,8 +223,8 @@ void mbed_mpu_enable_ram_xn(bool enable)
MPU->RASR = (MPU->RASR & ~MPU_RASR_ENABLE_Msk) | (enable ? MPU_RASR_ENABLE_Msk : 0); MPU->RASR = (MPU->RASR & ~MPU_RASR_ENABLE_Msk) | (enable ? MPU_RASR_ENABLE_Msk : 0);
// Ensure changes take effect // Ensure changes take effect
__ISB();
__DSB(); __DSB();
__ISB();
} }
#endif #endif

View File

@ -35,7 +35,7 @@ MBED_STATIC_ASSERT(MBED_MPU_ROM_END == 0x1fffffff, "Changing MBED_MPU_ROM_END fo
void mbed_mpu_init() void mbed_mpu_init()
{ {
// Flush memory writes before configuring the MPU. // Flush memory writes before configuring the MPU.
__DSB(); __DMB();
const uint32_t regions = (MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos; const uint32_t regions = (MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos;
if (regions < 4) { if (regions < 4) {
@ -127,40 +127,40 @@ void mbed_mpu_init()
(1 << MPU_CTRL_ENABLE_Pos); // Enable MPU (1 << MPU_CTRL_ENABLE_Pos); // Enable MPU
// Ensure changes take effect // Ensure changes take effect
__ISB();
__DSB(); __DSB();
__ISB();
} }
void mbed_mpu_free() void mbed_mpu_free()
{ {
// Flush memory writes before configuring the MPU. // Flush memory writes before configuring the MPU.
__DSB(); __DMB();
// Disable the MCU // Disable the MCU
MPU->CTRL = 0; MPU->CTRL = 0;
// Ensure changes take effect // Ensure changes take effect
__ISB();
__DSB(); __DSB();
__ISB();
} }
void mbed_mpu_enable_rom_wn(bool enable) void mbed_mpu_enable_rom_wn(bool enable)
{ {
// Flush memory writes before configuring the MPU. // Flush memory writes before configuring the MPU.
__DSB(); __DMB();
MPU->RNR = 0; MPU->RNR = 0;
MPU->RLAR = (MPU->RLAR & ~MPU_RLAR_EN_Msk) | (enable ? MPU_RLAR_EN_Msk : 0); MPU->RLAR = (MPU->RLAR & ~MPU_RLAR_EN_Msk) | (enable ? MPU_RLAR_EN_Msk : 0);
// Ensure changes take effect // Ensure changes take effect
__ISB();
__DSB(); __DSB();
__ISB();
} }
void mbed_mpu_enable_ram_xn(bool enable) void mbed_mpu_enable_ram_xn(bool enable)
{ {
// Flush memory writes before configuring the MPU. // Flush memory writes before configuring the MPU.
__DSB(); __DMB();
MPU->RNR = 1; MPU->RNR = 1;
MPU->RLAR = (MPU->RLAR & ~MPU_RLAR_EN_Msk) | (enable ? MPU_RLAR_EN_Msk : 0); MPU->RLAR = (MPU->RLAR & ~MPU_RLAR_EN_Msk) | (enable ? MPU_RLAR_EN_Msk : 0);
@ -172,8 +172,8 @@ void mbed_mpu_enable_ram_xn(bool enable)
MPU->RLAR = (MPU->RLAR & ~MPU_RLAR_EN_Msk) | (enable ? MPU_RLAR_EN_Msk : 0); MPU->RLAR = (MPU->RLAR & ~MPU_RLAR_EN_Msk) | (enable ? MPU_RLAR_EN_Msk : 0);
// Ensure changes take effect // Ensure changes take effect
__ISB();
__DSB(); __DSB();
__ISB();
} }
#endif #endif