From 14fdd1a8bfd97de46042cda6086347b0d66461d4 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Wed, 16 Jan 2013 03:05:01 +0000 Subject: MIPS: start{, 64}.S: fill branch delay slots with NOP instructions The romReserved and romExcHandle handlers are accessed by a branch instruction however the delay slots of those instructions are not filled. Because the start.S uses the 'noreorder' directive, the assembler will not fill the delay slots either, and leads to the following assembly code: 0000056c : 56c: 1000ffff b 56c 00000570 : 570: 1000ffff b 570 In the resulting code, the second branch instruction is placed into the delay slot of the first branch instruction, which is not allowed on the MIPS architecture. Signed-off-by: Gabor Juhos Cc: Daniel Schwierzeck --- arch/mips/cpu/mips64/start.S | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/mips/cpu/mips64') diff --git a/arch/mips/cpu/mips64/start.S b/arch/mips/cpu/mips64/start.S index 2b8d531e73..bc7e41eed5 100644 --- a/arch/mips/cpu/mips64/start.S +++ b/arch/mips/cpu/mips64/start.S @@ -259,3 +259,4 @@ in_ram: /* Exception handlers */ romReserved: b romReserved + nop -- cgit From 5b7dd8163d517c8f52971bc16fe92f831553d2bb Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Thu, 24 Jan 2013 06:27:51 +0000 Subject: MIPS: start.S: fix boundary check in relocate_code 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 Cc: Daniel Schwierzeck --- arch/mips/cpu/mips64/start.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/mips/cpu/mips64') diff --git a/arch/mips/cpu/mips64/start.S b/arch/mips/cpu/mips64/start.S index bc7e41eed5..aed82e1f07 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. */ -- cgit From f321b0f99fa0ccf1f25b3d9ab2140b98baa6fdbd Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Thu, 24 Jan 2013 06:27:52 +0000 Subject: MIPS: start.S: set sp register directly 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 Cc: Daniel Schwierzeck --- arch/mips/cpu/mips64/start.S | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch/mips/cpu/mips64') diff --git a/arch/mips/cpu/mips64/start.S b/arch/mips/cpu/mips64/start.S index aed82e1f07..d3c5ceaffd 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 -- cgit From b2fe86f8873088391d77224fb33544bc1e3b2c0a Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Thu, 24 Jan 2013 06:27:53 +0000 Subject: MIPS: start.S: save reused arguments earlier in relocate_code 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 Cc: Daniel Schwierzeck --- arch/mips/cpu/mips64/start.S | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch/mips/cpu/mips64') diff --git a/arch/mips/cpu/mips64/start.S b/arch/mips/cpu/mips64/start.S index d3c5ceaffd..3c0f1c3bd9 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 -- cgit From 248fe03f53772a61bb7355a4e45cd055dfdcf7b2 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Thu, 24 Jan 2013 06:27:54 +0000 Subject: MIPS: start.S: simplify relocation offset calculation 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 Cc: Daniel Schwierzeck --- arch/mips/cpu/mips64/start.S | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'arch/mips/cpu/mips64') diff --git a/arch/mips/cpu/mips64/start.S b/arch/mips/cpu/mips64/start.S index 3c0f1c3bd9..d213c8eed0 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 -- cgit From 67d80c9f97f1b73d227f64efebf204221a611a70 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Thu, 24 Jan 2013 06:27:55 +0000 Subject: MIPS: start.S: don't save flush_cache parameters in advance 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 Cc: Daniel Schwierzeck --- arch/mips/cpu/mips64/start.S | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'arch/mips/cpu/mips64') diff --git a/arch/mips/cpu/mips64/start.S b/arch/mips/cpu/mips64/start.S index d213c8eed0..80e6bb1398 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 -- cgit From 025f2b338072781cd747bf7365cf43fcf9f40f1a Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Wed, 30 Jan 2013 04:56:37 +0000 Subject: MIPS: simplify relocated _G_O_T_ address calculation The difference between the address of the original and the relocated _GLOBAL_OFFSET_TABLE_ is always the same as the relocation offset. The relocation offset is already computed and it is available in the 's1/t6' register. Use that to adjust the relocated _G_O_T_ address, instead of calculating the offset again from the _gp value. Signed-off-by: Gabor Juhos Cc: Daniel Schwierzeck Cc: Xiangfu Liu --- arch/mips/cpu/mips64/start.S | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'arch/mips/cpu/mips64') diff --git a/arch/mips/cpu/mips64/start.S b/arch/mips/cpu/mips64/start.S index 80e6bb1398..15225945e9 100644 --- a/arch/mips/cpu/mips64/start.S +++ b/arch/mips/cpu/mips64/start.S @@ -193,7 +193,6 @@ relocate_code: jr t0 nop - .dword _gp .dword _GLOBAL_OFFSET_TABLE_ .dword uboot_end_data .dword uboot_end @@ -208,9 +207,7 @@ in_ram: */ ld t3, -8(t0) # t3 <-- num_got_entries ld t8, -32(t0) # t8 <-- _GLOBAL_OFFSET_TABLE_ - ld t9, -40(t0) # t9 <-- _gp - dsub t8, t9 # compute offset - dadd t8, t8, gp # t8 now holds relocated _G_O_T_ + dadd t8, s1 # t8 now holds relocated _G_O_T_ daddi t8, t8, 16 # skipping first two entries dli t2, 2 1: -- cgit