]> git.sur5r.net Git - u-boot/blobdiff - cpu/ppc4xx/traps.c
Sync'd u-boot-net with mainline
[u-boot] / cpu / ppc4xx / traps.c
index 85f2ea4cce904e2fa776e76e0db2906c358f12e7..899cdbd1f4414c007b92450c0d732414987a12cf 100644 (file)
@@ -36,7 +36,9 @@
 #include <command.h>
 #include <asm/processor.h>
 
-#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+DECLARE_GLOBAL_DATA_PTR;
+
+#if defined(CONFIG_CMD_KGDB)
 int (*debugger_exception_handler)(struct pt_regs *) = 0;
 #endif
 
@@ -45,8 +47,7 @@ extern unsigned long search_exception_table(unsigned long);
 
 /* THIS NEEDS CHANGING to use the board info structure.
  */
-#define END_OF_MEM     0x00400000
-
+#define END_OF_MEM     (gd->bd->bi_memstart + gd->bd->bi_memsize)
 
 static __inline__ void set_tsr(unsigned long val)
 {
@@ -77,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
 
@@ -110,7 +111,7 @@ void show_regs(struct pt_regs * regs)
 {
        int i;
 
-       printf("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx DAR: %08lX\n",
+       printf("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx DEAR: %08lX\n",
               regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar);
        printf("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n",
               regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0,
@@ -120,14 +121,12 @@ 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");
                }
        }
@@ -139,13 +138,16 @@ _exception(int signr, struct pt_regs *regs)
 {
        show_regs(regs);
        print_backtrace((unsigned long *)regs->gpr[1]);
-       panic("Exception in kernel pc %lx signal %d",regs->nip,signr);
+       panic("Exception");
 }
 
 void
 MachineCheckException(struct pt_regs *regs)
 {
-       unsigned long fixup;
+       unsigned long fixup, val;
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+       u32 value2;
+#endif
 
        /* Probing PCI using config cycles cause this exception
         * when a device is not present.  Catch it and return to
@@ -156,32 +158,137 @@ MachineCheckException(struct pt_regs *regs)
                return;
        }
 
-#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#if defined(CONFIG_CMD_KGDB)
        if (debugger_exception_handler && (*debugger_exception_handler)(regs))
                return;
 #endif
 
-       printf("Machine check in kernel mode.\n");
+       printf("Machine Check Exception.\n");
        printf("Caused by (from msr): ");
-       printf("regs %p ",regs);
-       switch( regs->msr & 0x0000F000)
-       {
-       case (1<<12) :
-               printf("Machine check signal - probably due to mm fault\n"
-                      "with mmu off\n");
+       printf("regs %p ", regs);
+
+       val = get_esr();
+
+#if !defined(CONFIG_440)
+       if (val& ESR_IMCP) {
+               printf("Instruction");
+               mtspr(ESR, val & ~ESR_IMCP);
+       } 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 {
+               val = mfspr(MCSR);
+               if (val & MCSR_IB)
+                       printf("Instruction Read PLB Error\n");
+               if (val & MCSR_DRB)
+                       printf("Data Read PLB Error\n");
+               if (val & MCSR_DWB)
+                       printf("Data Write PLB Error\n");
+               if (val & MCSR_TLBP)
+                       printf("TLB Parity Error\n");
+               if (val & MCSR_ICP){
+                       /*flush_instruction_cache(); */
+                       printf("I-Cache Parity Error\n");
+               }
+               if (val & MCSR_DCSP)
+                       printf("D-Cache Search Parity Error\n");
+               if (val & MCSR_DCFP)
+                       printf("D-Cache Flush Parity Error\n");
+               if (val & MCSR_IMPE)
+                       printf("Machine Check exception is imprecise\n");
+
+               /* Clear MCSR */
+               mtspr(SPRN_MCSR, val);
+       }
+#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");
+       if (val & 0x10)
+               printf("DDR0: Single uncorrectable ECC event.\n");
+       if (val & 0x08)
+               printf("DDR0: Multiple correctable ECC events.\n");
+       if (val & 0x04)
+               printf("DDR0: Single correctable ECC event.\n");
+       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 (1<<13) :
-               printf("Transfer error ack signal\n");
+       case 2:
+               printf("DDR0: Masked write Out-of-Range command\n");
                break;
-       case (1<<14) :
-               printf("Data parity signal\n");
+       case 4:
+               printf("DDR0: Wrap write Out-of-Range command\n");
                break;
-       case (1<<15) :
-               printf("Address parity signal\n");
+       case 5:
+               printf("DDR0: Wrap read Out-of-Range command\n");
                break;
        default:
-               printf("Unknown values in msr\n");
+               mfsdram(DDR0_01, value2);
+               printf("DDR0: No DDR0 error know 0x%x %p\n", val, value2);
        }
