[U-Boot] Problem with ll_entry_* before relocation

Hello,
I am currently trying to get rid of some externs in the new i2c multibus approach, specially this externs:
http://git.denx.de/?p=u-boot/u-boot-i2c.git;a=blob;f=drivers/i2c/i2c_core.c;...
I tried to use the ll_entry_* defines see: include/linker_lists.h so the compiler will collect all i2c adapter(s), and no need to declare in the config file a list of used adapters. This approach works fine for using i2c after relocation, but did not work before, which is a must have for i2c ... Therefore I describe (Sorry, for the long EMail) here, whats I see on an arm926ejs based board, using eldk 5.2 with
[hs@pollux u-boot]$ arm-linux-gnueabi-gcc --version arm-linux-gnueabi-gcc (GCC) 4.6.4 20120303 (prerelease)
and hope someone has an idea or at least an explanation, why it is not working ...
First the defines I used for include/i2c.h (here shortened the defines just using one unsigned long var, not the "struct i2c_adap"):
#define U_BOOT_I2C_MKENT_COMPLETE_TRY(_hwadapnr) \ _hwadapnr;
#define U_BOOT_I2C_ADAP_COMPLETE_TRY(_name, _hwadapnr) \ ll_entry_declare(unsigned long, _name, try, try) = \ U_BOOT_I2C_MKENT_COMPLETE_TRY( _hwadapnr);
which i can use in drivers/i2c/soft_i2c.c as
U_BOOT_I2C_ADAP_COMPLETE_TRY(soft0, 0) U_BOOT_I2C_ADAP_COMPLETE_TRY(soft1, 1)
Following printf in for example i2c_set_bus_num():
int i2c_set_bus_num(unsigned int bus) { extern unsigned long _u_boot_list_try__start;
printf("%08lx %08lx\n", (unsigned long)_u_boot_list_try__start, (unsigned long)&_u_boot_list_try__start);
results in an output: before relocation e59ff00c 00000000 ^ wrong address (Explanation see below) after relocation: 00000000 a7fb5d08 ^ correct address
so, "&_u_boot_list_try__start" is only valid after relocation!
Debugging deeper in it ... Objdump:
000000a4 <i2c_set_bus_num>: extern unsigned long _u_boot_list_try__start;
printf("%08lx %08lx\n", (unsigned long)_u_boot_list_try__start, (unsigned long)&_u_boot_list_try__start); a4: e59f2014 ldr r2, [pc, #20] ; c0 <i2c_set_bus_num+0x1c> * bus - bus index, zero based * * Returns: 0 on success, not 0 on failure */ int i2c_set_bus_num(unsigned int bus) { a8: e92d4008 push {r3, lr} extern unsigned long _u_boot_list_try__start;
printf("%08lx %08lx\n", (unsigned long)_u_boot_list_try__start, (unsigned long)&_u_boot_list_try__start); ac: e5921000 ldr r1, [r2] b0: e59f000c ldr r0, [pc, #12] ; c4 <i2c_set_bus_num+0x20> b4: ebfffffe bl 0 <printf> i2c_mux_set_all();
breakpoint in i2c_set_bus_num
System.map: c001221c T i2c_set_bus_num
Core#0>bi 0xc001221c Breakpoint identification is 0 Core#0>g - TARGET: core #0 has entered debug mode Core#0>i Core number : 0 Core state : debug mode (ARM) Debug entry cause : Breakpoint Current PC : 0xc001221c Current CPSR : 0x600000d3 (Supervisor) Core#0>r GPR00: 00000000 c0030aeb 00000060 c001f028 GPR04: c0038ea4 fffffffc a7fb46c4 c0000b70 GPR08: a0000f00 00000001 c0000164 00000001 GPR12: 00000000 a0000ee0 c0000b80 c001221c PC : c001221c CPSR: 600000d3 Core#0>md 0xc001221c c001221c : e59f2014 e92d4008 e5921000 e59f000c . ...@-......... c001222c : ebffe57c e3a00000 e8bd8008 00000000 |............... ^ wrong should be c003bd08 c001223c : c003674c e92d4008 ebffc80c e3a00000 Lg...@-......... c001224c : e8bd4008 eafffff1 e92d40f8 e598307c .@.......@-.|0.. [...] Core#0>r GPR00: 00000000 c0030aeb 00000060 c001f028 GPR04: c0038ea4 fffffffc a7fb46c4 c0000b70 GPR08: a0000f00 00000001 c0000164 00000001 GPR12: 00000000 a0000ee0 c0000b80 c001221c PC : c001221c CPSR: 600000d3
from objdump pc @ 0xc001221c: a4: e59f2014 ldr r2, [pc, #20] ; c0 <i2c_set_bus_num+0x1c>
load r2 with c001221c + 1c (0xc0012238) = 0 ....
thats wrong, as _u_boot_list_try__start is c003bd08 ...
System.map: c003bd08 D _u_boot_list_i2c__end c003bd08 D _u_boot_list_try__start c003bd08 D _u_boot_list_try_soft0 c003bd0c D _u_boot_list_try_soft1 c003bd10 A __image_copy_end [...]
After relocation:
relo addr from i2c_set_bus_num:
c001221c + 0xE7F7A000 = a7f8c21c
Core#0>bi 0xa7f8c21c Breakpoint identification is 0 Core#0>g - TARGET: core #0 has entered debug mode Core#0>i Core number : 0 Core state : debug mode (ARM) Debug entry cause : Breakpoint Current PC : 0xa7f8c21c Current CPSR : 0x600000d3 (Supervisor) Core#0>r GPR00: 00000000 a7ec8e50 00000060 00000083 GPR04: 00000000 a7fb5940 00000000 a7ec9ec8 GPR08: a7ec9f60 00000000 00000003 a7ec92d1 GPR12: 00000034 a7ec9280 a7f7dcf8 a7f8c21c PC : a7f8c21c CPSR: 600000d3 Core#0>
Core#0>md 0xa7f8c21c a7f8c21c : e59f2014 e92d4008 e5921000 e59f000c . ...@-......... a7f8c22c : ebffe57c e3a00000 e8bd8008 a7fb5d08 |............].. ^ a7f8c23c : a7fb074c e92d4008 ebffc80c e3a00000 L....@-......... a7f8c24c : e8bd4008 eafffff1 e92d40f8 e598307c .@.......@-.|0.. a7f8c25c : e3a0601c e0030396 e59f5028 e1a07000 .`......(P...p.. [...] Core#0>
a4: e59f2014 ldr r2, [pc, #20] ; c0 <i2c_set_bus_num+0x1c>
load r2 with pc:0xa7f8c21c + 1c = 0xa7f8c238 = a7fb5d08 .... thats the correct value ... because:
c003bd08 + 0xE7F7A000 = 1a7fb5d08 relocated addr from _u_boot_list_try__start
with: c003bd08 D _u_boot_list_try__start c003bd08 D _u_boot_list_try_soft0 c003bd0c D _u_boot_list_try_soft1 c003bd10 A __image_copy_end
So, the question is, why is in the u-boot image the wrong value 0 for _u_boot_list_try__start?
Additionally, if I print "_u_boot_list_try_soft0" with
printf("%08lx %08lx\n", (unsigned long)_u_boot_list_try_soft0, (unsigned long)&_u_boot_list_try_soft0);
It has the correct value before and after relocation ... !!
objdump: printf("%08lx %08lx\n", (unsigned long)_u_boot_list_try__start, (unsigned long)&_u_boot_list_try__start); a8: e59f2024 ldr r2, [pc, #36] ; d4 <i2c_set_bus_num+0x30> ac: e59f4024 ldr r4, [pc, #36] ; d8 <i2c_set_bus_num+0x34> b0: e5921000 ldr r1, [r2] b4: e1a00004 mov r0, r4 b8: ebfffffe bl 0 <printf> printf("%08lx %08lx\n", (unsigned long)_u_boot_list_try_soft0, (unsigned long)&_u_boot_list_try_soft0); bc: e59f2018 ldr r2, [pc, #24] ; dc <i2c_set_bus_num+0x38> c0: e1a00004 mov r0, r4 c4: e5921000 ldr r1, [r2] c8: ebfffffe bl 0 <printf> i2c_mux_set_all();
_u_boot_list_try_soft0 in line bc: load to r2 from c001221c + 0x38 = 0xc0012254
and c0012254 contain c003bd20, which is the correct value for _u_boot_list_try_soft0 !!
System.map for this case: c003bd20 D _u_boot_list_try__start c003bd20 D _u_boot_list_try_soft0 c003bd24 D _u_boot_list_try_soft1 c003bd28 A __image_copy_end
Core#0>r GPR00: 00000000 c0030b03 00000060 c001f040 GPR04: c0038ebc fffffffc a7fb46dc c0000b70 GPR08: a0000f00 00000001 c0000164 00000001 GPR12: 00000000 a0000ee0 c0000b80 c001221c PC : c001221c CPSR: 600000d3 Core#0>md 0xc001221c c001221c : e92d4010 e59f2024 e59f4024 e5921000 .@-.$ ..$@...... c001222c : e1a00004 ebffe57b e59f2018 e1a00004 ....{.... ...... c001223c : e5921000 ebffe577 e3a00000 e8bd8010 ....w........... c001224c : 00000000 c0036764 c003bd20 e92d4008 ....dg.. ....@-. ^ ^ ^ correct value for _u_boot_list_try_soft0 again, wrong value for _u_boot_list_try__start
So the question is, whats the difference between _u_boot_list_try_soft0 and _u_boot_list_try__start ... any ideas?
Thanks in advance.
bye, Heiko

Dear Heiko Schocher,
Hello,
I am currently trying to get rid of some externs in the new i2c multibus approach, specially this externs:
http://git.denx.de/?p=u-boot/u-boot-i2c.git;a=blob;f=drivers/i2c/i2c_core.c ;h=2a559c9d81a945f219eab49d11e70c0ac4a6d6a4;hb=83ffd31c590dd5aedfef0c195b1f fc406e6d0e37#l31
I tried to use the ll_entry_* defines see: include/linker_lists.h so the compiler will collect all i2c adapter(s), and no need to declare in the config file a list of used adapters. This approach works fine for using i2c after relocation, but did not work before, which is a must have for i2c ... Therefore I describe (Sorry, for the long EMail) here, whats I see on an arm926ejs based board, using eldk 5.2 with
Albert has a patch for that, CCed.
Best regards, Marek Vasut

Hi Marek,
On Fri, 1 Feb 2013 10:00:55 +0100, Marek Vasut marex@denx.de wrote:
Dear Heiko Schocher,
Hello,
I am currently trying to get rid of some externs in the new i2c multibus approach, specially this externs:
http://git.denx.de/?p=u-boot/u-boot-i2c.git;a=blob;f=drivers/i2c/i2c_core.c ;h=2a559c9d81a945f219eab49d11e70c0ac4a6d6a4;hb=83ffd31c590dd5aedfef0c195b1f fc406e6d0e37#l31
I tried to use the ll_entry_* defines see: include/linker_lists.h so the compiler will collect all i2c adapter(s), and no need to declare in the config file a list of used adapters. This approach works fine for using i2c after relocation, but did not work before, which is a must have for i2c ... Therefore I describe (Sorry, for the long EMail) here, whats I see on an arm926ejs based board, using eldk 5.2 with
Albert has a patch for that, CCed.
II will send out the patch this afternoon; before 14:00 GMT+1 if I'm lucky, around 17:00 GMT+1 if not.
Best regards, Marek Vasut
Amicalement,

On Sat, 2 Feb 2013 12:05:02 +0100, Albert ARIBAUD albert.u.boot@aribaud.net wrote:
Hi Marek,
On Fri, 1 Feb 2013 10:00:55 +0100, Marek Vasut marex@denx.de wrote:
Dear Heiko Schocher,
Hello,
I am currently trying to get rid of some externs in the new i2c multibus approach, specially this externs:
http://git.denx.de/?p=u-boot/u-boot-i2c.git;a=blob;f=drivers/i2c/i2c_core.c ;h=2a559c9d81a945f219eab49d11e70c0ac4a6d6a4;hb=83ffd31c590dd5aedfef0c195b1f fc406e6d0e37#l31
I tried to use the ll_entry_* defines see: include/linker_lists.h so the compiler will collect all i2c adapter(s), and no need to declare in the config file a list of used adapters. This approach works fine for using i2c after relocation, but did not work before, which is a must have for i2c ... Therefore I describe (Sorry, for the long EMail) here, whats I see on an arm926ejs based board, using eldk 5.2 with
Albert has a patch for that, CCed.
II will send out the patch this afternoon; before 14:00 GMT+1 if I'm lucky, around 17:00 GMT+1 if not.
Rebased my patch on current u-boot/master required some non-trivial code changes, so I am currently running regression on ARM, and will run it also at least on PPC; then I'll submit the patch, most certainly near the end of the afternoon. Currently it is a one-patch series as I don't think I can actually split it much without badly preventing bisection, but let's just start with that and go forward with testing and reviewing.
Amicalement,
participants (3)
-
Albert ARIBAUD
-
Heiko Schocher
-
Marek Vasut