]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - arch/powerpc/xmon/xmon.c
Merge branch 'x86-mm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6.git] / arch / powerpc / xmon / xmon.c
index b481db1dacb4a7b3f2c35e49a0789612bbc591a7..e1f33a81e5e1f130cf3c1e0b82b4d9d751cf904b 100644 (file)
 #include <asm/spu.h>
 #include <asm/spu_priv1.h>
 #include <asm/firmware.h>
+#include <asm/setjmp.h>
+#include <asm/reg.h>
 
 #ifdef CONFIG_PPC64
 #include <asm/hvcall.h>
 #include <asm/paca.h>
-#include <asm/iseries/it_lp_reg_save.h>
 #endif
 
 #include "nonstdio.h"
@@ -54,7 +55,7 @@
 #define skipbl xmon_skipbl
 
 #ifdef CONFIG_SMP
-cpumask_t cpus_in_xmon = CPU_MASK_NONE;
+static cpumask_t cpus_in_xmon = CPU_MASK_NONE;
 static unsigned long xmon_taken = 1;
 static int xmon_owner;
 static int xmon_gate;
@@ -71,12 +72,9 @@ static unsigned long ncsum = 4096;
 static int termch;
 static char tmpstr[128];
 
-#define JMP_BUF_LEN    23
 static long bus_error_jmp[JMP_BUF_LEN];
 static int catch_memory_errors;
 static long *xmon_fault_jmp[NR_CPUS];
-#define setjmp xmon_setjmp
-#define longjmp xmon_longjmp
 
 /* Breakpoint stuff */
 struct bpt {
@@ -112,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 *);
@@ -153,15 +152,15 @@ static const char *getvecname(unsigned long vec);
 
 static int do_spu_cmd(void);
 
-int xmon_no_auto_backtrace;
+#ifdef CONFIG_44x
+static void dump_tlb_44x(void);
+#endif
+
+static int xmon_no_auto_backtrace;
 
 extern void xmon_enter(void);
 extern void xmon_leave(void);
 
-extern long setjmp(long *);
-extern void longjmp(long *, long);
-extern void xmon_save_regs(struct pt_regs *);
-
 #ifdef CONFIG_PPC64
 #define REG            "%.16lx"
 #define REGS_PER_LINE  4
@@ -199,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\
@@ -231,6 +231,9 @@ Commands:\n\
 #ifdef CONFIG_PPC_STD_MMU_32
 "  u   dump segment registers\n"
 #endif
+#ifdef CONFIG_44x
+"  u   dump TLB\n"
+#endif
 "  ?   help\n"
 "  zr  reboot\n\
   zh   halt\n"
@@ -325,6 +328,11 @@ static void release_output_lock(void)
 {
        xmon_speaker = 0;
 }
+
+int cpus_are_in_xmon(void)
+{
+       return !cpus_empty(cpus_in_xmon);
+}
 #endif
 
 static int xmon_core(struct pt_regs *regs, int fromipi)
@@ -525,7 +533,7 @@ int xmon(struct pt_regs *excp)
        struct pt_regs regs;
 
        if (excp == NULL) {
-               xmon_save_regs(&regs);
+               ppc_save_regs(&regs);
                excp = &regs;
        }
 
