Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux...
[deliverable/linux.git] / arch / blackfin / include / asm / entry.h
index ec58efc130e677cb5b688b691715e0d4d0a5761c..55b808fced7132185f91c04810aeb113369d83ac 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;                                                     \
This page took 0.034022 seconds and 5 git commands to generate.