#include <asm/regdef.h>
#include <asm/mipsregs.h>
-#ifndef CONFIG_SYS_MIPS_CACHE_MODE
-#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT
-#endif
-
#ifndef CONFIG_SYS_INIT_SP_ADDR
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + \
CONFIG_SYS_INIT_SP_OFFSET)
.set noreorder
- .globl _start
- .text
-_start:
- /* U-boot entry point */
+ENTRY(_start)
+ /* U-Boot entry point */
b reset
nop
/* Clear watch registers */
MTC0 zero, CP0_WATCHLO
- MTC0 zero, CP0_WATCHHI
+ mtc0 zero, CP0_WATCHHI
/* WP(Watch Pending), SW0/1 should be cleared */
mtc0 zero, CP0_CAUSE
mtc0 zero, CP0_COMPARE
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
- /* CONFIG0 register */
- li t0, CONF_CM_UNCACHED
+ mfc0 t0, CP0_CONFIG
+ and t0, t0, MIPS_CONF_IMPL
+ or t0, t0, CONF_CM_UNCACHED
mtc0 t0, CP0_CONFIG
+ ehb
#endif
/*
1:
PTR_L gp, 0(ra)
+#ifdef CONFIG_MIPS_CM
+ PTR_LA t9, mips_cm_map
+ jalr t9
+ nop
+#endif
+
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+# ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
/* Initialize any external memory */
PTR_LA t9, lowlevel_init
jalr t9
nop
+# endif
/* Initialize caches... */
PTR_LA t9, mips_cache_reset
jalr t9
nop
- /* ... and enable them */
- li t0, CONFIG_SYS_MIPS_CACHE_MODE
- mtc0 t0, CP0_CONFIG
+# ifndef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
+ /* Initialize any external memory */
+ PTR_LA t9, lowlevel_init
+ jalr t9
+ nop
+# endif
#endif
/* Set up temporary stack */
- PTR_LI t0, -16
+ li t0, -16
PTR_LI t1, CONFIG_SYS_INIT_SP_ADDR
and sp, t1, t0 # force 16 byte alignment
- PTR_SUB sp, sp, GD_SIZE # reserve space for gd
+ PTR_SUBU \
+ sp, sp, GD_SIZE # reserve space for gd
and sp, sp, t0 # force 16 byte alignment
move k0, sp # save gd pointer
#ifdef CONFIG_SYS_MALLOC_F_LEN
- PTR_LI t2, CONFIG_SYS_MALLOC_F_LEN
- PTR_SUB sp, sp, t2 # reserve space for early malloc
+ li t2, CONFIG_SYS_MALLOC_F_LEN
+ PTR_SUBU \
+ sp, sp, t2 # reserve space for early malloc
and sp, sp, t0 # force 16 byte alignment
#endif
move fp, sp
/* Clear gd */
move t0, k0
1:
- sw zero, 0(t0)
+ PTR_S zero, 0(t0)
blt t0, t1, 1b
- PTR_ADDI t0, 4
+ PTR_ADDIU t0, PTRSIZE
#ifdef CONFIG_SYS_MALLOC_F_LEN
- PTR_ADDU t0, k0, GD_MALLOC_BASE # gd->malloc_base offset
- sw sp, 0(t0)
+ PTR_S sp, GD_MALLOC_BASE(k0) # gd->malloc_base offset
#endif
+ move a0, zero # a0 <-- boot_flags = 0
PTR_LA t9, board_init_f
jr t9
move ra, zero
+ END(_start)
+
/*
* void relocate_code (addr_sp, gd, addr_moni)
*
* a1 = gd
* a2 = destination address
*/
- .globl relocate_code
- .ent relocate_code
-relocate_code:
+ENTRY(relocate_code)
move sp, a0 # set new stack pointer
move fp, sp
PTR_LI t0, CONFIG_SYS_MONITOR_BASE
PTR_SUB s1, s2, t0 # s1 <-- relocation offset
- PTR_LA t3, in_ram
- PTR_L t2, -(3 * PTRSIZE)(t3) # t2 <-- __image_copy_end
+ PTR_LA t2, __image_copy_end
move t1, a2
- PTR_ADD gp, s1 # adjust gp
-
/*
* t0 = source address
* t1 = target address
* t2 = source end address
*/
1:
- lw t3, 0(t0)
- sw t3, 0(t1)
- PTR_ADDU t0, 4
+ PTR_L t3, 0(t0)
+ PTR_S t3, 0(t1)
+ PTR_ADDU t0, PTRSIZE
blt t0, t2, 1b
- PTR_ADDU t1, 4
-
- /* If caches were enabled, we would have to flush them here. */
- PTR_SUB a1, t1, s2 # a1 <-- size
- PTR_LA t9, flush_cache
- jalr t9
- move a0, s2 # a0 <-- destination address
-
- /* Jump to where we've relocated ourselves */
- PTR_ADDI t0, s2, in_ram - _start
- jr t0
- nop
-
- PTR __rel_dyn_end
- PTR __rel_dyn_start
- PTR __image_copy_end
- PTR _GLOBAL_OFFSET_TABLE_
- PTR num_got_entries
+ PTR_ADDU t1, PTRSIZE
-in_ram:
/*
* 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.
*/
- PTR_L t3, -(1 * PTRSIZE)(t0) # t3 <-- num_got_entries
- PTR_L t8, -(2 * PTRSIZE)(t0) # t8 <-- _GLOBAL_OFFSET_TABLE_
+ PTR_LA t3, num_got_entries
+ PTR_LA t8, _GLOBAL_OFFSET_TABLE_
PTR_ADD t8, s1 # t8 now holds relocated _G_O_T_
- PTR_ADDI t8, t8, 2 * PTRSIZE # skipping first two entries
+ PTR_ADDIU t8, t8, 2 * PTRSIZE # skipping first two entries
PTR_LI t2, 2
1:
PTR_L t1, 0(t8)
PTR_ADD t1, s1
PTR_S t1, 0(t8)
2:
- PTR_ADDI t2, 1
+ PTR_ADDIU t2, 1
blt t2, t3, 1b
- PTR_ADDI t8, PTRSIZE
+ PTR_ADDIU t8, PTRSIZE
/* Update dynamic relocations */
- PTR_L t1, -(4 * PTRSIZE)(t0) # t1 <-- __rel_dyn_start
- PTR_L t2, -(5 * PTRSIZE)(t0) # t2 <-- __rel_dyn_end
+ PTR_LA t1, __rel_dyn_start
+ PTR_LA t2, __rel_dyn_end
b 2f # skip first reserved entry
- PTR_ADDI t1, 2 * PTRSIZE
+ PTR_ADDIU t1, 2 * PTRSIZE
1:
lw t8, -4(t1) # t8 <-- relocation info
2:
blt t1, t2, 1b
- PTR_ADDI t1, 2 * PTRSIZE # each rel.dyn entry is 2*PTRSIZE bytes
+ PTR_ADDIU t1, 2 * PTRSIZE # each rel.dyn entry is 2*PTRSIZE bytes
+
+ /*
+ * Flush caches to ensure our newly modified instructions are visible
+ * to the instruction cache. We're still running with the old GOT, so
+ * apply the reloc offset to the start address.
+ */
+ PTR_LA a0, __text_start
+ PTR_LA a1, __text_end
+ PTR_SUB a1, a1, a0
+ PTR_LA t9, flush_cache
+ jalr t9
+ PTR_ADD a0, s1
+
+ PTR_ADD gp, s1 # adjust gp
/*
* Clear BSS
1:
PTR_S zero, 0(t1)
blt t1, t2, 1b
- PTR_ADDI t1, PTRSIZE
+ PTR_ADDIU t1, PTRSIZE
move a0, s0 # a0 <-- gd
move a1, s2
jr t9
move ra, zero
- .end relocate_code
+ END(relocate_code)