DECLARE_GLOBAL_DATA_PTR;
-#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#if defined(CONFIG_CMD_KGDB)
int (*debugger_exception_handler)(struct pt_regs *) = 0;
#endif
#define ESR_DIZ 0x00400000
#define ESR_U0F 0x00008000
-#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG)
+#if defined(CONFIG_CMD_BEDBUG)
extern void do_bedbug_breakpoint(struct pt_regs *);
#endif
void
print_backtrace(unsigned long *sp)
{
- int cnt = 0;
- unsigned long i;
-
- printf("Call backtrace: ");
- while (sp) {
- if ((uint)sp > END_OF_MEM)
- break;
-
- i = sp[1];
- if (cnt++ % 7 == 0)
- printf("\n");
- printf("%08lX ", i);
- if (cnt > 32) break;
- sp = (unsigned long *)*sp;
- }
- printf("\n");
+ int cnt = 0;
+ unsigned long i;
+
+ printf("Call backtrace: ");
+ while (sp) {
+ if ((uint)sp > END_OF_MEM)
+ break;
+
+ i = sp[1];
+ if (cnt++ % 7 == 0)
+ printf("\n");
+ printf("%08lX ", i);
+ if (cnt > 32) break;
+ sp = (unsigned long *)*sp;
+ }
+ printf("\n");
}
void show_regs(struct pt_regs * regs)
printf("\n");
for (i = 0; i < 32; i++) {
- if ((i % 8) == 0)
- {
+ if ((i % 8) == 0) {
printf("GPR%02d: ", i);
}
printf("%08lX ", regs->gpr[i]);
- if ((i % 8) == 7)
- {
+ if ((i % 8) == 7) {
printf("\n");
}
}
MachineCheckException(struct pt_regs *regs)
{
unsigned long fixup, val;
-
- /* Probing PCI using config cycles cause this exception
- * when a device is not present. Catch it and return to
- * the PCI exception handler.
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+ u32 value2;
+ int corr_ecc = 0;
+ int uncorr_ecc = 0;
+#endif
+
+ /* Probing PCI(E) using config cycles may cause this exception
+ * when a device is not present. To gracefully recover in such
+ * scenarios config read/write routines need to be instrumented in
+ * order to return via fixup handler. For examples refer to
+ * pcie_in_8(), pcie_in_le16() and pcie_in_le32()
*/
if ((fixup = search_exception_table(regs->nip)) != 0) {
regs->nip = fixup;
+ val = mfspr(MCSR);
+ /* Clear MCSR */
+ mtspr(SPRN_MCSR, val);
return;
}
-#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#if defined(CONFIG_CMD_KGDB)
if (debugger_exception_handler && (*debugger_exception_handler)(regs))
return;
#endif
if (val& ESR_IMCP) {
printf("Instruction");
mtspr(ESR, val & ~ESR_IMCP);
- } else
+ } else {
printf("Data");
+ }
printf(" machine check.\n");
#elif defined(CONFIG_440)
if (val& ESR_IMCP){
printf("Instruction Synchronous Machine Check exception\n");
mtspr(SPRN_ESR, val & ~ESR_IMCP);
- }
- else {
+ } else {
val = mfspr(MCSR);
if (val & MCSR_IB)
printf("Instruction Read PLB Error\n");
/* Clear MCSR */
mtspr(SPRN_MCSR, val);
}
-#endif
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+ mfsdram(DDR0_00, val) ;
+ printf("DDR0: DDR0_00 %p\n", val);
+ val = (val >> 16) & 0xff;
+ if (val & 0x80)
+ printf("DDR0: At least one interrupt active\n");
+ if (val & 0x40)
+ printf("DDR0: DRAM initialization complete.\n");
+ if (val & 0x20) {
+ printf("DDR0: Multiple uncorrectable ECC events.\n");
+ uncorr_ecc = 1;
+ }
+ if (val & 0x10) {
+ printf("DDR0: Single uncorrectable ECC event.\n");
+ uncorr_ecc = 1;
+ }
+ if (val & 0x08) {
+ printf("DDR0: Multiple correctable ECC events.\n");
+ corr_ecc = 1;
+ }
+ if (val & 0x04) {
+ printf("DDR0: Single correctable ECC event.\n");
+ corr_ecc = 1;
+ }
+ if (val & 0x02)
+ printf("Multiple accesses outside the defined"
+ " physical memory space detected\n");
+ if (val & 0x01)
+ printf("DDR0: Single access outside the defined"
+ " physical memory space detected.\n");
+
+ mfsdram(DDR0_01, val);
+ val = (val >> 8) & 0x7;
+ switch (val ) {
+ case 0:
+ printf("DDR0: Write Out-of-Range command\n");
+ break;
+ case 1:
+ printf("DDR0: Read Out-of-Range command\n");
+ break;
+ case 2:
+ printf("DDR0: Masked write Out-of-Range command\n");
+ break;
+ case 4:
+ printf("DDR0: Wrap write Out-of-Range command\n");
+ break;
+ case 5:
+ printf("DDR0: Wrap read Out-of-Range command\n");
+ break;
+ default:
+ mfsdram(DDR0_01, value2);
+ printf("DDR0: No DDR0 error know 0x%x %p\n", val, value2);
+ }
+ mfsdram(DDR0_23, val);
+ if (((val >> 16) & 0xff) && corr_ecc)
+ printf("DDR0: Syndrome for correctable ECC event 0x%x\n",
+ (val >> 16) & 0xff);
+ mfsdram(DDR0_23, val);
+ if (((val >> 8) & 0xff) && uncorr_ecc)
+ printf("DDR0: Syndrome for uncorrectable ECC event 0x%x\n",
+ (val >> 8) & 0xff);
+ mfsdram(DDR0_33, val);
+ if (val)
+ printf("DDR0: Address of command that caused an "
+ "Out-of-Range interrupt %p\n", val);
+ mfsdram(DDR0_34, val);
+ if (val && uncorr_ecc)
+ printf("DDR0: Address of uncorrectable ECC event %p\n", val);
+ mfsdram(DDR0_35, val);
+ if (val && uncorr_ecc)
+ printf("DDR0: Address of uncorrectable ECC event %p\n", val);
+ mfsdram(DDR0_36, val);
+ if (val && uncorr_ecc)
+ printf("DDR0: Data of uncorrectable ECC event 0x%08x\n", val);
+ mfsdram(DDR0_37, val);
+ if (val && uncorr_ecc)
+ printf("DDR0: Data of uncorrectable ECC event 0x%08x\n", val);
+ mfsdram(DDR0_38, val);
+ if (val && corr_ecc)
+ printf("DDR0: Address of correctable ECC event %p\n", val);
+ mfsdram(DDR0_39, val);
+ if (val && corr_ecc)
+ printf("DDR0: Address of correctable ECC event %p\n", val);
+ mfsdram(DDR0_40, val);
+ if (val && corr_ecc)
+ printf("DDR0: Data of correctable ECC event 0x%08x\n", val);
+ mfsdram(DDR0_41, val);
+ if (val && corr_ecc)
+ printf("DDR0: Data of correctable ECC event 0x%08x\n", val);
+#endif /* CONFIG_440EPX */
+#endif /* CONFIG_440 */
show_regs(regs);
print_backtrace((unsigned long *)regs->gpr[1]);
panic("machine check");
void
AlignmentException(struct pt_regs *regs)
{
-#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#if defined(CONFIG_CMD_KGDB)
if (debugger_exception_handler && (*debugger_exception_handler)(regs))
return;
#endif
{
long esr_val;
-#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#if defined(CONFIG_CMD_KGDB)
if (debugger_exception_handler && (*debugger_exception_handler)(regs))
return;
#endif
void
UnknownException(struct pt_regs *regs)
{
-#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#if defined(CONFIG_CMD_KGDB)
if (debugger_exception_handler && (*debugger_exception_handler)(regs))
return;
#endif
{
printf("Debugger trap at @ %lx\n", regs->nip );
show_regs(regs);
-#if (CONFIG_COMMANDS & CFG_CMD_BEDBUG)
+#if defined(CONFIG_CMD_BEDBUG)
do_bedbug_breakpoint( regs );
#endif
}
__asm__ __volatile__( \
"1: lwz %0,0(%1)\n" \
- " eieio\n" \
- " li %0,0\n" \
- "2:\n" \
- ".section .fixup,\"ax\"\n" \
- "3: li %0,-1\n" \
- " b 2b\n" \
- ".section __ex_table,\"a\"\n" \
- " .align 2\n" \
- " .long 1b,3b\n" \
- ".text" \
- : "=r" (retval) : "r"(addr));
+ " eieio\n" \
+ " li %0,0\n" \
+ "2:\n" \
+ ".section .fixup,\"ax\"\n" \
+ "3: li %0,-1\n" \
+ " b 2b\n" \
+ ".section __ex_table,\"a\"\n" \
+ " .align 2\n" \
+ " .long 1b,3b\n" \
+ ".text" \
+ : "=r" (retval) : "r"(addr));
return (retval);
#endif