aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/include
diff options
context:
space:
mode:
authorRobin Getz <robin.getz@analog.com>2009-08-26 11:54:10 -0400
committerMike Frysinger <vapier@gentoo.org>2009-09-16 22:10:34 -0400
commitdedfd5d7f21b08d50ba8c0220778e119952e2f77 (patch)
tree2d6bf1d13dfe16679c126beed7f35a2f840d22bd /arch/blackfin/include
parent05d17dfaab6671def3fcdcd95c39fd49924dbb3b (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/blackfin/include')
-rw-r--r--arch/blackfin/include/asm/entry.h30
1 files changed, 26 insertions, 4 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]; \
491:
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; \