diff options
| -rw-r--r-- | target/linux/brcm-2.6/patches/003-bcm4710_cache_fixes.patch | 195 | 
1 files changed, 113 insertions, 82 deletions
| diff --git a/target/linux/brcm-2.6/patches/003-bcm4710_cache_fixes.patch b/target/linux/brcm-2.6/patches/003-bcm4710_cache_fixes.patch index 76e90584d..eaa523126 100644 --- a/target/linux/brcm-2.6/patches/003-bcm4710_cache_fixes.patch +++ b/target/linux/brcm-2.6/patches/003-bcm4710_cache_fixes.patch @@ -1,6 +1,6 @@  diff -urN linux.old/arch/mips/kernel/genex.S linux.dev/arch/mips/kernel/genex.S ---- linux.old/arch/mips/kernel/genex.S	2005-12-04 06:10:42.000000000 +0100 -+++ linux.dev/arch/mips/kernel/genex.S	2005-12-18 05:30:48.564937750 +0100 +--- linux.old/arch/mips/kernel/genex.S	2006-03-20 06:53:29.000000000 +0100 ++++ linux.dev/arch/mips/kernel/genex.S	2006-03-21 12:19:26.000000000 +0100  @@ -72,6 +72,10 @@   	.set	push   	.set	mips3 @@ -13,8 +13,8 @@ diff -urN linux.old/arch/mips/kernel/genex.S linux.dev/arch/mips/kernel/genex.S   	li	k0, 31<<2   	andi	k1, k1, 0x7c  diff -urN linux.old/arch/mips/mm/c-r4k.c linux.dev/arch/mips/mm/c-r4k.c ---- linux.old/arch/mips/mm/c-r4k.c	2005-12-04 06:10:42.000000000 +0100 -+++ linux.dev/arch/mips/mm/c-r4k.c	2005-12-18 06:08:19.112437750 +0100 +--- linux.old/arch/mips/mm/c-r4k.c	2006-03-20 06:53:29.000000000 +0100 ++++ linux.dev/arch/mips/mm/c-r4k.c	2006-03-21 12:19:26.000000000 +0100  @@ -14,6 +14,12 @@   #include <linux/mm.h>   #include <linux/bitops.h> @@ -71,48 +71,16 @@ diff -urN linux.old/arch/mips/mm/c-r4k.c linux.dev/arch/mips/mm/c-r4k.c   		r4k_blast_dcache = blast_dcache16;   	else if (dc_lsize == 32)   		r4k_blast_dcache = blast_dcache32; -@@ -486,6 +501,9 @@ - 			addr = start & ~(dc_lsize - 1); - 			aend = (end - 1) & ~(dc_lsize - 1); -  -+			BCM4710_PROTECTED_FILL_TLB(addr); -+			BCM4710_PROTECTED_FILL_TLB(aend); -+ - 			while (1) { - 				/* Hit_Writeback_Inv_D */ - 				protected_writeback_dcache_line(addr); -@@ -657,6 +675,10 @@ - 		R4600_HIT_CACHEOP_WAR_IMPL; - 		a = addr & ~(dc_lsize - 1); - 		end = (addr + size - 1) & ~(dc_lsize - 1); -+		 -+		BCM4710_FILL_TLB(a); -+		BCM4710_FILL_TLB(end); -+ - 		while (1) { - 			flush_dcache_line(a);	/* Hit_Writeback_Inv_D */ - 			if (a == end) -@@ -702,6 +724,10 @@ - 		R4600_HIT_CACHEOP_WAR_IMPL; - 		a = addr & ~(dc_lsize - 1); - 		end = (addr + size - 1) & ~(dc_lsize - 1); -+		 -+		BCM4710_FILL_TLB(a); -+		BCM4710_FILL_TLB(end); -+ - 		while (1) { - 			flush_dcache_line(a);	/* Hit_Writeback_Inv_D */ - 			if (a == end) -@@ -727,6 +753,8 @@ +@@ -660,6 +675,8 @@   	unsigned long addr = (unsigned long) arg;   	R4600_HIT_CACHEOP_WAR_IMPL;  +	BCM4710_PROTECTED_FILL_TLB(addr);  +	BCM4710_PROTECTED_FILL_TLB(addr + 4);   	protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); - 	if (!cpu_icache_snoops_remote_store) + 	if (!cpu_icache_snoops_remote_store && scache_size)   		protected_writeback_scache_line(addr & ~(sc_lsize - 1)); -@@ -1202,6 +1230,16 @@ +@@ -1136,6 +1153,16 @@   static inline void coherency_setup(void)   {   	change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); @@ -129,7 +97,7 @@ diff -urN linux.old/arch/mips/mm/c-r4k.c linux.dev/arch/mips/mm/c-r4k.c   	/*   	 * c0_status.cu=0 specifies that updates by the sc instruction use -@@ -1231,6 +1269,15 @@ +@@ -1165,6 +1192,15 @@   	/* Default cache error handler for R4000 and R5000 family */   	set_uncached_handler (0x100, &except_vec2_generic, 0x80); @@ -146,8 +114,8 @@ diff -urN linux.old/arch/mips/mm/c-r4k.c linux.dev/arch/mips/mm/c-r4k.c   	probe_pcache();   	setup_scache();  diff -urN linux.old/arch/mips/mm/tlbex.c linux.dev/arch/mips/mm/tlbex.c ---- linux.old/arch/mips/mm/tlbex.c	2005-12-15 12:57:27.945158000 +0100 -+++ linux.dev/arch/mips/mm/tlbex.c	2005-12-18 06:06:17.916863500 +0100 +--- linux.old/arch/mips/mm/tlbex.c	2006-03-21 12:12:38.000000000 +0100 ++++ linux.dev/arch/mips/mm/tlbex.c	2006-03-21 12:19:26.000000000 +0100  @@ -28,6 +28,10 @@   /* #define DEBUG_TLB */ @@ -173,11 +141,11 @@ diff -urN linux.old/arch/mips/mm/tlbex.c linux.dev/arch/mips/mm/tlbex.c   	 * create the plain linear handler   	 */  diff -urN linux.old/include/asm-mips/r4kcache.h linux.dev/include/asm-mips/r4kcache.h ---- linux.old/include/asm-mips/r4kcache.h	2005-12-17 22:39:19.281320000 +0100 -+++ linux.dev/include/asm-mips/r4kcache.h	2005-12-18 05:22:06.020280750 +0100 -@@ -15,6 +15,18 @@ - #include <asm/asm.h> +--- linux.old/include/asm-mips/r4kcache.h	2006-03-20 06:53:29.000000000 +0100 ++++ linux.dev/include/asm-mips/r4kcache.h	2006-03-21 18:40:32.000000000 +0100 +@@ -16,6 +16,18 @@   #include <asm/cacheops.h> + #include <asm/cpu-features.h>  +#ifdef CONFIG_BCM4710  +#define BCM4710_DUMMY_RREG() (((sbconfig_t *)(KSEG1ADDR(SB_ENUM_BASE + SBCONFIGOFF)))->sbimstate) @@ -194,7 +162,7 @@ diff -urN linux.old/include/asm-mips/r4kcache.h linux.dev/include/asm-mips/r4kca   /*    * This macro return a properly sign-extended address suitable as base address    * for indexed cache operations.  Two issues here: -@@ -45,6 +57,7 @@ +@@ -46,6 +58,7 @@   static inline void flush_dcache_line_indexed(unsigned long addr)   { @@ -202,7 +170,7 @@ diff -urN linux.old/include/asm-mips/r4kcache.h linux.dev/include/asm-mips/r4kca   	cache_op(Index_Writeback_Inv_D, addr);   } -@@ -60,11 +73,13 @@ +@@ -61,11 +74,13 @@   static inline void flush_dcache_line(unsigned long addr)   { @@ -216,15 +184,23 @@ diff -urN linux.old/include/asm-mips/r4kcache.h linux.dev/include/asm-mips/r4kca   	cache_op(Hit_Invalidate_D, addr);   } -@@ -104,6 +119,7 @@ +@@ -97,6 +112,7 @@ +  */ + static inline void protected_flush_icache_line(unsigned long addr) + { ++	BCM4710_DUMMY_RREG(); + 	protected_cache_op(Hit_Invalidate_I, addr); + } +  +@@ -108,6 +124,7 @@    */   static inline void protected_writeback_dcache_line(unsigned long addr)   {  +	BCM4710_DUMMY_RREG(); - 	__asm__ __volatile__( - 		"	.set	push			\n" - 		"	.set	noreorder		\n" -@@ -166,6 +182,49 @@ + 	protected_cache_op(Hit_Writeback_Inv_D, addr); + } +  +@@ -228,8 +245,52 @@   		: "r" (base),						\   		  "i" (op)); @@ -271,38 +247,93 @@ diff -urN linux.old/include/asm-mips/r4kcache.h linux.dev/include/asm-mips/r4kca  +	}  +}  + - static inline void blast_dcache16(void) - { - 	unsigned long start = INDEX_BASE; -@@ -213,7 +272,8 @@ - 	unsigned long ws_end = current_cpu_data.icache.ways << - 	                       current_cpu_data.icache.waybit; - 	unsigned long ws, addr; -- -+	 -+	BCM4710_FILL_TLB(start); - 	for (ws = 0; ws < ws_end; ws += ws_inc) - 		for (addr = start; addr < end; addr += 0x200) - 			cache16_unroll32(addr|ws,Index_Invalidate_I); -@@ -357,6 +417,7 @@ - 	                       current_cpu_data.icache.waybit; - 	unsigned long ws, addr; ++ + /* build blast_xxx, blast_xxx_page, blast_xxx_page_indexed */ +-#define __BUILD_BLAST_CACHE(pfx, desc, indexop, hitop, lsize) \ ++#define __BUILD_BLAST_CACHE(pfx, desc, indexop, hitop, lsize, war) \ + static inline void blast_##pfx##cache##lsize(void)			\ + {									\ + 	unsigned long start = INDEX_BASE;				\ +@@ -239,6 +300,7 @@ + 	                       current_cpu_data.desc.waybit;		\ + 	unsigned long ws, addr;						\ + 									\ ++	war								\ + 	for (ws = 0; ws < ws_end; ws += ws_inc)				\ + 		for (addr = start; addr < end; addr += lsize * 32)	\ + 			cache##lsize##_unroll32(addr|ws,indexop);	\ +@@ -249,6 +311,7 @@ + 	unsigned long start = page;					\ + 	unsigned long end = page + PAGE_SIZE;				\ + 									\ ++	war								\ + 	do {								\ + 		cache##lsize##_unroll32(start,hitop);			\ + 		start += lsize * 32;					\ +@@ -265,29 +328,31 @@ + 	                       current_cpu_data.desc.waybit;		\ + 	unsigned long ws, addr;						\ + 									\ ++	war								\ + 	for (ws = 0; ws < ws_end; ws += ws_inc)				\ + 		for (addr = start; addr < end; addr += lsize * 32)	\ + 			cache##lsize##_unroll32(addr|ws,indexop);	\ + } -+	BCM4710_FILL_TLB(start); - 	for (ws = 0; ws < ws_end; ws += ws_inc) - 		for (addr = start; addr < end; addr += 0x400) - 			cache32_unroll32(addr|ws,Index_Invalidate_I); -@@ -471,6 +532,7 @@ - 	unsigned long start = page; - 	unsigned long end = start + PAGE_SIZE; +-__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16) +-__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 16) +-__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 16) +-__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 32) +-__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 32) +-__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32) +-__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64) +-__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64) +-__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128) ++__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16, ) ++__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 16, BCM4710_FILL_TLB(start);) ++__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 16, ) ++__BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 32, ) ++__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 32, BCM4710_FILL_TLB(start);) ++__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32, ) ++__BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64, BCM4710_FILL_TLB(start);) ++__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64, ) ++__BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128, ) -+	BCM4710_FILL_TLB(start); - 	do { - 		cache64_unroll32(start,Hit_Invalidate_I); - 		start += 0x800; + /* build blast_xxx_range, protected_blast_xxx_range */ +-#define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop, prot) \ ++#define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop, prot, war) \ + static inline void prot##blast_##pfx##cache##_range(unsigned long start, \ + 						    unsigned long end)	\ + {									\ + 	unsigned long lsize = cpu_##desc##_line_size();			\ + 	unsigned long addr = start & ~(lsize - 1);			\ + 	unsigned long aend = (end - 1) & ~(lsize - 1);			\ ++	war								\ + 	while (1) {							\ + 		prot##cache_op(hitop, addr);				\ + 		if (addr == aend)					\ +@@ -296,12 +361,12 @@ + 	}								\ + } +  +-__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, protected_) +-__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, protected_) +-__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, protected_) +-__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, ) +-__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, ) ++__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, protected_, BCM4710_PROTECTED_FILL_TLB(addr); BCM4710_PROTECTED_FILL_TLB(aend);) ++__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, protected_, ) ++__BUILD_BLAST_CACHE_RANGE(i, icache, Hit_Invalidate_I, protected_, ) ++__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, , BCM4710_FILL_TLB(addr); BCM4710_FILL_TLB(aend);) ++__BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, , ) + /* blast_inv_dcache_range */ +-__BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D, ) ++__BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D, , ) +  + #endif /* _ASM_R4KCACHE_H */  diff -urN linux.old/include/asm-mips/stackframe.h linux.dev/include/asm-mips/stackframe.h ---- linux.old/include/asm-mips/stackframe.h	2005-12-04 06:10:42.000000000 +0100 -+++ linux.dev/include/asm-mips/stackframe.h	2005-12-18 05:33:02.405302250 +0100 +--- linux.old/include/asm-mips/stackframe.h	2006-03-20 06:53:29.000000000 +0100 ++++ linux.dev/include/asm-mips/stackframe.h	2006-03-21 12:19:26.000000000 +0100  @@ -285,6 +285,10 @@   		.macro	RESTORE_SP_AND_RET   		LONG_L	sp, PT_R29(sp) | 
