Hi, The following patch implements real cache line sizing for R3k processors instead of the current hardcoded single word (4 bytes). Having a true cache line size available will enable the possibility to tune cache flushing functions making them perform better if the line size is bigger than a word. The patch includes minor corrections as well (sorry -- splitting them up would be difficult due to overlapping areas). They should be mostly obvious. One that probably needs a comment is the change to the low bound of the cache size check. It's now 128 words, as the IDT sw development manual states in the portability section that the minimal size of the cache for their chips is 512 bytes each (two extraneous executions of the loops shouldn't hurt here anyway, even if we never meet such a CPU). I've successfully tested the patch on my hardware, but since DECstation 5000/240 features single-word-wide cache lines, it doesn't really bring anything new to my system apart from being more correct. ;-) I'd be pleased to hear from people having a different cache layout. Please apply. Maciej -- + Maciej W. Rozycki, Technical University of Gdansk, Poland + +--------------------------------------------------------------+ + e-mail: macro@ds2.pg.gda.pl, PGP key available + patch-mips-2.4.5-20010704-cacheline-6 diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/arch/mips/mm/r2300.c linux-mips-2.4.5-20010704/arch/mips/mm/r2300.c --- linux-mips-2.4.5-20010704.macro/arch/mips/mm/r2300.c Thu Jun 28 04:27:03 2001 +++ linux-mips-2.4.5-20010704/arch/mips/mm/r2300.c Sun Jul 15 23:24:16 2001 @@ -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 @@ unsigned long __init r3k_cache_size(unsi 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) diff -up --recursive --new-file linux-mips-2.4.5-20010704.macro/include/asm-mips/mipsregs.h linux-mips-2.4.5-20010704/include/asm-mips/mipsregs.h --- linux-mips-2.4.5-20010704.macro/include/asm-mips/mipsregs.h Thu Jul 5 01:19:13 2001 +++ linux-mips-2.4.5-20010704/include/asm-mips/mipsregs.h Sun Jul 15 21:45:28 2001 @@ -331,6 +331,7 @@ __BUILD_SET_CP0(config,CP0_CONFIG) /* bits 6 & 7 are reserved on R[23]000 */ #define ST0_ISC 0x00010000 #define ST0_SWC 0x00020000 +#define ST0_CM 0x00080000 /* * Bits specific to the R4640/R4650