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.

SYS/BIOS 6.45.01.29 ti.sysbios.family.arm.exc.Exception reports incorrect SP and LR values, leading to incorrect exception call stack

Other Parts Discussed in Thread: BEAGLEBOARD-X15, SYSBIOS

With SYS/BIOS 6.45.01.29 created a test program for a Cortex-A15 to test the SYS/BIOS decoding of an exception call stack, where the test program generates a Data Abort exception by attempting to read from a memory address which is not mapped. Used CCS 6.2.0.00050 and the compiler GNU v4.9.3. It was found that the incorrect exception call stack was reported in the ROV, and noticed that the exception was reporting incorrect values for the SP and LR values.

The following screenshot shows the state when the next instruction to be executed will generate a Data Abort exception:

i.e. the Data Abort exception is generated at PC=0x8000542C, SP=0x8001E150 and LR=0x8000551C.

The next screenshot shows the state after the SYS/BIOS exception handler has terminated the program, and reported the exception:

The problem is that:

a) The ROV Exception view and the exception dump to the console have both reported an incorrect LR value of 0x8002005C, rather than the actual value 0x8000551C

b) The ROV Exception view and the exception dump to the console have both reported an incorrect SP value of 0x8000542c, rather than the actual value 0x8001E150.

c) The ROV Exception call stack is incomplete - it shows the Data Abort exception occurred in bad_func() but has reported the incorrect call site since the reported LR value is incorrect.

