Merge git://git.denx.de/u-boot into u-boot
[oweals/u-boot.git] / cpu / ppc4xx / traps.c
index 7c44a2990b5dd515b6085e09a004628dc18dddee..55154b6f0110c262fb264a4e2bcfda7387f0174e 100644 (file)
@@ -38,7 +38,7 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#if defined(CONFIG_CMD_KGDB)
 int (*debugger_exception_handler)(struct pt_regs *) = 0;
 #endif
 
@@ -78,7 +78,7 @@ static __inline__ unsigned long get_esr(void)
 #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
 
@@ -145,17 +145,21 @@ void
 MachineCheckException(struct pt_regs *regs)
 {
        unsigned long fixup, val;
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+       u32 value2;
+       int corr_ecc = 0;
+       int uncorr_ecc = 0;
+#endif
 
-       /* Probing PCI using config cycles cause this exception
-        * when a device is not present.  Catch it and return to
-        * the PCI exception handler.
-        */
        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
@@ -166,7 +170,7 @@ MachineCheckException(struct pt_regs *regs)
 
        val = get_esr();
 
-#if !defined(CONFIG_440)
+#if !defined(CONFIG_440) && !defined(CONFIG_405EX)
        if (val& ESR_IMCP) {
                printf("Instruction");
                mtspr(ESR, val & ~ESR_IMCP);
@@ -175,7 +179,7 @@ MachineCheckException(struct pt_regs *regs)
        }
        printf(" machine check.\n");
 
-#elif defined(CONFIG_440)
+#elif defined(CONFIG_440) || defined(CONFIG_405EX)
        if (val& ESR_IMCP){
                printf("Instruction Synchronous Machine Check exception\n");
                mtspr(SPRN_ESR, val & ~ESR_IMCP);
@@ -183,10 +187,15 @@ MachineCheckException(struct pt_regs *regs)
                val = mfspr(MCSR);
                if (val & MCSR_IB)
                        printf("Instruction Read PLB Error\n");
+#if defined(CONFIG_440)
                if (val & MCSR_DRB)
                        printf("Data Read PLB Error\n");
                if (val & MCSR_DWB)
                        printf("Data Write PLB Error\n");
+#else
+               if (val & MCSR_DB)
+                       printf("Data PLB Error\n");
+#endif
                if (val & MCSR_TLBP)
                        printf("TLB Parity Error\n");
                if (val & MCSR_ICP){
@@ -203,7 +212,97 @@ MachineCheckException(struct pt_regs *regs)
                /* Clear MCSR */
                mtspr(SPRN_MCSR, val);
        }
-#endif
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+       mfsdram(DDR0_00, val) ;
+       printf("DDR0: DDR0_00 %lx\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%lx %x\n", val, value2);
+       }
+       mfsdram(DDR0_23, val);
+       if (((val >> 16) & 0xff) && corr_ecc)
+               printf("DDR0: Syndrome for correctable ECC event 0x%lx\n",
+                      (val >> 16) & 0xff);
+       mfsdram(DDR0_23, val);
+       if (((val >> 8) & 0xff) && uncorr_ecc)
+               printf("DDR0: Syndrome for uncorrectable ECC event 0x%lx\n",
+                      (val >> 8) & 0xff);
+       mfsdram(DDR0_33, val);
+       if (val)
+               printf("DDR0: Address of command that caused an "
+                      "Out-of-Range interrupt %lx\n", val);
+       mfsdram(DDR0_34, val);
+       if (val && uncorr_ecc)
+               printf("DDR0: Address of uncorrectable ECC event %lx\n", val);
+       mfsdram(DDR0_35, val);
+       if (val && uncorr_ecc)
+               printf("DDR0: Address of uncorrectable ECC event %lx\n", val);
+       mfsdram(DDR0_36, val);
+       if (val && uncorr_ecc)
+               printf("DDR0: Data of uncorrectable ECC event 0x%08lx\n", val);
+       mfsdram(DDR0_37, val);
+       if (val && uncorr_ecc)
+               printf("DDR0: Data of uncorrectable ECC event 0x%08lx\n", val);
+       mfsdram(DDR0_38, val);
+       if (val && corr_ecc)
+               printf("DDR0: Address of correctable ECC event %lx\n", val);
+       mfsdram(DDR0_39, val);
+       if (val && corr_ecc)
+               printf("DDR0: Address of correctable ECC event %lx\n", val);
+       mfsdram(DDR0_40, val);
+       if (val && corr_ecc)
+               printf("DDR0: Data of correctable ECC event 0x%08lx\n", val);
+       mfsdram(DDR0_41, val);
+       if (val && corr_ecc)
+               printf("DDR0: Data of correctable ECC event 0x%08lx\n", val);
+#endif /* CONFIG_440EPX */
+#endif /* CONFIG_440 */
        show_regs(regs);
        print_backtrace((unsigned long *)regs->gpr[1]);
        panic("machine check");
@@ -212,7 +311,7 @@ MachineCheckException(struct pt_regs *regs)
 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
@@ -227,7 +326,7 @@ ProgramCheckException(struct pt_regs *regs)
 {
        long esr_val;
 
-#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#if defined(CONFIG_CMD_KGDB)
        if (debugger_exception_handler && (*debugger_exception_handler)(regs))
                return;
 #endif
@@ -264,7 +363,7 @@ DecrementerPITException(struct pt_regs *regs)
 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
@@ -279,7 +378,7 @@ DebugException(struct pt_regs *regs)
 {
        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
 }