If I enable SMPU protection of the peripheral regional from 0xF0000000 - 0xFFFFFFFF with user and supervisor read and write permissions and configure both peripheral bridges to permit user access to all peripherals, I expect code executing in user context to be abe to write to the SIUL peripheral to set GPIOs. Instead, I'm observing an immediate machine check exception when my code writes. Example:
The CPU takes a machine check exception on the first GPIO write and our handler reports:
MCSRR0 = 0xfd40e8 (saved address of offending instruction)
MCSR = 0xa6004 (machine check syndrome) = MAV (MCAR address valid), U (user mode), ST (store type instruction), G (guarded instruction), BUS_WRERR (write bus error on store) bits set.
MCAR = 0xfffc1304 (machine check address - valid given MCSR.MAV is set)
The instruction at address 0xfd40e8 is:
00fd40e8: e_stb r4,4864(r9)
r9 = 0xfffc0004
r9 +4864 = 0xfffc1304 = SIUL2 GPIO Pad Data Output Register (SIUL2_GPDO4_7) and matches MCAR in machine check exception handler.
If I set a breakpoint immediately before the e_stb, the MSR is 0x202d000 with PR=1 indicating the processor is in user mode.
The SMPU error registers *before* the e_stb are:
SMPU_ERR_ADR0 = FFFFC004
SMPU_ERR_ADTL0 = 00000200
SMPU_ERR_ACDL0 = 02000080
This is an artifact of the SMPU init issue tracked in SMPU flags spurious access violation immediately after enabling. The registers remain unchanged after the e_stb, indicating the SMPU doesn't have any problem with the access which makes me suspect the Peripheral bridges or the SIUL peripheral itself is rejecting the user privilege write.
I have tried to force the peripheral bridges into a maximally permissive configuration as follows:
AIPS_A.MPRA.R |= 0x77777000;
AIPS_A.MPRB.R |= 0x77000000;
AIPS_B.MPRA.R |= 0x77777000;
AIPS_B.MPRB.R |= 0x77000000;
for (int i = 0; i < 8; i++)
// can't write to PACRE aka PACR
// see https://community.nxp.com/thread/433251
if (i != 4)
AIPS_A.PACR[i].R = 0;
AIPS_B.PACR[i].R = 0;
for (int i = 0; i < 32; i++)
AIPS_A.OPACR[i].R = 0;
AIPS_B.OPACR[i].R = 0;
But the write still fails. I don't see any privilege checking in the SIUL peripheral itself.
1) Why is this user write triggering a machine check exception given the SMPU and peripheral bridge configuration should allow it?
2) Is there some other configuration I'm missing that's necessary to allow user privilege writes to the SIUL peripheral?