[U-Boot-Users] MIPS build environment

Hello all MIPS u-booters.
I'd like to discuss how we can make the MIPS build environment a little bit easier to use. For example, the cpu/mips/config.mk assumes big endian, and although I'll be the first to stand up and say that's the only proper and useful byte ordering, there are people willing to pay me to assist with the alternative :-) I'd like it if we can just find a way to invoke 'mipseb-*' or 'mipsel-*' based upon the configuration chosen and let it go at that.
I'd also like us to agree to use up to date tools. Again, the config.mk with the test and hard coded flags depending upon tools seems unnecessary since the newer tools have been around for a while and proven to work.
Unless I'm doing something wrong, I also have to use binutils with the 'allow_branch_to_undefined' patch.
Comments? Other concerns?
Thanks.
-- Dan

On Fri, 2005-01-28 at 18:13 -0800, Dan Malek wrote:
to assist with the alternative :-) I'd like it if we can just find a way to invoke 'mipseb-*' or 'mipsel-*' based upon the configuration chosen and let it go at that.
That would be great!
Unless I'm doing something wrong, I also have to use binutils with the 'allow_branch_to_undefined' patch.
It looks to me that the code uses bal in an attempt to be position independent. It also uses a rather complicated got loading sequence. This is IMO futile, as the rest of u-boot (especially the copy to RAM routine) isn't position independent. So you can as well just load the full address of the called routines into a temporary register and jump through the register. See the patch below.
Tom
--- start.S.jnx 2005-01-20 21:51:00.000000000 +0100 +++ start.S 2005-01-20 22:01:39.000000000 +0100 @@ -28,6 +28,35 @@ #include <asm/regdef.h> #include <asm/mipsregs.h>
+#define NEWASM + +#ifdef NEWASM + +#define BAL(x) \ + lui t0, %hi(x) ; \ + ori t0, t0, %lo(x) ; \ + jalr t0 + +#define LOADGOT \ + lui gp, %hi(_GLOBAL_OFFSET_TABLE_) ; \ + ori gp, gp, %lo(_GLOBAL_OFFSET_TABLE_) + +#else + +#define BAL(x) \ + bal x + +#define LOADGOT \ + bal 1f ; \ + nop ; \ + .word _GLOBAL_OFFSET_TABLE_ - 1f + 4 ; \ +1: ; \ + move gp, ra ; \ + lw t1, 0(ra) ; \ + add gp, t1 + +#endif +
#define RVECENT(f,n) \ b f; nop @@ -237,18 +266,18 @@ #ifdef CONFIG_INCA_IP /* Disable INCA-IP Watchdog. */ - bal disable_incaip_wdt + BAL(disable_incaip_wdt) nop #endif
/* Initialize any external memory. */ - bal memsetup + BAL(memsetup) nop
/* Initialize caches... */ - bal mips_cache_reset + BAL(mips_cache_reset) nop
/* ... and enable them. @@ -260,7 +289,7 @@ /* Set up temporary stack. */ li a0, CFG_INIT_SP_OFFSET - bal mips_cache_lock + BAL(mips_cache_lock) nop
li t0, CFG_SDRAM_BASE + CFG_INIT_SP_OFFSET @@ -268,13 +297,8 @@
/* Initialize GOT pointer. */ - bal 1f - nop - .word _GLOBAL_OFFSET_TABLE_ - 1f + 4 -1: - move gp, ra - lw t1, 0(ra) - add gp, t1 + LOADGOT + la t9, board_init_f j t9 nop

Dear Thomas,
in message 1106994990.5393.8.camel@gamecube.scs.ch you wrote:
Unless I'm doing something wrong, I also have to use binutils with the 'allow_branch_to_undefined' patch.
It looks to me that the code uses bal in an attempt to be position independent. It also uses a rather complicated got loading sequence. This is IMO futile, as the rest of u-boot (especially the copy to RAM routine) isn't position independent. So you can as well just load the full address of the called routines into a temporary register and jump through the register. See the patch below.
No, you're moving into the wrong direction. I hereby reject this patch, and will do the same woth all other attempts that go into that direction.
It was very unfortunate that the MIPS port copied the memory layout and relocation part from ARMBoot, which broke with the IMHO better design in PPCBoot. If we change the current code, then please let's do it right and implement it similar as on PowerPC, i. e. get rid of the hard-coded text addresses in RAM - instead let's auto-determine the relocation address based on the actual RAM size in the system, always relocating U-Boot to the very end of available RAM.
This is where the ARM and MIPS ports should move to.
Best regards,
Wolfgang Denk

On Sat, 2005-01-29 at 18:08 +0100, Wolfgang Denk wrote:
No, you're moving into the wrong direction. I hereby reject this patch, and will do the same woth all other attempts that go into that direction.
Sorry for miscommunicating, I didn't mean to ask you to apply it, I meant it to stimulate discussion, which succeeded :)
Now I think there's a misunderstanding. There are two parts of u-boot, namely the part that runs off SDRAM and the part that runs off the ROM. For both parts the decision whether PIC or fixed address code should be used is independent.
You argue for PIC/relocatable code in the main u-boot part that runs off SDRAM. Rightly so, IMO. The patch I posted applies however to the part that runs off ROM (FLASH) (SDRAM doesn't even work before the call to memsetup, because the SDRAM controller and cache aren't setup yet). Now this code is typically located at the reset vector address, and this address is normally fixed by the silicon/cpu architecture. For this part of u-boot, relocatability is less useful. Now MIPS has a feature to allow the machine to be booted from JTAG by relocating the reset vector into a memory space that when accessed causes a JTAG transaction with the debug PC to supply the data, so for this feature relocatability of the ROM part of u-boot could be somewhat useful.
Tom

Dear Thomas,
in message 1107042893.5393.19.camel@gamecube.scs.ch you wrote:
Now I think there's a misunderstanding. There are two parts of u-boot,
No, srictly speaking there are not two parts of U-Boot. U-Boot is one part, which runs from two different memory locations: first from ROM, and later from RAM.
namely the part that runs off SDRAM and the part that runs off the ROM. For both parts the decision whether PIC or fixed address code should be used is independent.
You have to be very careful, as the code from the "ROM part" will call the very same routines as the code from the "RAM part", and everythink is linked into the very same binary image.
You argue for PIC/relocatable code in the main u-boot part that runs off SDRAM. Rightly so, IMO. The patch I posted applies however to the part that runs off ROM (FLASH) (SDRAM doesn't even work before the call to memsetup, because the SDRAM controller and cache aren't setup yet). Now
I see. Sorry, I missed that.
Best regards,
Wolfgang Denk

Hi Dan,
in message e7af2eca2d0ca4432255ff965eb51330@embeddededge.com you wrote:
I'd like to discuss how we can make the MIPS build environment a little bit easier to use. For example, the cpu/mips/config.mk assumes big endian, and although I'll be the first to stand up
It was pure chance that the first two MIPS system to which we ported U-Boot (INCA-IP and Purple) happened to be big endian. We, too, have LE MIPS systems in the queue.
to assist with the alternative :-) I'd like it if we can just find a way to invoke 'mipseb-*' or 'mipsel-*' based upon the configuration chosen and let it go at that.
Please feel free to go on :-)
I'd also like us to agree to use up to date tools.
Yes, but please not not break backward compatibility.
Again, the config.mk with the test and hard coded flags depending upon tools seems unnecessary since the newer tools have been around for a while and proven to work.
It's true that newer tools are available and working fine, but that doesn't mean that we can brak support for the old toolchains. There are many projects running in Big Companies wheare introducing a new toolchain is sinply not possible with reasonable efforts.
Unless I'm doing something wrong, I also have to use binutils with the 'allow_branch_to_undefined' patch.
Yes, this is correct, at least with the current code. Please feel free to improve that.
Best regards,
Wolfgang Denk

