diff options
author | Robin Getz <robin.getz@analog.com> | 2009-08-26 15:54:10 +0000 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2009-09-16 22:10:34 -0400 |
commit | dedfd5d7f21b08d50ba8c0220778e119952e2f77 (patch) | |
tree | 2d6bf1d13dfe16679c126beed7f35a2f840d22bd /arch/blackfin/include/asm | |
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/blackfin/include/asm')
-rw-r--r-- | arch/blackfin/include/asm/entry.h | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/arch/blackfin/include/asm/entry.h b/arch/blackfin/include/asm/entry.h index ec58efc130e..55b808fced7 100644 --- a/arch/blackfin/include/asm/entry.h +++ b/arch/blackfin/include/asm/entry.h @@ -36,6 +36,21 @@ # define LOAD_IPIPE_IPEND #endif +/* + * Workaround for anomalies 05000283 and 05000315 + */ +#if ANOMALY_05000283 || ANOMALY_05000315 +# define ANOMALY_283_315_WORKAROUND(preg, dreg) \ + cc = dreg == dreg; \ + preg.h = HI(CHIPID); \ + preg.l = LO(CHIPID); \ + if cc jump 1f; \ + dreg.l = W[preg]; \ +1: +#else +# define ANOMALY_283_315_WORKAROUND(preg, dreg) +#endif /* ANOMALY_05000283 || ANOMALY_05000315 */ + #ifndef CONFIG_EXACT_HWERR /* As a debugging aid - we save IPEND when DEBUG_KERNEL is on, * otherwise it is a waste of cycles. @@ -88,17 +103,22 @@ * As you can see by the code - we actually need to do two SSYNCS - one to * make sure the read/writes complete, and another to make sure the hardware * error is recognized by the core. + * + * The extra nop before the SSYNC is to make sure we work around 05000244, + * since the 283/315 workaround includes a branch to the end */ #define INTERRUPT_ENTRY(N) \ - SSYNC; \ - SSYNC; \ [--sp] = SYSCFG; \ [--sp] = P0; /*orig_p0*/ \ [--sp] = R0; /*orig_r0*/ \ [--sp] = (R7:0,P5:0); \ R1 = ASTAT; \ + ANOMALY_283_315_WORKAROUND(p0, r0) \ P0.L = LO(ILAT); \ P0.H = HI(ILAT); \ + NOP; \ + SSYNC; \ + SSYNC; \ R0 = [P0]; \ CC = BITTST(R0, EVT_IVHW_P); \ IF CC JUMP 1f; \ @@ -118,15 +138,17 @@ RTI; #define TIMER_INTERRUPT_ENTRY(N) \ - SSYNC; \ - SSYNC; \ [--sp] = SYSCFG; \ [--sp] = P0; /*orig_p0*/ \ [--sp] = R0; /*orig_r0*/ \ [--sp] = (R7:0,P5:0); \ R1 = ASTAT; \ + ANOMALY_283_315_WORKAROUND(p0, r0) \ P0.L = LO(ILAT); \ P0.H = HI(ILAT); \ + NOP; \ + SSYNC; \ + SSYNC; \ R0 = [P0]; \ CC = BITTST(R0, EVT_IVHW_P); \ IF CC JUMP 1f; \ |