Hello,I'm facing an unexpected issue while configuring the MPU on a Cortex-M7 (STM32H7). Basically, after setting the MPU in privileged thread mode, the execution continues up to when I switch to unprivileged thread mode writing into the CONTROL register. At that point, the MemManage Fault exception is triggered, signaling a stacking and instruction violation access errors. I'm confused, did I do something conceptually wrong or it can be a bug? I'm posting the code below. I've deliberately set the regions larger than needed in an effort to debug the code.
void mpu_config_test(void) { ARM_MPU_Disable(); /* * Set region 0 : FLASH : code * Normal memory, non-sharable write through, no write allocate * C = 1, B = 0, TEX = 0, S = 0 * SRD = 0, XN = 0 * AP = Privileged : Read-only / Unprivileged : Read-only */ MPU->RBAR = ARM_MPU_RBAR(0U, 0x00000000); MPU->RASR = ARM_MPU_RASR_EX( 0U, /* DisableExec: 1 = disable instruction fetches */ ARM_MPU_AP_FULL, /* AccessPermission */ ARM_MPU_ACCESS_NORMAL( /* Memory access attribution */ ARM_MPU_CACHEP_WT_NWA, /* Outer cache policy */ ARM_MPU_CACHEP_WT_NWA, /* Inner cache policy */ 0 /* Sharable */ ), 0x00UL, /* SubRegionDisable */ ARM_MPU_REGION_SIZE_256MB /* Size */ ); /* * Set region 1 : SRAM : stack + global * Normal memory, sharable, write through, no write allocate. * C = 1, B = 0, TEX = 0, S = 1 * SRD = 0, XN = 1 * AP = Privileged : full-access / Unprivileged : full-access */ MPU->RBAR = ARM_MPU_RBAR(1U, 0x20000000); MPU->RASR = ARM_MPU_RASR_EX( 0U, /* DisableExec: 1 = disable instruction fetches */ ARM_MPU_AP_FULL, /* AccessPermission */ ARM_MPU_ACCESS_NORMAL( /* Memory access attribution */ ARM_MPU_CACHEP_WT_NWA, /* Outer cache policy */ ARM_MPU_CACHEP_WT_NWA, /* Inner cache policy */ 1 /* Sharable */ ), 0x00UL, /* SubRegionDisable */ ARM_MPU_REGION_SIZE_256MB /* Size */ ); /* Set region 2 : peripherals * Device memory, sharable * C = 1, B = 0, TEX = 0, S = 1 * SRD = 0, XN = 1 * AP = Privileged : full-access / Unprivileged : full-access */ MPU->RBAR = ARM_MPU_RBAR(2U, 0x40000000); MPU->RASR = ARM_MPU_RASR_EX( 0U, /* DisableExec: 1 = disable instruction fetches */ ARM_MPU_AP_FULL, /* AccessPermission */ ARM_MPU_ACCESS_DEVICE( /* Memory access attribution */ 1 /* Sharable */ ), 0x00UL, /* SubRegionDisable */ ARM_MPU_REGION_SIZE_256MB /* Size */ ); /* Enable default memory map as a background region for privileged access */ ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk); } int main() { /* Initialize the system */ /* .... */ /* Config the MPU */ mpu_config_test(); /* Some other code that runs correctly */ /* Drop down to unprivileged thread mode */ asm volatile ( "MRS R0, CONTROL\n\t" "ORR R0, R0, #0x1\n\t" "MSR CONTROL, R0\n\t" /* <-- this instruction triggers the fault */ "ISB \n\t" ); }