patch-2.4.10 linux/arch/mips/mm/r2300.c
Next file: linux/arch/mips/mm/r4xx0.c
Previous file: linux/arch/mips/mm/mips32.c
Back to the patch index
Back to the overall index
- Lines: 98
- Date:
Sun Sep 9 10:43:02 2001
- Orig file:
v2.4.9/linux/arch/mips/mm/r2300.c
- Orig date:
Wed Jul 25 17:10:18 2001
diff -u --recursive --new-file v2.4.9/linux/arch/mips/mm/r2300.c linux/arch/mips/mm/r2300.c
@@ -33,7 +33,7 @@
/* For R3000 cores with R4000 style caches */
static unsigned long icache_size, dcache_size; /* Size in bytes */
static unsigned long icache_lsize, dcache_lsize; /* Size in bytes */
-static unsigned long scache_size = 0;
+static unsigned long scache_size;
#include <asm/cacheops.h>
#include <asm/r4kcache.h>
@@ -134,31 +134,64 @@
dummy = *p;
status = read_32bit_cp0_register(CP0_STATUS);
- if (dummy != 0xa5a55a5a || (status & (1<<19))) {
+ if (dummy != 0xa5a55a5a || (status & ST0_CM)) {
size = 0;
} else {
- for (size = 512; size <= 0x40000; size <<= 1)
+ for (size = 128; size <= 0x40000; size <<= 1)
*(p + size) = 0;
*p = -1;
- for (size = 512;
+ for (size = 128;
(size <= 0x40000) && (*(p + size) == 0);
size <<= 1)
;
if (size > 0x40000)
size = 0;
}
+
write_32bit_cp0_register(CP0_STATUS, flags);
return size * sizeof(*p);
}
+unsigned long __init r3k_cache_lsize(unsigned long ca_flags)
+{
+ unsigned long flags, status, lsize, i, j;
+ volatile unsigned long *p;
+
+ p = (volatile unsigned long *) KSEG0;
+
+ flags = read_32bit_cp0_register(CP0_STATUS);
+
+ /* isolate cache space */
+ write_32bit_cp0_register(CP0_STATUS, (ca_flags|flags)&~ST0_IEC);
+
+ for (i = 0; i < 128; i++)
+ *(p + i) = 0;
+ *(volatile unsigned char *)p = 0;
+ for (lsize = 1; lsize < 128; lsize <<= 1) {
+ *(p + lsize);
+ status = read_32bit_cp0_register(CP0_STATUS);
+ if (!(status & ST0_CM))
+ break;
+ }
+ for (i = 0; i < 128; i += lsize)
+ *(volatile unsigned char *)(p + i) = 0;
+
+ write_32bit_cp0_register(CP0_STATUS, flags);
+
+ return lsize * sizeof(*p);
+}
+
static void __init r3k_probe_cache(void)
{
dcache_size = r3k_cache_size(ST0_ISC);
- dcache_lsize = 4;
+ if (dcache_size)
+ dcache_lsize = r3k_cache_lsize(ST0_ISC);
+
icache_size = r3k_cache_size(ST0_ISC|ST0_SWC);
- icache_lsize = 4;
+ if (icache_size)
+ icache_lsize = r3k_cache_lsize(ST0_ISC|ST0_SWC);
}
static void r3k_flush_icache_range(unsigned long start, unsigned long end)
@@ -391,11 +424,17 @@
flags = read_32bit_cp0_register(CP0_STATUS);
+ write_32bit_cp0_register(CP0_STATUS, flags&~ST0_IEC);
+
+ /* Fill the TLB to avoid an exception with caches isolated. */
+ asm ( "lw\t$0,0x000(%0)\n\t"
+ "lw\t$0,0x004(%0)\n\t"
+ : : "r" (addr) );
+
write_32bit_cp0_register(CP0_STATUS, (ST0_ISC|ST0_SWC|flags)&~ST0_IEC);
asm ( "sb\t$0,0x000(%0)\n\t"
"sb\t$0,0x004(%0)\n\t"
- "sb\t$0,0x008(%0)\n\t"
: : "r" (addr) );
write_32bit_cp0_register(CP0_STATUS, flags);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)