[U-Boot] [PATCH 0/5] MIPS: start.S: relocate_code fixes and cleanups

This series contain various patches for the relocate_code function. The first patch fixes a minor issue in the relocation code, and the subsequent patches are doing some optimalization and cleanup.
Gabor Juhos (5): MIPS: start.S: fix boundary check in relocate_code MIPS: start.S: set sp register directly MIPS: start.S: save reused arguments earlier in relocate_code MIPS: start.S: simplify relocation offset calculation MIPS: start.S: don't save flush_cache parameters in advance
arch/mips/cpu/mips32/start.S | 34 ++++++++++------------------------ arch/mips/cpu/mips64/start.S | 34 ++++++++++------------------------ arch/mips/cpu/xburst/start.S | 2 +- 3 files changed, 21 insertions(+), 49 deletions(-)
-- 1.7.10

The loop code copies more data with one than necessary due to the 'ble' instuction. Use the 'blt' instruction instead to fix that.
Due to the lack of suitable hardware the Xburst specific code is compile tested only. However the change is quite obvious.
Signed-off-by: Gabor Juhos juhosg@openwrt.org Cc: Daniel Schwierzeck daniel.schwierzeck@googlemail.com --- arch/mips/cpu/mips32/start.S | 2 +- arch/mips/cpu/mips64/start.S | 2 +- arch/mips/cpu/xburst/start.S | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S index 22a9c1b..a4fc1ec 100644 --- a/arch/mips/cpu/mips32/start.S +++ b/arch/mips/cpu/mips32/start.S @@ -313,7 +313,7 @@ relocate_code: lw t3, 0(t0) sw t3, 0(t1) addu t0, 4 - ble t0, t2, 1b + blt t0, t2, 1b addu t1, 4
/* If caches were enabled, we would have to flush them here. */ diff --git a/arch/mips/cpu/mips64/start.S b/arch/mips/cpu/mips64/start.S index bc7e41e..aed82e1 100644 --- a/arch/mips/cpu/mips64/start.S +++ b/arch/mips/cpu/mips64/start.S @@ -192,7 +192,7 @@ relocate_code: lw t3, 0(t0) sw t3, 0(t1) daddu t0, 4 - ble t0, t2, 1b + blt t0, t2, 1b daddu t1, 4
/* If caches were enabled, we would have to flush them here. */ diff --git a/arch/mips/cpu/xburst/start.S b/arch/mips/cpu/xburst/start.S index 3a8280c..194d745 100644 --- a/arch/mips/cpu/xburst/start.S +++ b/arch/mips/cpu/xburst/start.S @@ -87,7 +87,7 @@ relocate_code: lw t3, 0(t0) sw t3, 0(t1) addu t0, 4 - ble t0, t2, 1b + blt t0, t2, 1b addu t1, 4
/* If caches were enabled, we would have to flush them here. */

The current code uses two instructions to load the stack pointer into the 'sp' register.
This results in the following assembly code:
468: 3c088040 lui t0,0x8040 46c: 251d0000 addiu sp,t0,0
The first instuction loads the stack pointer into the 't0' register then the value of the 'sp' register is computed by adding zero to the value of the 't0' register. The same issue present on the 64-bit version as well:
56c: 3c0c8040 lui t0,0x8040 570: 659d0000 daddiu sp,t0,0
Change the code to load the stack pointer directly into the 'sp' register. The generated code is functionally equivalent to the previous version but it is simpler.
32-bit: 468: 3c1d8040 lui sp,0x8040
64-bit: 56c: 3c1d8040 lui sp,0x8040
Signed-off-by: Gabor Juhos juhosg@openwrt.org Cc: Daniel Schwierzeck daniel.schwierzeck@googlemail.com --- arch/mips/cpu/mips32/start.S | 3 +-- arch/mips/cpu/mips64/start.S | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S index a4fc1ec..88e8036 100644 --- a/arch/mips/cpu/mips32/start.S +++ b/arch/mips/cpu/mips32/start.S @@ -258,8 +258,7 @@ reset: #endif
/* Set up temporary stack */ - li t0, CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_INIT_SP_OFFSET - la sp, 0(t0) + li sp, CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_INIT_SP_OFFSET
la t9, board_init_f jr t9 diff --git a/arch/mips/cpu/mips64/start.S b/arch/mips/cpu/mips64/start.S index aed82e1..d3c5cea 100644 --- a/arch/mips/cpu/mips64/start.S +++ b/arch/mips/cpu/mips64/start.S @@ -137,8 +137,7 @@ reset: #endif
/* Set up temporary stack */ - dli t0, CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_INIT_SP_OFFSET - dla sp, 0(t0) + dli sp, CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_INIT_SP_OFFSET
dla t9, board_init_f jr t9

