Print this page
unix: enable caches in locore
The loader should really be as simple as possible to be as small as
possible.  It should configure the machine so that unix can make certain
assumptions but it should leave more complex initialization to unix.

@@ -40,11 +40,11 @@
  * - virtual memory is enabled
  *   - we (unix) are mapped right were we want to be
  *   - a UART has been enabled & any memory mapped registers have been 1:1
  *     mapped
  *   - ATAGs have been updated to tell us what the mappings are
- * - I/D L1 caches have been enabled
+ * - I/D L1 caches have may be disabled
  */
 
         /*
          * External globals
          */

@@ -87,10 +87,24 @@
         /* Enable highvecs (moves the base of the exception vector) */
         mrc     p15, 0, r3, c1, c0, 0
         orr     r3, r3, #(1 << 13)
         mcr     p15, 0, r3, c1, c0, 0
 
+        /*
+         * Go ahead now and enable the L1 I/D caches.  (Involves
+         * invalidating the caches and the TLB.)
+         */
+        mov     r4, #0
+        mov     r5, #0
+        mcr     p15, 0, r4, c7, c7, 0   /* invalidate caches */
+        mcr     p15, 0, r4, c8, c7, 0   /* invalidate tlb */
+        mcr     p15, 0, r5, c7, c10, 4  /* DSB */
+        mrc     p15, 0, r4, c1, c0, 0
+        orr     r4, #0x04       /* D-cache */
+        orr     r4, #0x1000     /* I-cache */
+        mcr     p15, 0, r4, c1, c0, 0
+
         /* invoke machine specific setup */
         bl      _mach_start
 
         bl      _fakebop_start
         SET_SIZE(_start)

@@ -109,11 +123,10 @@
          * We got here from _kobj_init() via exitto().  We have a few different
          * tasks that we need to take care of before we hop into mlsetup and
          * then main. We're never going back so we shouldn't feel compelled to
          * preserve any registers.
          *
-         *  o Enable our I/D-caches
          *  o Save the boot syscalls and bootops for later
          *  o Set up our stack to be the real stack of t0stack.
          *  o Save t0 as curthread
          *  o Set up a struct REGS for mlsetup
          *  o Make sure that we're 8 byte aligned for the call

@@ -160,18 +173,10 @@
          */
         ldr     r0, =t0
         mcr     p15, 0, r0, c13, c0, 4
 
         /*
-         * Go ahead now and enable the L1 I/D caches.  
-         */
-        mrc     p15, 0, r0, c1, c0, 0
-        orr     r0, #0x04       /* D-cache */
-        orr     r0, #0x1000     /* I-cache */
-        mcr     p15, 0, r0, c1, c0, 0
-
-        /*
          * mlsetup() takes the struct regs as an argument. main doesn't take
          * any and should never return. Currently, we have an 8-byte aligned
          * stack.  We want to push a zero frame pointer to terminate any
          * stack walking, but that would cause us to end up with only a
          * 4-byte aligned stack.  So, to keep things nice and correct, we