+diff -urN linux.old/arch/mips/mm/tlb-r4k.c linux.dev/arch/mips/mm/tlb-r4k.c
+--- linux.old/arch/mips/mm/tlb-r4k.c 2005-07-05 16:46:49.000000000 +0200
++++ linux.dev/arch/mips/mm/tlb-r4k.c 2005-07-05 16:42:36.000000000 +0200
+@@ -38,6 +38,7 @@
+ old_ctx = read_c0_entryhi();
+ write_c0_entrylo0(0);
+ write_c0_entrylo1(0);
++ BARRIER;
+
+ entry = read_c0_wired();
+
+@@ -47,6 +48,7 @@
+ write_c0_index(entry);
+ mtc0_tlbw_hazard();
+ tlb_write_indexed();
++ BARRIER;
+ entry++;
+ }
+ tlbw_use_hazard();
+@@ -98,6 +100,7 @@
+ write_c0_entryhi(KSEG0 + idx*0x2000);
+ mtc0_tlbw_hazard();
+ tlb_write_indexed();
++ BARRIER;
+ }
+ tlbw_use_hazard();
+ write_c0_entryhi(oldpid);
+@@ -136,6 +139,7 @@
+ tlbw_use_hazard();
+
+ finish:
++ BARRIER;
+ write_c0_entryhi(oldpid);
+ local_irq_restore(flags);
+ }
+@@ -204,6 +208,7 @@
+ pmdp = pmd_offset(pgdp, address);
+ idx = read_c0_index();
+ ptep = pte_offset(pmdp, address);
++ BARRIER;
+ #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+ write_c0_entrylo0(ptep->pte_high);
+ ptep++;
+@@ -220,6 +225,7 @@
+ tlb_write_indexed();
+ tlbw_use_hazard();
+ write_c0_entryhi(pid);
++ BARRIER;
+ local_irq_restore(flags);
+ }
+
+@@ -317,6 +323,7 @@
+ }
+
+ write_c0_index(temp_tlb_entry);
++ BARRIER;
+ write_c0_pagemask(pagemask);
+ write_c0_entryhi(entryhi);
+ write_c0_entrylo0(entrylo0);
+diff -urN linux.old/arch/mips/mm/tlbex-mips32.S linux.dev/arch/mips/mm/tlbex-mips32.S
+--- linux.old/arch/mips/mm/tlbex-mips32.S 2005-07-05 16:46:49.000000000 +0200
++++ linux.dev/arch/mips/mm/tlbex-mips32.S 2005-07-05 16:42:36.000000000 +0200
+@@ -90,6 +90,9 @@
+ .set noat
+ LEAF(except_vec0_r4000)
+ .set mips3
++#ifdef CONFIG_BCM4704
++ nop
++#endif
+ #ifdef CONFIG_SMP
+ mfc0 k1, CP0_CONTEXT
+ la k0, pgd_current
+diff -urN linux.old/include/asm-mips/r4kcache.h linux.dev/include/asm-mips/r4kcache.h
+--- linux.old/include/asm-mips/r4kcache.h 2005-07-05 16:46:49.000000000 +0200
++++ linux.dev/include/asm-mips/r4kcache.h 2005-07-05 16:42:36.000000000 +0200
+@@ -15,6 +15,18 @@
+ #include <asm/asm.h>
+ #include <asm/cacheops.h>
+
++#ifdef CONFIG_BCM4710
++#define BCM4710_DUMMY_RREG() (((sbconfig_t *)(KSEG1ADDR(SB_ENUM_BASE + SBCONFIGOFF)))->sbimstate)
++
++#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()
++
++#define BCM4710_FILL_TLB(addr)
++#define BCM4710_PROTECTED_FILL_TLB(addr)
++#endif
++
+ #define cache_op(op,addr) \
+ __asm__ __volatile__( \
+ " .set noreorder \n" \
+@@ -32,6 +44,7 @@
+
+ static inline void flush_dcache_line_indexed(unsigned long addr)
+ {
++ BCM4710_DUMMY_RREG();
+ cache_op(Index_Writeback_Inv_D, addr);
+ }
+
+@@ -47,6 +60,7 @@
+
+ static inline void flush_dcache_line(unsigned long addr)
+ {
++ BCM4710_DUMMY_RREG();
+ cache_op(Hit_Writeback_Inv_D, addr);
+ }
+
+@@ -91,6 +105,7 @@
+ */
+ static inline void protected_writeback_dcache_line(unsigned long addr)
+ {
++ BCM4710_DUMMY_RREG();
+ __asm__ __volatile__(
+ ".set noreorder\n\t"
+ ".set mips3\n"
+@@ -138,6 +153,59 @@
+ : "r" (base), \
+ "i" (op));
+
++#define cache_unroll(base,op) \
++ __asm__ __volatile__(" \
++ .set noreorder; \
++ .set mips3; \
++ cache %1, (%0); \
++ .set mips0; \
++ .set reorder" \
++ : \
++ : "r" (base), \
++ "i" (op));
++
++
++static inline void blast_dcache(void)
++{
++ unsigned long start = KSEG0;
++ unsigned long end = start + current_cpu_data.dcache.waysize;
++
++ while(start < end) {
++ BCM4710_DUMMY_RREG();
++ cache_unroll(start,Index_Writeback_Inv_D);
++ start += current_cpu_data.dcache.linesz;
++ }
++}
++
++static inline void blast_dcache_page(unsigned long page)
++{
++ unsigned long start = page;
++ unsigned long end = start + PAGE_SIZE;
++
++ BCM4710_FILL_TLB(start);
++ do {
++ BCM4710_DUMMY_RREG();
++ cache_unroll(start,Hit_Writeback_Inv_D);
++ start += current_cpu_data.dcache.linesz;
++ } while (start < end);
++}
++
++static inline void blast_dcache_page_indexed(unsigned long page)
++{
++ unsigned long start = page;
++ unsigned long end = start + PAGE_SIZE;
++ unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit;
++ unsigned long ws_end = current_cpu_data.dcache.ways <<
++ current_cpu_data.dcache.waybit;
++ unsigned long ws, addr;
++
++ for (ws = 0; ws < ws_end; ws += ws_inc)
++ for (addr = start; addr < end; addr += start += current_cpu_data.dcache.linesz) {
++ BCM4710_DUMMY_RREG();
++ cache_unroll(addr,Index_Writeback_Inv_D);
++ }
++}
++
+ static inline void blast_dcache16(void)
+ {
+ unsigned long start = KSEG0;
+@@ -148,8 +216,9 @@
+ unsigned long ws, addr;
+
+ for (ws = 0; ws < ws_end; ws += ws_inc)
+- for (addr = start; addr < end; addr += 0x200)
++ for (addr = start; addr < end; addr += 0x200) {
+ cache16_unroll32(addr|ws,Index_Writeback_Inv_D);
++ }
+ }
+
+ static inline void blast_dcache16_page(unsigned long page)
+@@ -173,8 +242,9 @@
+ unsigned long ws, addr;
+
+ for (ws = 0; ws < ws_end; ws += ws_inc)
+- for (addr = start; addr < end; addr += 0x200)
++ for (addr = start; addr < end; addr += 0x200) {
+ cache16_unroll32(addr|ws,Index_Writeback_Inv_D);
++ }
+ }
+
+ static inline void blast_icache16(void)
+@@ -196,6 +266,7 @@
+ unsigned long start = page;
+ unsigned long end = start + PAGE_SIZE;
+
++ BCM4710_FILL_TLB(start);
+ do {
+ cache16_unroll32(start,Hit_Invalidate_I);
+ start += 0x200;
+@@ -281,6 +352,7 @@
+ : "r" (base), \
+ "i" (op));
+
++
+ static inline void blast_dcache32(void)
+ {
+ unsigned long start = KSEG0;
+@@ -291,8 +363,9 @@
+ unsigned long ws, addr;
+
+ for (ws = 0; ws < ws_end; ws += ws_inc)
+- for (addr = start; addr < end; addr += 0x400)
++ for (addr = start; addr < end; addr += 0x400) {
+ cache32_unroll32(addr|ws,Index_Writeback_Inv_D);
++ }
+ }
+
+ static inline void blast_dcache32_page(unsigned long page)
+@@ -316,8 +389,9 @@
+ unsigned long ws, addr;
+
+ for (ws = 0; ws < ws_end; ws += ws_inc)
+- for (addr = start; addr < end; addr += 0x400)
++ for (addr = start; addr < end; addr += 0x400) {
+ cache32_unroll32(addr|ws,Index_Writeback_Inv_D);
++ }
+ }
+
+ static inline void blast_icache32(void)
+@@ -339,6 +413,7 @@
+ unsigned long start = page;
+ unsigned long end = start + PAGE_SIZE;
+
++ BCM4710_FILL_TLB(start);
+ do {
+ cache32_unroll32(start,Hit_Invalidate_I);
+ start += 0x400;
+@@ -443,6 +518,7 @@
+ unsigned long start = page;
+ unsigned long end = start + PAGE_SIZE;
+
++ BCM4710_FILL_TLB(start);
+ do {
+ cache64_unroll32(start,Hit_Invalidate_I);
+ start += 0x800;
+diff -urN linux.old/include/asm-mips/stackframe.h linux.dev/include/asm-mips/stackframe.h
+--- linux.old/include/asm-mips/stackframe.h 2005-07-05 16:46:49.000000000 +0200
++++ linux.dev/include/asm-mips/stackframe.h 2005-07-05 16:42:36.000000000 +0200
+@@ -172,6 +172,46 @@
+ rfe; \
+ .set pop
+
++#elif defined(CONFIG_BCM4710) || defined(CONFIG_BCM4704)
++
++#define RESTORE_SOME \
++ .set push; \
++ .set reorder; \
++ mfc0 t0, CP0_STATUS; \
++ .set pop; \
++ ori t0, 0x1f; \
++ xori t0, 0x1f; \
++ mtc0 t0, CP0_STATUS; \
++ li v1, 0xff00; \
++ and t0, v1; \
++ lw v0, PT_STATUS(sp); \
++ nor v1, $0, v1; \
++ and v0, v1; \
++ or v0, t0; \
++ ori v1, v0, ST0_IE; \
++ xori v1, v1, ST0_IE; \
++ mtc0 v1, CP0_STATUS; \
++ mtc0 v0, CP0_STATUS; \
++ lw v1, PT_EPC(sp); \
++ mtc0 v1, CP0_EPC; \
++ lw $31, PT_R31(sp); \
++ lw $28, PT_R28(sp); \
++ lw $25, PT_R25(sp); \
++ lw $7, PT_R7(sp); \
++ lw $6, PT_R6(sp); \
++ lw $5, PT_R5(sp); \
++ lw $4, PT_R4(sp); \
++ lw $3, PT_R3(sp); \
++ lw $2, PT_R2(sp)
++
++#define RESTORE_SP_AND_RET \
++ lw sp, PT_R29(sp); \
++ nop; \
++ nop; \
++ .set mips3; \
++ eret; \
++ .set mips0
++
+ #else
+
+ #define RESTORE_SOME \