Technical discussions about the TI C54x DSPs (including the c5401, c5402, c5402a, c5404, c5407, c5409, c5409a, c5410, c5410a, c5416, c5420, c5421, c5441, c549, c5470 and c5471).
Hey all, I'm getting stuck somewhere in the GBL_init module of DSP/BIOS. I know I get past the part where it calls the USERINITFXN because I am able to turn off leds up until my function calls RET (it's an assembly function). However, when I put code in the BIOS_init function after it calls GBL_init, my code never gets called. Here is the code from GBL_init including where it calls my USERINITFXN function (from gbl.h54): .if (GBL_USERINIT != 0) ; USERINITFXN below is defined in GBL_config ssbx cpl ; CPL = 1 for C convention .if __far_mode fcall :USERINITFXN: ; (*fxn)() ; the 'fcall' instruction pushes a 2-word ; return address on the stack; the SP will ; be even on C function entry .else call :USERINITFXN: ; (*fxn)() ; the 'call' instruction pushes a one word ; return address on the stack; the SP will ; be odd on C function entry .endif rsbx cpl ; make CPL = 0 for BIOS environment .endif ; ; Calling TRC_init from here until there is at trc.cdb file. ; TRC_init ; ; fill memory using triples (nwords, addr, value) from ; gblinit table. ; ld #0, b .if __far_mode ldx #gblinit, 16, a ; a = far gblinit address or #gblinit, a, a .else rsbx sxm ; so 'ld #K,a' will not sign extend nop ld #gblinit, a ; a = gblinit address .endif loop0?: reada *(bl) ; b = nwords bc done?, beq add #1, a nop reada *(ar2) ; ar2 = address add #1, a nop reada *(ar3) ; ar3 = value add #1, a nop loop1?: mvkd #ar3, *ar2+ sub #1, b bc loop1?, bgt b loop0? done?: ld #1, b .if __far_mode ldx #GBL_initdone, 16, a or #GBL_initdone, a, a .else rsbx sxm nop ld #GBL_initdone, a .endif writa *(bl) .endm Any ideas on what could be snagging here? Thanks, Jess Howe
Jess-
> I'm getting stuck somewhere in the GBL_init module of DSP/BIOS. I know I get past the part
where it calls the USERINITFXN because I am able to turn off leds up until my function calls
RET (it's an assembly function). However, when I put code in the BIOS_init function after it
calls GBL_init, my code never gets called. Here is the code from GBL_init including where it
calls my USERINITFXN function (from gbl.h54):
Where is the RET statement that you mention? Don't you need something like:
.if __far_mode
fret
.else
ret
.endif
Also, I hope you're right about DSP/BIOS using CPL set to 1. If it were me, I'd
*save* the state of the CPL bit before changing to C convention, then restore it to
whatever DSP/BIOS wanted it to be.
-Jeff
> .if (GBL_USERINIT != 0)
> ; USERINITFXN below is defined in GBL_config
> ssbx cpl ; CPL = 1 for C convention
> .if __far_mode
> fcall :USERINITFXN: ; (*fxn)()
> ; the 'fcall' instruction pushes a 2-word
> ; return address on the stack; the SP will
> ; be even on C function entry
> .else
> call :USERINITFXN: ; (*fxn)()
> ; the 'call' instruction pushes a one word
> ; return address on the stack; the SP will
> ; be odd on C function entry
> .endif
> rsbx cpl ; make CPL = 0 for BIOS environment
> .endif
>
> ;
> ; Calling TRC_init from here until there is at trc.cdb file.
> ;
> TRC_init
>
> ;
> ; fill memory using triples (nwords, addr, value) from
> ; gblinit table.
> ;
>
> ld #0, b
> .if __far_mode
> ldx #gblinit, 16, a ; a = far gblinit address
> or #gblinit, a, a
> .else
> rsbx sxm ; so 'ld #K,a' will not sign extend
> nop
> ld #gblinit, a ; a = gblinit address
> .endif
>
> loop0?:
> reada *(bl) ; b = nwords
> bc done?, beq
> add #1, a
> nop
> reada *(ar2) ; ar2 = address
> add #1, a
> nop
> reada *(ar3) ; ar3 = value
> add #1, a
> nop
> loop1?:
> mvkd #ar3, *ar2+
> sub #1, b
> bc loop1?, bgt
>
> b loop0?
> done?:
>
> ld #1, b
> .if __far_mode
> ldx #GBL_initdone, 16, a
> or #GBL_initdone, a, a
> .else
> rsbx sxm
> nop
> ld #GBL_initdone, a
> .endif
> writa *(bl)
>
> .endm
>
> Any ideas on what could be snagging here?
>
> Thanks,
> Jess Howe