Hi everyone, I was trying to run FreeRTOS-MPU at the non-secure world (MPU_NS enabled) and some trusted code at the secure world (MPU_S disabled).
When I enabled SAU but disabled both MPU_S and MPU_NS, the program ran normally.
However, if I configured MPU_NS with proper permissions, the program encountered unexplainable errors.
In the vRestoreContextOfFirstTask function, the load instruction (address 0x08041030) after the store instruction (address 0x08041026) that enabled the MPU, triggered a Secure HardFault.
Dump of assembler code for function vRestoreContextOfFirstTask: 0x08040ff0 <+0>: ldr r2, [pc, #108] @ (0x8041060 <vRestoreContextOfFirstTask+112>) 0x08040ff2 <+2>: ldr r3, [r2, #0] 0x08040ff4 <+4>: ldr r0, [r3, #0] 0x08040ff6 <+6>: dmb sy 0x08040ffa <+10>: ldr r2, [pc, #108] @ (0x8041068 <vRestoreContextOfFirstTask+120>) 0x08040ffc <+12>: ldr r4, [r2, #0] 0x08040ffe <+14>: bic.w r4, r4, #1 0x08041002 <+18>: str r4, [r2, #0] 0x08041004 <+20>: adds r3, #4 0x08041006 <+22>: ldr r4, [r3, #0] 0x08041008 <+24>: ldr r2, [pc, #96] @ (0x804106c <vRestoreContextOfFirstTask+124>) 0x0804100a <+26>: str r4, [r2, #0] 0x0804100c <+28>: ldr r2, [pc, #96] @ (0x8041070 <vRestoreContextOfFirstTask+128>) 0x0804100e <+30>: movs r4, #4 0x08041010 <+32>: str r4, [r2, #0] 0x08041012 <+34>: adds r3, #4 0x08041014 <+36>: ldr r2, [pc, #92] @ (0x8041074 <vRestoreContextOfFirstTask+132>) 0x08041016 <+38>: ldmia.w r3!, {r4, r5, r6, r7, r8, r9, r10, r11} 0x0804101a <+42>: stmia.w r2!, {r4, r5, r6, r7, r8, r9, r10, r11} 0x0804101e <+46>: ldr r2, [pc, #72] @ (0x8041068 <vRestoreContextOfFirstTask+120>) 0x08041020 <+48>: ldr r4, [r2, #0] 0x08041022 <+50>: orr.w r4, r4, #5 0x08041026 <+54>: str r4, [r2, #0] 0x08041028 <+56>: dsb sy 0x0804102c <+60>: isb sy => 0x08041030 <+64>: ldr r1, [r0, #0] 0x08041032 <+66>: add.w r0, r0, #4 0x08041036 <+70>: ldr r2, [r0, #0] 0x08041038 <+72>: add.w r0, r0, #4 0x0804103c <+76>: ldr r3, [r0, #0] 0x0804103e <+78>: add.w r0, r0, #4 0x08041042 <+82>: ldr r4, [r0, #0] 0x08041044 <+84>: add.w r0, r0, #4 0x08041048 <+88>: ldr r5, [pc, #24] @ (0x8041064 <vRestoreContextOfFirstTask+116>) 0x0804104a <+90>: str r1, [r5, #0] 0x0804104c <+92>: msr PSPLIM, r2 0x08041050 <+96>: msr CONTROL, r3 0x08041054 <+100>: adds r0, #32 0x08041056 <+102>: msr PSP, r0 0x0804105a <+106>: isb sy 0x0804105e <+110>: bx r4 0x08041060 <+112>: strh r4, [r7, #0] 0x08041062 <+114>: movs r0, #1 0x08041064 <+116>: strh r0, [r3, r1] 0x08041066 <+118>: movs r0, #2 0x08041068 <+120>: @ <UNDEFINED> instruction: 0xed94e000 0x0804106c <+124>: @ <UNDEFINED> instruction: 0xedc0e000 0x08041070 <+128>: @ <UNDEFINED> instruction: 0xed98e000 0x08041074 <+132>: @ <UNDEFINED> instruction: 0xed9ce000 0x08041078 <+136>: nop End of assembler dump.
And I then checked the HFSR register, its value was 0x40000000. HFSR.FORCED indicated that there was an escalated exception.
0xe000ed2c: 0x40000000
So I further checked the CFSR_NS register, its value was 0x00000082. Apparently, there was a MemMange Fault and it finally escalated to a HardFault.
0xe000ed28: 0x00000082
And I also checked the MMFAR register, its value was 0x2002b460, where was exactly read by the load instruction at address 0x08041030.
0xe000ed34: 0x2002b460
However, MPU_NS allowed read and write access to 0x2002b460 by any privileged level. Below is the configurations of MPU_NS, region 4 allows any privilege level read and write to range 0x200274a0 and 0x2002b4bf.
[+] MPU Region ID: 0 [+] MPU_RNR MPU_RNR.REGION: 0 [+] MPU_RBAR MPU_RBAR: 0x8040006 MPU_RBAR.XN: 0x0 MPU_RBAR.AP: 0x3 Privileged access: R.O. Unprivileged access: R.O. MPU_RBAR.SH: 0x0 MPU_RBAR.BASE: 0x8040000 [+] MPU_RLAR MPU_RLAR: 0x807ffe1 MPU_RLAR.EN: 0x1 MPU_RLAR.AttrIndx: 0x0 MPU_RLAR.PXN: 0x0 MPU_RLAR.LIMIT: 0x807ffe0 ------------------------------ [+] MPU Region ID: 1 [+] MPU_RNR MPU_RNR.REGION: 1 [+] MPU_RBAR MPU_RBAR: 0x0 MPU_RBAR.XN: 0x0 MPU_RBAR.AP: 0x0 Privileged access: R.W. Unprivileged access: N.A. MPU_RBAR.SH: 0x0 MPU_RBAR.BASE: 0x0 [+] MPU_RLAR MPU_RLAR: 0x0 MPU_RLAR.EN: 0x0 MPU_RLAR.AttrIndx: 0x0 MPU_RLAR.PXN: 0x0 MPU_RLAR.LIMIT: 0x0 ------------------------------ [+] MPU Region ID: 2 [+] MPU_RNR MPU_RNR.REGION: 2 [+] MPU_RBAR MPU_RBAR: 0x0 MPU_RBAR.XN: 0x0 MPU_RBAR.AP: 0x0 Privileged access: R.W. Unprivileged access: N.A. MPU_RBAR.SH: 0x0 MPU_RBAR.BASE: 0x0 [+] MPU_RLAR MPU_RLAR: 0x0 MPU_RLAR.EN: 0x0 MPU_RLAR.AttrIndx: 0x0 MPU_RLAR.PXN: 0x0 MPU_RLAR.LIMIT: 0x0 ------------------------------ [+] MPU Region ID: 3 [+] MPU_RNR MPU_RNR.REGION: 3 [+] MPU_RBAR MPU_RBAR: 0x20018003 MPU_RBAR.XN: 0x1 MPU_RBAR.AP: 0x1 Privileged access: R.W. Unprivileged access: R.W. MPU_RBAR.SH: 0x0 MPU_RBAR.BASE: 0x20018000 [+] MPU_RLAR MPU_RLAR: 0x2003ffe1 MPU_RLAR.EN: 0x1 MPU_RLAR.AttrIndx: 0x0 MPU_RLAR.PXN: 0x0 MPU_RLAR.LIMIT: 0x2003ffe0 ------------------------------ [+] MPU Region ID: 4 [+] MPU_RNR MPU_RNR.REGION: 4 [+] MPU_RBAR MPU_RBAR: 0x200274a2 MPU_RBAR.XN: 0x0 MPU_RBAR.AP: 0x1 Privileged access: R.W. Unprivileged access: R.W. MPU_RBAR.SH: 0x0 MPU_RBAR.BASE: 0x200274a0 [+] MPU_RLAR MPU_RLAR: 0x2002b4a1 MPU_RLAR.EN: 0x1 MPU_RLAR.AttrIndx: 0x0 MPU_RLAR.PXN: 0x0 MPU_RLAR.LIMIT: 0x2002b4a0 ------------------------------ [+] MPU Region ID: 5 [+] MPU_RNR MPU_RNR.REGION: 5 [+] MPU_RBAR MPU_RBAR: 0x0 MPU_RBAR.XN: 0x0 MPU_RBAR.AP: 0x0 Privileged access: R.W. Unprivileged access: N.A. MPU_RBAR.SH: 0x0 MPU_RBAR.BASE: 0x0 [+] MPU_RLAR MPU_RLAR: 0x0 MPU_RLAR.EN: 0x0 MPU_RLAR.AttrIndx: 0x0 MPU_RLAR.PXN: 0x0 MPU_RLAR.LIMIT: 0x0 ------------------------------ [+] MPU Region ID: 6 [+] MPU_RNR MPU_RNR.REGION: 6 [+] MPU_RBAR MPU_RBAR: 0x0 MPU_RBAR.XN: 0x0 MPU_RBAR.AP: 0x0 Privileged access: R.W. Unprivileged access: N.A. MPU_RBAR.SH: 0x0 MPU_RBAR.BASE: 0x0 [+] MPU_RLAR MPU_RLAR: 0x0 MPU_RLAR.EN: 0x0 MPU_RLAR.AttrIndx: 0x0 MPU_RLAR.PXN: 0x0 MPU_RLAR.LIMIT: 0x0 ------------------------------ [+] MPU Region ID: 7 [+] MPU_RNR MPU_RNR.REGION: 7 [+] MPU_RBAR MPU_RBAR: 0x0 MPU_RBAR.XN: 0x0 MPU_RBAR.AP: 0x0 Privileged access: R.W. Unprivileged access: N.A. MPU_RBAR.SH: 0x0 MPU_RBAR.BASE: 0x0 [+] MPU_RLAR MPU_RLAR: 0x0 MPU_RLAR.EN: 0x0 MPU_RLAR.AttrIndx: 0x0 MPU_RLAR.PXN: 0x0 MPU_RLAR.LIMIT: 0x0 ------------------------------
So the program tried to read 4 bytes of memory and its target was permitted by MPU_NS. However, it still triggered an MemManage Fault and escalated to a HardFault eventually.
However, it seemed strange that the value of SHCSR_NS indicating that the MemMange Fault for non-secure world was enabled.
0xe000ed24: 0x00050080
Is there anything configured wrong or something conflicted between SAU and MPU? Thanks!