X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=cpu%2Fmips%2Fstart.S;h=57db589b94f266e7057ca966a72b6487918cd186;hb=92b8964bed0d1b779d9e26be4e16755b5c635415;hp=b5043937293c634cf60c89f5b0662302e0e6a766;hpb=3b57fe0a70b903f4db66c558bb9828bc58acf06b;p=oweals%2Fu-boot.git diff --git a/cpu/mips/start.S b/cpu/mips/start.S index b504393729..57db589b94 100644 --- a/cpu/mips/start.S +++ b/cpu/mips/start.S @@ -22,12 +22,33 @@ * MA 02111-1307 USA */ - #include -#include #include #include + /* + * For the moment disable interrupts, mark the kernel mode and + * set ST0_KX so that the CPU does not spit fire when using + * 64-bit addresses. + */ + .macro setup_c0_status set clr + .set push + mfc0 t0, CP0_STATUS + or t0, ST0_CU0 | \set | 0x1f | \clr + xor t0, 0x1f | \clr + mtc0 t0, CP0_STATUS + .set noreorder + sll zero, 3 # ehb + .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 @@ -65,7 +86,7 @@ _start: RVECENT(romReserved,14) RVECENT(romReserved,15) RVECENT(romReserved,16) - RVECENT(romReserved,17) + RVECENT(romReserved,17) RVECENT(romReserved,18) RVECENT(romReserved,19) RVECENT(romReserved,20) @@ -111,7 +132,7 @@ _start: RVECENT(romReserved,60) RVECENT(romReserved,61) RVECENT(romReserved,62) - RVECENT(romReserved,63) + RVECENT(romReserved,63) XVECENT(romExcHandle,0x200) /* bfc00200: R4000 tlbmiss vector */ RVECENT(romReserved,65) RVECENT(romReserved,66) @@ -127,7 +148,7 @@ _start: RVECENT(romReserved,76) RVECENT(romReserved,77) RVECENT(romReserved,78) - RVECENT(romReserved,79) + RVECENT(romReserved,79) XVECENT(romExcHandle,0x280) /* bfc00280: R4000 xtlbmiss vector */ RVECENT(romReserved,81) RVECENT(romReserved,82) @@ -143,7 +164,7 @@ _start: RVECENT(romReserved,92) RVECENT(romReserved,93) RVECENT(romReserved,94) - RVECENT(romReserved,95) + RVECENT(romReserved,95) XVECENT(romExcHandle,0x300) /* bfc00300: R4000 cache vector */ RVECENT(romReserved,97) RVECENT(romReserved,98) @@ -176,7 +197,7 @@ _start: 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 @@ -192,7 +213,7 @@ _start: .word 0x00000000 .word 0x03e00008 .word 0x00000000 - .word 0x00000000 + .word 0x00000000 /* 0xbfc00428 */ .word 0xdc870000 .word 0xfca70000 @@ -203,7 +224,7 @@ _start: .word 0x00000000 .word 0x03e00008 .word 0x00000000 - .word 0x00000000 + .word 0x00000000 #endif /* CONFIG_PURPLE */ .align 4 reset: @@ -213,69 +234,64 @@ reset: mtc0 zero, CP0_WATCHLO mtc0 zero, CP0_WATCHHI - /* STATUS register */ - mfc0 k0, CP0_STATUS - li k1, ~ST0_IE - and k0, k1 - mtc0 k0, CP0_STATUS - - /* CAUSE register */ + /* WP(Watch Pending), SW0/1 should be cleared. */ mtc0 zero, CP0_CAUSE + setup_c0_status_reset + /* Init Timer */ mtc0 zero, CP0_COUNT mtc0 zero, CP0_COMPARE +#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) /* CONFIG0 register */ li t0, CONF_CM_UNCACHED mtc0 t0, CP0_CONFIG +#endif /* !CONFIG_SKIP_LOWLEVEL_INIT */ -#ifdef CONFIG_INCA_IP - /* Disable INCA-IP Watchdog. + /* Initialize $gp. */ - bal disable_incaip_wdt + bal 1f nop -#endif + .word _gp +1: + lw gp, 0(ra) - /* Initialize any external memory. +#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) + /* Initialize any external memory. */ - bal memsetup + la t9, lowlevel_init + jalr t9 nop /* Initialize caches... */ - bal mips_cache_reset + la t9, mips_cache_reset + jalr t9 nop /* ... and enable them. */ li t0, CONF_CM_CACHABLE_NONCOHERENT mtc0 t0, CP0_CONFIG - +#endif /* !CONFIG_SKIP_LOWLEVEL_INIT */ /* Set up temporary stack. */ - li a0, CFG_INIT_SP_OFFSET - bal mips_cache_lock +#ifdef CONFIG_SYS_INIT_RAM_LOCK_MIPS + li a0, CONFIG_SYS_INIT_SP_OFFSET + la t9, mips_cache_lock + jalr t9 nop +#endif - li t0, CFG_SDRAM_BASE + CFG_INIT_SP_OFFSET + li t0, CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_INIT_SP_OFFSET la sp, 0(t0) - /* Initialize GOT pointer. - */ - bal 1f - nop - .word _GLOBAL_OFFSET_TABLE_ - 1f + 4 -1: - move gp, ra - lw t1, 0(ra) - add gp, t1 la t9, board_init_f - j t9 + jr t9 nop - /* * void relocate_code (addr_sp, gd, addr_moni) * @@ -289,28 +305,37 @@ reset: .globl relocate_code .ent relocate_code relocate_code: - move sp, a0 /* Set new stack pointer */ + move sp, a0 /* Set new stack pointer */ + + 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 GOT pointer: + * Fix $gp: * - * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address + * New $gp = (Old $gp - CONFIG_SYS_MONITOR_BASE) + Destination Address */ move t6, gp - sub gp, CFG_MONITOR_BASE - add gp, a2 /* gp now adjusted */ - sub t6, gp, t6 /* t6 <-- relocation offset */ - - li t0, CFG_MONITOR_BASE - la t3, in_ram - lw t2, -12(t3) /* t2 <-- uboot_end_data */ - move t1, a2 + sub gp, CONFIG_SYS_MONITOR_BASE + add gp, a2 /* gp now adjusted */ + sub s1, gp, t6 /* s1 <-- relocation offset */ /* * t0 = source address * t1 = target address * t2 = source end address */ + + /* + * 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 */ + /* On the purple board we copy the code earlier in a special way * in order to solve flash problems */ @@ -320,32 +345,47 @@ relocate_code: sw t3, 0(t1) addu t0, 4 ble t0, t2, 1b - addu t1, 4 /* delay slot */ + addu t1, 4 /* delay slot */ #endif /* If caches were enabled, we would have to flush them here. */ + /* a0 & a1 are already set up for flush_cache(start, size) */ + la t9, flush_cache + jalr t9 + nop + /* Jump to where we've relocated ourselves. */ - addi t0, a2, in_ram - _start - j t0 + addi t0, s2, in_ram - _start + jr t0 nop + .word _gp + .word _GLOBAL_OFFSET_TABLE_ .word uboot_end_data .word uboot_end .word num_got_entries in_ram: - /* Now we want to update GOT. + /* + * Now we want to update GOT. + * + * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object + * generated by GNU ld. Skip these reserved entries from relocation. */ lw t3, -4(t0) /* t3 <-- num_got_entries */ - addi t4, gp, 8 /* Skipping first two 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 _GLOBAL_OFFSET_TABLE_ */ + addi t4, t4, 8 /* Skipping first two entries. */ li t2, 2 1: lw t1, 0(t4) beqz t1, 2f - add t1, t6 + add t1, s1 sw t1, 0(t4) 2: addi t2, 1 @@ -356,28 +396,26 @@ in_ram: */ lw t1, -12(t0) /* t1 <-- uboot_end_data */ lw t2, -8(t0) /* t2 <-- uboot_end */ - add t1, t6 /* adjust pointers */ - add t2, t6 + add t1, s1 /* adjust pointers */ + add t2, s1 sub t1, 4 -1: addi t1, 4 +1: + addi t1, 4 bltl t1, t2, 1b sw zero, 0(t1) /* delay slot */ - - move a0, a1 + + move a0, s0 /* a0 <-- gd */ la t9, board_init_r - j t9 - move a1, a2 /* delay slot */ + jr t9 + move a1, s2 /* delay slot */ .end relocate_code - - /* Exception handlers. */ romReserved: - b romReserved + b romReserved romExcHandle: - b romExcHandle - + b romExcHandle