
On Thu, Sep 23, 2010 at 1:04 PM, Albert ARIBAUD albert.aribaud@free.fr wrote:
Note that if I'm not mistaken, your build uses r9 as the pic base, not 10 -- this is a possibility, and my patches are written so as to allow either register use.
I don't know for sure so I did a little poking around:
c1080688 <board_init_f>: c1080688: e59fa118 ldr sl, [pc, #280] ; c10807a8 <board_init_f+0x120> c108068c: e59f8118 ldr r8, [pc, #280] ; c10807ac <board_init_f+0x124>
(gdb) info registers [...] r9 0xc1098564 3238626660 r10 0xc1098564 3238626660 [...] pc 0xc1080688 0xc1080688 <board_init_f> [...] (gdb) ni 514 gd = (gd_t *) (CONFIG_SYS_INIT_SP_ADDR); (gdb) info registers [...] r9 0xc1098564 3238626660 r10 0x17ecc 97996 [...] pc 0xc108068c 0xc108068c <board_init_f+4> [...] (gdb) p /x $sl $1 = 0x17ecc (gdb) p /x $r10 $2 = 0x17ecc (gdb) p /x $r9 $3 = 0xc1098564 (gdb) p *0xc10807a8 $4 = 97996 (gdb) p /x *0xc10807a8 $5 = 0x17ecc
I think that confirms that sl == r10 .
Now, we need to find out why board_init_f fails to go through the init sequence and print out at least the banner and some diagnostics.
Please build with my two patches alone (i.e., put -msingle-pic-base back in place, which will remove the recomputation of the pic base in every function), and run it until board_init_f() calls its first init function through (*init_fnc_ptr)(). This call should be materialized by a 'blx <reg>' instruction; please report the value of <reg> at that point as well as the addresses of arch_cpu_init, board_early_init_f, and timer_init; <reg> should be one of these depending on the board config.
<reg> is r10/sl :
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { if ((*init_fnc_ptr)() != 0) { c1080690: e12fff3a blx sl c1080694: e2844004 add r4, r4, #4 ; 0x4 c1080698: e3500000 cmp r0, #0 ; 0x0 c108069c: 0a000000 beq c10806a4 <board_init_f+0x58> hang (); c10806a0: ebffff76 bl c1080480 <hang>
Here's the addresses you requested for the very first time it hit that function call through (*init_fnc_prt)(): (gdb) p /x $pc $4 = 0xc1080690 (gdb) p /x $sl $5 = 0xc1091e6c (gdb) p /x $r10 $6 = 0xc1091e6c
There is no arch_cpu_init or board_early_init_f; timer_init is at 0xc1091e6c. So it is timer_init which is being called above.
The call to timer_init completes successfully; the next function pointer dereferenced and called is 0xc1087e04 == env_init. That call completes successfully. The next is 0xc10804f8 == init_baudrate; it completes successfully. The next call is 0xc108119c == serial_init; it completes successfully. The next is 0xc1086550 == console_init_f; it completes successfully. The next is 0xc10804d0 == display_banner; it completes successfully. They all did. Execution reaches the call to relocate_code and enters; the last instruction I am able to single-step is the 'ldr r10, _got_base' in the following lines from your patch:
/*
* Set pic base register to the current GOT position. Since we are
* now running from RAM, we need to offset it from its link-time to
* its run-time position.
*/
ldr r9, relocate_got_base_r
sub r9, pc, r9
ldr r10, _got_base
+relocate_got_base_r:
add r10, r9, r10
mov r9, r10
Thanks again for your help in testing my patches!
My pleasure. I hope we can get them working on the da850evm.
Best Regards, Ben Gardiner
--- Nanometrics Inc. http://www.nanometrics.ca