[U-Boot] MIPS cpu has problem detecting CFI
Andrew Dyer
amdyer at gmail.com
Sat Oct 10 22:47:36 CEST 2009
On Sat, Oct 10, 2009 at 12:27 PM, <myuboot at fastmail.fm> wrote:
> On Fri, 09 Oct 2009 12:16 -0500, "Andrew Dyer" <amdyer at gmail.com> wrote:
>> On Fri, Oct 9, 2009 at 11:21 AM, <myuboot at fastmail.fm> wrote:
>> > I think I found a problem in cpu/mips/start.S.
>> >
>> > gp register is used to point to the SDRAM. But after gp is adjusted to
>> > proper location, a C function flush_cache is called. But this function
>> > actually changes gp register before gp is used to jump to SDRAM. That
>> > makes the u-boot run from flash and fails to detect CFI.
>> >
>> > Here is the assembler code for flush_cache.c
>> > (gdb) disassem 0xb0000798
>> > Dump of assembler code for function flush_cache:
>> > 0xb000078c <flush_cache+0>: lui gp,0x3
>> > 0xb0000790 <flush_cache+4>: addiu gp,gp,-32300
>> > 0xb0000794 <flush_cache+8>: addu gp,gp,t9
>> >
>> > And here is how I fixed the issue -
>> >
>> >
>> > diff --git a/u-boot-2009.08/cpu/mips/start.S
>> > b/u-boot-2009.08/cpu/mips/start.S
>> > index 57db589..0e8f8ed 100644
>> > --- a/u-boot-2009.08/cpu/mips/start.S
>> > +++ b/u-boot-2009.08/cpu/mips/start.S
>> > @@ -321,6 +321,7 @@ relocate_code:
>> > move t6, gp
>> > sub gp, CONFIG_SYS_MONITOR_BASE
>> > add gp, a2 /* gp now adjusted */
>> > + move t8, gp
>> > sub s1, gp, t6 /* s1 <-- relocation offset */
>> >
>> > /*
>> > @@ -358,6 +359,7 @@ relocate_code:
>> >
>> > /* Jump to where we've relocated ourselves.
>> > */
>> > + move gp, t8
>> > addi t0, s2, in_ram - _start
>> > jr t0
>> > nop
>>
>> Something seems weird here - IIRC, $gp is supposed to be saved in the
>> stack frame during the function prologue and restored from the frame
>> on exit. Also I think relying on $t8 is risky, as I don't believe it
>> is guaranteed by the ABI to be preserved across function calls.
>>
>> What compiler are you using? Can you post the whole flush_cache()
>> disassembly?
>
> You may be right. The c function should get the input arguments through
> stack. I just use the same toolchain(with -S option) to generate the
> assembler code and the assembler code does not show the modification on
> the gp register. I am attaching the whole assembler code file here too.
> But the assembler code I sent in my previous mail did show the gp
> pointer is changed. In that email, I got that assembler using gdb
> through a BDI debugger. I don't have BDI with me today so I cann't give
> you the whole assembler code using BDI.
>
> Could it be the gcc toolchain generates the wrong code when it is
> creating object file, but generates correct assembler code? Or the BDI
> is changing the assembler code at run time such that I see the wrong
> assembler code? But if that is the case, I don't know how to explain
> with my workaround/fix the board did come up even without bdi and it
> seems to work every time. I am so confused now. Any suggestion on
> anything I can try?
1) please don't top post, put replies on the bottom, I fixed this in this post.
2) reply to the list, there are a lot of smart people (better versed
in toolchains than I) who read it.
I've cc'd the list on this one.
3) the assembler looks fine, but it doesn't have the function prologue
that the gdb dump shows. I doubt the bdi is modifying the asm. I
/think/ the linker might be the part that inserts that or maybe the
compile after it generates the asm. Try looking at the output of
'${CROSS_COMPILE}objdump --source cpu.o' and then
'${CROSS_COMPILE}objdump --source u-boot'.
4) where did the toolchain come from, what version, etc.? Maybe run
gcc with the -v option to see the subprograms and options it sets.
5) try downloading the mips ELDK and build u-boot with that.
More information about the U-Boot
mailing list