diff options
author | Atsushi Nemoto <anemo@mba.ocn.ne.jp> | 2006-02-02 11:34:01 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2006-02-07 08:30:26 -0500 |
commit | c226f2601f55010936f0f3c77ae167a02339f566 (patch) | |
tree | a0b178eef5c305881beaf0e76c8e82a03b74772d /include/asm-mips | |
parent | dbee90b7f90df6398f0877cd38dfaa76addb0619 (diff) |
[MIPS] TX49 MFC0 bug workaround
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. It
doesn't harm to always clear those bits, so we change the code to do so.
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'include/asm-mips')
-rw-r--r-- | include/asm-mips/interrupt.h | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/include/asm-mips/interrupt.h b/include/asm-mips/interrupt.h index 0da5818a2d62..774348734fa0 100644 --- a/include/asm-mips/interrupt.h +++ b/include/asm-mips/interrupt.h | |||
@@ -47,6 +47,17 @@ static inline void local_irq_enable(void) | |||
47 | * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs | 47 | * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs |
48 | * no nops at all. | 48 | * no nops at all. |
49 | */ | 49 | */ |
50 | /* | ||
51 | * For TX49, operating only IE bit is not enough. | ||
52 | * | ||
53 | * If mfc0 $12 follows store and the mfc0 is last instruction of a | ||
54 | * page and fetching the next instruction causes TLB miss, the result | ||
55 | * of the mfc0 might wrongly contain EXL bit. | ||
56 | * | ||
57 | * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008 | ||
58 | * | ||
59 | * Workaround: mask EXL bit of the result or place a nop before mfc0. | ||
60 | */ | ||
50 | __asm__ ( | 61 | __asm__ ( |
51 | " .macro local_irq_disable\n" | 62 | " .macro local_irq_disable\n" |
52 | " .set push \n" | 63 | " .set push \n" |
@@ -55,8 +66,8 @@ __asm__ ( | |||
55 | " di \n" | 66 | " di \n" |
56 | #else | 67 | #else |
57 | " mfc0 $1,$12 \n" | 68 | " mfc0 $1,$12 \n" |
58 | " ori $1,1 \n" | 69 | " ori $1,0x1f \n" |
59 | " xori $1,1 \n" | 70 | " xori $1,0x1f \n" |
60 | " .set noreorder \n" | 71 | " .set noreorder \n" |
61 | " mtc0 $1,$12 \n" | 72 | " mtc0 $1,$12 \n" |
62 | #endif | 73 | #endif |
@@ -96,8 +107,8 @@ __asm__ ( | |||
96 | " andi \\result, 1 \n" | 107 | " andi \\result, 1 \n" |
97 | #else | 108 | #else |
98 | " mfc0 \\result, $12 \n" | 109 | " mfc0 \\result, $12 \n" |
99 | " ori $1, \\result, 1 \n" | 110 | " ori $1, \\result, 0x1f \n" |
100 | " xori $1, 1 \n" | 111 | " xori $1, 0x1f \n" |
101 | " .set noreorder \n" | 112 | " .set noreorder \n" |
102 | " mtc0 $1, $12 \n" | 113 | " mtc0 $1, $12 \n" |
103 | #endif | 114 | #endif |
@@ -136,8 +147,8 @@ __asm__ ( | |||
136 | #else | 147 | #else |
137 | " mfc0 $1, $12 \n" | 148 | " mfc0 $1, $12 \n" |
138 | " andi \\flags, 1 \n" | 149 | " andi \\flags, 1 \n" |
139 | " ori $1, 1 \n" | 150 | " ori $1, 0x1f \n" |
140 | " xori $1, 1 \n" | 151 | " xori $1, 0x1f \n" |
141 | " or \\flags, $1 \n" | 152 | " or \\flags, $1 \n" |
142 | " mtc0 \\flags, $12 \n" | 153 | " mtc0 \\flags, $12 \n" |
143 | #endif | 154 | #endif |