Blackfin: workaround anomaly 05000283
authorRobin Getz <robin.getz@analog.com>
Wed, 26 Aug 2009 15:54:10 +0000 (15:54 +0000)
committerMike Frysinger <vapier@gentoo.org>
Thu, 17 Sep 2009 02:10:34 +0000 (22:10 -0400)
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>
arch/blackfin/include/asm/entry.h
arch/blackfin/mach-common/entry.S
arch/blackfin/mach-common/interrupt.S

index ec58efc..55b808f 100644 (file)
 # 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.
  * 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;                                                     \
     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;                                                     \
index a9b15aa..01af24c 100644 (file)
@@ -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 */
 
index c754ff7..82d417e 100644 (file)
@@ -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