]> git.sur5r.net Git - u-boot/blobdiff - arch/mips/cpu/start.S
Merge git://git.denx.de/u-boot-fsl-qoriq
[u-boot] / arch / mips / cpu / start.S
index 827a544987852587a1ca7018e2a160c4b71b19ca..3f0fc125475271835456db3490bd47a61a3dbb1b 100644 (file)
@@ -108,9 +108,28 @@ ENTRY(_start)
 
        .align 4
 reset:
+#if __mips_isa_rev >= 6
+       mfc0    t0, CP0_CONFIG, 5
+       and     t0, t0, MIPS_CONF5_VP
+       beqz    t0, 1f
+        nop
+
+       b       2f
+        mfc0   t0, CP0_GLOBALNUMBER
+#endif
+
+1:     mfc0    t0, CP0_EBASE
+       and     t0, t0, EBASE_CPUNUM
+
+       /* Hang if this isn't the first CPU in the system */
+2:     beqz    t0, 4f
+        nop
+3:     wait
+       b       3b
+        nop
 
        /* Clear watch registers */
-       MTC0    zero, CP0_WATCHLO
+4:     MTC0    zero, CP0_WATCHLO
        mtc0    zero, CP0_WATCHHI
 
        /* WP(Watch Pending), SW0/1 should be cleared */
@@ -123,9 +142,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
 
        /*
@@ -140,16 +161,31 @@ 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
+
+# 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 */
@@ -206,12 +242,9 @@ 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
@@ -224,32 +257,14 @@ ENTRY(relocate_code)
        blt     t0, t2, 1b
         PTR_ADDU t1, PTRSIZE
 
-       /* 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_ADDIU 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
-
-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_ADDIU t8, t8, 2 * PTRSIZE   # skipping first two entries
        PTR_LI  t2, 2
@@ -264,8 +279,8 @@ in_ram:
         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_ADDIU t1, 2 * PTRSIZE
@@ -289,6 +304,20 @@ in_ram:
        blt     t1, t2, 1b
         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
         *