aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin
diff options
context:
space:
mode:
authorRobin Getz <robin.getz@analog.com>2007-10-09 05:24:30 -0400
committerBryan Wu <bryan.wu@analog.com>2007-10-09 05:24:30 -0400
commit2ebcade590dcf822dcdadcc4f8f68efd3ff2e217 (patch)
tree38532077386784de87ac65aba73e22c399c96ecb /arch/blackfin
parent0ae53640b54f2c30e52044f7102ba08915b988a7 (diff)
Blackfin arch: fix endless loop bug when a double fault happens
Today when a double fault happens (exception during an exception handling event), we go into an endless loop, with nothing comming out the UART. With this patch, we actually see that we have commited a double fault event Signed-off-by: Robin Getz <robin.getz@analog.com> Signed-off-by: Bryan Wu <bryan.wu@analog.com>
Diffstat (limited to 'arch/blackfin')
-rw-r--r--arch/blackfin/kernel/traps.c8
-rw-r--r--arch/blackfin/mach-common/entry.S69
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
135asmlinkage 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
135asmlinkage void trap_c(struct pt_regs *fp) 143asmlinkage 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
177ENTRY(_ex_trap_c) 163ENTRY(_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;
221ENDPROC(_ex_trap_c) 214ENDPROC(_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 */
219ENTRY(_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
260ENDPROC(_double_fault)
261
223ENTRY(_exception_to_level5) 262ENTRY(_exception_to_level5)
224 SAVE_ALL_SYS 263 SAVE_ALL_SYS
225 264