Save the reused parameters at the beginning of the 'relocate_code' function. This makes the function a bit more readable.
Signed-off-by: Gabor Juhos juhosg@openwrt.org Cc: Daniel Schwierzeck daniel.schwierzeck@googlemail.com --- arch/mips/cpu/mips32/start.S | 5 +++-- arch/mips/cpu/mips64/start.S | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S index 88e8036..64a606f 100644 --- a/arch/mips/cpu/mips32/start.S +++ b/arch/mips/cpu/mips32/start.S @@ -279,11 +279,13 @@ reset: relocate_code: move sp, a0 # set new stack pointer
+ move s0, a1 # save gd in s0 + move s2, a2 # save destination address in s2 + li t0, CONFIG_SYS_MONITOR_BASE la t3, in_ram lw t2, -12(t3) # t2 <-- uboot_end_data move t1, a2 - move s2, a2 # s2 <-- destination address
/* * Fix $gp: @@ -304,7 +306,6 @@ relocate_code: /* * Save destination address and size for later usage in flush_cache() */ - move s0, a1 # save gd in s0 move a0, t1 # a0 <-- destination addr sub a1, t2, t0 # a1 <-- size
diff --git a/arch/mips/cpu/mips64/start.S b/arch/mips/cpu/mips64/start.S index d3c5cea..3c0f1c3 100644 --- a/arch/mips/cpu/mips64/start.S +++ b/arch/mips/cpu/mips64/start.S @@ -158,11 +158,13 @@ reset: relocate_code: move sp, a0 # set new stack pointer
+ move s0, a1 # save gd in s0 + move s2, a2 # save destination address in s2 + dli t0, CONFIG_SYS_MONITOR_BASE dla t3, in_ram ld t2, -24(t3) # t2 <-- uboot_end_data move t1, a2 - move s2, a2 # s2 <-- destination address
/* * Fix $gp: @@ -183,7 +185,6 @@ relocate_code: /* * Save destination address and size for dlater usage in flush_cache() */ - move s0, a1 # save gd in s0 move a0, t1 # a0 <-- destination addr dsub a1, t2, t0 # a1 <-- size

