armv7: integrate cache maintenance support
authorAneesh V <aneesh@ti.com>
Thu, 16 Jun 2011 23:30:49 +0000 (23:30 +0000)
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>
Mon, 4 Jul 2011 08:55:25 +0000 (10:55 +0200)
- Enable I-cache on bootup
- Enable MMU and D-cache immediately after relocation
- Do necessary initialization before enabling d-cache and MMU
- Changes to cleanup_before_linux()
- Make changes according to the new framework

Signed-off-by: Aneesh V <aneesh@ti.com>
arch/arm/cpu/armv7/cpu.c
arch/arm/cpu/armv7/start.S
arch/arm/lib/board.c
arch/arm/lib/cache-cp15.c
arch/arm/lib/cache.c

index bc4238f6d8656f54417c80e98e49b97c478d1c9e..def9ced64faffdf744f65f673ee8002cb8c8c40f 100644 (file)
 #include <command.h>
 #include <asm/system.h>
 #include <asm/cache.h>
-
-static void cache_flush(void);
+#include <asm/armv7.h>
 
 int cleanup_before_linux(void)
 {
-       unsigned int i;
-
        /*
         * this function is called just before we call linux
         * it prepares the processor for linux
@@ -50,31 +47,29 @@ int cleanup_before_linux(void)
         */
        disable_interrupts();
 
-       /* turn off I/D-cache */
+       /*
+        * Turn off I-cache and invalidate it
+        */
        icache_disable();
-       dcache_disable();
-
-       /* invalidate I-cache */
-       cache_flush();
+       invalidate_icache_all();
 
-#ifndef CONFIG_L2_OFF
-       /* turn off L2 cache */
-       l2_cache_disable();
-       /* invalidate L2 cache also */
-       invalidate_dcache(get_device_type());
-#endif
-       i = 0;
-       /* mem barrier to sync up things */
-       asm("mcr p15, 0, %0, c7, c10, 4": :"r"(i));
+       /*
+        * turn off D-cache
+        * dcache_disable() in turn flushes the d-cache and disables MMU
+        */
+       dcache_disable();
 
-#ifndef CONFIG_L2_OFF
-       l2_cache_enable();
-#endif
+       /*
+        * After D-cache is flushed and before it is disabled there may
+        * be some new valid entries brought into the cache. We are sure
+        * that these lines are not dirty and will not affect our execution.
+        * (because unwinding the call-stack and setting a bit in CP15 SCTRL
+        * is all we did during this. We have not pushed anything on to the
+        * stack. Neither have we affected any static data)
+        * So just invalidate the entire d-cache again to avoid coherency
+        * problems for kernel
+        */
+       invalidate_dcache_all();
 
        return 0;
 }
-
-static void cache_flush(void)
-{
-       asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (0));
-}
index d91ae12cb99b29cccb33f62215f267fb063c7376..0e698b624b6c161467b9153201ad37f9abb2e3d2 100644 (file)
@@ -255,6 +255,14 @@ clbss_l:str        r2, [r0]                /* clear loop...                    */
  * initialization, now running from RAM.
  */
 jump_2_ram:
+/*
+ * If I-cache is enabled invalidate it
+ */
+#ifndef CONFIG_SYS_ICACHE_OFF
+       mcr     p15, 0, r0, c7, c5, 0   @ invalidate icache
+       mcr     p15, 0, r0, c7, c10, 4  @ DSB
+       mcr     p15, 0, r0, c7, c5, 4   @ ISB
+#endif
        ldr     r0, _board_init_r_ofs
        adr     r1, _start
        add     lr, r0, r1
@@ -290,6 +298,9 @@ cpu_init_crit:
        mov     r0, #0                  @ set up for MCR
        mcr     p15, 0, r0, c8, c7, 0   @ invalidate TLBs
        mcr     p15, 0, r0, c7, c5, 0   @ invalidate icache
+       mcr     p15, 0, r0, c7, c5, 6   @ invalidate BP array
+       mcr     p15, 0, r0, c7, c10, 4  @ DSB
+       mcr     p15, 0, r0, c7, c5, 4   @ ISB
 
        /*
         * disable MMU stuff and caches
@@ -298,7 +309,12 @@ cpu_init_crit:
        bic     r0, r0, #0x00002000     @ clear bits 13 (--V-)
        bic     r0, r0, #0x00000007     @ clear bits 2:0 (-CAM)
        orr     r0, r0, #0x00000002     @ set bit 1 (--A-) Align
-       orr     r0, r0, #0x00000800     @ set bit 12 (Z---) BTB
+       orr     r0, r0, #0x00000800     @ set bit 11 (Z---) BTB
+#ifdef CONFIG_SYS_ICACHE_OFF
+       bic     r0, r0, #0x00001000     @ clear bit 12 (I) I-cache
+#else
+       orr     r0, r0, #0x00001000     @ set bit 12 (I) I-cache
+#endif
        mcr     p15, 0, r0, c1, c0, 0
 
        /*
index 4f88f5823b1e6a24226914dbeb3ad3c5b24fec51..fc52a26b797a47c2945e9846c4d877efb58b091b 100644 (file)
@@ -450,6 +450,12 @@ void board_init_r (gd_t *id, ulong dest_addr)
        gd->flags |= GD_FLG_RELOC;      /* tell others: relocation done */
 
        monitor_flash_len = _end_ofs;
+       /*
+        * Enable D$:
+        * I$, if needed, must be already enabled in start.S
+        */
+       dcache_enable();
+
        debug ("monitor flash len: %08lX\n", monitor_flash_len);
        board_init();   /* Setup chipselects */
 
index ba73fb925cfc8372bdcf18fa04a78304b7255102..51831a96b54c5562e36f9e14c740d38e452cd345 100644 (file)
 
 DECLARE_GLOBAL_DATA_PTR;
 
+void __arm_init_before_mmu(void)
+{
+}
+void arm_init_before_mmu(void)
+       __attribute__((weak, alias("__arm_init_before_mmu")));
+
 static void cp_delay (void)
 {
        volatile int i;
@@ -65,6 +71,7 @@ static inline void mmu_setup(void)
        int i;
        u32 reg;
 
+       arm_init_before_mmu();
        /* Set up an identity-mapping for all 4GB, rw for everyone */
        for (i = 0; i < 4096; i++)
                page_table[i] = i << 20 | (3 << 10) | 0x12;
index 27123cd121f03c57a03aa4e73e92682dbd7c408c..dc3242c90d8d17d7529e277dd0552f76971dcc5d 100644 (file)
@@ -37,11 +37,6 @@ void  __flush_cache(unsigned long start, unsigned long size)
        asm("0: mrc p15, 0, r15, c7, c10, 3\n\t" "bne 0b\n" : : : "memory");
        /* disable write buffer as well (page 2-22) */
        asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
-#endif
-#ifdef CONFIG_OMAP34XX
-       void v7_flush_cache_all(void);
-
-       v7_flush_cache_all();
 #endif
        return;
 }