AnsweredAssumed Answered

First instruction in normal mode gives an external abort.

Question asked by Bill Pringlemeir on Feb 17, 2015
Latest reply on Mar 26, 2015 by Bill Pringlemeir

The first instruction I ever execute on the Vybrid tower Cortex-A5 in normal world with external aborts trapping to monitor gives a fault.  I looked at a CP15 register and I believe that the 'External Abort' was clear on boot, but the first instruction I execute gives an external abort.  I read the Cortex-A5 TRM and have the following initialization code of the normal world CP15,

 

@ Clear fault registers.
mov r1, #0
mcr p15, 0, r1, c6, c0, 0   @ dfar
mcr p15, 0, r1, c5, c0, 0   @ dfsr
mcr p15, 0, r1, c6, c0, 2   @ ifar
mcr p15, 0, r1, c5, c0, 1   @ ifsr
mcr p15, 2, r1, c0, c0, 0   @ csselr (cache size select)
mcr      p15, 0, r1, c12, c0, 0  @ VBAR
mcr p15, 0, r1, c2, c0, 0   @ TTBR0
mcr p15, 0, r1, c2, c0, 1   @ TTBR1
mcr p15, 0, r1, c2, c0, 2   @ TTBCR (ttb control)
mcr p15, 0, r1, c13, c0, 1  @ CONTEXTIDR
movw r1, #0x5555
movt r1, #0x5555
mcr p15, 0, r1, c3, c0, 0   @ NS-DACR set to all access.

 

@ Zero non-reserved bits in SCTLR, system control register.
mrc p15, 0, r1, c1, c0, 0 @ Read Control Register configuration data
bic r1, r1, #(7<<28)|(1<<25) @ TE, AFE, TRE, EE
bic r1, r1, #(3<<12)|(1<<10) @ V, I, SW
bic r1, r1, #7    @ C, A, M
mcr p15, 0, r1, c1, c0, 0 @ Write Control Register configuration data

 

@@ Cortex-A Series programmers guide pg15.-3, example 15-3...

 

@ Invalidate L1 Caches (normal world)
@ Invalidate Instruction cache
mov r1, #0
mcr p15, 0, r1, c7, c5, 0

 

@ Invalidate Data cache
@ to make the code general purpose, we calculate the
@ cache size first and loop through each set + way

    mrc p15, 1, r0, c0, c0, 0 @ Read Cache Size ID

    ldr r3, =0x1ff

    and r0, r3, r0, lsr #13   @ r0 = no. of sets - 1

    mov r1, #0     @ r1 = way counter way_loop
2:    mov r3, #0     @ way_loop
1:    mov r2, r1, lsl #30 @ r3 = set counter set_loop
    orr r2, r2, r3, lsl #5 @ r2 = set-way cache operation format

    mcr p15, 0, r2, c7, c6, 2 @ Invalidate line described by r2

    add r3, r3, #1 @ Increment set counter
    cmp r0, r3     @ Last set reached yet?
    bne 1b         @ if not, iterate set_loop
    add r1, r1, #1 @ else, next
    cmp r1, #4     @ Last way reached yet?
    bne 2b         @ if not, iterate way_loop

 

    @ Invalidate TLB

    mcr p15, 0, r1, c8, c7, 0

isb

 

    @ Branch Prediction invalidate

mcr p15, 0, r1, c7, c5, 6

 

 

 

Are there other CP15 registers that may cause the ExtAbt?  I have no clue as to what peripheral may cause this as the 'FSR/FAR' are all none relevant.  I only look at the PC (dabt lr) and it give the first instruction +8.  The exception mode is at monitor mode 10h or data abort.  It seems to happen whether it is OCRAM or DDR3.  I am guessing that it is due to the CP15 environment of the first instruction to execute.  The initial monitor code to secure switch is,

 

/* The 'System control register' or SCR in CP15 c1, c1, 0

   configures TrustZone; monitor mode and 'normal' capabilities.

*/

/* Set 'A' (external abort) flag from 'normal' mode. */

#define SCR_AW  (1<<5)

/* Mask FIQ/secure interrupts from 'normal' mode. */

#define SCR_FW  (1<<4)

/* Branch to monitor on external abort. */

#define SCR_EA  (1<<3)

/* Branch to monitor on FIQ. */

#define SCR_FIQ (1<<2)

/* Branch to monitor on IRQ. */

#define SCR_IRQ (1<<1)

/* 1 is non-secure/normal and 0 is secure! */

#define SCR_NS  (1<<0)

 

/* Switch to non-secure world, route FIQ to monitor,
no alignment traps. */
mov    r1, #(SCR_XX|SCR_FIQ|SCR_NS)
mcr    p15, 0, r1, c1, c1, 0
isb

 

/* load gen-regs */
msr spsr_fsxc, lr
ldm    sp, {r0 - r12, pc}^

 

 

 

This is executing in monitor mode.  After the initial 'external abort' the secure world to normal world switching is fine without any abort exceptions.  SCR_XX is to trap external aborts to the monitor (SCR_EA); after the initial fault I use the SCR_AW flag as there are no more (spurious?) external aborts.  Is there any way to know if it is a Freescale IP which causes the ExtAbt vs. a Cortex-A5 internal (Freescale vs ARM CPU issue)?  I read the L2 cache document and nothing jumped out.  Initially, the caches are off when the normal world executes, but I guess data may pass through the caches and some access check happens?  Dumping the L2 registers didn't seem to show anything significant.  The 'TZASC' fuse is off and not configured (although defaults indicate all access).  I can only start the normal world from TZASC peripherals?

Outcomes