We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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!