diff options
Diffstat (limited to 'arch/mips/cpu/mips64/start.S')
-rw-r--r-- | arch/mips/cpu/mips64/start.S | 110 |
1 files changed, 71 insertions, 39 deletions
diff --git a/arch/mips/cpu/mips64/start.S b/arch/mips/cpu/mips64/start.S index 15225945e9b..dc7ce07ce78 100644 --- a/arch/mips/cpu/mips64/start.S +++ b/arch/mips/cpu/mips64/start.S @@ -31,6 +31,14 @@ #define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT #endif +#ifdef CONFIG_SYS_LITTLE_ENDIAN +#define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \ + (((r_type) << 24) | ((r_type2) << 16) | ((r_type3) << 8) | (ssym)) +#else +#define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \ + ((r_type) | ((r_type2) << 8) | ((r_type3) << 16) | (ssym) << 24) +#endif + /* * For the moment disable interrupts, mark the kernel mode and * set ST0_KX so that the CPU does not spit fire when using @@ -52,40 +60,40 @@ .globl _start .text _start: - .org 0x000 + /* U-boot entry point */ b reset nop - .org 0x080 - b romReserved - nop - .org 0x100 - b romReserved - nop - .org 0x180 - b romReserved - nop + .org 0x200 - b romReserved + /* TLB refill, 32 bit task */ +1: b 1b nop + .org 0x280 - b romReserved + /* XTLB refill, 64 bit task */ +1: b 1b nop + .org 0x300 - b romReserved + /* Cache error exception */ +1: b 1b nop + .org 0x380 - b romReserved + /* General exception */ +1: b 1b + nop + + .org 0x400 + /* Catch interrupt exceptions */ +1: b 1b nop + .org 0x480 - b romReserved + /* EJTAG debug exception */ +1: b 1b nop - /* - * We hope there are no more reserved vectors! - * 128 * 8 == 1024 == 0x400 - * so this is address R_VEC+0x400 == 0xbfc00400 - */ - .org 0x500 .align 4 reset: @@ -165,7 +173,7 @@ relocate_code: dsub s1, s2, t0 # s1 <-- relocation offset dla t3, in_ram - ld t2, -24(t3) # t2 <-- uboot_end_data + ld t2, -24(t3) # t2 <-- __image_copy_end move t1, a2 dadd gp, s1 # adjust gp @@ -193,9 +201,10 @@ relocate_code: jr t0 nop + .dword __rel_dyn_end + .dword __rel_dyn_start + .dword __image_copy_end .dword _GLOBAL_OFFSET_TABLE_ - .dword uboot_end_data - .dword uboot_end .dword num_got_entries in_ram: @@ -206,7 +215,7 @@ in_ram: * generated by GNU ld. Skip these reserved entries from relocation. */ ld t3, -8(t0) # t3 <-- num_got_entries - ld t8, -32(t0) # t8 <-- _GLOBAL_OFFSET_TABLE_ + ld t8, -16(t0) # t8 <-- _GLOBAL_OFFSET_TABLE_ dadd t8, s1 # t8 now holds relocated _G_O_T_ daddi t8, t8, 16 # skipping first two entries dli t2, 2 @@ -220,17 +229,45 @@ in_ram: blt t2, t3, 1b daddi t8, 8 - /* Clear BSS */ - ld t1, -24(t0) # t1 <-- uboot_end_data - ld t2, -16(t0) # t2 <-- uboot_end - dadd t1, s1 # adjust pointers - dadd t2, s1 + /* Update dynamic relocations */ + ld t1, -32(t0) # t1 <-- __rel_dyn_start + ld t2, -40(t0) # t2 <-- __rel_dyn_end + + b 2f # skip first reserved entry + daddi t1, 16 - dsub t1, 8 1: - daddi t1, 8 - bltl t1, t2, 1b - sd zero, 0(t1) + lw t8, -4(t1) # t8 <-- relocation info + + dli t3, MIPS64_R_INFO(0x00, 0x00, 0x12, 0x03) + bne t8, t3, 2f # skip non R_MIPS_REL32 entries + nop + + ld t3, -16(t1) # t3 <-- location to fix up in FLASH + + ld t8, 0(t3) # t8 <-- original pointer + dadd t8, s1 # t8 <-- adjusted pointer + + dadd t3, s1 # t3 <-- location to fix up in RAM + sd t8, 0(t3) + +2: + blt t1, t2, 1b + daddi t1, 16 # each rel.dyn entry is 16 bytes + + /* + * Clear BSS + * + * GOT is now relocated. Thus __bss_start and __bss_end can be + * accessed directly via $gp. + */ + dla t1, __bss_start # t1 <-- __bss_start + dla t2, __bss_end # t2 <-- __bss_end + +1: + sd zero, 0(t1) + blt t1, t2, 1b + daddi t1, 8 move a0, s0 # a0 <-- gd dla t9, board_init_r @@ -238,8 +275,3 @@ in_ram: move a1, s2 .end relocate_code - - /* Exception handlers */ -romReserved: - b romReserved - nop |