Can Cortex-M33 MCUs enable SAU and MPU_NS simultaneously?

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!