drm/i915: remove unused intel_pipe_get_connector()
[safe/jmp/linux-2.6] / arch / powerpc / xmon / xmon.c
index 076368c..8bad7d5 100644 (file)
@@ -41,6 +41,7 @@
 #include <asm/spu_priv1.h>
 #include <asm/firmware.h>
 #include <asm/setjmp.h>
+#include <asm/reg.h>
 
 #ifdef CONFIG_PPC64
 #include <asm/hvcall.h>
@@ -60,7 +61,7 @@ static int xmon_owner;
 static int xmon_gate;
 #endif /* CONFIG_SMP */
 
-static unsigned long in_xmon = 0;
+static unsigned long in_xmon __read_mostly = 0;
 
 static unsigned long adrs;
 static int size = 1;
@@ -109,6 +110,7 @@ static int bsesc(void);
 static void dump(void);
 static void prdump(unsigned long, long);
 static int ppc_inst_dump(unsigned long, long, int);
+static void dump_log_buf(void);
 static void backtrace(struct pt_regs *);
 static void excprint(struct pt_regs *);
 static void prregs(struct pt_regs *);
@@ -159,8 +161,6 @@ static int xmon_no_auto_backtrace;
 extern void xmon_enter(void);
 extern void xmon_leave(void);
 
-extern void xmon_save_regs(struct pt_regs *);
-
 #ifdef CONFIG_PPC64
 #define REG            "%.16lx"
 #define REGS_PER_LINE  4
@@ -198,6 +198,7 @@ Commands:\n\
   di   dump instructions\n\
   df   dump float values\n\
   dd   dump double values\n\
+  dl    dump the kernel log buffer\n\
   dr   dump stream of raw bytes\n\
   e    print exception information\n\
   f    flush cache\n\
@@ -334,6 +335,16 @@ int cpus_are_in_xmon(void)
 }
 #endif
 
+static inline int unrecoverable_excp(struct pt_regs *regs)
+{
+#ifdef CONFIG_4xx
+       /* We have no MSR_RI bit on 4xx, so we simply return false */
+       return 0;
+#else
+       return ((regs->msr & MSR_RI) == 0);
+#endif
+}
+
 static int xmon_core(struct pt_regs *regs, int fromipi)
 {
        int cmd = 0;
@@ -387,7 +398,7 @@ static int xmon_core(struct pt_regs *regs, int fromipi)
        bp = NULL;
        if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
                bp = at_breakpoint(regs->nip);
-       if (bp || (regs->msr & MSR_RI) == 0)
+       if (bp || unrecoverable_excp(regs))
                fromipi = 0;
 
        if (!fromipi) {
@@ -398,7 +409,7 @@ static int xmon_core(struct pt_regs *regs, int fromipi)
                               cpu, BP_NUM(bp));
                        xmon_print_symbol(regs->nip, " ", ")\n");
                }
-               if ((regs->msr & MSR_RI) == 0)
+               if (unrecoverable_excp(regs))
                        printf("WARNING: exception is not recoverable, "
                               "can't continue\n");
                release_output_lock();
@@ -489,7 +500,7 @@ static int xmon_core(struct pt_regs *regs, int fromipi)
                        printf("Stopped at breakpoint %x (", BP_NUM(bp));
                        xmon_print_symbol(regs->nip, " ", ")\n");
                }
-               if ((regs->msr & MSR_RI) == 0)
+               if (unrecoverable_excp(regs))
                        printf("WARNING: exception is not recoverable, "
                               "can't continue\n");
                remove_bpts();
@@ -506,6 +517,15 @@ static int xmon_core(struct pt_regs *regs, int fromipi)
        in_xmon = 0;
 #endif
 
+#ifdef CONFIG_BOOKE
+       if (regs->msr & MSR_DE) {
+               bp = at_breakpoint(regs->nip);
+               if (bp != NULL) {
+                       regs->nip = (unsigned long) &bp->instr[0];
+                       atomic_inc(&bp->ref_count);
+               }
+       }
+#else
        if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
                bp = at_breakpoint(regs->nip);
                if (bp != NULL) {
@@ -519,7 +539,7 @@ static int xmon_core(struct pt_regs *regs, int fromipi)
                        }
                }
        }
-
+#endif
        insert_cpu_bpts();
 
        local_irq_restore(flags);
@@ -532,7 +552,7 @@ int xmon(struct pt_regs *excp)
        struct pt_regs regs;
 
        if (excp == NULL) {
-               xmon_save_regs(&regs);
+               ppc_save_regs(&regs);
                excp = &regs;
        }
 
@@ -883,6 +903,14 @@ cmds(struct pt_regs *excp)
        }
 }
 
+#ifdef CONFIG_BOOKE
+static int do_step(struct pt_regs *regs)
+{
+       regs->msr |= MSR_DE;
+       mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
+       return 1;
+}
+#else
 /*
  * Step a single instruction.
  * Some instructions we emulate, others we execute with MSR_SE set.
@@ -913,6 +941,7 @@ static int do_step(struct pt_regs *regs)
        regs->msr |= MSR_SE;
        return 1;
 }
+#endif
 
 static void bootcmds(void)
 {
@@ -1612,7 +1641,8 @@ static void super_regs(void)
                               ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
                        printf("    Saved Gpr3=%.16lx  Saved Gpr4=%.16lx \n",
                               ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
-                       printf("    Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
+                       printf("    Saved Gpr5=%.16lx \n",
+                               ptrLpPaca->gpr5_dword.saved_gpr5);
                }
 #endif
 
@@ -2010,6 +2040,8 @@ dump(void)
                        nidump = MAX_DUMP;
                adrs += ppc_inst_dump(adrs, nidump, 1);
                last_cmd = "di\n";
+       } else if (c == 'l') {
+               dump_log_buf();
        } else if (c == 'r') {
                scanhex(&ndump);
                if (ndump == 0)
@@ -2123,6 +2155,49 @@ print_address(unsigned long addr)
        xmon_print_symbol(addr, "\t# ", "");
 }
 
+void
+dump_log_buf(void)
+{
+        const unsigned long size = 128;
+        unsigned long end, addr;
+        unsigned char buf[size + 1];
+
+        addr = 0;
+        buf[size] = '\0';
+
+        if (setjmp(bus_error_jmp) != 0) {
+                printf("Unable to lookup symbol __log_buf!\n");
+                return;
+        }
+
+        catch_memory_errors = 1;
+        sync();
+        addr = kallsyms_lookup_name("__log_buf");
+
+        if (! addr)
+                printf("Symbol __log_buf not found!\n");
+        else {
+                end = addr + (1 << CONFIG_LOG_BUF_SHIFT);
+                while (addr < end) {
+                        if (! mread(addr, buf, size)) {
+                                printf("Can't read memory at address 0x%lx\n", addr);
+                                break;
+                        }
+
+                        printf("%s", buf);
+
+                        if (strlen(buf) < size)
+                                break;
+
+                        addr += size;
+                }
+        }
+
+        sync();
+        /* wait a little while to see if we get a machine check */
+        __delay(200);
+        catch_memory_errors = 0;
+}
 
 /*
  * Memory operations - move, set, print differences
@@ -2524,7 +2599,7 @@ static void xmon_print_symbol(unsigned long address, const char *mid,
        printf("%s", after);
 }
 
-#ifdef CONFIG_PPC64
+#ifdef CONFIG_PPC_BOOK3S_64
 static void dump_slb(void)
 {
        int i;