diff options
author | Robin Getz <robin.getz@analog.com> | 2009-08-26 11:54:10 -0400 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2009-09-16 22:10:34 -0400 |
commit | dedfd5d7f21b08d50ba8c0220778e119952e2f77 (patch) | |
tree | 2d6bf1d13dfe16679c126beed7f35a2f840d22bd /arch | |
parent | 05d17dfaab6671def3fcdcd95c39fd49924dbb3b (diff) |
Blackfin: workaround anomaly 05000283
Make sure our interrupt entry code with exact hardware errors handles
anomaly 05000283 (infinite stall in system MMR kill) so we don't stall
while under load.
Signed-off-by: Robin Getz <robin.getz@analog.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/blackfin/include/asm/entry.h | 30 | ||||
-rw-r--r-- | arch/blackfin/mach-common/entry.S | 18 | ||||
-rw-r--r-- | arch/blackfin/mach-common/interrupt.S | 19 |
3 files changed, 31 insertions, 36 deletions
diff --git a/arch/blackfin/include/asm/entry.h b/arch/blackfin/include/asm/entry.h index ec58efc130e6..55b808fced71 100644 --- a/arch/blackfin/include/asm/entry.h +++ b/arch/blackfin/include/asm/entry.h | |||
@@ -36,6 +36,21 @@ | |||
36 | # define LOAD_IPIPE_IPEND | 36 | # define LOAD_IPIPE_IPEND |
37 | #endif | 37 | #endif |
38 | 38 | ||
39 | /* | ||
40 | * Workaround for anomalies 05000283 and 05000315 | ||
41 | */ | ||
42 | #if ANOMALY_05000283 || ANOMALY_05000315 | ||
43 | # define ANOMALY_283_315_WORKAROUND(preg, dreg) \ | ||
44 | cc = dreg == dreg; \ | ||
45 | preg.h = HI(CHIPID); \ | ||
46 | preg.l = LO(CHIPID); \ | ||
47 | if cc jump 1f; \ | ||
48 | dreg.l = W[preg]; \ | ||
49 | 1: | ||
50 | #else | ||
51 | # define ANOMALY_283_315_WORKAROUND(preg, dreg) | ||
52 | #endif /* ANOMALY_05000283 || ANOMALY_05000315 */ | ||
53 | |||
39 | #ifndef CONFIG_EXACT_HWERR | 54 | #ifndef CONFIG_EXACT_HWERR |
40 | /* As a debugging aid - we save IPEND when DEBUG_KERNEL is on, | 55 | /* As a debugging aid - we save IPEND when DEBUG_KERNEL is on, |
41 | * otherwise it is a waste of cycles. | 56 | * otherwise it is a waste of cycles. |
@@ -88,17 +103,22 @@ | |||
88 | * As you can see by the code - we actually need to do two SSYNCS - one to | 103 | * As you can see by the code - we actually need to do two SSYNCS - one to |
89 | * make sure the read/writes complete, and another to make sure the hardware | 104 | * make sure the read/writes complete, and another to make sure the hardware |
90 | * error is recognized by the core. | 105 | * error is recognized by the core. |
106 | * | ||
107 | * The extra nop before the SSYNC is to make sure we work around 05000244, | ||
108 | * since the 283/315 workaround includes a branch to the end | ||
91 | */ | 109 | */ |
92 | #define INTERRUPT_ENTRY(N) \ | 110 | #define INTERRUPT_ENTRY(N) \ |
93 | SSYNC; \ | ||
94 | SSYNC; \ | ||
95 | [--sp] = SYSCFG; \ | 111 | [--sp] = SYSCFG; \ |
96 | [--sp] = P0; /*orig_p0*/ \ | 112 | [--sp] = P0; /*orig_p0*/ \ |
97 | [--sp] = R0; /*orig_r0*/ \ | 113 | [--sp] = R0; /*orig_r0*/ \ |
98 | [--sp] = (R7:0,P5:0); \ | 114 | [--sp] = (R7:0,P5:0); \ |
99 | R1 = ASTAT; \ | 115 | R1 = ASTAT; \ |
116 | ANOMALY_283_315_WORKAROUND(p0, r0) \ | ||
100 | P0.L = LO(ILAT); \ | 117 | P0.L = LO(ILAT); \ |
101 | P0.H = HI(ILAT); \ | 118 | P0.H = HI(ILAT); \ |
119 | NOP; \ | ||
120 | SSYNC; \ | ||
121 | SSYNC; \ | ||
102 | R0 = [P0]; \ | 122 | R0 = [P0]; \ |
103 | CC = BITTST(R0, EVT_IVHW_P); \ | 123 | CC = BITTST(R0, EVT_IVHW_P); \ |
104 | IF CC JUMP 1f; \ | 124 | IF CC JUMP 1f; \ |
@@ -118,15 +138,17 @@ | |||
118 | RTI; | 138 | RTI; |
119 | 139 | ||
120 | #define TIMER_INTERRUPT_ENTRY(N) \ | 140 | #define TIMER_INTERRUPT_ENTRY(N) \ |
121 | SSYNC; \ | ||
122 | SSYNC; \ | ||
123 | [--sp] = SYSCFG; \ | 141 | [--sp] = SYSCFG; \ |
124 | [--sp] = P0; /*orig_p0*/ \ | 142 | [--sp] = P0; /*orig_p0*/ \ |
125 | [--sp] = R0; /*orig_r0*/ \ | 143 | [--sp] = R0; /*orig_r0*/ \ |
126 | [--sp] = (R7:0,P5:0); \ | 144 | [--sp] = (R7:0,P5:0); \ |
127 | R1 = ASTAT; \ | 145 | R1 = ASTAT; \ |
146 | ANOMALY_283_315_WORKAROUND(p0, r0) \ | ||
128 | P0.L = LO(ILAT); \ | 147 | P0.L = LO(ILAT); \ |
129 | P0.H = HI(ILAT); \ | 148 | P0.H = HI(ILAT); \ |
149 | NOP; \ | ||
150 | SSYNC; \ | ||
151 | SSYNC; \ | ||
130 | R0 = [P0]; \ | 152 | R0 = [P0]; \ |
131 | CC = BITTST(R0, EVT_IVHW_P); \ | 153 | CC = BITTST(R0, EVT_IVHW_P); \ |
132 | IF CC JUMP 1f; \ | 154 | IF CC JUMP 1f; \ |
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index a9b15aaf5254..01af24cde362 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S | |||
@@ -513,14 +513,7 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/ | |||
513 | ssync; | 513 | ssync; |
514 | #endif | 514 | #endif |
515 | 515 | ||
516 | #if ANOMALY_05000283 || ANOMALY_05000315 | 516 | ANOMALY_283_315_WORKAROUND(p5, r7) |
517 | cc = r7 == r7; | ||
518 | p5.h = HI(CHIPID); | ||
519 | p5.l = LO(CHIPID); | ||
520 | if cc jump 1f; | ||
521 | r7.l = W[p5]; | ||
522 | 1: | ||
523 | #endif | ||
524 | 517 | ||
525 | #ifdef CONFIG_DEBUG_DOUBLEFAULT | 518 | #ifdef CONFIG_DEBUG_DOUBLEFAULT |
526 | /* | 519 | /* |
@@ -1134,14 +1127,7 @@ ENTRY(_early_trap) | |||
1134 | SAVE_ALL_SYS | 1127 | SAVE_ALL_SYS |
1135 | trace_buffer_stop(p0,r0); | 1128 | trace_buffer_stop(p0,r0); |
1136 | 1129 | ||
1137 | #if ANOMALY_05000283 || ANOMALY_05000315 | 1130 | ANOMALY_283_315_WORKAROUND(p4, r5) |
1138 | cc = r5 == r5; | ||
1139 | p4.h = HI(CHIPID); | ||
1140 | p4.l = LO(CHIPID); | ||
1141 | if cc jump 1f; | ||
1142 | r5.l = W[p4]; | ||
1143 | 1: | ||
1144 | #endif | ||
1145 | 1131 | ||
1146 | /* Turn caches off, to ensure we don't get double exceptions */ | 1132 | /* Turn caches off, to ensure we don't get double exceptions */ |
1147 | 1133 | ||
diff --git a/arch/blackfin/mach-common/interrupt.S b/arch/blackfin/mach-common/interrupt.S index c754ff74bd5d..82d417ef4b5b 100644 --- a/arch/blackfin/mach-common/interrupt.S +++ b/arch/blackfin/mach-common/interrupt.S | |||
@@ -119,14 +119,8 @@ __common_int_entry: | |||
119 | fp = 0; | 119 | fp = 0; |
120 | #endif | 120 | #endif |
121 | 121 | ||
122 | #if ANOMALY_05000283 || ANOMALY_05000315 | 122 | ANOMALY_283_315_WORKAROUND(p5, r7) |
123 | cc = r7 == r7; | 123 | |
124 | p5.h = HI(CHIPID); | ||
125 | p5.l = LO(CHIPID); | ||
126 | if cc jump 1f; | ||
127 | r7.l = W[p5]; | ||
128 | 1: | ||
129 | #endif | ||
130 | r1 = sp; | 124 | r1 = sp; |
131 | SP += -12; | 125 | SP += -12; |
132 | #ifdef CONFIG_IPIPE | 126 | #ifdef CONFIG_IPIPE |
@@ -158,14 +152,7 @@ ENTRY(_evt_ivhw) | |||
158 | fp = 0; | 152 | fp = 0; |
159 | #endif | 153 | #endif |
160 | 154 | ||
161 | #if ANOMALY_05000283 || ANOMALY_05000315 | 155 | ANOMALY_283_315_WORKAROUND(p5, r7) |
162 | cc = r7 == r7; | ||
163 | p5.h = HI(CHIPID); | ||
164 | p5.l = LO(CHIPID); | ||
165 | if cc jump 1f; | ||
166 | r7.l = W[p5]; | ||
167 | 1: | ||
168 | #endif | ||
169 | 156 | ||
170 | /* Handle all stacked hardware errors | 157 | /* Handle all stacked hardware errors |
171 | * To make sure we don't hang forever, only do it 10 times | 158 | * To make sure we don't hang forever, only do it 10 times |