The test project is attached 8321.task_GPEVM_AM572X_SiRevA_CortexA.zip. The test program was run on a BeagleBoard-X15 Rev A2.

  • I have traced the cause of the incorrect LR and SP registers in the SYS/BIOS exception trace to the ti_sysbios_family_arm_exc_Exception_excHandlerDataAsm__I function in bios_6_45_01_29\packages\ti\sysbios\family\arm\exc\Exception_asm_gnu.asm :

    @
    @  ======== Exception_excHandlerDataAsm ========
    @  Data Abort Exception handler
    @
    
            .func ti_sysbios_family_arm_exc_Exception_excHandlerDataAsm__I
    
    ti_sysbios_family_arm_exc_Exception_excHandlerDataAsm__I:
            stmfd   sp!, {r0-r12}   @ save r4-r12 while we're at it
    
            mrc     p15, #0, r12, c5, c0, #0 @ read DFSR into r12
            stmfd   sp!, {r12}      @ save DFSR
            mrc     p15, #0, r12, c5, c0, #1 @ read IFSR into r12
            stmfd   sp!, {r12}      @ save DFSR
            mrc     p15, #0, r12, c6, c0, #0 @ read DFAR into r12
            stmfd   sp!, {r12}      @ save DFAR
            mrc     p15, #0, r12, c6, c0, #2 @ read IFAR into r12
            stmfd   sp!, {r12}      @ save IFAR
    
            mrs     r12, cpsr
            add     r12, r12, #1    @ replace abort (0x17) with 0x18 
            push    {r12}           @ save current CPSR
    
            mov     r0, sp          @ pass sp to exception handler
            sub     lr, lr, #8      @ back up to offending instruction
            mov     r1, lr          @ pass lr (=pc)
    
            mrs     r2, cpsr
            orr     r12, r2, #0x1f  @ switch to SYS mode
            msr     cpsr_cf, r12    @
    
            stmfd   r0!, {lr}       @ save system lr too
            mov     r12, sp
            stmfd   r0!, {r12}      @ save system sp
            mrs     r12, cpsr
            stmfd   r0!, {r12}      @ save system cpsr
    
            msr     cpsr_cf, r2     @ switch back to previous mode
    
            push    {r0}            @ dummy store to 8-byte align the stack
    
            ldr     pc, excHandlerAddr
            .endfunc
    

    The saving of the system lr, system sp and system cpsr registers is performed in SYS mode, where the r0 register points to the ABT mode stack. i.e. the ti_sysbios_family_arm_exc_Exception_excHandlerDataAsm__I function temporarily changes to SYS mode and then back to ABT mode. The problem is that the ABT mode SP is NOT decremented by 12 to account for the 12 bytes which have been stored for the values of the system lr, system sp and system cpsr registers. The end result is that the system lr and system sp values which have been stored on the ABT mode stack then get overwritten by subsequent pushes to the ABT mode stack.

    Also, the ABT mode stack is not 8 byte aligned on entry to the excHandlerAddr C function which violates the ARM EABI (since the ti_sysbios_family_arm_exc_Exception_excHandlerDataAsm__I function decrements the ABT mode SP by an odd number of 4 bytes words).

    As a fix a "sub     sp, sp, #12" instruction was added to the ti_sysbios_family_arm_exc_Exception_excHandlerDataAsm__I function:

    ti_sysbios_family_arm_exc_Exception_excHandlerDataAsm__I:
            stmfd   sp!, {r0-r12}   @ save r4-r12 while we're at it
    
            mrc     p15, #0, r12, c5, c0, #0 @ read DFSR into r12
            stmfd   sp!, {r12}      @ save DFSR
            mrc     p15, #0, r12, c5, c0, #1 @ read IFSR into r12
            stmfd   sp!, {r12}      @ save DFSR
            mrc     p15, #0, r12, c6, c0, #0 @ read DFAR into r12
            stmfd   sp!, {r12}      @ save DFAR
            mrc     p15, #0, r12, c6, c0, #2 @ read IFAR into r12
            stmfd   sp!, {r12}      @ save IFAR
    
            mrs     r12, cpsr
            add     r12, r12, #1    @ replace abort (0x17) with 0x18 
            push    {r12}           @ save current CPSR
    
            mov     r0, sp          @ pass sp to exception handler
            sub     lr, lr, #8      @ back up to offending instruction
            mov     r1, lr          @ pass lr (=pc)
    
            mrs     r2, cpsr
            orr     r12, r2, #0x1f  @ switch to SYS mode
            msr     cpsr_cf, r12    @
    
            stmfd   r0!, {lr}       @ save system lr too
            mov     r12, sp
            stmfd   r0!, {r12}      @ save system sp
            mrs     r12, cpsr
            stmfd   r0!, {r12}      @ save system cpsr
    
            msr     cpsr_cf, r2     @ switch back to previous mode
    
            sub     sp, sp, #12     @ adjust the current mode stack to account for the lr, sp and cpsr saved in SYS mode above
    
            push    {r0}            @ dummy store to 8-byte align the stack
    
            ldr     pc, excHandlerAddr
            .endfunc

    With the above fix the state prior to the instruction which generates a Data Abort exception:

    And after the SYS/BIOS exception handling has aborted the program:

    The modification to the ti_sysbios_family_arm_exc_Exception_excHandlerDataAsm__I function had the desired effect in that:

    a) The ROV Exception view and exception dump in the console now report PC, LR and SP values which match those prior to executing the instruction which generates the Data Abort exception.

    b) The ROV Exception call stack now matches that in the debugger prior to executing the instruction which generates the Data Abort exception.

    Note that while I found the problem in the Data Abort Exception handler for the bios_6_45_01_29\packages\ti\sysbios\family\arm\exc\Exception_asm_gnu.asm used for the GNU compiler, from looking at the SYS/BIOS code believe the same problem exists in:

    a) The Common Exception handler in the bios_6_45_01_29\packages\ti\sysbios\family\arm\exc\Exception_asm_gnu.asm file

    b) The Data Abort Exception and Common Exception handlers in the bios_6_45_01_29\packages\ti\sysbios\family\arm\exc\Exception_asm.asm used for the TI compiler.

  • Thanks for the detailed post. I'll have someone more familiar with the exception handling look into this on Monday.

    Todd
  • Looks like it is an issue. We'll respond when we have a complete answer.

    Todd
  • Hi Chester,

    First of all I would like to thank you for reporting the issue and providing detailed debug information. The debug info was very helpful in quickly assessing the problem.

    We see the problem and agree with your conclusion about the cause of the problem i.e. the exception handler is not updating the abort mode SP as required. I have filed a bug to track this issue (SYSBIOS-307). Unfortunately, our bug database is not public yet so you will not be able to check on the bug status.

    Best,
    Ashish
  • Ashish Kapania said:
    I have filed a bug to track this issue (SYSBIOS-307).

    I confirm that SYSBIOS-307 has been fixed in SYS/BIOS 6.50.00.10.

    Edit: I was going to verify Ashish's previous post as the answer, but the forum isn't giving me that option.

  • Thanks for verifying the fix.

    Best,

    Ashish