AnsweredAssumed Answered

User writes to SIUL fail with SMPU and peripheral bridge configured to allow

Question asked by Daniel Wax Employee on Oct 24, 2016
Latest reply on Nov 2, 2016 by Peter Vlna

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:

 

void PBRIDGE_init(void)
{
    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[4]
        // 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.

 

Questions:

 

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?

Outcomes