On Fri, Jan 28, 2005 at 06:13:23PM -0800, Dan Malek wrote:
Unless I'm doing something wrong, I also have to use binutils with the 'allow_branch_to_undefined' patch.
Hmm, why do you need this?
The only problematic place IIRC is in start.S which is trivially fixable without any additional toolchain patches or hacks like "mips_allow_branch_to_undefined". Just move initialization of GOT pointer right after CONFIG0 and use la/jalr instead of bal when calling memsetup, mips_cache_reset etc. This is what I did for MVL 3.1 based MIPS toolchain.
As a side note, "Setup temporary stack" is completely bogus and isn't needed, at least for 4kc which has a write-through dcache (4kc is the only MIPS arch currently supported, btw).
-- Eugene

In message 20050130002030.GA24482@gate.ebshome.net you wrote:
As a side note, "Setup temporary stack" is completely bogus and isn't needed, at least for 4kc which has a write-through dcache (4kc is the only MIPS arch currently supported, btw).
Supported where or by what? You aren't speaking about U-Boot here, right? Because Infineon's Purple board is a 5Kc system.
Best regards,
Wolfgang Denk

On Sun, Jan 30, 2005 at 02:24:34AM +0100, Wolfgang Denk wrote:
In message 20050130002030.GA24482@gate.ebshome.net you wrote:
As a side note, "Setup temporary stack" is completely bogus and isn't needed, at least for 4kc which has a write-through dcache (4kc is the only MIPS arch currently supported, btw).
Supported where or by what? You aren't speaking about U-Boot here, right? Because Infineon's Purple board is a 5Kc system.
This is taken from cpu/mips/config.mk
MIPSFLAGS=$(shell \ if [ "$v" -lt "14" ]; then \ echo "-mcpu=4kc -EB -mabicalls"; \ else \ echo "-march=4kc -mtune=4kc -Wa,-mips_allow_branch_to_undefined -EB -mabicalls"; \ fi)
Also, this is part from Makefile:
ifeq ($(ARCH),mips) CROSS_COMPILE = mips_4KC- endif
So, what is all this then, an exercise in obfuscation? I can tell, it was successfully, I really thought only 4kc is supported, my apologies, Wolfgang.
Anyway, my comment still stands, this is bogus and cannot work for 4kc at least. The only reason INCA-IP port works is because memory is really initialized before stack is accessed.
-- Eugene

On Jan 29, 2005, at 5:43 PM, Eugene Surovegin wrote:
This is taken from cpu/mips/config.mk
Which is the main thing I want to fix. I don't yet know the proper solution, but it sounds like there is at least consensus to try another approach. The main reason I'm asking is that I don't have access to other MIPS boards for testing, and I didn't know the history of this development. I have several Alchemy Au1xxx boards that I intend to get running with u-boot, in both big and little endian modes, along with a couple of R4Kc custom cores.
ifeq ($(ARCH),mips) CROSS_COMPILE = mips_4KC- endif
Any objections to setting CROSS_COMPILE in include/config.mk and allow setting it within the 'mkconfig' part of the Makefile? I still don't know what to do with the rest of the config.mk, as it sets R4Kc specific flags based upon the binutils version.
Thanks.
-- Dan

Deear Dan,
in message ff6e59bad677e5375666e34e99d50cbd@embeddededge.com you wrote:
ifndef CROSS_COMPILE
ifeq ($(ARCH),mips) CROSS_COMPILE = mips_4KC- endif
endif
Any objections to setting CROSS_COMPILE in include/config.mk and allow setting it within the 'mkconfig' part of the Makefile?
Yes. Please don't do this, as it is not necessary. The "mips_4KC-" setting above is just the default which is used when the user does not supply a CROSS_COMPILE setting either in his environment or in the make command line. This should be sufficient.
I still don't know what to do with the rest of the config.mk, as it sets R4Kc specific flags based upon the binutils version.
This is because we needed a way to find out if "allow_branch_to_undefined" is available; maybe you know a better approach.
Best regards,
Wolfgang Denk

