[MIPS] Allow setting of the cache attribute at run time.
Chris Dearman [Tue, 18 Sep 2007 23:58:24 +0000 (00:58 +0100)]
Slightly tacky, but there is a precedent in the sparc archirecture code.

Signed-off-by: Chris Dearman <chris@mips.com>
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

arch/mips/Kconfig.debug
arch/mips/configs/mipssim_defconfig
arch/mips/configs/pnx8550-jbs_defconfig
arch/mips/configs/pnx8550-stb810_defconfig
arch/mips/mm/c-r4k.c
arch/mips/mm/cache.c
arch/mips/philips/pnx8550/jbs/board_setup.c
arch/mips/philips/pnx8550/stb810/board_setup.c
include/asm-mips/io.h
include/asm-mips/pgtable-bits.h
include/asm-mips/pgtable.h

index fd7124c..f18cf92 100644 (file)
@@ -73,14 +73,4 @@ config RUNTIME_DEBUG
          include/asm-mips/debug.h for debuging macros.
          If unsure, say N.
 
-config MIPS_UNCACHED
-       bool "Run uncached"
-       depends on DEBUG_KERNEL && !SMP && !SGI_IP27
-       help
-         If you say Y here there kernel will disable all CPU caches.  This will
-         reduce the system's performance dramatically but can help finding
-         otherwise hard to track bugs.  It can also useful if you're doing
-         hardware debugging with a logic analyzer and need to see all traffic
-         on the bus.
-
 endmenu
index 6db0bda..4f6bce9 100644 (file)
@@ -641,7 +641,6 @@ CONFIG_CROSSCOMPILE=y
 CONFIG_CMDLINE="nfsroot=192.168.192.169:/u1/mipsel,timeo=20 ip=dhcp"
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_RUNTIME_DEBUG is not set
-# CONFIG_MIPS_UNCACHED is not set
 
 #
 # Security options
index 518a608..780c7fc 100644 (file)
@@ -1223,7 +1223,6 @@ CONFIG_CMDLINE="console=ttyS1,38400n8 kgdb=ttyS0 root=/dev/nfs ip=bootp"
 # CONFIG_KGDB is not set
 CONFIG_SYS_SUPPORTS_KGDB=y
 # CONFIG_RUNTIME_DEBUG is not set
-# CONFIG_MIPS_UNCACHED is not set
 
 #
 # Security options
index 68351eb..267f21e 100644 (file)
@@ -1213,7 +1213,6 @@ CONFIG_CMDLINE="console=ttyS1,38400n8 kgdb=ttyS0 root=/dev/nfs ip=bootp"
 # CONFIG_KGDB is not set
 CONFIG_SYS_SUPPORTS_KGDB=y
 # CONFIG_RUNTIME_DEBUG is not set
-# CONFIG_MIPS_UNCACHED is not set
 
 #
 # Security options
index 77aefb4..3d3e536 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/linkage.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/module.h>
 #include <linux/bitops.h>
 
 #include <asm/bcache.h>
@@ -1216,9 +1217,25 @@ void au1x00_fixup_config_od(void)
        }
 }
 
