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.

SYSBIOS and VFP/NEON registers in task context

Other Parts Discussed in Thread: SYSBIOS, OMAP3530

Hello!

We have device based on OMAP3530 with SYSBIOS. We would like use VFP/NEON instructions in several tasks and interrupts processing.

Does SYSBIOS support storing/restoring VPU/NEON registers in task context switch?

BR

Sergey

  • Sergey,

    Yes. The appropriate VFP/NEON register context is saved and restored during a task switch as well as when an interrupt is handled.

    Please use the "ti.targets.arm.elf.A8Fnv" target to build your application.

    Alan

  • Thanks for answer.

    We use only Cortex-A8 part of OMAP3530. We have done ti.targets.arm.elf.A8Fnv, but we have strange problems. Our code is ported on several platforms and debugged well. Under SYSBIOS we can see chaotic bugs in different parts of code, but all of them are concerned with floating-point. We have rebuilt our code with sotf float-point and problem resolves (but through-put is descend) .

    I have tried to find task/interrupt context store/restore code and can see next inside SYSBIOS 6.32.04.49:

    file ccs5\bios\packages\ti\sysbios\family\arm\a8\intcps\Hwi_asm.s470 :

    ..................

    ti_sysbios_family_arm_a8_intcps_Hwi_dispatchIRQ__I:

    ................
        .if __TI_VFP_SUPPORT__ | __TI_NEON_SUPPORT__
                vstmdb    {D0-D7}, r13!    ; save vfp scratch regs
        .endif
        mov    r4, sp        ; save sp
        bic    sp, sp, #0x7    ; align stack to 8 bytes
            bl      ti_sysbios_family_arm_a8_intcps_Hwi_dispatchIRQC__I
        mov    sp, r4        ; restore sp
        .if __TI_VFP_SUPPORT__ | __TI_NEON_SUPPORT__
              vldmia    {D0-D7}, r13!    ; restore vfp scratch regs
        .endif
    ..................

    If I understand rightly method ti_sysbios_family_arm_a8_intcps_Hwi_dispatchIRQ__I is called as global interrupt handler for IRQ exceptions. It stores D0-D7 registers and after calls ti_sysbios_family_arm_a8_intcps_Hwi_dispatchIRQC__I. I understand why only D0-D7 are stored, because D8-D15 will be restored by C-function if they are used. But what about FPSCR (float-point status and control register) ?

    file ccs5\bios\packages\ti\sysbios\family\arm\a8\intcps\Hwi.c :

    ..................

    Void Hwi_dispatchIRQC(Hwi_Irp irp)

    {

    ..................

        /* call user's ISR func */
        (hwi->fxn)(hwi->arg);

    ..................

    }

    Name Hwi_dispatchIRQC is defined as ti_sysbios_family_arm_a8_intcps_Hwi_dispatchIRQC__I, so Hwi_dispatchIRQC and ti_sysbios_family_arm_a8_intcps_Hwi_dispatchIRQC__I are the same method.

    After calling Hwi_dispatchIRQC some system processing is done, then user defined interrupt handler is called,  but  FPSCR is not stored !!!! We can do some VFP instructions and corrupt  FPSCR register inside user defined interrupt handler, so we can have VFP problems after restore context of interrupted user task.

    I see listings of our code and do not  understand how C-function (user defined interrupt handler) will restore FPSCR?

    Is it right or I don't understand something ? How FPSCR will be restored? May be special compiler key or pragma must be used ?

    BR

    Sergey

  • Sergey,

    I'm looking into this more deeply. I'll get back with you soon.

    We have regression tests that simultaneously perform floating point operations in Hwi, Swi, and Task threads while sweeping the Hwi through all of the Swi and Task code so I'm surprised we didn't catch this problem.

    Perhaps we need to do a specific kind of floating point operation to trigger the problem?

    Alan

  • This is definitely a bug in SYS/BIOS.

    I've filed bug number SDOCM00098740 to track the issue.

    I'll provide you a workaround ASAP.

    Are you using the BIOS.libType = BIOS.LibType_Custom option in your config file?

    This will allow you to make a change in the interrupt dispatcher assembly code and rebuild your application using the changed code.

    Alan

  • We've done a quick test of a code change that seems to do the trick.

    In your SYS/BIOS installation area, edit this file:

       packages/ti/sysbios/family/arm/a8/intcps/Hwi_asm.s470

    find these lines:

        .if __TI_VFP_SUPPORT__ | __TI_NEON_SUPPORT__
            vstmdb  {D0-D7}, r13!   ; save vfp scratch regs
        .endif
            mov     r4, sp          ; save sp
            bic     sp, sp, #0x7    ; align stack to 8 bytes
            bl      ti_sysbios_family_arm_a8_intcps_Hwi_dispatchIRQC__I
            mov     sp, r4          ; restore sp
        .if __TI_VFP_SUPPORT__ | __TI_NEON_SUPPORT__
            vldmia  {D0-D7}, r13!   ; restore vfp scratch regs
        .endif

    And change them to this:

        .if __TI_VFP_SUPPORT__ | __TI_NEON_SUPPORT__
            vstmdb  {D0-D7}, r13!   ; save vfp scratch regs
            vmrs    r1, FPSCR
            push    {r1}
        .endif
            mov     r4, sp          ; save sp
            bic     sp, sp, #0x7    ; align stack to 8 bytes
            bl      ti_sysbios_family_arm_a8_intcps_Hwi_dispatchIRQC__I
            mov     sp, r4          ; restore sp
        .if __TI_VFP_SUPPORT__ | __TI_NEON_SUPPORT__
            pop     {r1}
            vmsr    FPSCR, r1
            vldmia  {D0-D7}, r13!   ; restore vfp scratch regs
        .endif

    Then clean and rebuild your application.

    The new code will take effect if you have this in your config script:

        BIOS.libType = BIOS.LibType_Custom;

    Please report back with the results of your testing.

    Alan

  • Thanks for answer.

    System does not hang up with your fix AND adding "BIOS.libType = BIOS.LibType_Custom;" to cfg file (without adding system hangs up on start).

    We need some time (7-8 hours) for check float-point problems with our fix.

    I done my fix yesterday and we can say that it resolves our VFP problem WITHOUT adding "BIOS.libType = BIOS.LibType_Custom;" to cfg file

        .if __TI_VFP_SUPPORT__ | __TI_NEON_SUPPORT__
        FMRX    r2, fpexc
        FMRX    r3, fpscr
        STMDB    sp!, {r2-r3}
        vstmdb    {D0-D7}, r13!    ; save vfp scratch regs
        .endif
        mov    r4, sp        ; save sp
        bic    sp, sp, #0x7    ; align stack to 8 bytes
            bl      ti_sysbios_family_arm_a8_intcps_Hwi_dispatchIRQC__I
        mov    sp, r4        ; restore sp
        .if __TI_VFP_SUPPORT__ | __TI_NEON_SUPPORT__
        vldmia    {D0-D7}, r13!    ; restore vfp scratch regs
        LDMIA    sp!, {r0-r1}
        FMXR    fpexc, r0
        FMXR    fpscr, r1
        .endif

    I understand that FPEXC register is not necessary for storing but I think that stack pointer should be rounded to 8.

    Sergey

  • Your fix resolves our VFP problems (with adding "BIOS.libType = BIOS.LibType_Custom;" to cfg file).

    Sergey

  • Sergey,

    While saving and restoring the FPEXC register doesn't seem to be required for your particular application, I think it is prudent to do so. We will add this to our implementation.

    The ISR stack is already being forced to 8 byte alignment by this instruction:

            bic     sp, sp, #0x7    ; align stack to 8 bytes

    which is executed prior to calling the "ti_sysbios_family_arm_a8_intcps_Hwi_dispatchIRQC__I" C function.

    We are planning to release a 6.34.05 version of SYS/BIOS with this fix in place in a few weeks.

    Are you able to live with this workaround until then?

    Alan

  • Alan,

    Thanks. We shall wait  valid SYSBIOS version and use your current change.

    Sergey

  • Alan,

    Can you tell me the specific kind of floating point operation that how to tigger the problem?

    Aojiang