[U-Boot] [PATCH 2/2] [NEXT] arm926ejs: reduce code size with -msingle-pic-base

Ben Gardiner
2010-09-23T21:13:05Z

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.