diff options
-rw-r--r-- | arch/blackfin/kernel/traps.c | 8 | ||||
-rw-r--r-- | arch/blackfin/mach-common/entry.S | 69 |
2 files changed, 62 insertions, 15 deletions
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 1a8a5f171bc8..ba68eb2ec929 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c | |||
@@ -132,6 +132,14 @@ static int printk_address(unsigned long address) | |||
132 | } | 132 | } |
133 | #endif | 133 | #endif |
134 | 134 | ||
135 | asmlinkage void double_fault_c(struct pt_regs *fp) | ||
136 | { | ||
137 | printk(KERN_EMERG "\n" KERN_EMERG "Double Fault\n"); | ||
138 | dump_bfin_regs(fp, (void *)fp->retx); | ||
139 | panic("Double Fault - unrecoverable event\n"); | ||
140 | |||
141 | } | ||
142 | |||
135 | asmlinkage void trap_c(struct pt_regs *fp) | 143 | asmlinkage void trap_c(struct pt_regs *fp) |
136 | { | 144 | { |
137 | #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON | 145 | #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON |
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 | ||