+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-06-26 16:24:26.000000000 +0200
++++ linux.dev/arch/mips/mm/tlb-r4k.c 2005-06-29 20:29:16.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-06-26 16:27:01.000000000 +0200
++++ linux.dev/arch/mips/mm/tlbex-mips32.S 2005-06-29 20:24:54.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-06-26 16:27:01.000000000 +0200
++++ linux.dev/include/asm-mips/r4kcache.h 2005-06-30 22:39:42.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"
+@@ -148,8 +163,10 @@
+ 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) {
++ BCM4710_DUMMY_RREG();
+ cache16_unroll32(addr|ws,Index_Writeback_Inv_D);
++ }
+ }
+
+ static inline void blast_dcache16_page(unsigned long page)
+@@ -157,7 +174,9 @@
+ unsigned long start = page;
+ unsigned long end = start + PAGE_SIZE;
+
++ BCM4710_FILL_TLB(start);
+ do {
++ BCM4710_DUMMY_RREG();
+ cache16_unroll32(start,Hit_Writeback_Inv_D);
+ start += 0x200;
+ } while (start < end);
+@@ -173,8 +192,10 @@
+ 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) {
++ BCM4710_DUMMY_RREG();
+ cache16_unroll32(addr|ws,Index_Writeback_Inv_D);
++ }
+ }
+
+ static inline void blast_icache16(void)
+@@ -196,6 +217,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 +303,7 @@
+ : "r" (base), \
+ "i" (op));
+
++
+ static inline void blast_dcache32(void)
+ {
+ unsigned long start = KSEG0;
+@@ -291,8 +314,10 @@
+ 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) {
++ BCM4710_DUMMY_RREG();
+ cache32_unroll32(addr|ws,Index_Writeback_Inv_D);
++ }
+ }
+
+ static inline void blast_dcache32_page(unsigned long page)
+@@ -300,7 +325,9 @@
+ unsigned long start = page;
+ unsigned long end = start + PAGE_SIZE;
+
++ BCM4710_FILL_TLB(start);
+ do {
++ BCM4710_DUMMY_RREG();
+ cache32_unroll32(start,Hit_Writeback_Inv_D);
+ start += 0x400;
+ } while (start < end);
+@@ -316,8 +343,10 @@
+ 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) {
++ BCM4710_DUMMY_RREG();
+ cache32_unroll32(addr|ws,Index_Writeback_Inv_D);
++ }
+ }
+
+ static inline void blast_icache32(void)
+@@ -339,6 +368,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 +473,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-06-26 16:27:01.000000000 +0200
++++ linux.dev/include/asm-mips/stackframe.h 2005-06-30 19:04:46.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 \