diff options
Diffstat (limited to 'arch/blackfin/include/asm/entry.h')
-rw-r--r-- | arch/blackfin/include/asm/entry.h | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/arch/blackfin/include/asm/entry.h b/arch/blackfin/include/asm/entry.h index ec58efc130e6..55b808fced71 100644 --- a/arch/blackfin/include/asm/entry.h +++ b/arch/blackfin/include/asm/entry.h | |||
@@ -36,6 +36,21 @@ | |||
36 | # define LOAD_IPIPE_IPEND | 36 | # define LOAD_IPIPE_IPEND |
37 | #endif | 37 | #endif |
38 | 38 | ||
39 | /* | ||
40 | * Workaround for anomalies 05000283 and 05000315 | ||
41 | */ | ||
42 | #if ANOMALY_05000283 || ANOMALY_05000315 | ||
43 | # define ANOMALY_283_315_WORKAROUND(preg, dreg) \ | ||
44 | cc = dreg == dreg; \ | ||
45 | preg.h = HI(CHIPID); \ | ||
46 | preg.l = LO(CHIPID); \ | ||
47 | if cc jump 1f; \ | ||
48 | dreg.l = W[preg]; \ | ||
49 | 1: | ||
50 | #else | ||
51 | # define ANOMALY_283_315_WORKAROUND(preg, dreg) | ||
52 | #endif /* ANOMALY_05000283 || ANOMALY_05000315 */ | ||
53 | |||
39 | #ifndef CONFIG_EXACT_HWERR | 54 | #ifndef CONFIG_EXACT_HWERR |
40 | /* As a debugging aid - we save IPEND when DEBUG_KERNEL is on, | 55 | /* As a debugging aid - we save IPEND when DEBUG_KERNEL is on, |
41 | * otherwise it is a waste of cycles. | 56 | * otherwise it is a waste of cycles. |
@@ -88,17 +103,22 @@ | |||
88 | * As you can see by the code - we actually need to do two SSYNCS - one to | 103 | * As you can see by the code - we actually need to do two SSYNCS - one to |
89 | * make sure the read/writes complete, and another to make sure the hardware | 104 | * make sure the read/writes complete, and another to make sure the hardware |
90 | * error is recognized by the core. | 105 | * error is recognized by the core. |
106 | * | ||
107 | * The extra nop before the SSYNC is to make sure we work around 05000244, | ||
108 | * since the 283/315 workaround includes a branch to the end | ||
91 | */ | 109 | */ |
92 | #define INTERRUPT_ENTRY(N) \ | 110 | #define INTERRUPT_ENTRY(N) \ |
93 | SSYNC; \ | ||
94 | SSYNC; \ | ||
95 | [--sp] = SYSCFG; \ | 111 | [--sp] = SYSCFG; \ |
96 | [--sp] = P0; /*orig_p0*/ \ | 112 | [--sp] = P0; /*orig_p0*/ \ |
97 | [--sp] = R0; /*orig_r0*/ \ | 113 | [--sp] = R0; /*orig_r0*/ \ |
98 | [--sp] = (R7:0,P5:0); \ | 114 | [--sp] = (R7:0,P5:0); \ |
99 | R1 = ASTAT; \ | 115 | R1 = ASTAT; \ |
116 | ANOMALY_283_315_WORKAROUND(p0, r0) \ | ||
100 | P0.L = LO(ILAT); \ | 117 | P0.L = LO(ILAT); \ |
101 | P0.H = HI(ILAT); \ | 118 | P0.H = HI(ILAT); \ |
119 | NOP; \ | ||
120 | SSYNC; \ | ||
121 | SSYNC; \ | ||
102 | R0 = [P0]; \ | 122 | R0 = [P0]; \ |
103 | CC = BITTST(R0, EVT_IVHW_P); \ | 123 | CC = BITTST(R0, EVT_IVHW_P); \ |
104 | IF CC JUMP 1f; \ | 124 | IF CC JUMP 1f; \ |
@@ -118,15 +138,17 @@ | |||
118 | RTI; | 138 | RTI; |
119 | 139 | ||
120 | #define TIMER_INTERRUPT_ENTRY(N) \ | 140 | #define TIMER_INTERRUPT_ENTRY(N) \ |
121 | SSYNC; \ | ||
122 | SSYNC; \ | ||
123 | [--sp] = SYSCFG; \ | 141 | [--sp] = SYSCFG; \ |
124 | [--sp] = P0; /*orig_p0*/ \ | 142 | [--sp] = P0; /*orig_p0*/ \ |
125 | [--sp] = R0; /*orig_r0*/ \ | 143 | [--sp] = R0; /*orig_r0*/ \ |
126 | [--sp] = (R7:0,P5:0); \ | 144 | [--sp] = (R7:0,P5:0); \ |
127 | R1 = ASTAT; \ | 145 | R1 = ASTAT; \ |
146 | ANOMALY_283_315_WORKAROUND(p0, r0) \ | ||
128 | P0.L = LO(ILAT); \ | 147 | P0.L = LO(ILAT); \ |
129 | P0.H = HI(ILAT); \ | 148 | P0.H = HI(ILAT); \ |
149 | NOP; \ | ||
150 | SSYNC; \ | ||
151 | SSYNC; \ | ||
130 | R0 = [P0]; \ | 152 | R0 = [P0]; \ |
131 | CC = BITTST(R0, EVT_IVHW_P); \ | 153 | CC = BITTST(R0, EVT_IVHW_P); \ |
132 | IF CC JUMP 1f; \ | 154 | IF CC JUMP 1f; \ |