This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS570LS3137 -- rev B -- errata DEVICE#140 (CCM failure on boot) still present?

Other Parts Discussed in Thread: HALCOGEN

Dear Texas Instruments,

The silicon errata for the TMS570LS31x rev A lists a problem where the CCMR4 failure bit is set in ESMSR2 on cold boot (not warm boot).

This problem is not supposed to affect rev B silicon (and indeed the rev B errata doc doesn't mention it at all).

However, we are observing this exact problem in rev B silicon: Bit is set, nERROR is output, must be cleared on boot with a special ESM-clearing-rain-dance thingo, and so on.  Can we confirm that it's supposed to have been fixed in all rev B chips?

  • Yes, this erratum was fixed in revision B silicon and has been verifed as fixed. I can think of three possibilities (forgive me if I state the obvious).

    1. Is it really rev B silicon? This can be verified by reading the device ID at location 0xFFFFFFF0. The value 0x802AAD05 means it is rev A, the value 0x802AAD15 means it is rev B.

    2. A CPU register was not properly initialized before it was used in a write. This gives exactly the same signature as erratum device#140. This can happen if the C compiler generates a subroutine call that pushes some register, such as LR, onto the stack before the register is initialized. The TI start up example code has some explicit register loads to prevent this problem.  A quick check is to program a "branch to self" instruction at the reset vector. This prevents any additional instructions from being executed. If the nERROR output does not become active, the problem is not the device#140 erratum.

    3. It is a defective part. (unlikely) Has more than one part shown this behavior?

    Of course it can be something else, but that is all I have thought of so far.

    Best regards,

    Bob Crosby

  • It's definitely revB silicon.  But #2 looks like it's on the money.  A tight loop at startup does _not_ trigger nERROR.

    Funny thing is we _do_ initialize our registers.

    By moving around the infinite loop, I've localized the error light to what looks like some floating point code that gets used in early initialization (to compute timing parameters).  So my guess is that some of the floating point state is not being initialized.  The funny thing is that the floating point registers _are_ all carefully reset to known values.  But maybe there's something obscure; I'll recheck the relevant reference manuals.

  • The FPU itself needs to be enabled, before any floating point registers can be accessed.

    After all the register initialization, you also need to make a few 'seemingly' meaningless branches to initialize some internal (hidden) states of the CPUs to the same value so that you won't get a core compare error.

    There is startup code that comes with HalCoGen that you can reference, in the 'sys_core.asm' file.

    After the main core registers, the floating point registers and the branches are done like this in 'sys_core.asm'... but maybe you can use the whole file.

    The mrc/mcr is enabling the FPU ... has to be done before using any floating point opcodes.

    mrc p15, #0x00, r2, c1, c0, #0x02

    orr r2, r2, #0xF00000

    mcr p15, #0x00, r2, c1, c0, #0x02

    mov r2, #0x40000000

    fmxr fpexc, r2

    fmdrr d0, r1, r1

    fmdrr d1, r1, r1

    fmdrr d2, r1, r1

    fmdrr d3, r1, r1

    fmdrr d4, r1, r1

    fmdrr d5, r1, r1

    fmdrr d6, r1, r1

    fmdrr d7, r1, r1

    fmdrr d8, r1, r1

    fmdrr d9, r1, r1

    fmdrr d10, r1, r1

    fmdrr d11, r1, r1

    fmdrr d12, r1, r1

    fmdrr d13, r1, r1

    fmdrr d14, r1, r1

    fmdrr d15, r1, r1

    bl next1

    next1

    bl next2

    next2

    bl next3

    next3

    bl next4

    next4

    bx r0

     

  • Yep, I found our problem, and you were right on the money.  Here was our FP register initialization code:

    /* Initialize VFP registers */
    MOV   R1, #0
    FMDRR D0, R1, R1
    FMDRR D1, R1, R1
    FMDRR D2, R1, R1
    FMDRR D3, R1, R1
    FMDRR D4, R1, R1
    FMDRR D5, R1, R1
    FMDRR D6, R1, R1
    FMDRR D7, R1, R1
    FMDRR D8, R1, R1
    FMDRR D0, R1, R1
    FMDRR D10, R1, R1
    FMDRR D11, R1, R1
    FMDRR D12, R1, R1
    FMDRR D13, R1, R1
    FMDRR D14, R1, R1
    FMDRR D15, R1, R1

    See anything wrong in there?  :-)  Thanks, your suggestion really narrowed down the search.

  • Yep, we were already doing all that (but thanks).  Our problem was a little more... silly... than that (see below)!

  • Ah, double D0... ;)