@@ -591,7 +599,7 @@ static int xmon_iabr_match(struct pt_regs *regs)
 {
        if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
                return 0;
-       if (iabr == 0)
+       if (iabr == NULL)
                return 0;
        xmon_core(regs, 0);
        return 1;
@@ -833,7 +841,7 @@ cmds(struct pt_regs *excp)
                        mdelay(2000);
                        return cmd;
                case '?':
-                       printf(help_string);
+                       xmon_puts(help_string);
                        break;
                case 'b':
                        bpt_cmds();
@@ -855,6 +863,11 @@ cmds(struct pt_regs *excp)
                case 'u':
                        dump_segments();
                        break;
+#endif
+#ifdef CONFIG_4xx
+               case 'u':
+                       dump_tlb_44x();
+                       break;
 #endif
                default:
                        printf("Unrecognized command: ");
@@ -1135,7 +1148,7 @@ bpt_cmds(void)
                } else {
                        /* assume a breakpoint address */
                        bp = at_breakpoint(a);
-                       if (bp == 0) {
+                       if (bp == NULL) {
                                printf("No breakpoint at %x\n", a);
                                break;
                        }
@@ -1217,7 +1230,6 @@ static void get_function_bounds(unsigned long pc, unsigned long *startp,
 {
        unsigned long size, offset;
        const char *name;
-       char *modname;
 
        *startp = *endp = 0;
        if (pc == 0)
@@ -1225,7 +1237,7 @@ static void get_function_bounds(unsigned long pc, unsigned long *startp,
        if (setjmp(bus_error_jmp) == 0) {
                catch_memory_errors = 1;
                sync();
-               name = kallsyms_lookup(pc, &size, &offset, &modname, tmpstr);
+               name = kallsyms_lookup(pc, &size, &offset, NULL, tmpstr);
                if (name != NULL) {
                        *startp = pc - offset;
                        *endp = pc - offset + size;
@@ -1237,15 +1249,12 @@ static void get_function_bounds(unsigned long pc, unsigned long *startp,
 
 static int xmon_depth_to_print = 64;
 
-#ifdef CONFIG_PPC64
-#define LRSAVE_OFFSET          0x10
-#define REG_FRAME_MARKER       0x7265677368657265ul    /* "regshere" */
-#define MARKER_OFFSET          0x60
+#define LRSAVE_OFFSET          (STACK_FRAME_LR_SAVE * sizeof(unsigned long))
+#define MARKER_OFFSET          (STACK_FRAME_MARKER * sizeof(unsigned long))
+
+#ifdef __powerpc64__
 #define REGS_OFFSET            0x70
 #else
-#define LRSAVE_OFFSET          4
-#define REG_FRAME_MARKER       0x72656773
-#define MARKER_OFFSET          8
 #define REGS_OFFSET            16
 #endif
 
@@ -1311,7 +1320,7 @@ static void xmon_show_stack(unsigned long sp, unsigned long lr,
                /* Look for "regshere" marker to see if this is
                   an exception frame. */
                if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long))
-                   && marker == REG_FRAME_MARKER) {
+                   && marker == STACK_FRAME_REGS_MARKER) {
                        if (mread(sp + REGS_OFFSET, &regs, sizeof(regs))
                            != sizeof(regs)) {
                                printf("Couldn't read registers at %lx\n",
@@ -1345,6 +1354,7 @@ static void backtrace(struct pt_regs *excp)
 
 static void print_bug_trap(struct pt_regs *regs)
 {
+#ifdef CONFIG_BUG
        const struct bug_entry *bug;
        unsigned long addr;
 
@@ -1365,9 +1375,10 @@ static void print_bug_trap(struct pt_regs *regs)
 #else
        printf("kernel BUG at %p!\n", (void *)bug->bug_addr);
 #endif
+#endif /* CONFIG_BUG */
 }
 
-void excprint(struct pt_regs *fp)
+static void excprint(struct pt_regs *fp)
 {
        unsigned long trap;
 
@@ -1405,7 +1416,7 @@ void excprint(struct pt_regs *fp)
                print_bug_trap(fp);
 }
 
-void prregs(struct pt_regs *fp)
+static void prregs(struct pt_regs *fp)
 {
        int n, trap;
        unsigned long base;
@@ -1460,7 +1471,7 @@ void prregs(struct pt_regs *fp)
                printf("dar = "REG"   dsisr = %.8lx\n", fp->dar, fp->dsisr);
 }
 
-void cacheflush(void)
+static void cacheflush(void)
 {
        int cmd;
        unsigned long nflush;
@@ -1492,7 +1503,7 @@ void cacheflush(void)
        catch_memory_errors = 0;
 }
 
-unsigned long
+static unsigned long
 read_spr(int n)
 {
        unsigned int instrs[2];
@@ -1530,7 +1541,7 @@ read_spr(int n)
        return ret;
 }
 
-void
+static void
 write_spr(int n, unsigned long val)
 {
        unsigned int instrs[2];
@@ -1568,7 +1579,7 @@ static unsigned long regno;
 extern char exc_prolog;
 extern char dec_exc;
 
-void super_regs(void)
+static void super_regs(void)
 {
        int cmd;
        unsigned long val;
@@ -1591,7 +1602,6 @@ void super_regs(void)
                if (firmware_has_feature(FW_FEATURE_ISERIES)) {
                        struct paca_struct *ptrPaca;
                        struct lppaca *ptrLpPaca;
-                       struct ItLpRegSave *ptrLpRegSave;
 
                        /* Dump out relevant Paca data areas. */
                        printf("Paca: \n");
@@ -1604,15 +1614,6 @@ void super_regs(void)
                        printf("    Saved Gpr3=%.16lx  Saved Gpr4=%.16lx \n",
                               ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
                        printf("    Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
-
-                       printf("  Local Processor Register Save Area (LpRegSave): \n");
-                       ptrLpRegSave = ptrPaca->reg_save_ptr;
-                       printf("    Saved Sprg0=%.16lx  Saved Sprg1=%.16lx \n",
-                              ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
-                       printf("    Saved Sprg2=%.16lx  Saved Sprg3=%.16lx \n",
-                              ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
-                       printf("    Saved Msr  =%.16lx  Saved Nia  =%.16lx \n",
-                              ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
                }
 #endif
 
@@ -1636,7 +1637,7 @@ void super_regs(void)
 /*
  * Stuff for reading and writing memory safely
  */
-int
+static int
 mread(unsigned long adrs, void *buf, int size)
 {
        volatile int n;
@@ -1673,7 +1674,7 @@ mread(unsigned long adrs, void *buf, int size)
        return n;
 }
 
-int
+static int
 mwrite(unsigned long adrs, void *buf, int size)
 {
        volatile int n;
@@ -1738,7 +1739,7 @@ static int handle_fault(struct pt_regs *regs)
 
 #define SWAP(a, b, t)  ((t) = (a), (a) = (b), (b) = (t))
 
-void
+static void
 byterev(unsigned char *val, int size)
 {
        int t;
@@ -1800,7 +1801,7 @@ static char *memex_subcmd_help_string =
     "  x        exit this mode\n"
     "";
 
-void
+static void
 memex(void)
 {
        int cmd, inc, i, nslash;
@@ -1951,7 +1952,7 @@ memex(void)
        }
 }
 
-int
+static int
 bsesc(void)
 {
        int c;
@@ -1991,7 +1992,7 @@ static void xmon_rawdump (unsigned long adrs, long ndump)
 #define isxdigit(c)    (('0' <= (c) && (c) <= '9') \
                         || ('a' <= (c) && (c) <= 'f') \
                         || ('A' <= (c) && (c) <= 'F'))
-void
+static void
 dump(void)
 {
        int c;
@@ -2010,6 +2011,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)
@@ -2029,7 +2032,7 @@ dump(void)
        }
 }
 
-void
+static void
 prdump(unsigned long adrs, long ndump)
 {
        long n, m, c, r, nr;
@@ -2073,7 +2076,7 @@ prdump(unsigned long adrs, long ndump)
 
 typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr);
 
-int
+static int
 generic_inst_dump(unsigned long adr, long count, int praddr,
                        instruction_dump_func dump_func)
 {
@@ -2111,7 +2114,7 @@ generic_inst_dump(unsigned long adr, long count, int praddr,
        return adr - first_adr;
 }
 
-int
+static int
 ppc_inst_dump(unsigned long adr, long count, int praddr)
 {
        return generic_inst_dump(adr, count, praddr, print_insn_powerpc);
@@ -2123,6 +2126,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
@@ -2133,7 +2179,7 @@ static unsigned long mval;                /* byte value to set memory to */
 static unsigned long mcount;           /* # bytes to affect */
 static unsigned long mdiffs;           /* max # differences to print */
 
-void
+static void
 memops(int cmd)
 {
        scanhex((void *)&mdest);
@@ -2159,7 +2205,7 @@ memops(int cmd)
        }
 }
 
-void
+static void
 memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
 {
        unsigned n, prt;
@@ -2177,7 +2223,7 @@ memdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr)
 static unsigned mend;
 static unsigned mask;
 
-void
+static void
 memlocate(void)
 {
        unsigned a, n;
@@ -2210,7 +2256,7 @@ memlocate(void)
 static unsigned long mskip = 0x1000;
 static unsigned long mlim = 0xffffffff;
 
-void
+static void
 memzcan(void)
 {
        unsigned char v;
@@ -2237,7 +2283,7 @@ memzcan(void)
                printf("%.8x\n", a - mskip);
 }
 
-void proccall(void)
+static void proccall(void)
 {
        unsigned long args[8];
        unsigned long ret;
@@ -2395,7 +2441,7 @@ scanhex(unsigned long *vp)
        return 1;
 }
 
-void
+static void
 scannl(void)
 {
        int c;
@@ -2406,7 +2452,7 @@ scannl(void)
                c = inchar();
 }
 
-int hexdigit(int c)
+static int hexdigit(int c)
 {
        if( '0' <= c && c <= '9' )
                return c - '0';
@@ -2437,13 +2483,13 @@ getstring(char *s, int size)
 static char line[256];
 static char *lineptr;
 
-void
+static void
 flush_input(void)
 {
        lineptr = NULL;
 }
 
-int
+static int
 inchar(void)
 {
        if (lineptr == NULL || *lineptr == 0) {
@@ -2456,7 +2502,7 @@ inchar(void)
        return *lineptr++;
 }
 
-void
+static void
 take_input(char *str)
 {
        lineptr = str;
@@ -2528,16 +2574,33 @@ static void xmon_print_symbol(unsigned long address, const char *mid,
 static void dump_slb(void)
 {
        int i;
-       unsigned long tmp;
+       unsigned long esid,vsid,valid;
+       unsigned long llp;
 
        printf("SLB contents of cpu %x\n", smp_processor_id());
 
-       for (i = 0; i < SLB_NUM_ENTRIES; i++) {
-               asm volatile("slbmfee  %0,%1" : "=r" (tmp) : "r" (i));
-               printf("%02d %016lx ", i, tmp);
-
-               asm volatile("slbmfev  %0,%1" : "=r" (tmp) : "r" (i));
-               printf("%016lx\n", tmp);
+       for (i = 0; i < mmu_slb_size; i++) {
+               asm volatile("slbmfee  %0,%1" : "=r" (esid) : "r" (i));
+               asm volatile("slbmfev  %0,%1" : "=r" (vsid) : "r" (i));
+               valid = (esid & SLB_ESID_V);
+               if (valid | esid | vsid) {
+                       printf("%02d %016lx %016lx", i, esid, vsid);
+                       if (valid) {
+                               llp = vsid & SLB_VSID_LLP;
+                               if (vsid & SLB_VSID_B_1T) {
+                                       printf("  1T  ESID=%9lx  VSID=%13lx LLP:%3lx \n",
+                                               GET_ESID_1T(esid),
+                                               (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T,
+                                               llp);
+                               } else {
+                                       printf(" 256M ESID=%9lx  VSID=%13lx LLP:%3lx \n",
+                                               GET_ESID(esid),
+                                               (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT,
+                                               llp);
+                               }
+                       } else
+                               printf("\n");
+               }
        }
 }
 
@@ -2582,7 +2645,34 @@ void dump_segments(void)
 }
 #endif
 
-void xmon_init(int enable)
+#ifdef CONFIG_44x
+static void dump_tlb_44x(void)
+{
+       int i;
+
+       for (i = 0; i < PPC44x_TLB_SIZE; i++) {
+               unsigned long w0,w1,w2;
+               asm volatile("tlbre  %0,%1,0" : "=r" (w0) : "r" (i));
+               asm volatile("tlbre  %0,%1,1" : "=r" (w1) : "r" (i));
+               asm volatile("tlbre  %0,%1,2" : "=r" (w2) : "r" (i));
+               printf("[%02x] %08x %08x %08x ", i, w0, w1, w2);
+               if (w0 & PPC44x_TLB_VALID) {
+                       printf("V %08x -> %01x%08x %c%c%c%c%c",
+                              w0 & PPC44x_TLB_EPN_MASK,
+                              w1 & PPC44x_TLB_ERPN_MASK,
+                              w1 & PPC44x_TLB_RPN_MASK,
+                              (w2 & PPC44x_TLB_W) ? 'W' : 'w',
+                              (w2 & PPC44x_TLB_I) ? 'I' : 'i',
+                              (w2 & PPC44x_TLB_M) ? 'M' : 'm',
+                              (w2 & PPC44x_TLB_G) ? 'G' : 'g',
+                              (w2 & PPC44x_TLB_E) ? 'E' : 'e');
+               }
+               printf("\n");
+       }
+}
+#endif /* CONFIG_44x */
+
+static void xmon_init(int enable)
 {
 #ifdef CONFIG_PPC_ISERIES
        if (firmware_has_feature(FW_FEATURE_ISERIES))
@@ -2635,7 +2725,7 @@ static int __init setup_xmon_sysrq(void)
 __initcall(setup_xmon_sysrq);
 #endif /* CONFIG_MAGIC_SYSRQ */
 
-int __initdata xmon_early, xmon_off;
+static int __initdata xmon_early, xmon_off;
 
 static int __init early_parse_xmon(char *p)
 {
@@ -2806,9 +2896,10 @@ static void dump_spu_fields(struct spu *spu)
        DUMP_FIELD(spu, "0x%lx", ls_size);
        DUMP_FIELD(spu, "0x%x", node);
        DUMP_FIELD(spu, "0x%lx", flags);
-       DUMP_FIELD(spu, "0x%lx", dar);
-       DUMP_FIELD(spu, "0x%lx", dsisr);
        DUMP_FIELD(spu, "%d", class_0_pending);
+       DUMP_FIELD(spu, "0x%lx", class_0_dar);
+       DUMP_FIELD(spu, "0x%lx", class_1_dar);
+       DUMP_FIELD(spu, "0x%lx", class_1_dsisr);
        DUMP_FIELD(spu, "0x%lx", irqs[0]);
        DUMP_FIELD(spu, "0x%lx", irqs[1]);
        DUMP_FIELD(spu, "0x%lx", irqs[2]);