+       mfsdram(DDR0_23, val);
+       if ( (val >> 16) & 0xff)
+               printf("DDR0: Syndrome for correctable ECC event 0x%x\n",
+                      (val >> 16) & 0xff);
+       mfsdram(DDR0_23, val);
+       if ( (val >> 8) & 0xff)
+               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)
+               printf("DDR0: Address of uncorrectable ECC event %p\n", val);
+       mfsdram(DDR0_35, val);
+       if (val)
+               printf("DDR0: Address of uncorrectable ECC event %p\n", val);
+       mfsdram(DDR0_36, val);
+       if (val)
+               printf("DDR0: Data of uncorrectable ECC event 0x%08x\n", val);
+       mfsdram(DDR0_37, val);
+       if (val)
+               printf("DDR0: Data of uncorrectable ECC event 0x%08x\n", val);
+       mfsdram(DDR0_38, val);
+       if (val)
+               printf("DDR0: Address of correctable ECC event %p\n", val);
+       mfsdram(DDR0_39, val);
+       if (val)
+               printf("DDR0: Address of correctable ECC event %p\n", val);
+       mfsdram(DDR0_40, val);
+       if (val)
+               printf("DDR0: Data of correctable ECC event 0x%08x\n", val);
+       mfsdram(DDR0_41, val);
+       if (val)
+               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");
@@ -190,7 +297,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
@@ -203,21 +310,21 @@ AlignmentException(struct pt_regs *regs)
 void
 ProgramCheckException(struct pt_regs *regs)
 {
-        long esr_val;
+       long esr_val;
 
-#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#if defined(CONFIG_CMD_KGDB)
        if (debugger_exception_handler && (*debugger_exception_handler)(regs))
                return;
 #endif
 
        show_regs(regs);
 
-        esr_val = get_esr();
-        if( esr_val & ESR_PIL )
+       esr_val = get_esr();
+       if( esr_val & ESR_PIL )
                printf( "** Illegal Instruction **\n" );
-        else if( esr_val & ESR_PPR )
+       else if( esr_val & ESR_PPR )
                printf( "** Privileged Instruction **\n" );
-        else if( esr_val & ESR_PTR )
+       else if( esr_val & ESR_PTR )
                printf( "** Trap Instruction **\n" );
 
        print_backtrace((unsigned long *)regs->gpr[1]);
@@ -225,24 +332,24 @@ ProgramCheckException(struct pt_regs *regs)
 }
 
 void
-PITException(struct pt_regs *regs)
+DecrementerPITException(struct pt_regs *regs)
 {
-        /*
-         * Reset PIT interrupt
-         */
-        set_tsr(0x08000000);
-
-        /*
-         * Call timer_interrupt routine in interrupts.c
-         */
-        timer_interrupt(NULL);
+       /*
+        * Reset PIT interrupt
+        */
+       set_tsr(0x08000000);
+
+       /*
+        * Call timer_interrupt routine in interrupts.c
+        */
+       timer_interrupt(NULL);
 }
 
 
 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
@@ -257,7 +364,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
 }
@@ -273,17 +380,17 @@ addr_probe(uint *addr)
 
        __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