[U-Boot] weak functions not being over-ridden (location dependent)
Remy Bohmer
linux at bohmer.net
Wed Nov 26 14:01:50 CET 2008
Hello Graeme,
> I have a very strange problem - I am trying to define a weak function, but
> whether or not the function is overridden depends on where I put the
> overriding function. Case in point:
You are not the only one, I have seen this also with the LED interface
in U-boot.
My workaround was simple: remove the weak functions... I never took
the time to figure it out exactly, so I am curious if anyone knows the
real answer.
Remy
2008/11/26 Graeme Russ <graeme.russ at gmail.com>:
> Hi All,
>
> I have a very strange problem - I am trying to define a weak function, but
> whether or not the function is overridden depends on where I put the
> overriding function. Case in point:
>
> common.h defines reset_cpu() thusly:
>
> void reset_cpu (ulong addr);
>
> in cpu/i386/reset.c I have:
>
> void __reset_cpu(ulong addr)
> {
> printf("Resetting using i386 Triple Fault\n");
> set_vector(13, generate_gpf); /* general protection fault handler */
> set_vector(8, generate_gpf); /* double fault handler */
> generate_gpf(); /* start the show */
> }
> void reset_cpu(ulong addr) __attribute__((weak, alias("__reset_cpu")));
>
> Now, if I implement reset_cpu () in cpu/i386/sc520/reset.c
>
> void reset_cpu(ulong addr)
> {
> printf("Resetting using SC520 MMCR\n");
> /* Write a '1' to the SYS_RST of the RESCFG MMCR */
> write_mmcr_word(SC520_RESCFG, 0x0001);
>
> /* NOTREACHED */
> }
>
> and issue a reset from the prompt, it uses the Triple Fault
>
> If I move reset_cpu () in board/eNET/eNET.c, it uses the MMCR
>
> Now, if I remove __reset_cpu () (and the weak definition) and leave the
> reset_cpu in cpu/i386/sc520/reset.c, it uses the MMCR to reset the CPU. So
> /cpu/i386/sc520/reset.c is being compiled and the library is being linked in.
>
> If I go back to __reset_cpu(), weak function and reset_cpu () in
> cpu/i386/sc520, u-boot.map reveals:
>
> .text 0x000000003804ecd4 0x6d cpu/i386/libi386.a(reset.o)
> 0x000000003804ecdb __reset_cpu
> 0x000000003804ecd4 generate_gpf
> 0x000000003804ed10 do_reset
> 0x000000003804ecdb reset_cpu
>
> and no other references to reset_cpu
>
> Move reset_cpu () to board/eNET/eNET.c and I get
>
> .text 0x00000000380499a0 0x312 board/eNET/libeNET.a(eNET.o)
> 0x00000000380499f8 dram_init
> 0x00000000380499e4 last_stage_init
> 0x0000000038049a07 init_sc520_enet
> 0x0000000038049a46 reset_cpu
> 0x0000000038049a69 board_init
> 0x00000000380499bb board_flash_get_legacy
> .
> .
> .
> .text 0x000000003804ecf8 0x6d cpu/i386/libi386.a(reset.o)
> 0x000000003804ecff __reset_cpu
> 0x000000003804ecf8 generate_gpf
> 0x000000003804ed34 do_reset
>
>
> If I do not define the weak function and implement reset_cpu () in BOTH
> cpu/i386/reset.c and cpu/i386/sc520/reset.c I get no complaints from the
> linker, and the reset is performed via triple-fault. u-boot.map reveals:
>
> .text 0x000000003804ecd4 0x6d cpu/i386/libi386.a(reset.o)
> 0x000000003804ecd4 generate_gpf
> 0x000000003804ed10 do_reset
> 0x000000003804ecdb reset_cpu
>
> Why is the linker silently discarding an obvious symbol conflict?
>
> Any ideas?
>
> Thanks,
>
> Graeme
>
>
>
>
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>
More information about the U-Boot
mailing list