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()
{
// 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) {
@ -178,40 +178,40 @@ 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();
}
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);
// 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);
@ -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);
// Ensure changes take effect
__ISB();
__DSB();
__ISB();
}
#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()
{
// 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) {
@ -127,40 +127,40 @@ 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 MCU
MPU->CTRL = 0;
// Ensure changes take effect
__ISB();
__DSB();
__ISB();
}
void mbed_mpu_enable_rom_wn(bool enable)
{
// Flush memory writes before configuring the MPU.
__DSB();
__DMB();
MPU->RNR = 0;
MPU->RLAR = (MPU->RLAR & ~MPU_RLAR_EN_Msk) | (enable ? MPU_RLAR_EN_Msk : 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->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);
// Ensure changes take effect
__ISB();
__DSB();
__ISB();
}
#endif