ARC: Disable caches in early boot if so configured
authorVineet Gupta <vgupta@synopsys.com>
Fri, 7 Mar 2014 12:38:11 +0000 (18:08 +0530)
committerVineet Gupta <vgupta@synopsys.com>
Tue, 3 Jun 2014 09:44:48 +0000 (15:14 +0530)
Requested-by: Noam Camus <noamc@ezchip.com>
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
arch/arc/include/asm/cache.h
arch/arc/kernel/head.S
arch/arc/mm/cache_arc700.c

index 2fd3162..c1d3d2d 100644 (file)
@@ -55,4 +55,31 @@ extern void read_decode_cache_bcr(void);
 
 #endif /* !__ASSEMBLY__ */
 
+/* Instruction cache related Auxiliary registers */
+#define ARC_REG_IC_BCR         0x77    /* Build Config reg */
+#define ARC_REG_IC_IVIC                0x10
+#define ARC_REG_IC_CTRL                0x11
+#define ARC_REG_IC_IVIL                0x19
+#if defined(CONFIG_ARC_MMU_V3) || defined (CONFIG_ARC_MMU_V4)
+#define ARC_REG_IC_PTAG                0x1E
+#endif
+
+/* Bit val in IC_CTRL */
+#define IC_CTRL_CACHE_DISABLE   0x1
+
+/* Data cache related Auxiliary registers */
+#define ARC_REG_DC_BCR         0x72    /* Build Config reg */
+#define ARC_REG_DC_IVDC                0x47
+#define ARC_REG_DC_CTRL                0x48
+#define ARC_REG_DC_IVDL                0x4A
+#define ARC_REG_DC_FLSH                0x4B
+#define ARC_REG_DC_FLDL                0x4C
+#if defined(CONFIG_ARC_MMU_V3) || defined (CONFIG_ARC_MMU_V4)
+#define ARC_REG_DC_PTAG                0x5C
+#endif
+
+/* Bit val in DC_CTRL */
+#define DC_CTRL_INV_MODE_FLUSH  0x40
+#define DC_CTRL_FLUSH_STATUS    0x100
+
 #endif /* _ASM_CACHE_H */
index 4ad0491..07a58f2 100644 (file)
  *      to skip certain things during boot on simulator
  */
 
+#include <linux/linkage.h>
 #include <asm/asm-offsets.h>
 #include <asm/entry.h>
-#include <linux/linkage.h>
 #include <asm/arcregs.h>
+#include <asm/cache.h>
+
+.macro CPU_EARLY_SETUP
+
+       ; Setting up Vectror Table (in case exception happens in early boot
+       sr      @_int_vec_base_lds, [AUX_INTR_VEC_BASE]
+
+       ; Disable I-cache/D-cache if kernel so configured
+       lr      r5, [ARC_REG_IC_BCR]
+       breq    r5, 0, 1f               ; I$ doesn't exist
+       lr      r5, [ARC_REG_IC_CTRL]
+#ifdef CONFIG_ARC_HAS_ICACHE
+       bclr    r5, r5, 0               ; 0 - Enable, 1 is Disable
+#else
+       bset    r5, r5, 0               ; I$ exists, but is not used
+#endif
+       sr      r5, [ARC_REG_IC_CTRL]
+
+1:
+       lr      r5, [ARC_REG_DC_BCR]
+       breq    r5, 0, 1f               ; D$ doesn't exist
+       lr      r5, [ARC_REG_DC_CTRL]
+       bclr    r5, r5, 6               ; Invalidate (discard w/o wback)
+#ifdef CONFIG_ARC_HAS_DCACHE
+       bclr    r5, r5, 0               ; Enable (+Inv)
+#else
+       bset    r5, r5, 0               ; Disable (+Inv)
+#endif
+       sr      r5, [ARC_REG_DC_CTRL]
+
+1:
+.endm
 
        .cpu A7
 
@@ -27,7 +59,7 @@ stext:
        ; Don't clobber r0-r2 yet. It might have bootloader provided info
        ;-------------------------------------------------------------------
 
-       sr      @_int_vec_base_lds, [AUX_INTR_VEC_BASE]
+       CPU_EARLY_SETUP
 
 #ifdef CONFIG_SMP
        ; Ensure Boot (Master) proceeds. Others wait in platform dependent way
@@ -90,7 +122,7 @@ stext:
 
 first_lines_of_secondary:
 
-       sr      @_int_vec_base_lds, [AUX_INTR_VEC_BASE]
+       CPU_EARLY_SETUP
 
        ; setup per-cpu idle task as "current" on this CPU
        ld      r0, [@secondary_idle_tsk]
index 23c3832..1f676c4 100644 (file)
 #include <asm/cachectl.h>
 #include <asm/setup.h>
 
-/* Instruction cache related Auxiliary registers */
-#define ARC_REG_IC_BCR         0x77    /* Build Config reg */
-#define ARC_REG_IC_IVIC                0x10
-#define ARC_REG_IC_CTRL                0x11
-#define ARC_REG_IC_IVIL                0x19
-#if (CONFIG_ARC_MMU_VER > 2)
-#define ARC_REG_IC_PTAG                0x1E
-#endif
-
-/* Bit val in IC_CTRL */
-#define IC_CTRL_CACHE_DISABLE   0x1
-
-/* Data cache related Auxiliary registers */
-#define ARC_REG_DC_BCR         0x72    /* Build Config reg */
-#define ARC_REG_DC_IVDC                0x47
-#define ARC_REG_DC_CTRL                0x48
-#define ARC_REG_DC_IVDL                0x4A
-#define ARC_REG_DC_FLSH                0x4B
-#define ARC_REG_DC_FLDL                0x4C
-#if (CONFIG_ARC_MMU_VER > 2)
-#define ARC_REG_DC_PTAG                0x5C
-#endif
-
-/* Bit val in DC_CTRL */
-#define DC_CTRL_INV_MODE_FLUSH  0x40
-#define DC_CTRL_FLUSH_STATUS    0x100
-
 char *arc_cache_mumbojumbo(int c, char *buf, int len)
 {
        int n = 0;
@@ -168,72 +141,43 @@ void read_decode_cache_bcr(void)
  */
 void arc_cache_init(void)
 {
-       unsigned int cpu = smp_processor_id();
-       struct cpuinfo_arc_cache *ic = &cpuinfo_arc700[cpu].icache;
-       struct cpuinfo_arc_cache *dc = &cpuinfo_arc700[cpu].dcache;
-       unsigned int dcache_does_alias, temp;
+       unsigned int __maybe_unused cpu = smp_processor_id();
+       struct cpuinfo_arc_cache __maybe_unused *ic, __maybe_unused *dc;
        char str[256];
 
        printk(arc_cache_mumbojumbo(0, str, sizeof(str)));
 
-       if (!ic->ver)
-               goto chk_dc;
-
 #ifdef CONFIG_ARC_HAS_ICACHE
-       /* 1. Confirm some of I-cache params which Linux assumes */
-       if (ic->line_len != L1_CACHE_BYTES)
-               panic("Cache H/W doesn't match kernel Config");
-
-       if (ic->ver != CONFIG_ARC_MMU_VER)
-               panic("Cache ver doesn't match MMU ver\n");
-#endif
-
-       /* Enable/disable I-Cache */
-       temp = read_aux_reg(ARC_REG_IC_CTRL);
-
-#ifdef CONFIG_ARC_HAS_ICACHE
-       temp &= ~IC_CTRL_CACHE_DISABLE;
-#else
-       temp |= IC_CTRL_CACHE_DISABLE;
+       ic = &cpuinfo_arc700[cpu].icache;
+       if (ic->ver) {
+               if (ic->line_len != L1_CACHE_BYTES)
+                       panic("ICache line [%d] != kernel Config [%d]",
+                             ic->line_len, L1_CACHE_BYTES);
+
+               if (ic->ver != CONFIG_ARC_MMU_VER)
+                       panic("Cache ver [%d] doesn't match MMU ver [%d]\n",
+                             ic->ver, CONFIG_ARC_MMU_VER);
+       }
 #endif
 
-       write_aux_reg(ARC_REG_IC_CTRL, temp);
-
-chk_dc:
-       if (!dc->ver)
-               return;
-
 #ifdef CONFIG_ARC_HAS_DCACHE
-       if (dc->line_len != L1_CACHE_BYTES)
-               panic("Cache H/W doesn't match kernel Config");
+       dc = &cpuinfo_arc700[cpu].dcache;
+       if (dc->ver) {
+               unsigned int dcache_does_alias;
 
-       /* check for D-Cache aliasing */
-       dcache_does_alias = (dc->sz / dc->assoc) > PAGE_SIZE;
+               if (dc->line_len != L1_CACHE_BYTES)
+                       panic("DCache line [%d] != kernel Config [%d]",
+                             dc->line_len, L1_CACHE_BYTES);
 
-       if (dcache_does_alias && !cache_is_vipt_aliasing())
-               panic("Enable CONFIG_ARC_CACHE_VIPT_ALIASING\n");
-       else if (!dcache_does_alias && cache_is_vipt_aliasing())
-               panic("Don't need CONFIG_ARC_CACHE_VIPT_ALIASING\n");
-#endif
+               /* check for D-Cache aliasing */
+               dcache_does_alias = (dc->sz / dc->assoc) > PAGE_SIZE;
 
-       /* Set the default Invalidate Mode to "simpy discard dirty lines"
-        *  as this is more frequent then flush before invalidate
-        * Ofcourse we toggle this default behviour when desired
-        */
-       temp = read_aux_reg(ARC_REG_DC_CTRL);
-       temp &= ~DC_CTRL_INV_MODE_FLUSH;
-
-#ifdef CONFIG_ARC_HAS_DCACHE
-       /* Enable D-Cache: Clear Bit 0 */
-       write_aux_reg(ARC_REG_DC_CTRL, temp & ~IC_CTRL_CACHE_DISABLE);
-#else
-       /* Flush D cache */
-       write_aux_reg(ARC_REG_DC_FLSH, 0x1);
-       /* Disable D cache */
-       write_aux_reg(ARC_REG_DC_CTRL, temp | IC_CTRL_CACHE_DISABLE);
+               if (dcache_does_alias && !cache_is_vipt_aliasing())
+                       panic("Enable CONFIG_ARC_CACHE_VIPT_ALIASING\n");
+               else if (!dcache_does_alias && cache_is_vipt_aliasing())
+                       panic("Don't need CONFIG_ARC_CACHE_VIPT_ALIASING\n");
+       }
 #endif
-
-       return;
 }
 
 #define OP_INV         0x1