+static int __cpuinitdata cca = -1;
+
+static int __init cca_setup(char *str)
+{
+       get_option(&str, &cca);
+
+       return 1;
+}
+
+__setup("cca=", cca_setup);
+
 static void __cpuinit coherency_setup(void)
 {
-       change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT);
+       if (cca < 0 || cca > 7)
+               cca = read_c0_config() & CONF_CM_CMASK;
+       _page_cachable_default = cca << _CACHE_SHIFT;
+
+       pr_debug("Using cache attribute %d\n", cca);
+       change_c0_config(CONF_CM_CMASK, cca);
 
        /*
         * c0_status.cu=0 specifies that updates by the sc instruction use
index f590367..034e850 100644 (file)
@@ -130,8 +130,28 @@ void __update_cache(struct vm_area_struct *vma, unsigned long address,
        }
 }
 
-static char cache_panic[] __cpuinitdata =
-       "Yeee, unsupported cache architecture.";
+unsigned long _page_cachable_default;
+EXPORT_SYMBOL_GPL(_page_cachable_default);
+
+static inline void setup_protection_map(void)
+{
+       protection_map[0] = PAGE_NONE;
+       protection_map[1] = PAGE_READONLY;
+       protection_map[2] = PAGE_COPY;
+       protection_map[3] = PAGE_COPY;
+       protection_map[4] = PAGE_READONLY;
+       protection_map[5] = PAGE_READONLY;
+       protection_map[6] = PAGE_COPY;
+       protection_map[7] = PAGE_COPY;
+       protection_map[8] = PAGE_NONE;
+       protection_map[9] = PAGE_READONLY;
+       protection_map[10] = PAGE_SHARED;
+       protection_map[11] = PAGE_SHARED;
+       protection_map[12] = PAGE_READONLY;
+       protection_map[13] = PAGE_READONLY;
+       protection_map[14] = PAGE_SHARED;
+       protection_map[15] = PAGE_SHARED;
+}
 
 void __devinit cpu_cache_init(void)
 {
@@ -139,34 +159,29 @@ void __devinit cpu_cache_init(void)
                extern void __weak r3k_cache_init(void);
 
                r3k_cache_init();
-               return;
        }
        if (cpu_has_6k_cache) {
                extern void __weak r6k_cache_init(void);
 
                r6k_cache_init();
-               return;
        }
        if (cpu_has_4k_cache) {
                extern void __weak r4k_cache_init(void);
 
                r4k_cache_init();
-               return;
        }
        if (cpu_has_8k_cache) {
                extern void __weak r8k_cache_init(void);
 
                r8k_cache_init();
-               return;
        }
        if (cpu_has_tx39_cache) {
                extern void __weak tx39_cache_init(void);
 
                tx39_cache_init();
-               return;
        }
 
-       panic(cache_panic);
+       setup_protection_map();
 }
 
 int __weak __uncached_access(struct file *file, unsigned long addr)
index f92826e..e550a3e 100644 (file)
@@ -53,8 +53,8 @@ void __init board_setup(void)
 
        /* clear all three cache coherency fields */
        config0 &= ~(0x7 | (7<<25) | (7<<28));
-       config0 |= (CONF_CM_DEFAULT | (CONF_CM_DEFAULT<<25) |
-                       (CONF_CM_DEFAULT<<28));
+       config0 |= (_page_cachable_default >> _CACHE_SHIFT) |
+                  (CONF_CM_DEFAULT << 25) | (CONF_CM_DEFAULT << 28);
        write_c0_config(config0);
        BARRIER;
 
index 345d71e..d461d7a 100644 (file)
@@ -39,8 +39,8 @@ void __init board_setup(void)
 
        /* clear all three cache coherency fields */
        config0 &= ~(0x7 | (7<<25) | (7<<28));
-       config0 |= (CONF_CM_DEFAULT | (CONF_CM_DEFAULT<<25) |
-                       (CONF_CM_DEFAULT<<28));
+       config0 |= (_page_cachable_default >> _CACHE_SHIFT) |
+                  (CONF_CM_DEFAULT << 25) | (CONF_CM_DEFAULT << 28);
        write_c0_config(config0);
 
        configpr = read_c0_config7();
index e62058b..f18d281 100644 (file)
@@ -273,7 +273,7 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size,
  * memory-like regions on I/O busses.
  */
 #define ioremap_cachable(offset, size)                                 \
