aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/mach-common
diff options
context:
space:
mode:
authorGraf Yang <graf.yang@analog.com>2009-07-22 07:56:24 -0400
committerMike Frysinger <vapier@gentoo.org>2009-09-16 21:31:57 -0400
commit01b9f4b0ed3b1111b2080a3c9bcb66df1fdf48b7 (patch)
tree0963b346d63cc7ee44e3e769cc8435d224e17a87 /arch/blackfin/mach-common
parent858c5e9abc5c614b2eceb6a361118f31821ac968 (diff)
Blackfin: improve double fault debug handling
Since the hardware only provides reporting for the last exception handled, and the values are valid only when executing the exception handler, we need to save the context for reporting at a later point. While we do this for one exception, it doesn't work properly when handling a second one as the original exception is clobbered by the double fault. So when double fault debugging is enabled, create a dedicated shadow of these values and save/restore out of there. Now the crash report properly displays the first exception as well as the second one. Signed-off-by: Graf Yang <graf.yang@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch/blackfin/mach-common')
-rw-r--r--arch/blackfin/mach-common/entry.S22
-rw-r--r--arch/blackfin/mach-common/head.S8
2 files changed, 17 insertions, 13 deletions
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index cbc5b6d1ed0..4e8e3fe0ba1 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -326,8 +326,6 @@ ENTRY(_ex_trap_c)
326 [p4] = r7; 326 [p4] = r7;
327 csync; 327 csync;
328 328
329#ifndef CONFIG_DEBUG_DOUBLEFAULT
330
331 /* 329 /*
332 * Save these registers, as they are only valid in exception context 330 * Save these registers, as they are only valid in exception context
333 * (where we are now - as soon as we defer to IRQ5, they can change) 331 * (where we are now - as soon as we defer to IRQ5, they can change)
@@ -347,7 +345,10 @@ ENTRY(_ex_trap_c)
347 345
348 r6 = retx; 346 r6 = retx;
349 [p5 + PDA_RETX] = r6; 347 [p5 + PDA_RETX] = r6;
350#endif 348
349 r6 = SEQSTAT;
350 [p5 + PDA_SEQSTAT] = r6;
351
351 /* Save the state of single stepping */ 352 /* Save the state of single stepping */
352 r6 = SYSCFG; 353 r6 = SYSCFG;
353 [p5 + PDA_SYSCFG] = r6; 354 [p5 + PDA_SYSCFG] = r6;
@@ -444,6 +445,9 @@ ENTRY(_exception_to_level5)
444 r6 = [p5 + PDA_SYSCFG]; 445 r6 = [p5 + PDA_SYSCFG];
445 [sp + PT_SYSCFG] = r6; 446 [sp + PT_SYSCFG] = r6;
446 447
448 r6 = [p5 + PDA_SEQSTAT]; /* Read back seqstat */
449 [sp + PT_SEQSTAT] = r6;
450
447 /* Restore the hardware error vector. */ 451 /* Restore the hardware error vector. */
448 r7.h = _evt_ivhw; 452 r7.h = _evt_ivhw;
449 r7.l = _evt_ivhw; 453 r7.l = _evt_ivhw;
@@ -496,7 +500,7 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
496 */ 500 */
497 EX_SCRATCH_REG = sp; 501 EX_SCRATCH_REG = sp;
498 GET_PDA_SAFE(sp); 502 GET_PDA_SAFE(sp);
499 sp = [sp + PDA_EXSTACK] 503 sp = [sp + PDA_EXSTACK];
500 /* Try to deal with syscalls quickly. */ 504 /* Try to deal with syscalls quickly. */
501 [--sp] = ASTAT; 505 [--sp] = ASTAT;
502 [--sp] = (R7:6,P5:4); 506 [--sp] = (R7:6,P5:4);
@@ -532,18 +536,18 @@ ENTRY(_trap) /* Exception: 4th entry into system event table(supervisor mode)*/
532 p4.l = lo(DCPLB_FAULT_ADDR); 536 p4.l = lo(DCPLB_FAULT_ADDR);
533 p4.h = hi(DCPLB_FAULT_ADDR); 537 p4.h = hi(DCPLB_FAULT_ADDR);
534 r7 = [p4]; 538 r7 = [p4];
535 [p5 + PDA_DCPLB] = r7; 539 [p5 + PDA_DF_DCPLB] = r7;
536 540
537 p4.l = lo(ICPLB_FAULT_ADDR); 541 p4.l = lo(ICPLB_FAULT_ADDR);
538 p4.h = hi(ICPLB_FAULT_ADDR); 542 p4.h = hi(ICPLB_FAULT_ADDR);
539 r7 = [p4]; 543 r7 = [p4];
540 [p5 + PDA_ICPLB] = r7; 544 [p5 + PDA_DF_ICPLB] = r7;
541 545
542 r6 = retx; 546 r7 = retx;
543 [p5 + PDA_RETX] = r6; 547 [p5 + PDA_DF_RETX] = r7;
544 548
545 r7 = SEQSTAT; /* reason code is in bit 5:0 */ 549 r7 = SEQSTAT; /* reason code is in bit 5:0 */
546 [p5 + PDA_SEQSTAT] = r7; 550 [p5 + PDA_DF_SEQSTAT] = r7;
547#else 551#else
548 r7 = SEQSTAT; /* reason code is in bit 5:0 */ 552 r7 = SEQSTAT; /* reason code is in bit 5:0 */
549#endif 553#endif
diff --git a/arch/blackfin/mach-common/head.S b/arch/blackfin/mach-common/head.S
index 66910121fa6..9c79dfea2a5 100644
--- a/arch/blackfin/mach-common/head.S
+++ b/arch/blackfin/mach-common/head.S
@@ -124,22 +124,22 @@ ENTRY(__start)
124 * below 124 * below
125 */ 125 */
126 GET_PDA(p0, r0); 126 GET_PDA(p0, r0);
127 r6 = [p0 + PDA_RETX]; 127 r6 = [p0 + PDA_DF_RETX];
128 p1.l = _init_saved_retx; 128 p1.l = _init_saved_retx;
129 p1.h = _init_saved_retx; 129 p1.h = _init_saved_retx;
130 [p1] = r6; 130 [p1] = r6;
131 131
132 r6 = [p0 + PDA_DCPLB]; 132 r6 = [p0 + PDA_DF_DCPLB];
133 p1.l = _init_saved_dcplb_fault_addr; 133 p1.l = _init_saved_dcplb_fault_addr;
134 p1.h = _init_saved_dcplb_fault_addr; 134 p1.h = _init_saved_dcplb_fault_addr;
135 [p1] = r6; 135 [p1] = r6;
136 136
137 r6 = [p0 + PDA_ICPLB]; 137 r6 = [p0 + PDA_DF_ICPLB];
138 p1.l = _init_saved_icplb_fault_addr; 138 p1.l = _init_saved_icplb_fault_addr;
139 p1.h = _init_saved_icplb_fault_addr; 139 p1.h = _init_saved_icplb_fault_addr;
140 [p1] = r6; 140 [p1] = r6;
141 141
142 r6 = [p0 + PDA_SEQSTAT]; 142 r6 = [p0 + PDA_DF_SEQSTAT];
143 p1.l = _init_saved_seqstat; 143 p1.l = _init_saved_seqstat;
144 p1.h = _init_saved_seqstat; 144 p1.h = _init_saved_seqstat;
145 [p1] = r6; 145 [p1] = r6;