diff options
Diffstat (limited to 'arch/blackfin/mach-common/entry.S')
-rw-r--r-- | arch/blackfin/mach-common/entry.S | 59 |
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 */ |
858 | 4: | 870 | 4: |
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) | |||
929 | ENDPROC(_return_from_int) | 941 | ENDPROC(_return_from_int) |
930 | 942 | ||
931 | ENTRY(_lower_to_irq14) | 943 | ENTRY(_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; |
960 | ENDPROC(_lower_to_irq14) | ||
961 | |||
941 | ENTRY(_evt14_softirq) | 962 | ENTRY(_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; |
972 | ENDPROC(_evt14_softirq) | ||
951 | 973 | ||
952 | _schedule_and_signal_from_int: | 974 | ENTRY(_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; |
1007 | ENDPROC(_schedule_and_signal_from_int) | ||
985 | 1008 | ||
986 | _schedule_and_signal: | 1009 | ENTRY(_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: | |||
1001 | 1: | 1024 | 1: |
1002 | RESTORE_CONTEXT | 1025 | RESTORE_CONTEXT |
1003 | rti; | 1026 | rti; |
1004 | ENDPROC(_lower_to_irq14) | 1027 | ENDPROC(_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 |