
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@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@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot