#include <linux/fs.h>
#include <asm/traps.h>
#include <asm/cacheflush.h>
+#include <asm/cplb.h>
#include <asm/blackfin.h>
#include <asm/irq_handler.h>
#include <linux/irq.h>
#include <asm/dma.h>
#ifdef CONFIG_KGDB
-# include <linux/debugger.h>
# include <linux/kgdb.h>
# define CHK_DEBUGGER_TRAP() \
do { \
- CHK_DEBUGGER(trapnr, sig, info.si_code, fp, ); \
+ kgdb_handle_exception(trapnr, sig, info.si_code, fp); \
} while (0)
# define CHK_DEBUGGER_TRAP_MAYBE() \
do { \
CSYNC();
}
-unsigned long saved_icplb_fault_addr, saved_dcplb_fault_addr;
+/*
+ * Used to save the RETX, SEQSTAT, I/D CPLB FAULT ADDR
+ * values across the transition from exception to IRQ5.
+ * We put these in L1, so they are going to be in a valid
+ * location during exception context
+ */
+__attribute__((l1_data))
+unsigned long saved_retx, saved_seqstat,
+ saved_icplb_fault_addr, saved_dcplb_fault_addr;
static void decode_address(char *buf, unsigned long address)
{
console_verbose();
oops_in_progress = 1;
printk(KERN_EMERG "\n" KERN_EMERG "Double Fault\n");
- dump_bfin_process(fp);
- dump_bfin_mem(fp);
- show_regs(fp);
+#ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT
+ if (((long)fp->seqstat & SEQSTAT_EXCAUSE) == VEC_UNCOV) {
+ char buf[150];
+ decode_address(buf, saved_retx);
+ printk(KERN_EMERG "While handling exception (EXCAUSE = 0x%x) at %s:\n",
+ (int)saved_seqstat & SEQSTAT_EXCAUSE, buf);
+ decode_address(buf, saved_dcplb_fault_addr);
+ printk(KERN_NOTICE " DCPLB_FAULT_ADDR: %s\n", buf);
+ decode_address(buf, saved_icplb_fault_addr);
+ printk(KERN_NOTICE " ICPLB_FAULT_ADDR: %s\n", buf);
+
+ decode_address(buf, fp->retx);
+ printk(KERN_NOTICE "The instruction at %s caused a double exception\n",
+ buf);
+ } else
+#endif
+ {
+ dump_bfin_process(fp);
+ dump_bfin_mem(fp);
+ show_regs(fp);
+ }
panic("Double Fault - unrecoverable event\n");
}
info.si_code = SEGV_STACKFLOW;
sig = SIGSEGV;
printk(KERN_NOTICE EXC_0x03(KERN_NOTICE));
- CHK_DEBUGGER_TRAP();
+ CHK_DEBUGGER_TRAP_MAYBE();
+ break;
+ /* 0x04 - User Defined */
+ /* 0x05 - User Defined */
+ /* 0x06 - User Defined */
+ /* 0x07 - User Defined */
+ /* 0x08 - User Defined */
+ /* 0x09 - User Defined */
+ /* 0x0A - User Defined */
+ /* 0x0B - User Defined */
+ /* 0x0C - User Defined */
+ /* 0x0D - User Defined */
+ /* 0x0E - User Defined */
+ /* 0x0F - User Defined */
+ /*
+ * If we got here, it is most likely that someone was trying to use a
+ * custom exception handler, and it is not actually installed properly
+ */
+ case VEC_EXCPT04 ... VEC_EXCPT15:
+ info.si_code = ILL_ILLPARAOP;
+ sig = SIGILL;
+ printk(KERN_NOTICE EXC_0x04(KERN_NOTICE));
+ CHK_DEBUGGER_TRAP_MAYBE();
break;
- /* 0x04 - User Defined, Caught by default */
- /* 0x05 - User Defined, Caught by default */
- /* 0x06 - User Defined, Caught by default */
- /* 0x07 - User Defined, Caught by default */
- /* 0x08 - User Defined, Caught by default */
- /* 0x09 - User Defined, Caught by default */
- /* 0x0A - User Defined, Caught by default */
- /* 0x0B - User Defined, Caught by default */
- /* 0x0C - User Defined, Caught by default */
- /* 0x0D - User Defined, Caught by default */
- /* 0x0E - User Defined, Caught by default */
- /* 0x0F - User Defined, Caught by default */
/* 0x10 HW Single step, handled here */
case VEC_STEP:
info.si_code = TRAP_STEP;
info.si_code = TRAP_TRACEFLOW;
sig = SIGTRAP;
printk(KERN_NOTICE EXC_0x11(KERN_NOTICE));
- CHK_DEBUGGER_TRAP();
+ CHK_DEBUGGER_TRAP_MAYBE();
break;
/* 0x12 - Reserved, Caught by default */
/* 0x13 - Reserved, Caught by default */
info.si_code = ILL_ILLOPC;
sig = SIGILL;
printk(KERN_NOTICE EXC_0x21(KERN_NOTICE));
- CHK_DEBUGGER_TRAP();
+ CHK_DEBUGGER_TRAP_MAYBE();
break;
/* 0x22 - Illegal Instruction Combination, handled here */
case VEC_ILGAL_I:
info.si_code = ILL_ILLPARAOP;
sig = SIGILL;
printk(KERN_NOTICE EXC_0x22(KERN_NOTICE));
- CHK_DEBUGGER_TRAP();
+ CHK_DEBUGGER_TRAP_MAYBE();
break;
/* 0x23 - Data CPLB protection violation, handled here */
case VEC_CPLB_VL:
info.si_code = ILL_CPLB_VI;
sig = SIGBUS;
printk(KERN_NOTICE EXC_0x23(KERN_NOTICE));
- CHK_DEBUGGER_TRAP();
+ CHK_DEBUGGER_TRAP_MAYBE();
break;
/* 0x24 - Data access misaligned, handled here */
case VEC_MISALI_D:
info.si_code = BUS_ADRALN;
sig = SIGBUS;
printk(KERN_NOTICE EXC_0x24(KERN_NOTICE));
- CHK_DEBUGGER_TRAP();
+ CHK_DEBUGGER_TRAP_MAYBE();
break;
/* 0x25 - Unrecoverable Event, handled here */
case VEC_UNCOV:
info.si_code = ILL_ILLEXCPT;
sig = SIGILL;
printk(KERN_NOTICE EXC_0x25(KERN_NOTICE));
- CHK_DEBUGGER_TRAP();
+ CHK_DEBUGGER_TRAP_MAYBE();
break;
/* 0x26 - Data CPLB Miss, normal case is handled in _cplb_hdr,
error case is handled here */
info.si_code = BUS_ADRALN;
sig = SIGBUS;
printk(KERN_NOTICE EXC_0x26(KERN_NOTICE));
- CHK_DEBUGGER_TRAP();
break;
/* 0x27 - Data CPLB Multiple Hits - Linux Trap Zero, handled here */
case VEC_CPLB_MHIT:
else
#endif
printk(KERN_NOTICE EXC_0x27(KERN_NOTICE));
- CHK_DEBUGGER_TRAP();
+ CHK_DEBUGGER_TRAP_MAYBE();
break;
/* 0x28 - Emulation Watchpoint, handled here */
case VEC_WATCH:
info.si_code = BUS_OPFETCH;
sig = SIGBUS;
printk(KERN_NOTICE "BF535: VEC_ISTRU_VL\n");
- CHK_DEBUGGER_TRAP();
+ CHK_DEBUGGER_TRAP_MAYBE();
break;
#else
/* 0x29 - Reserved, Caught by default */
info.si_code = BUS_ADRALN;
sig = SIGBUS;
printk(KERN_NOTICE EXC_0x2A(KERN_NOTICE));
- CHK_DEBUGGER_TRAP();
+ CHK_DEBUGGER_TRAP_MAYBE();
break;
/* 0x2B - Instruction CPLB protection violation, handled here */
case VEC_CPLB_I_VL:
info.si_code = ILL_CPLB_VI;
sig = SIGBUS;
printk(KERN_NOTICE EXC_0x2B(KERN_NOTICE));
- CHK_DEBUGGER_TRAP();
+ CHK_DEBUGGER_TRAP_MAYBE();
break;
/* 0x2C - Instruction CPLB miss, handled in _cplb_hdr */
case VEC_CPLB_I_M:
info.si_code = ILL_CPLB_MISS;
sig = SIGBUS;
printk(KERN_NOTICE EXC_0x2C(KERN_NOTICE));
- CHK_DEBUGGER_TRAP();
break;
/* 0x2D - Instruction CPLB Multiple Hits, handled here */
case VEC_CPLB_I_MHIT:
else
#endif
printk(KERN_NOTICE EXC_0x2D(KERN_NOTICE));
- CHK_DEBUGGER_TRAP();
+ CHK_DEBUGGER_TRAP_MAYBE();
break;
/* 0x2E - Illegal use of Supervisor Resource, handled here */
case VEC_ILL_RES:
info.si_code = ILL_PRVOPC;
sig = SIGILL;
printk(KERN_NOTICE EXC_0x2E(KERN_NOTICE));
- CHK_DEBUGGER_TRAP();
+ CHK_DEBUGGER_TRAP_MAYBE();
break;
/* 0x2F - Reserved, Caught by default */
/* 0x30 - Reserved, Caught by default */
printk(KERN_NOTICE HWC_default(KERN_NOTICE));
break;
}
- CHK_DEBUGGER_TRAP();
+ CHK_DEBUGGER_TRAP_MAYBE();
break;
+ /*
+ * We should be handling all known exception types above,
+ * if we get here we hit a reserved one, so panic
+ */
default:
- info.si_code = TRAP_ILLTRAP;
- sig = SIGTRAP;
+ oops_in_progress = 1;
+ info.si_code = ILL_ILLPARAOP;
+ sig = SIGILL;
printk(KERN_EMERG "Caught Unhandled Exception, code = %08lx\n",
(fp->seqstat & SEQSTAT_EXCAUSE));
- CHK_DEBUGGER_TRAP();
+ CHK_DEBUGGER_TRAP_MAYBE();
break;
}