aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/mach-common/entry.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/mach-common/entry.S')
-rw-r--r--arch/blackfin/mach-common/entry.S59
1 files changed, 41 insertions, 18 deletions
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index f0636fdcb353..da0558ad1b1a 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -200,7 +200,18 @@ ENTRY(_ex_single_step)
200 cc = r7 == 0; 200 cc = r7 == 0;
201 if !cc jump 1f; 201 if !cc jump 1f;
202#endif 202#endif
203 203#ifdef CONFIG_EXACT_HWERR
204 /* Read the ILAT, and to check to see if the process we are
205 * single stepping caused a previous hardware error
206 * If so, do not single step, (which lowers to IRQ5, and makes
207 * us miss the error).
208 */
209 p5.l = lo(ILAT);
210 p5.h = hi(ILAT);
211 r7 = [p5];
212 cc = bittst(r7, EVT_IVHW_P);
213 if cc jump 1f;
214#endif
204 /* Single stepping only a single instruction, so clear the trace 215 /* Single stepping only a single instruction, so clear the trace
205 * bit here. */ 216 * bit here. */
206 r7 = syscfg; 217 r7 = syscfg;
@@ -262,15 +273,6 @@ ENTRY(_bfin_return_from_exception)
262 r6 = 0x25; 273 r6 = 0x25;
263 CC = R7 == R6; 274 CC = R7 == R6;
264 if CC JUMP _double_fault; 275 if CC JUMP _double_fault;
265
266 /* Did we cause a HW error? */
267 p5.l = lo(ILAT);
268 p5.h = hi(ILAT);
269 r6 = [p5];
270 r7 = 0x20; /* Did I just cause anther HW error? */
271 r6 = r7 & r6;
272 CC = R7 == R6;
273 if CC JUMP _double_fault;
274#endif 276#endif
275 277
276 (R7:6,P5:4) = [sp++]; 278 (R7:6,P5:4) = [sp++];
@@ -472,6 +474,16 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
472 [--sp] = ASTAT; 474 [--sp] = ASTAT;
473 [--sp] = (R7:6,P5:4); 475 [--sp] = (R7:6,P5:4);
474 476
477#ifdef CONFIG_EXACT_HWERR
478 /* Make sure all pending read/writes complete. This will ensure any
479 * accesses which could cause hardware errors completes, and signal
480 * the the hardware before we do something silly, like crash the
481 * kernel. We don't need to work around anomaly 05000312, since
482 * we are already atomic
483 */
484 ssync;
485#endif
486
475#if ANOMALY_05000283 || ANOMALY_05000315 487#if ANOMALY_05000283 || ANOMALY_05000315
476 cc = r7 == r7; 488 cc = r7 == r7;
477 p5.h = HI(CHIPID); 489 p5.h = HI(CHIPID);
@@ -854,7 +866,7 @@ ENTRY(_ret_from_exception)
854 p1.h = _schedule_and_signal; 866 p1.h = _schedule_and_signal;
855 [p0] = p1; 867 [p0] = p1;
856 csync; 868 csync;
857 raise 15; /* raise evt14 to do signal or reschedule */ 869 raise 15; /* raise evt15 to do signal or reschedule */
8584: 8704:
859 r0 = syscfg; 871 r0 = syscfg;
860 bitclr(r0, 0); 872 bitclr(r0, 0);
@@ -915,7 +927,7 @@ ENTRY(_return_from_int)
915 p1.h = _schedule_and_signal_from_int; 927 p1.h = _schedule_and_signal_from_int;
916 [p0] = p1; 928 [p0] = p1;
917 csync; 929 csync;
918#if ANOMALY_05000281 930#if ANOMALY_05000281 || ANOMALY_05000461
919 r0.l = lo(SAFE_USER_INSTRUCTION); 931 r0.l = lo(SAFE_USER_INSTRUCTION);
920 r0.h = hi(SAFE_USER_INSTRUCTION); 932 r0.h = hi(SAFE_USER_INSTRUCTION);
921 reti = r0; 933 reti = r0;
@@ -929,18 +941,27 @@ ENTRY(_return_from_int)
929ENDPROC(_return_from_int) 941ENDPROC(_return_from_int)
930 942
931ENTRY(_lower_to_irq14) 943ENTRY(_lower_to_irq14)
932#if ANOMALY_05000281 944#if ANOMALY_05000281 || ANOMALY_05000461
933 r0.l = lo(SAFE_USER_INSTRUCTION); 945 r0.l = lo(SAFE_USER_INSTRUCTION);
934 r0.h = hi(SAFE_USER_INSTRUCTION); 946 r0.h = hi(SAFE_USER_INSTRUCTION);
935 reti = r0; 947 reti = r0;
936#endif 948#endif
937 r0 = 0x401f; 949
950#ifdef CONFIG_DEBUG_HWERR
951 /* enable irq14 & hwerr interrupt, until we transition to _evt14_softirq */
952 r0 = (EVT_IVG14 | EVT_IVHW | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU);
953#else
954 /* Only enable irq14 interrupt, until we transition to _evt14_softirq */
955 r0 = (EVT_IVG14 | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU);
956#endif
938 sti r0; 957 sti r0;
939 raise 14; 958 raise 14;
940 rti; 959 rti;
960ENDPROC(_lower_to_irq14)
961
941ENTRY(_evt14_softirq) 962ENTRY(_evt14_softirq)
942#ifdef CONFIG_DEBUG_HWERR 963#ifdef CONFIG_DEBUG_HWERR
943 r0 = 0x3f; 964 r0 = (EVT_IVHW | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU);
944 sti r0; 965 sti r0;
945#else 966#else
946 cli r0; 967 cli r0;
@@ -948,8 +969,9 @@ ENTRY(_evt14_softirq)
948 [--sp] = RETI; 969 [--sp] = RETI;
949 SP += 4; 970 SP += 4;
950 rts; 971 rts;
972ENDPROC(_evt14_softirq)
951 973
952_schedule_and_signal_from_int: 974ENTRY(_schedule_and_signal_from_int)
953 /* To end up here, vector 15 was changed - so we have to change it 975 /* To end up here, vector 15 was changed - so we have to change it
954 * back. 976 * back.
955 */ 977 */
@@ -982,8 +1004,9 @@ _schedule_and_signal_from_int:
982 call _finish_atomic_sections; 1004 call _finish_atomic_sections;
983 sp += 12; 1005 sp += 12;
984 jump.s .Lresume_userspace; 1006 jump.s .Lresume_userspace;
1007ENDPROC(_schedule_and_signal_from_int)
985 1008
986_schedule_and_signal: 1009ENTRY(_schedule_and_signal)
987 SAVE_CONTEXT_SYSCALL 1010 SAVE_CONTEXT_SYSCALL
988 /* To end up here, vector 15 was changed - so we have to change it 1011 /* To end up here, vector 15 was changed - so we have to change it
989 * back. 1012 * back.
@@ -1001,7 +1024,7 @@ _schedule_and_signal:
10011: 10241:
1002 RESTORE_CONTEXT 1025 RESTORE_CONTEXT
1003 rti; 1026 rti;
1004ENDPROC(_lower_to_irq14) 1027ENDPROC(_schedule_and_signal)
1005 1028
1006/* We handle this 100% in exception space - to reduce overhead 1029/* We handle this 100% in exception space - to reduce overhead
1007 * Only potiential problem is if the software buffer gets swapped out of the 1030 * Only potiential problem is if the software buffer gets swapped out of the