diff options
Diffstat (limited to 'arch/blackfin/mach-common/entry.S')
-rw-r--r-- | arch/blackfin/mach-common/entry.S | 69 |
1 files changed, 54 insertions, 15 deletions
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index 3feca05694f8..e2239361cac3 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S | |||
@@ -29,21 +29,7 @@ | |||
29 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 29 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
30 | */ | 30 | */ |
31 | 31 | ||
32 | /* | 32 | /* NOTE: This code handles signal-recognition, which happens every time |
33 | * 25-Dec-2004 - LG Soft India | ||
34 | * 1. Fix in return_from_int, to make sure any pending | ||
35 | * system call in ILAT for this process to get | ||
36 | * executed, otherwise in case context switch happens, | ||
37 | * system call of first process (i.e in ILAT) will be | ||
38 | * carried forward to the switched process. | ||
39 | * 2. Removed Constant references for the following | ||
40 | * a. IPEND | ||
41 | * b. EXCAUSE mask | ||
42 | * c. PAGE Mask | ||
43 | */ | ||
44 | |||
45 | /* | ||
46 | * NOTE: This code handles signal-recognition, which happens every time | ||
47 | * after a timer-interrupt and after each system call. | 33 | * after a timer-interrupt and after each system call. |
48 | */ | 34 | */ |
49 | 35 | ||
@@ -175,6 +161,13 @@ ENTRY(_ex_replaceable) | |||
175 | nop; | 161 | nop; |
176 | 162 | ||
177 | ENTRY(_ex_trap_c) | 163 | ENTRY(_ex_trap_c) |
164 | /* Make sure we are not in a double fault */ | ||
165 | p4.l = lo(IPEND); | ||
166 | p4.h = hi(IPEND); | ||
167 | r7 = [p4]; | ||
168 | CC = BITTST (r7, 5); | ||
169 | if CC jump _double_fault; | ||
170 | |||
178 | /* Call C code (trap_c) to handle the exception, which most | 171 | /* Call C code (trap_c) to handle the exception, which most |
179 | * likely involves sending a signal to the current process. | 172 | * likely involves sending a signal to the current process. |
180 | * To avoid double faults, lower our priority to IRQ5 first. | 173 | * To avoid double faults, lower our priority to IRQ5 first. |
@@ -220,6 +213,52 @@ ENTRY(_ex_trap_c) | |||
220 | rtx; | 213 | rtx; |
221 | ENDPROC(_ex_trap_c) | 214 | ENDPROC(_ex_trap_c) |
222 | 215 | ||
216 | /* We just realized we got an exception, while we were processing a different | ||
217 | * exception. This is a unrecoverable event, so crash | ||
218 | */ | ||
219 | ENTRY(_double_fault) | ||
220 | /* Turn caches & protection off, to ensure we don't get any more | ||
221 | * double exceptions | ||
222 | */ | ||
223 | |||
224 | P4.L = LO(IMEM_CONTROL); | ||
225 | P4.H = HI(IMEM_CONTROL); | ||
226 | |||
227 | R5 = [P4]; /* Control Register*/ | ||
228 | BITCLR(R5,ENICPLB_P); | ||
229 | SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ | ||
230 | .align 8; | ||
231 | [P4] = R5; | ||
232 | SSYNC; | ||
233 | |||
234 | P4.L = LO(DMEM_CONTROL); | ||
235 | P4.H = HI(DMEM_CONTROL); | ||
236 | R5 = [P4]; | ||
237 | BITCLR(R5,ENDCPLB_P); | ||
238 | SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ | ||
239 | .align 8; | ||
240 | [P4] = R5; | ||
241 | SSYNC; | ||
242 | |||
243 | /* Fix up the stack */ | ||
244 | (R7:6,P5:4) = [sp++]; | ||
245 | ASTAT = [sp++]; | ||
246 | SP = EX_SCRATCH_REG; | ||
247 | |||
248 | /* We should be out of the exception stack, and back down into | ||
249 | * kernel or user space stack | ||
250 | */ | ||
251 | SAVE_ALL_SYS | ||
252 | |||
253 | r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */ | ||
254 | SP += -12; | ||
255 | call _double_fault_c; | ||
256 | SP += 12; | ||
257 | .L_double_fault_panic: | ||
258 | JUMP .L_double_fault_panic | ||
259 | |||
260 | ENDPROC(_double_fault) | ||
261 | |||
223 | ENTRY(_exception_to_level5) | 262 | ENTRY(_exception_to_level5) |
224 | SAVE_ALL_SYS | 263 | SAVE_ALL_SYS |
225 | 264 | ||