From mboxrd@z Thu Jan 1 00:00:00 1970 From: Heiko Schocher Date: Fri, 01 Feb 2013 10:53:50 +0100 Subject: [U-Boot] Problem with ll_entry_* before relocation Message-ID: <510B90AE.4040409@denx.de> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de 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=83ffd31c590dd5aedfef0c195b1ffc406e6d0e37#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 [hs at 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 : 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 * 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 b4: ebfffffe bl 0 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 . ... at -......... c001222c : ebffe57c e3a00000 e8bd8008 00000000 |............... ^ wrong should be c003bd08 c001223c : c003674c e92d4008 ebffc80c e3a00000 Lg... at -......... c001224c : e8bd4008 eafffff1 e92d40f8 e598307c . at .......@-.|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 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 . ... at -......... a7f8c22c : ebffe57c e3a00000 e8bd8008 a7fb5d08 |............].. ^ a7f8c23c : a7fb074c e92d4008 ebffc80c e3a00000 L.... at -......... a7f8c24c : e8bd4008 eafffff1 e92d40f8 e598307c . at .......@-.|0.. a7f8c25c : e3a0601c e0030396 e59f5028 e1a07000 .`......(P...p.. [...] Core#0> a4: e59f2014 ldr r2, [pc, #20] ; c0 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 ac: e59f4024 ldr r4, [pc, #36] ; d8 b0: e5921000 ldr r1, [r2] b4: e1a00004 mov r0, r4 b8: ebfffffe bl 0 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 c0: e1a00004 mov r0, r4 c4: e5921000 ldr r1, [r2] c8: ebfffffe bl 0 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 . at -.$ ..$@...... c001222c : e1a00004 ebffe57b e59f2018 e1a00004 ....{.... ...... c001223c : e5921000 ebffe577 e3a00000 e8bd8010 ....w........... c001224c : 00000000 c0036764 c003bd20 e92d4008 ....dg.. .... at -. ^ ^ ^ 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 -- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany