ATCM ECC error causes prefetch abort despite ECC check being disabled.


I am working with TI's TMS570LS3137 (ARM Cortex R4F).

A certain part of my code consistently causes a prefetch abort (I say part because the exact location seems to vary slightly).

To try and identify the cause I set a breakpoint at the prefetch abort handler (0x0000000C) and looked at the following registers:

  • r14_abt = 0x10
    • Here I would expect to see the value of the link register when the abort occured. 0x10 makes no sense to me as that is the address of the data abort vector.
  • IFAR (Instruction Fault Address Register) = 0x0000000C
    • The abort occured when trying to execute from address 0x0000000C. At no point does my code ever attempt to execute from that address.
  • IFSR (Instruction Fault Status Register) = 0x00000409
    • The cause of the abort was a Synchronous Parity/ECC error.
  • AIFSR (Auxiliary Instruction Fault Status Register) = 0x00400000
    • The error occured in ATCM. This should not be possible as I have disabled the CPU's parity/ECC check for both ATCM & BTCM by clearing ATCMPCEN, B0TCMPCEN and B1TCMPCEN

Here is how I disabled parity/ECC check:

// Disable CPU parity/ECC check
asm(" PUSH {r1}");
asm(" MRC p15, #0, r1, c1, c0, #1");    // Read ACTLR
asm(" BIC r1, r1, #0x0E000000");        // Clear ATCMPCEN, B0TCMPCEN, B1TCMPCEN
asm(" MCR p15, #0, r1, c1, c0, #1");    // Write ACTLR
asm(" POP {r1}");

These observations leave me with two questions:

  1. Am I misinterpreting the value of r14_abt & IFAR?
  2. Am I not disabling parity/ECC check correctly?

Thank you in advance

  • Little unrelated, but: You should not use multiple asm() statements if you want the code be placed the way you wrote it:

    asm(" PUSH {r1}\n"
        " MRC p15, #0, r1, c1, c0, #1\n"    /* Read ACTLR */
        " BIC r1, r1, #0x0E000000\n"        /* Clear ATCMPCEN, B0TCMPCEN, B1TCMPCEN */
        " MCR p15, #0, r1, c1, c0, #1\n"    /* Write ACTLR */
        " POP {r1}");

  • This signal might be useful for you : PARECCENRAM[2:0]

    TCMs parity or ECC check enable. Tie each bit LOW to disable parity or ECC checking on the appropriate TCM at reset.

  • Thank you for your replies. 

    It turns out the root cause was not ECC.

    Some background: I was working on a bootloader and the abort often occured during erasing of flash. I ultimately fixed the problem by disabling interrupts before erasing. I suspect that interrupts occured during erasing which then caused an instruction fetch from 0x00000018 (IRQ vector). This address is mapped to the same flash bank that was being erased. According to the documentation of the flash controller it is not allowed to execute from a bank while it is being erased. I think that this ultimately caused the prefetch abort. 

    The fact that the IFSR reported a Synchronous Parity/ECC error is puzzling, but I can live with it, since I was able to fix the problem :^)

More questions in this forum