On Sun, Jan 30, 2005 at 10:18:55AM +0100, Wolfgang Denk wrote:
This is because we needed a way to find out if "allow_branch_to_undefined" is available; maybe you know a better approach.
Why not just modify start.S (I posted a patch earlier in this thread) so we don't need this "allow_branch_to_undefined" hack at all?
-- Eugene

Dear Eugene,
in message 20050130014351.GB24482@gate.ebshome.net you wrote:
This is taken from cpu/mips/config.mk
As Dan already pointed out the config.mk file probably needs some adaption to support other MIPS configurations. It just happened to work like this for the currently supported boards.
Also, this is part from Makefile:
ifeq ($(ARCH),mips) CROSS_COMPILE = mips_4KC- endif
Yes, I know. But the Purple is really a 5Kc system - as far as U-Boot was concerned the code there was no prolems using the 4Kc configuration for it.
So, what is all this then, an exercise in obfuscation? I can tell, it
No, lazuiness - you only change what really needs to be changed to get something working. As long as this is a one-time use this is IMHO even acceptable. It's when more systems get added when you have to think about a more general approach.
Anyway, my comment still stands, this is bogus and cannot work for 4kc at least. The only reason INCA-IP port works is because memory is really initialized before stack is accessed.
Please feel free to submit a patch.
Best regards,
Wolfgang Denk

On Sun, Jan 30, 2005 at 10:13:54AM +0100, Wolfgang Denk wrote:
Anyway, my comment still stands, this is bogus and cannot work for 4kc at least. The only reason INCA-IP port works is because memory is really initialized before stack is accessed.
Please feel free to submit a patch.
Unfortunately, it's not that simple :). This is one of those rare cases when bug might have become a "feature". Let me explain.
Comment about setting up a temporary stack is obviously incorrect, but there is side effect of this cache locking (probably unintentional).
Dcache is never get _unlocked_ after we copied U-Boot into the RAM. This effectively _disables_ dcache, because it's highly unlikely that we will use those addresses again during normal operation. This in turn makes cache-coherency (4kc is non-cache coherent core) a non-issue, making drivers simpler.
When I first discovered this "cache-locking-for-temporary-stack" inconsistency, my first attempt was to remove cache locking altogether, and it even worked, although I haven't done extensive testing.
Then I started thinking about side effect I just described and I wasn't quite sure that just removing this was safe. This is the main reason I haven't submitted patch in the first place, because I didn't have time to audit all the code for the cache-coherency problems.
From quick look at the net driver I think it's OK. Also write-through
cache makes life much simpler than write-back one.
So, currently I have two possible paths:
1) Remove cache locking for 4kc (e.g. put #ifdef CONFIG_PURPLE) or maybe add CONFIG_WRITE_THROUGH_CACHE and use it.
2) Call dcache_disable instead.
Option 1) seems more clean, although potentially more dangerous. Option 2) looks safe and keeps current *behavior* while making it explicit.
Wolfgang, what do you think is the best way to go? Or maybe there is an option 3) I haven't thought of.
-- Eugene

In message 20050130102615.GC24482@gate.ebshome.net you wrote:
So, currently I have two possible paths:
- Remove cache locking for 4kc (e.g. put #ifdef CONFIG_PURPLE) or
maybe add CONFIG_WRITE_THROUGH_CACHE and use it.
- Call dcache_disable instead.
Option 1) seems more clean, although potentially more dangerous. Option 2) looks safe and keeps current *behavior* while making it explicit.
I haven't seen any additional comments about this, or have I been missing these?
In case it still matters: my preference is 2)
Best regards,
Wolfgang Denk
participants (4)
-
Dan Malek
-
Eugene Surovegin
-
Thomas Sailer
-
Wolfgang Denk