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/mips32/start.S | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/mips/cpu/mips32') diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S index 9c1b2f76d0..22a9c1bff5 100644 --- a/arch/mips/cpu/mips32/start.S +++ b/arch/mips/cpu/mips32/start.S @@ -380,6 +380,8 @@ in_ram: /* Exception handlers */ romReserved: b romReserved + nop romExcHandle: b romExcHandle + 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/mips32/start.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/mips/cpu/mips32') diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S index 22a9c1bff5..a4fc1ec0a4 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. */ -- 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/mips32/start.S | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch/mips/cpu/mips32') diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S index a4fc1ec0a4..88e8036175 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 -- 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/mips32/start.S | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch/mips/cpu/mips32') diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S index 88e8036175..64a606f715 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 -- 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/mips32/start.S | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'arch/mips/cpu/mips32') diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S index 64a606f715..d67dafacd4 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 -- 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/mips32/start.S | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'arch/mips/cpu/mips32') diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S index d67dafacd4..77f1103216 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 -- 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/mips32/start.S | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'arch/mips/cpu/mips32') diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S index 77f1103216..51ce914fad 100644 --- a/arch/mips/cpu/mips32/start.S +++ b/arch/mips/cpu/mips32/start.S @@ -314,7 +314,6 @@ relocate_code: jr t0 nop - .word _gp .word _GLOBAL_OFFSET_TABLE_ .word uboot_end_data .word uboot_end @@ -329,9 +328,7 @@ in_ram: */ lw t3, -4(t0) # t3 <-- num_got_entries lw t4, -16(t0) # t4 <-- _GLOBAL_OFFSET_TABLE_ - lw t5, -20(t0) # t5 <-- _gp - sub t4, t5 # compute offset - add t4, t4, gp # t4 now holds relocated _G_O_T_ + add t4, s1 # t4 now holds relocated _G_O_T_ addi t4, t4, 8 # skipping first two entries li t2, 2 1: -- cgit From 9950b90d3851bf9e850fd3d39f539697b8fca7f5 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Wed, 30 Jan 2013 02:22:51 +0000 Subject: MIPS: remove OUTPUT_FORMAT from linker scripts The OUTPUT_FORMAT command in linker scripts was always misused due to some endianess and toolchain problems. Use GCC flags to ensure proper output format, and get rid of the OUTPUT_FORMAT commands in the board specific u-boot.lds files. Signed-off-by: Gabor Juhos Cc: Daniel Schwierzeck Cc: Stefan Roese Cc: Wolfgang Denk Cc: Xiangfu Liu --- arch/mips/cpu/mips32/config.mk | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch/mips/cpu/mips32') diff --git a/arch/mips/cpu/mips32/config.mk b/arch/mips/cpu/mips32/config.mk index 481e9844db..7399701fe9 100644 --- a/arch/mips/cpu/mips32/config.mk +++ b/arch/mips/cpu/mips32/config.mk @@ -30,5 +30,11 @@ MIPSFLAGS := -march=mips32r2 PLATFORM_CPPFLAGS += $(MIPSFLAGS) +PLATFORM_CPPFLAGS += -mabi=32 -DCONFIG_32BIT +ifdef CONFIG_SYS_BIG_ENDIAN +PLATFORM_LDFLAGS += -m elf32btsmip +else +PLATFORM_LDFLAGS += -m elf32ltsmip +endif CONFIG_STANDALONE_LOAD_ADDR ?= 0x80200000 -T mips.lds -- cgit From 4dc7412afa4fe47a02805525e415656d67764839 Mon Sep 17 00:00:00 2001 From: Daniel Schwierzeck Date: Tue, 12 Feb 2013 22:22:12 +0100 Subject: MIPS: start.S: remove obsolete 64 bit handling in setup_c0_status Signed-off-by: Daniel Schwierzeck --- arch/mips/cpu/mips32/start.S | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'arch/mips/cpu/mips32') diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S index 51ce914fad..65acf7d2a1 100644 --- a/arch/mips/cpu/mips32/start.S +++ b/arch/mips/cpu/mips32/start.S @@ -47,14 +47,6 @@ .set pop .endm - .macro setup_c0_status_reset -#ifdef CONFIG_64BIT - setup_c0_status ST0_KX 0 -#else - setup_c0_status 0 0 -#endif - .endm - #define RVECENT(f,n) \ b f; nop #define XVECENT(f,bev) \ @@ -222,7 +214,7 @@ reset: /* WP(Watch Pending), SW0/1 should be cleared */ mtc0 zero, CP0_CAUSE - setup_c0_status_reset + setup_c0_status 0 0 /* Init Timer */ mtc0 zero, CP0_COUNT -- cgit From 8b1c7345c6d5ed20b6b5ec8db17a3282e592184d Mon Sep 17 00:00:00 2001 From: Daniel Schwierzeck Date: Tue, 12 Feb 2013 22:22:12 +0100 Subject: MIPS: start.S: unify and simplify reset vector handling Adopt reset vector handling from Yamon. Signed-off-by: Daniel Schwierzeck --- arch/mips/cpu/mips32/start.S | 186 +++++++++---------------------------------- 1 file changed, 36 insertions(+), 150 deletions(-) (limited to 'arch/mips/cpu/mips32') diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S index 65acf7d2a1..7373d4edc4 100644 --- a/arch/mips/cpu/mips32/start.S +++ b/arch/mips/cpu/mips32/start.S @@ -47,19 +47,16 @@ .set pop .endm -#define RVECENT(f,n) \ - b f; nop -#define XVECENT(f,bev) \ - b f ; \ - li k0,bev - .set noreorder .globl _start .text _start: - RVECENT(reset,0) # U-boot entry point - RVECENT(reset,1) # software reboot + /* U-boot entry point */ + b reset + nop + + .org 0x10 #ifdef CONFIG_SYS_XWAY_EBU_BOOTCFG /* * Almost all Lantiq XWAY SoC devices have an external bus unit (EBU) to @@ -69,141 +66,39 @@ _start: * device with correct parameters. This config option is board-specific. */ .word CONFIG_SYS_XWAY_EBU_BOOTCFG - .word 0x00000000 -#else - RVECENT(romReserved,2) + .word 0x0 #endif - RVECENT(romReserved,3) - RVECENT(romReserved,4) - RVECENT(romReserved,5) - RVECENT(romReserved,6) - RVECENT(romReserved,7) - RVECENT(romReserved,8) - RVECENT(romReserved,9) - RVECENT(romReserved,10) - RVECENT(romReserved,11) - RVECENT(romReserved,12) - RVECENT(romReserved,13) - RVECENT(romReserved,14) - RVECENT(romReserved,15) - RVECENT(romReserved,16) - RVECENT(romReserved,17) - RVECENT(romReserved,18) - RVECENT(romReserved,19) - RVECENT(romReserved,20) - RVECENT(romReserved,21) - RVECENT(romReserved,22) - RVECENT(romReserved,23) - RVECENT(romReserved,24) - RVECENT(romReserved,25) - RVECENT(romReserved,26) - RVECENT(romReserved,27) - RVECENT(romReserved,28) - RVECENT(romReserved,29) - RVECENT(romReserved,30) - RVECENT(romReserved,31) - RVECENT(romReserved,32) - RVECENT(romReserved,33) - RVECENT(romReserved,34) - RVECENT(romReserved,35) - RVECENT(romReserved,36) - RVECENT(romReserved,37) - RVECENT(romReserved,38) - RVECENT(romReserved,39) - RVECENT(romReserved,40) - RVECENT(romReserved,41) - RVECENT(romReserved,42) - RVECENT(romReserved,43) - RVECENT(romReserved,44) - RVECENT(romReserved,45) - RVECENT(romReserved,46) - RVECENT(romReserved,47) - RVECENT(romReserved,48) - RVECENT(romReserved,49) - RVECENT(romReserved,50) - RVECENT(romReserved,51) - RVECENT(romReserved,52) - RVECENT(romReserved,53) - RVECENT(romReserved,54) - RVECENT(romReserved,55) - RVECENT(romReserved,56) - RVECENT(romReserved,57) - RVECENT(romReserved,58) - RVECENT(romReserved,59) - RVECENT(romReserved,60) - RVECENT(romReserved,61) - RVECENT(romReserved,62) - RVECENT(romReserved,63) - XVECENT(romExcHandle,0x200) # bfc00200: R4000 tlbmiss vector - RVECENT(romReserved,65) - RVECENT(romReserved,66) - RVECENT(romReserved,67) - RVECENT(romReserved,68) - RVECENT(romReserved,69) - RVECENT(romReserved,70) - RVECENT(romReserved,71) - RVECENT(romReserved,72) - RVECENT(romReserved,73) - RVECENT(romReserved,74) - RVECENT(romReserved,75) - RVECENT(romReserved,76) - RVECENT(romReserved,77) - RVECENT(romReserved,78) - RVECENT(romReserved,79) - XVECENT(romExcHandle,0x280) # bfc00280: R4000 xtlbmiss vector - RVECENT(romReserved,81) - RVECENT(romReserved,82) - RVECENT(romReserved,83) - RVECENT(romReserved,84) - RVECENT(romReserved,85) - RVECENT(romReserved,86) - RVECENT(romReserved,87) - RVECENT(romReserved,88) - RVECENT(romReserved,89) - RVECENT(romReserved,90) - RVECENT(romReserved,91) - RVECENT(romReserved,92) - RVECENT(romReserved,93) - RVECENT(romReserved,94) - RVECENT(romReserved,95) - XVECENT(romExcHandle,0x300) # bfc00300: R4000 cache vector - RVECENT(romReserved,97) - RVECENT(romReserved,98) - RVECENT(romReserved,99) - RVECENT(romReserved,100) - RVECENT(romReserved,101) - RVECENT(romReserved,102) - RVECENT(romReserved,103) - RVECENT(romReserved,104) - RVECENT(romReserved,105) - RVECENT(romReserved,106) - RVECENT(romReserved,107) - RVECENT(romReserved,108) - RVECENT(romReserved,109) - RVECENT(romReserved,110) - RVECENT(romReserved,111) - XVECENT(romExcHandle,0x380) # bfc00380: R4000 general vector - RVECENT(romReserved,113) - RVECENT(romReserved,114) - RVECENT(romReserved,115) - RVECENT(romReserved,116) - RVECENT(romReserved,116) - RVECENT(romReserved,118) - RVECENT(romReserved,119) - RVECENT(romReserved,120) - RVECENT(romReserved,121) - RVECENT(romReserved,122) - RVECENT(romReserved,123) - RVECENT(romReserved,124) - RVECENT(romReserved,125) - RVECENT(romReserved,126) - RVECENT(romReserved,127) - /* - * We hope there are no more reserved vectors! - * 128 * 8 == 1024 == 0x400 - * so this is address R_VEC+0x400 == 0xbfc00400 - */ + .org 0x200 + /* TLB refill, 32 bit task */ +1: b 1b + nop + + .org 0x280 + /* XTLB refill, 64 bit task */ +1: b 1b + nop + + .org 0x300 + /* Cache error exception */ +1: b 1b + nop + + .org 0x380 + /* General exception */ +1: b 1b + nop + + .org 0x400 + /* Catch interrupt exceptions */ +1: b 1b + nop + + .org 0x480 + /* EJTAG debug exception */ +1: b 1b + nop + .align 4 reset: @@ -351,12 +246,3 @@ in_ram: move a1, s2 .end relocate_code - - /* Exception handlers */ -romReserved: - b romReserved - nop - -romExcHandle: - b romExcHandle - nop -- cgit From 696a3b2a5368360c149335e2a35b8900a78f47fa Mon Sep 17 00:00:00 2001 From: Daniel Schwierzeck Date: Tue, 12 Feb 2013 22:22:13 +0100 Subject: MIPS: start.S: optimize BSS initialization Get the start and end address for clearing BSS from the newly introduced symbols __bss_start and __bss_end. After GOT is relocated, those symbols are already pointing to the correct addresses. Also optimize the loop by moving the address incrementation to the delay slot to avoid the initial sub instruction. Signed-off-by: Daniel Schwierzeck --- arch/mips/cpu/mips32/start.S | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'arch/mips/cpu/mips32') diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S index 7373d4edc4..cd8b914da3 100644 --- a/arch/mips/cpu/mips32/start.S +++ b/arch/mips/cpu/mips32/start.S @@ -228,17 +228,19 @@ in_ram: blt t2, t3, 1b addi t4, 4 - /* Clear BSS */ - lw t1, -12(t0) # t1 <-- uboot_end_data - lw t2, -8(t0) # t2 <-- uboot_end - add t1, s1 # adjust pointers - add t2, s1 + /* + * Clear BSS + * + * GOT is now relocated. Thus __bss_start and __bss_end can be + * accessed directly via $gp. + */ + la t1, __bss_start # t1 <-- __bss_start + la t2, __bss_end # t2 <-- __bss_end - sub t1, 4 1: - addi t1, 4 - bltl t1, t2, 1b - sw zero, 0(t1) + sw zero, 0(t1) + blt t1, t2, 1b + addi t1, 4 move a0, s0 # a0 <-- gd la t9, board_init_r -- cgit From 28875e2c4731296ee7ed645d07f1c28c0301f1c4 Mon Sep 17 00:00:00 2001 From: Daniel Schwierzeck Date: Tue, 12 Feb 2013 22:22:13 +0100 Subject: MIPS: start.S: use symbol __image_copy_end for U-Boot image relocation Use the newly introduced symbol __image_copy_end as end address for relocation of U-Boot image. This is needed for dynamic relocation added in later patches. This patch obsoletes the symbols uboot_end and uboot_end_data which are removed. Signed-off-by: Daniel Schwierzeck --- arch/mips/cpu/mips32/start.S | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'arch/mips/cpu/mips32') diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S index cd8b914da3..649c0bbf5c 100644 --- a/arch/mips/cpu/mips32/start.S +++ b/arch/mips/cpu/mips32/start.S @@ -173,7 +173,7 @@ relocate_code: sub s1, s2, t0 # s1 <-- relocation offset la t3, in_ram - lw t2, -12(t3) # t2 <-- uboot_end_data + lw t2, -12(t3) # t2 <-- __image_copy_end move t1, a2 add gp, s1 # adjust gp @@ -201,9 +201,8 @@ relocate_code: jr t0 nop + .word __image_copy_end .word _GLOBAL_OFFSET_TABLE_ - .word uboot_end_data - .word uboot_end .word num_got_entries in_ram: @@ -214,7 +213,7 @@ in_ram: * generated by GNU ld. Skip these reserved entries from relocation. */ lw t3, -4(t0) # t3 <-- num_got_entries - lw t4, -16(t0) # t4 <-- _GLOBAL_OFFSET_TABLE_ + lw t4, -8(t0) # t4 <-- _GLOBAL_OFFSET_TABLE_ add t4, s1 # t4 now holds relocated _G_O_T_ addi t4, t4, 8 # skipping first two entries li t2, 2 -- cgit From 04380c651a2ff0d1495822321d2b7668dcd02537 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 12 Feb 2013 22:22:13 +0100 Subject: MIPS: add dynamic relocation support The code handles relocation entries with the following relocation types only: mips32: R_MIPS_REL32 mips64: R_MIPS_REL+R_MIPS_64 xburst: R_MIPS_REL32 Other relocation entries are skipped without processing. The code must be extended if other relocation types must be supported. Add -pie to LDFLAGS_FINAL to generate the .rel.dyn fixup table, which will be applied to the relocated image before transferring control to it. The CONFIG_NEEDS_MANUAL_RELOC is not needed after the patch, so remove that as well. Signed-off-by: Gabor Juhos Signed-off-by: Daniel Schwierzeck --- arch/mips/cpu/mips32/start.S | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'arch/mips/cpu/mips32') diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S index 649c0bbf5c..76abbaa273 100644 --- a/arch/mips/cpu/mips32/start.S +++ b/arch/mips/cpu/mips32/start.S @@ -201,6 +201,8 @@ relocate_code: jr t0 nop + .word __rel_dyn_end + .word __rel_dyn_start .word __image_copy_end .word _GLOBAL_OFFSET_TABLE_ .word num_got_entries @@ -227,6 +229,32 @@ in_ram: blt t2, t3, 1b addi t4, 4 + /* Update dynamic relocations */ + lw t1, -16(t0) # t1 <-- __rel_dyn_start + lw t2, -20(t0) # t2 <-- __rel_dyn_end + + b 2f # skip first reserved entry + addi t1, 8 + +1: + lw t3, -4(t1) # t3 <-- relocation info + + sub t3, 3 + bnez t3, 2f # skip non R_MIPS_REL32 entries + nop + + lw t3, -8(t1) # t3 <-- location to fix up in FLASH + + lw t4, 0(t3) # t4 <-- original pointer + add t4, s1 # t4 <-- adjusted pointer + + add t3, s1 # t3 <-- location to fix up in RAM + sw t4, 0(t3) + +2: + blt t1, t2, 1b + addi t1, 8 # each rel.dyn entry is 8 bytes + /* * Clear BSS * -- cgit