l2 cache support for the O2

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello again,

	This patch adds support for the secondary cache on the O2. It
works basically as the cache support for the ip22 (i.e. using the
board_cache interface)

Vivien Chappelier.
diff -Naur linux/arch/mips64/defconfig-ip32 linux.patch/arch/mips64/defconfig-ip32
--- linux/arch/mips64/defconfig-ip32	Tue Jan  1 21:51:11 2002
+++ linux.patch/arch/mips64/defconfig-ip32	Thu Jan  3 20:43:10 2002
@@ -27,6 +27,7 @@
 CONFIG_MAPPED_PCI_IO=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_ARC_MEMORY=y
+CONFIG_BOARD_SCACHE=y
 CONFIG_L1_CACHE_SHIFT=5
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
diff -Naur linux/arch/mips64/sgi-ip32/Makefile linux.patch/arch/mips64/sgi-ip32/Makefile
--- linux/arch/mips64/sgi-ip32/Makefile	Tue Jan  1 21:51:12 2002
+++ linux.patch/arch/mips64/sgi-ip32/Makefile	Thu Jan  3 20:42:15 2002
@@ -18,7 +18,7 @@
 all: ip32-kern.a ip32-irq-glue.o
 
 obj-y	+= ip32-rtc.o ip32-setup.o ip32-irq.o ip32-irq-glue.o ip32-timer.o \
-	   crime.o ip32-reset.o
+	   crime.o ip32-reset.o ip32-sc.o
 
 obj-$(CONFIG_PCI)   += ip32-pci.o ip32-pci-dma.o
 
