Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+26 −4
Original line number Diff line number Diff line
@@ -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;							\
+2 −16
Original line number Diff line number Diff line
@@ -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
	/*
@@ -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 */

+3 −16
Original line number Diff line number Diff line
@@ -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
@@ -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