-       __ioremap_mode((offset), (size), PAGE_CACHABLE_DEFAULT)
+       __ioremap_mode((offset), (size), _page_cachable_default)
 
 /*
  * These two are MIPS specific ioremap variant.  ioremap_cacheable_cow
index 728fbe7..60e2f93 100644 (file)
 
 #define _PAGE_CHG_MASK  (PAGE_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED | _CACHE_MASK)
 
-#ifdef CONFIG_MIPS_UNCACHED
-#define PAGE_CACHABLE_DEFAULT  _CACHE_UNCACHED
-#elif defined(CONFIG_DMA_NONCOHERENT)
-#define PAGE_CACHABLE_DEFAULT  _CACHE_CACHABLE_NONCOHERENT
-#elif defined(CONFIG_CPU_RM9000)
-#define PAGE_CACHABLE_DEFAULT  _CACHE_CWB
-#elif defined(CONFIG_SOC_AU1X00)
-#define PAGE_CACHABLE_DEFAULT  _CACHE_CACHABLE_NONCOHERENT
-#else
-#define PAGE_CACHABLE_DEFAULT  _CACHE_CACHABLE_COW
-#endif
-
 #define CONF_CM_DEFAULT                (PAGE_CACHABLE_DEFAULT>>_CACHE_SHIFT)
 
 #endif /* _ASM_PGTABLE_BITS_H */
index 009b7b1..582f56f 100644 (file)
@@ -23,15 +23,15 @@ struct vm_area_struct;
 
 #define PAGE_NONE      __pgprot(_PAGE_PRESENT | _CACHE_CACHABLE_NONCOHERENT)
 #define PAGE_SHARED    __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
-                       PAGE_CACHABLE_DEFAULT)
+                                _page_cachable_default)
 #define PAGE_COPY      __pgprot(_PAGE_PRESENT | _PAGE_READ | \
-                       PAGE_CACHABLE_DEFAULT)
+                                _page_cachable_default)
 #define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_READ | \
-                       PAGE_CACHABLE_DEFAULT)
+                                _page_cachable_default)
 #define PAGE_KERNEL    __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
-                       _PAGE_GLOBAL | PAGE_CACHABLE_DEFAULT)
+                                _PAGE_GLOBAL | _page_cachable_default)
 #define PAGE_USERIO    __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
-                       PAGE_CACHABLE_DEFAULT)
+                                _page_cachable_default)
 #define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | \
                        __WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED)
 
@@ -40,23 +40,30 @@ struct vm_area_struct;
  * read. Also, write permissions imply read permissions. This is the closest
  * we can get by reasonable means..
  */
-#define __P000 PAGE_NONE
-#define __P001 PAGE_READONLY
-#define __P010 PAGE_COPY
-#define __P011 PAGE_COPY
-#define __P100 PAGE_READONLY
-#define __P101 PAGE_READONLY
-#define __P110 PAGE_COPY
-#define __P111 PAGE_COPY
-
-#define __S000 PAGE_NONE
-#define __S001 PAGE_READONLY
-#define __S010 PAGE_SHARED
-#define __S011 PAGE_SHARED
-#define __S100 PAGE_READONLY
-#define __S101 PAGE_READONLY
-#define __S110 PAGE_SHARED
-#define __S111 PAGE_SHARED
+
+/*
+ * Dummy values to fill the table in mmap.c
+ * The real values will be generated at runtime
+ */
+#define __P000 __pgprot(0)
+#define __P001 __pgprot(0)
+#define __P010 __pgprot(0)
+#define __P011 __pgprot(0)
+#define __P100 __pgprot(0)
+#define __P101 __pgprot(0)
+#define __P110 __pgprot(0)
+#define __P111 __pgprot(0)
+
+#define __S000 __pgprot(0)
+#define __S001 __pgprot(0)
+#define __S010 __pgprot(0)
+#define __S011 __pgprot(0)
+#define __S100 __pgprot(0)
+#define __S101 __pgprot(0)
+#define __S110 __pgprot(0)
+#define __S111 __pgprot(0)
+
+extern unsigned long _page_cachable_default;
 
 /*
  * ZERO_PAGE is a global shared page that is always zero; used