diff -Naur linux/arch/mips64/sgi-ip32/ip32-sc.c linux.patch/arch/mips64/sgi-ip32/ip32-sc.c
--- linux/arch/mips64/sgi-ip32/ip32-sc.c	Thu Jan  1 01:00:00 1970
+++ linux.patch/arch/mips64/sgi-ip32/ip32-sc.c	Thu Jan  3 20:42:30 2002
@@ -0,0 +1,154 @@
+/*
+ * ip32-sc.c: O2 cache management functions.
+ *
+ * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org),
+ * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com).
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/mipsregs.h>
+#include <asm/bcache.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/mmu_context.h>
+
+/* Secondary cache size in bytes, if present.  */
+static unsigned long scache_size;
+
+#undef DEBUG_CACHE
+
+#define SC_LINE 32
+
+#define Clear_SD                0x03
+#define Index_Load_Tag_SD	0x07
+#define Index_Store_Tag_SD	0x0B
+#define Page_Writeback_Inv_SD   0x17
+
+#if 0 /* This is supposed to flush the whole cache but doesn't seem to work */
+static inline void flush_scache_all(void)
+{ 
+        unsigned long addr = KSEG0;
+
+	set_taglo(0);
+        __asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */
+	__asm__ __volatile__("\n\t.set noreorder\n\t"
+			     "cache 0x03, (%0)\n\t"
+			     ".set reorder\n\t" : : "r" (addr));
+}
+#endif
+
+static inline void flush_scache_page(unsigned long page)
+{
+	__asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */
+	__asm__ __volatile__("\n\t.set noreorder\n\t"
+			     "cache 0x17, (%0)\n\t"
+			     ".set reorder\n\t" : : "r" (page));
+}
+
+static inline void flush_scache_all(void)
+{
+        unsigned long start = KSEG0;  /* unmapped */
+	unsigned long end = (start + scache_size);
+
+	set_taglo(0);
+	while(start < end) {
+	        flush_scache_page(start);
+		start += PAGE_SIZE;
+	}
+}
+
+static void ip32_sc_wback_invalidate(unsigned long addr, unsigned long size)
+{
+	unsigned long begin, end;
+	unsigned int flags;
+
+#ifdef DEBUG_CACHE
+	printk("ip32_sc_wback_invalidate[%08lx,%08lx]", addr, size);
+#endif
+
+	if (!size)
+		return;
+
+	/* Which pages to flush?  */
+	begin = (addr & PAGE_MASK);
+	end = (addr+size+PAGE_SIZE-1) & PAGE_MASK;
+	/* Which lines to flush?  */ 
+	begin = KSEG0 + (begin & (scache_size - SC_LINE)); /* unmapped */
+	end = KSEG0 + (end & (scache_size - SC_LINE));
+
+	set_taglo(0); /* invalidate flushed page */
+	__save_and_cli(flags);
+	if(begin < end) {
+	  for(addr = begin; addr < end; addr += PAGE_SIZE)
+	    flush_scache_page(addr);
+	  __asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */
+	} else {
+	  for(addr = begin; addr < (KSEG0+scache_size); addr += PAGE_SIZE)
+	    flush_scache_page(addr);
+	  __asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */
+	  for(addr = KSEG0; addr < end; addr += PAGE_SIZE)
+	    flush_scache_page(addr);
+	  __asm__ __volatile__("nop; nop; nop; nop;"); /* avoid the hazard */
+	}
+	__restore_flags(flags);
+}
+
+static void ip32_sc_enable(void)
+{
+        unsigned long flags;
+
+	/* This is really cool... */
+#ifdef DEBUG_CACHE
+	printk("Enabling R5000 SCACHE\n");
+#endif
+	__save_and_cli(flags);
+	change_cp0_config(CONF_SE, CONF_SE);
+	flush_scache_all();
+	__restore_flags(flags);
+}
+
+static void ip32_sc_disable(void)
+{
+        unsigned long flags;
+#ifdef DEBUG_CACHE
+	printk("Disabling R5000 SCACHE\n");
+#endif
+	__save_and_cli(flags);
+	flush_scache_all();
+	change_cp0_config(CONF_SE, 0);
+	__restore_flags(flags);
+}
+
+static inline int __init ip32_sc_probe(void)
+{
+	unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
+
+	if(config & CONF_SC)
+		return(0);
+	  
+	scache_size = (512*1024) << ((config >> 20)&3);
+
+	printk("R5000 SCACHE size %ldK, linesize 32 bytes.\n",
+	       scache_size >> 10);
+
+	return 1;
+}
+
+struct bcache_ops ip32_sc_ops = {
+	ip32_sc_enable,
+	ip32_sc_disable,
+	ip32_sc_wback_invalidate,
+	ip32_sc_wback_invalidate
+};
+
+void __init ip32_sc_init(void)
+{
+	if (ip32_sc_probe()) {
+		ip32_sc_enable();
+		bcops = &ip32_sc_ops;
+	}
+}
diff -Naur linux/arch/mips64/sgi-ip32/ip32-setup.c linux.patch/arch/mips64/sgi-ip32/ip32-setup.c
--- linux/arch/mips64/sgi-ip32/ip32-setup.c	Wed Jan  2 23:49:19 2002
+++ linux.patch/arch/mips64/sgi-ip32/ip32-setup.c	Thu Jan  3 20:42:06 2002
@@ -59,6 +59,7 @@
 
 extern void ip32_time_init(void);
 extern void ip32_reboot_setup(void);
+extern void ip32_sc_init(void);
 
 void __init bus_error_init(void)
 {
@@ -94,6 +95,7 @@
 	conswitchp = &dummy_con;
 #endif
 	ip32_reboot_setup();
+	ip32_sc_init();
 
 	rtc_ops = &ip32_rtc_ops;
 	board_time_init = ip32_time_init;
--- linux/arch/mips64/config.in	Tue Jan  1 21:51:10 2002
+++ linux.patch/arch/mips64/config.in	Thu Jan  3 22:08:33 2002
@@ -91,7 +91,7 @@
    define_bool CONFIG_ARC32 y
    define_bool CONFIG_PC_KEYB y
    define_bool CONFIG_PCI y
-   #define_bool CONFIG_BOARD_SCACHE y
+   define_bool CONFIG_BOARD_SCACHE y
    define_bool CONFIG_MAPPED_PCI_IO y
    define_bool CONFIG_NONCOHERENT_IO y
    define_bool CONFIG_ARC_MEMORY y

[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux