Commit dedfd5d7 authored by Robin Getz's avatar Robin Getz Committed by Mike Frysinger

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: default avatarRobin Getz <robin.getz@analog.com>
Signed-off-by: default avatarMike Frysinger <vapier@gentoo.org>
parent 05d17dfa
...@@ -36,6 +36,21 @@ ...@@ -36,6 +36,21 @@
# define LOAD_IPIPE_IPEND # define LOAD_IPIPE_IPEND
#endif #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 #ifndef CONFIG_EXACT_HWERR
/* As a debugging aid - we save IPEND when DEBUG_KERNEL is on, /* As a debugging aid - we save IPEND when DEBUG_KERNEL is on,
* otherwise it is a waste of cycles. * otherwise it is a waste of cycles.
...@@ -88,17 +103,22 @@ ...@@ -88,17 +103,22 @@
* As you can see by the code - we actually need to do two SSYNCS - one to * 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 * make sure the read/writes complete, and another to make sure the hardware
* error is recognized by the core. * 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) \ #define INTERRUPT_ENTRY(N) \
SSYNC; \
SSYNC; \
[--sp] = SYSCFG; \ [--sp] = SYSCFG; \
[--sp] = P0; /*orig_p0*/ \ [--sp] = P0; /*orig_p0*/ \
[--sp] = R0; /*orig_r0*/ \ [--sp] = R0; /*orig_r0*/ \
[--sp] = (R7:0,P5:0); \ [--sp] = (R7:0,P5:0); \
R1 = ASTAT; \ R1 = ASTAT; \
ANOMALY_283_315_WORKAROUND(p0, r0) \
P0.L = LO(ILAT); \ P0.L = LO(ILAT); \
P0.H = HI(ILAT); \ P0.H = HI(ILAT); \
NOP; \
SSYNC; \
SSYNC; \
R0 = [P0]; \ R0 = [P0]; \
CC = BITTST(R0, EVT_IVHW_P); \ CC = BITTST(R0, EVT_IVHW_P); \
IF CC JUMP 1f; \ IF CC JUMP 1f; \
...@@ -118,15 +138,17 @@ ...@@ -118,15 +138,17 @@
RTI; RTI;
#define TIMER_INTERRUPT_ENTRY(N) \ #define TIMER_INTERRUPT_ENTRY(N) \
SSYNC; \
SSYNC; \
[--sp] = SYSCFG; \ [--sp] = SYSCFG; \
[--sp] = P0; /*orig_p0*/ \ [--sp] = P0; /*orig_p0*/ \
[--sp] = R0; /*orig_r0*/ \ [--sp] = R0; /*orig_r0*/ \
[--sp] = (R7:0,P5:0); \ [--sp] = (R7:0,P5:0); \
R1 = ASTAT; \ R1 = ASTAT; \
ANOMALY_283_315_WORKAROUND(p0, r0) \
P0.L = LO(ILAT); \ P0.L = LO(ILAT); \
P0.H = HI(ILAT); \ P0.H = HI(ILAT); \
NOP; \
SSYNC; \
SSYNC; \
R0 = [P0]; \ R0 = [P0]; \
CC = BITTST(R0, EVT_IVHW_P); \ CC = BITTST(R0, EVT_IVHW_P); \
IF CC JUMP 1f; \ IF CC JUMP 1f; \
......
...@@ -513,14 +513,7 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/ ...@@ -513,14 +513,7 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
ssync; ssync;
#endif #endif
#if ANOMALY_05000283 || ANOMALY_05000315 ANOMALY_283_315_WORKAROUND(p5, r7)
cc = r7 == r7;
p5.h = HI(CHIPID);
p5.l = LO(CHIPID);
if cc jump 1f;
r7.l = W[p5];
1:
#endif
#ifdef CONFIG_DEBUG_DOUBLEFAULT #ifdef CONFIG_DEBUG_DOUBLEFAULT
/* /*
...@@ -1134,14 +1127,7 @@ ENTRY(_early_trap) ...@@ -1134,14 +1127,7 @@ ENTRY(_early_trap)
SAVE_ALL_SYS SAVE_ALL_SYS
trace_buffer_stop(p0,r0); trace_buffer_stop(p0,r0);
#if ANOMALY_05000283 || ANOMALY_05000315 ANOMALY_283_315_WORKAROUND(p4, r5)
cc = r5 == r5;
p4.h = HI(CHIPID);
p4.l = LO(CHIPID);
if cc jump 1f;
r5.l = W[p4];
1:
#endif
/* Turn caches off, to ensure we don't get double exceptions */ /* Turn caches off, to ensure we don't get double exceptions */
......
...@@ -119,14 +119,8 @@ __common_int_entry: ...@@ -119,14 +119,8 @@ __common_int_entry:
fp = 0; fp = 0;
#endif #endif
#if ANOMALY_05000283 || ANOMALY_05000315 ANOMALY_283_315_WORKAROUND(p5, r7)
cc = r7 == r7;
p5.h = HI(CHIPID);
p5.l = LO(CHIPID);
if cc jump 1f;
r7.l = W[p5];
1:
#endif
r1 = sp; r1 = sp;
SP += -12; SP += -12;
#ifdef CONFIG_IPIPE #ifdef CONFIG_IPIPE
...@@ -158,14 +152,7 @@ ENTRY(_evt_ivhw) ...@@ -158,14 +152,7 @@ ENTRY(_evt_ivhw)
fp = 0; fp = 0;
#endif #endif
#if ANOMALY_05000283 || ANOMALY_05000315 ANOMALY_283_315_WORKAROUND(p5, r7)
cc = r7 == r7;
p5.h = HI(CHIPID);
p5.l = LO(CHIPID);
if cc jump 1f;
r7.l = W[p5];
1:
#endif
/* Handle all stacked hardware errors /* Handle all stacked hardware errors
* To make sure we don't hang forever, only do it 10 times * To make sure we don't hang forever, only do it 10 times
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment