>>>>> On Thu, 2 Feb 2006 17:24:34 +0000, Ralf Baechle <ralf@xxxxxxxxxxxxxx> said: ralf> It should be ok for any R4000-style status register. I'm not ralf> sure about R3000 - but I'm sure Maciej will know. If he agrees ralf> I'd say let's go for it. It should be OK for all CPU while STI/CLI/KMODE macro always clear bit[4:1] of status register. Could you confirm, Maciej ? So here is a patch against current GIT. Always clear bit[4:1] of status register. This makes interrupt.h TX49 bug proof. TX49XX_MFC0_WAR is not needed anymore. Signed-off-by: Atsushi Nemoto <anemo@xxxxxxxxxxxxx> diff --git a/include/asm-mips/interrupt.h b/include/asm-mips/interrupt.h index 951ee7a..7743487 100644 --- a/include/asm-mips/interrupt.h +++ b/include/asm-mips/interrupt.h @@ -13,7 +13,6 @@ #include <linux/config.h> #include <asm/hazards.h> -#include <asm/war.h> __asm__ ( " .macro local_irq_enable \n" @@ -48,6 +47,17 @@ static inline void local_irq_enable(void * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs * no nops at all. */ +/* + * For TX49, operating only IE bit is not enough. + * + * If mfc0 $12 follows store and the mfc0 is last instruction of a + * page and fetching the next instruction causes TLB miss, the result + * of the mfc0 might wrongly contain EXL bit. + * + * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008 + * + * Workaround: mask EXL bit of the result or place a nop before mfc0. + */ __asm__ ( " .macro local_irq_disable\n" " .set push \n" @@ -56,13 +66,8 @@ __asm__ ( " di \n" #else " mfc0 $1,$12 \n" -#if TX49XX_MFC0_WAR && defined(MODULE) - " ori $1,3 \n" - " xori $1,3 \n" -#else - " ori $1,1 \n" - " xori $1,1 \n" -#endif + " ori $1,0x1f \n" + " xori $1,0x1f \n" " .set noreorder \n" " mtc0 $1,$12 \n" #endif @@ -102,13 +107,8 @@ __asm__ ( " andi \\result, 1 \n" #else " mfc0 \\result, $12 \n" -#if TX49XX_MFC0_WAR && defined(MODULE) - " ori $1, \\result, 3 \n" - " xori $1, 3 \n" -#else - " ori $1, \\result, 1 \n" - " xori $1, 1 \n" -#endif + " ori $1, \\result, 0x1f \n" + " xori $1, 0x1f \n" " .set noreorder \n" " mtc0 $1, $12 \n" #endif @@ -147,13 +147,8 @@ __asm__ ( #else " mfc0 $1, $12 \n" " andi \\flags, 1 \n" -#if TX49XX_MFC0_WAR && defined(MODULE) - " ori $1, 3 \n" - " xori $1, 3 \n" -#else - " ori $1, 1 \n" - " xori $1, 1 \n" -#endif + " ori $1, 0x1f \n" + " xori $1, 0x1f \n" " or \\flags, $1 \n" " mtc0 \\flags, $12 \n" #endif diff --git a/include/asm-mips/war.h b/include/asm-mips/war.h index 859520a..229afaa 100644 --- a/include/asm-mips/war.h +++ b/include/asm-mips/war.h @@ -169,19 +169,6 @@ #endif /* - * If mfc0 $12 follows store and the mfc0 is last instruction of a - * page and fetching the next instruction causes TLB miss, the result - * of the mfc0 might wrongly contain EXL bit. - * - * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008 - * - * Workaround: mask EXL bit of the result or place a nop before mfc0. - */ -#ifdef CONFIG_CPU_TX49XX -#define TX49XX_MFC0_WAR 1 -#endif - -/* * On the RM9000 there is a problem which makes the CreateDirtyExclusive * cache operation unusable on SMP systems. */