paoloteti / ti-hercules-bsp

Bare Metal Board Support Package for Texas Instruments Cortex-R4F/R5F TMS570
Other
25 stars 4 forks source link

_cpustack stuck in infinite loop #5

Closed gregokent closed 6 years ago

gregokent commented 6 years ago

With the recent change in moving the stack initialization to real asm in a separate file, execution gets stuck as the function calls return up the stack. Disassembly of tms570::syscore::init_stack_pointers():

000059e8 <_ZN6tms5707syscore19init_stack_pointers17h2772bef3066c54d3E>:
    59e8:       eb001fa1        bl      d874 <_cpu_stack>
    59ec:       e12fff1e        bx      lr

Disassembly of _cpu_stack:

0000d874 <_cpu_stack>:
    d874:       f1020011        cps     #17
    d878:       e59fd030        ldr     sp, [pc, #48]   ; d8b0 <fiq_sp>
    d87c:       f1020012        cps     #18
    d880:       e59fd02c        ldr     sp, [pc, #44]   ; d8b4 <irq_sp>
    d884:       f1020013        cps     #19
    d888:       e59fd01c        ldr     sp, [pc, #28]   ; d8ac <svc_sp>
    d88c:       f1020017        cps     #23
    d890:       e59fd020        ldr     sp, [pc, #32]   ; d8b8 <abort_sp>
    d894:       f102001b        cps     #27
    d898:       e59fd01c        ldr     sp, [pc, #28]   ; d8bc <undef_sp>
    d89c:       f102001f        cps     #31
    d8a0:       e59fd000        ldr     sp, [pc]        ; d8a8 <user_sp>
    d8a4:       e12fff1e        bx      lr

When 59e8 executes, the value of the LR gets set to 59ec. When d8a4 executes it branches back to 59ec, which is a branch to link register, which still has the value 59ec, so it branches to 59ec, so on and so forth.

I changed tms570::syscore::init_stack_pointers() to use the asm again, exactly as it is in cpustack.s with the linker defined addresses and it works just fine.

I am using a TMS570LC43xx.

paoloteti commented 6 years ago

Yes this call is not optimized enough and generate a double bx lr that is wrong before stack initialization.

Could you try to inline init_stack_pointers() in this way:

#[naked]
#[inline(always)]
pub unsafe fn init_stack_pointers() {
    _cpu_stack()
}

otherwise I can just rename cpu_stack()or drop init_stack_pointers() to avoid the inner call.