Skip to content

Commit

Permalink
Blackfin: workaround anomaly 05000283
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Robin Getz authored and Mike Frysinger committed Sep 17, 2009
1 parent 05d17df commit dedfd5d
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 36 deletions.
30 changes: 26 additions & 4 deletions arch/blackfin/include/asm/entry.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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; \
Expand All @@ -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; \
Expand Down
18 changes: 2 additions & 16 deletions arch/blackfin/mach-common/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -513,14 +513,7 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
ssync;
#endif

#if ANOMALY_05000283 || ANOMALY_05000315
cc = r7 == r7;
p5.h = HI(CHIPID);
p5.l = LO(CHIPID);
if cc jump 1f;
r7.l = W[p5];
1:
#endif
ANOMALY_283_315_WORKAROUND(p5, r7)

#ifdef CONFIG_DEBUG_DOUBLEFAULT
/*
Expand Down Expand Up @@ -1134,14 +1127,7 @@ ENTRY(_early_trap)
SAVE_ALL_SYS
trace_buffer_stop(p0,r0);

#if ANOMALY_05000283 || ANOMALY_05000315
cc = r5 == r5;
p4.h = HI(CHIPID);
p4.l = LO(CHIPID);
if cc jump 1f;
r5.l = W[p4];
1:
#endif
ANOMALY_283_315_WORKAROUND(p4, r5)

/* Turn caches off, to ensure we don't get double exceptions */

Expand Down
19 changes: 3 additions & 16 deletions arch/blackfin/mach-common/interrupt.S
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,8 @@ __common_int_entry:
fp = 0;
#endif

#if ANOMALY_05000283 || ANOMALY_05000315
cc = r7 == r7;
p5.h = HI(CHIPID);
p5.l = LO(CHIPID);
if cc jump 1f;
r7.l = W[p5];
1:
#endif
ANOMALY_283_315_WORKAROUND(p5, r7)

r1 = sp;
SP += -12;
#ifdef CONFIG_IPIPE
Expand Down Expand Up @@ -158,14 +152,7 @@ ENTRY(_evt_ivhw)
fp = 0;
#endif

#if ANOMALY_05000283 || ANOMALY_05000315
cc = r7 == r7;
p5.h = HI(CHIPID);
p5.l = LO(CHIPID);
if cc jump 1f;
r7.l = W[p5];
1:
#endif
ANOMALY_283_315_WORKAROUND(p5, r7)

/* Handle all stacked hardware errors
* To make sure we don't hang forever, only do it 10 times
Expand Down

0 comments on commit dedfd5d

Please sign in to comment.