]> git.sur5r.net Git - u-boot/blobdiff - arch/mips/cpu/start.S
MIPS: Fix cache maintenance in relocate_code & simplify
[u-boot] / arch / mips / cpu / start.S
index e95cdca61eba2db1b88700c7d297558a09e405d1..cbc02fa9fe0ddce156be9ca808ac5be83ddde2aa 100644 (file)
 #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)
@@ -57,7 +53,7 @@
        .set noreorder
 
 ENTRY(_start)
-       /* U-boot entry point */
+       /* U-Boot entry point */
        b       reset
         nop
 
@@ -115,7 +111,7 @@ reset:
 
        /* 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
@@ -127,9 +123,11 @@ reset:
        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
 
        /*
@@ -144,32 +142,45 @@ reset:
 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
@@ -177,15 +188,15 @@ reset:
        /* 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
@@ -212,52 +223,31 @@ ENTRY(relocate_code)
        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)
@@ -265,16 +255,16 @@ in_ram:
         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
@@ -293,7 +283,21 @@ in_ram:
 
 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
@@ -307,7 +311,7 @@ in_ram:
 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