From 71595d7ce82c7b229eeb77a44b43c6e3b3c11df7 Mon Sep 17 00:00:00 2001
From: Felix Fietkau <nbd@openwrt.org>
Date: Thu, 24 Sep 2009 21:20:44 +0000
Subject: [PATCH] brcm47xx - add cache workarounds to 2.6.28 (merged from
 2.6.30), fixes #4293, should fix #2374

SVN-Revision: 17710
---
 .../patches-2.6.28/920-cache-wround.patch     | 135 ++++++++++++++++++
 1 file changed, 135 insertions(+)
 create mode 100644 target/linux/brcm47xx/patches-2.6.28/920-cache-wround.patch

diff --git a/target/linux/brcm47xx/patches-2.6.28/920-cache-wround.patch b/target/linux/brcm47xx/patches-2.6.28/920-cache-wround.patch
new file mode 100644
index 0000000000..9986f5ac1c
--- /dev/null
+++ b/target/linux/brcm47xx/patches-2.6.28/920-cache-wround.patch
@@ -0,0 +1,135 @@
+--- a/arch/mips/include/asm/r4kcache.h
++++ b/arch/mips/include/asm/r4kcache.h
+@@ -20,10 +20,25 @@
+ #ifdef CONFIG_BCM47XX
+ #include <asm/paccess.h>
+ #include <linux/ssb/ssb.h>
+-#define BCM4710_DUMMY_RREG() ((void) *((u8 *) KSEG1ADDR(SSB_ENUM_BASE + SSB_IMSTATE)))
++#define BCM4710_DUMMY_RREG() bcm4710_dummy_rreg()
++
++static inline unsigned long bcm4710_dummy_rreg(void) {
++      return (*(volatile unsigned long *)(KSEG1ADDR(SSB_ENUM_BASE + SSB_IMSTATE)));
++}
++
++#define BCM4710_FILL_TLB(addr) bcm4710_fill_tlb((void*)(addr))
++
++static inline unsigned long bcm4710_fill_tlb(void *addr) {
++      return (*(unsigned long *)addr);
++}
++
++#define BCM4710_PROTECTED_FILL_TLB(addr) bcm4710_protected_fill_tlb((void*)(addr))
++
++static inline void bcm4710_protected_fill_tlb(void *addr) {
++      unsigned long x;
++      get_dbe(x, (unsigned long *)addr);;
++}
+ 
+-#define BCM4710_FILL_TLB(addr) (*(volatile unsigned long *)(addr))
+-#define BCM4710_PROTECTED_FILL_TLB(addr) ({ unsigned long x; get_dbe(x, (volatile unsigned long *)(addr)); })
+ #else
+ #define BCM4710_DUMMY_RREG()
+ 
+--- a/arch/mips/mm/tlbex.c
++++ b/arch/mips/mm/tlbex.c
+@@ -548,6 +548,9 @@ build_get_pgde32(u32 **p, unsigned int t
+ #endif
+ 	uasm_i_addu(p, ptr, tmp, ptr);
+ #else
++#ifdef CONFIG_BCM47XX
++	uasm_i_nop(p);
++#endif
+ 	UASM_i_LA_mostly(p, ptr, pgdc);
+ #endif
+ 	uasm_i_mfc0(p, tmp, C0_BADVADDR); /* get faulting address */
+@@ -678,12 +681,12 @@ static void __cpuinit build_r4000_tlb_re
+ 		/* No need for uasm_i_nop */
+ 	}
+ 
+-#ifdef CONFIG_BCM47XX
+-	uasm_i_nop(&p);
+-#endif
+ #ifdef CONFIG_64BIT
+ 	build_get_pmde64(&p, &l, &r, K0, K1); /* get pmd in K1 */
+ #else
++# ifdef CONFIG_BCM47XX
++	uasm_i_nop(&p);
++# endif
+ 	build_get_pgde32(&p, K0, K1); /* get pgd in K1 */
+ #endif
+ 
+@@ -691,6 +694,9 @@ static void __cpuinit build_r4000_tlb_re
+ 	build_update_entries(&p, K0, K1);
+ 	build_tlb_write_entry(&p, &l, &r, tlb_random);
+ 	uasm_l_leave(&l, p);
++#ifdef CONFIG_BCM47XX
++	uasm_i_nop(&p);
++#endif
+ 	uasm_i_eret(&p); /* return from trap */
+ 
+ #ifdef CONFIG_64BIT
+@@ -1088,12 +1094,12 @@ build_r4000_tlbchange_handler_head(u32 *
+ 				   struct uasm_reloc **r, unsigned int pte,
+ 				   unsigned int ptr)
+ {
+-#ifdef CONFIG_BCM47XX
+-	uasm_i_nop(p);
+-#endif
+ #ifdef CONFIG_64BIT
+ 	build_get_pmde64(p, l, r, pte, ptr); /* get pmd in ptr */
+ #else
++# ifdef CONFIG_BCM47XX
++	uasm_i_nop(p);
++# endif
+ 	build_get_pgde32(p, pte, ptr); /* get pgd in ptr */
+ #endif
+ 
+@@ -1121,6 +1127,9 @@ build_r4000_tlbchange_handler_tail(u32 *
+ 	build_update_entries(p, tmp, ptr);
+ 	build_tlb_write_entry(p, l, r, tlb_indexed);
+ 	uasm_l_leave(l, *p);
++#ifdef CONFIG_BCM47XX
++	uasm_i_nop(p);
++#endif
+ 	uasm_i_eret(p); /* return from trap */
+ 
+ #ifdef CONFIG_64BIT
+--- a/arch/mips/kernel/genex.S
++++ b/arch/mips/kernel/genex.S
+@@ -22,6 +22,19 @@
+ #include <asm/page.h>
+ #include <asm/thread_info.h>
+ 
++#ifdef CONFIG_BCM47XX
++# ifdef eret
++#  undef eret
++# endif
++# define eret 					\
++	.set push;				\
++	.set noreorder;				\
++	 nop; 					\
++	 nop;					\
++	 eret;					\
++	.set pop;
++#endif
++
+ #define PANIC_PIC(msg)					\
+ 		.set push;				\
+ 		.set	reorder;			\
+@@ -54,7 +67,6 @@ NESTED(except_vec3_generic, 0, sp)
+ 	.set	noat
+ #ifdef CONFIG_BCM47XX
+ 	nop
+-	nop
+ #endif
+ #if R5432_CP0_INTERRUPT_WAR
+ 	mfc0	k0, CP0_INDEX
+@@ -79,6 +91,9 @@ NESTED(except_vec3_r4000, 0, sp)
+ 	.set	push
+ 	.set	mips3
+ 	.set	noat
++#ifdef CONFIG_BCM47XX
++	nop
++#endif
+ 	mfc0	k1, CP0_CAUSE
+ 	li	k0, 31<<2
+ 	andi	k1, k1, 0x7c
-- 
GitLab