The current code uses four instructions and a temporary register to calculate the relocation offset and to adjust the gp register.
The relocation offset can be calculated directly from the CONFIG_SYS_MONITOR_BASE constant and from the destination address. The resulting offset can be used to adjust the gp pointer.
This approach makes the code a bit simpler because it needs two instructions only.
Signed-off-by: Gabor Juhos juhosg@openwrt.org Cc: Daniel Schwierzeck daniel.schwierzeck@googlemail.com --- arch/mips/cpu/mips32/start.S | 12 +++--------- arch/mips/cpu/mips64/start.S | 12 +++--------- 2 files changed, 6 insertions(+), 18 deletions(-)
diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S index 64a606f..d67dafa 100644 --- a/arch/mips/cpu/mips32/start.S +++ b/arch/mips/cpu/mips32/start.S @@ -283,19 +283,13 @@ relocate_code: move s2, a2 # save destination address in s2
li t0, CONFIG_SYS_MONITOR_BASE + sub s1, s2, t0 # s1 <-- relocation offset + la t3, in_ram lw t2, -12(t3) # t2 <-- uboot_end_data move t1, a2
- /* - * Fix $gp: - * - * New $gp = (Old $gp - CONFIG_SYS_MONITOR_BASE) + Destination Address - */ - move t6, gp - sub gp, CONFIG_SYS_MONITOR_BASE - add gp, a2 # gp now adjusted - sub s1, gp, t6 # s1 <-- relocation offset + add gp, s1 # adjust gp
/* * t0 = source address diff --git a/arch/mips/cpu/mips64/start.S b/arch/mips/cpu/mips64/start.S index 3c0f1c3..d213c8e 100644 --- a/arch/mips/cpu/mips64/start.S +++ b/arch/mips/cpu/mips64/start.S @@ -162,19 +162,13 @@ relocate_code: move s2, a2 # save destination address in s2
dli t0, CONFIG_SYS_MONITOR_BASE + dsub s1, s2, t0 # s1 <-- relocation offset + dla t3, in_ram ld t2, -24(t3) # t2 <-- uboot_end_data move t1, a2
- /* - * Fix $gp: - * - * New $gp = (Old $gp - CONFIG_SYS_MONITOR_BASE) + Destination Address - */ - move t8, gp - dsub gp, CONFIG_SYS_MONITOR_BASE - dadd gp, a2 # gp now adjusted - dsub s1, gp, t8 # s1 <-- relocation offset + dadd gp, s1 # adjust gp
/* * t0 = source address

Saving the parameters in advance unnecessarily complicates the code. The destination address is already saved in the 's2' register, and that register is not clobbered by the copy loop. The size of the copied data can be computed after the copy loop is done.
Change the code to compute the size parameter right before calling flush_cache, and set the destination address parameter in the delay slot of the actuall call.
Signed-off-by: Gabor Juhos juhosg@openwrt.org Cc: Daniel Schwierzeck daniel.schwierzeck@googlemail.com --- arch/mips/cpu/mips32/start.S | 12 ++---------- arch/mips/cpu/mips64/start.S | 12 ++---------- 2 files changed, 4 insertions(+), 20 deletions(-)
diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S index d67dafa..77f1103 100644 --- a/arch/mips/cpu/mips32/start.S +++ b/arch/mips/cpu/mips32/start.S @@ -296,13 +296,6 @@ relocate_code: * t1 = target address * t2 = source end address */ - - /* - * Save destination address and size for later usage in flush_cache() - */ - move a0, t1 # a0 <-- destination addr - sub a1, t2, t0 # a1 <-- size - 1: lw t3, 0(t0) sw t3, 0(t1) @@ -311,11 +304,10 @@ relocate_code: addu t1, 4
/* If caches were enabled, we would have to flush them here. */ - - /* a0 & a1 are already set up for flush_cache(start, size) */ + sub a1, t1, s2 # a1 <-- size la t9, flush_cache jalr t9 - nop + move a0, s2 # a0 <-- destination address
/* Jump to where we've relocated ourselves */ addi t0, s2, in_ram - _start diff --git a/arch/mips/cpu/mips64/start.S b/arch/mips/cpu/mips64/start.S index d213c8e..80e6bb1 100644 --- a/arch/mips/cpu/mips64/start.S +++ b/arch/mips/cpu/mips64/start.S @@ -175,13 +175,6 @@ relocate_code: * t1 = target address * t2 = source end address */ - - /* - * Save destination address and size for dlater usage in flush_cache() - */ - move a0, t1 # a0 <-- destination addr - dsub a1, t2, t0 # a1 <-- size - 1: lw t3, 0(t0) sw t3, 0(t1) @@ -190,11 +183,10 @@ relocate_code: daddu t1, 4
/* If caches were enabled, we would have to flush them here. */ - - /* a0 & a1 are already set up for flush_cache(start, size) */ + dsub a1, t1, s2 # a1 <-- size dla t9, flush_cache jalr t9 - nop + move a0, s2 # a0 <-- destination address
/* Jump to where we've relocated ourselves */ daddi t0, s2, in_ram - _start

2013/1/24 Gabor Juhos juhosg@openwrt.org:
This series contain various patches for the relocate_code function. The first patch fixes a minor issue in the relocation code, and the subsequent patches are doing some optimalization and cleanup.
Gabor Juhos (5): MIPS: start.S: fix boundary check in relocate_code MIPS: start.S: set sp register directly MIPS: start.S: save reused arguments earlier in relocate_code MIPS: start.S: simplify relocation offset calculation MIPS: start.S: don't save flush_cache parameters in advance
arch/mips/cpu/mips32/start.S | 34 ++++++++++------------------------ arch/mips/cpu/mips64/start.S | 34 ++++++++++------------------------ arch/mips/cpu/xburst/start.S | 2 +- 3 files changed, 21 insertions(+), 49 deletions(-)
all five patches applied to u-boot-mips/master, thanks
participants (2)
-
Daniel Schwierzeck
-
Gabor Juhos