]> git.hungrycats.org Git - linux/commitdiff
[PATCH] various xmon cleanups
authorAnton Blanchard <anton@samba.org>
Fri, 13 Feb 2004 23:30:14 +0000 (15:30 -0800)
committerAnton Blanchard <anton@samba.org>
Fri, 13 Feb 2004 23:30:14 +0000 (15:30 -0800)
Heres a patch I've had for a while, it removes a bunch of debugger code
which is good :) The next patch will sanitise it (and the rest of the
debugger hooks).

Various xmon cleanups

- recover from bad SPR read/write (we get a program check)
- remove some old code (bat and segment register stuff)
- update the help text to match reality
- add a "press ? for help" when xmon first appears to make rusty happy
- protect against flushing bad parts of memory from Milton
- dont print iseries specific stuff on pseries in SPR dump (S)
- add code to dump the segment table or SLB
- remove a number of functions that wouldnt work on LPAR

arch/ppc64/kernel/traps.c
arch/ppc64/xmon/privinst.h
arch/ppc64/xmon/xmon.c

index e11e2c52c4a7b8651e68f218cb8cf67f52b36d61..6df8cfca3ba075e557482a644394437564f82c69 100644 (file)
@@ -372,6 +372,13 @@ ProgramCheckException(struct pt_regs *regs)
 {
        siginfo_t info;
 
+#ifdef CONFIG_DEBUG_KERNEL
+       if (debugger_fault_handler) {
+               debugger_fault_handler(regs);
+               return;
+       }
+#endif
+
        if (regs->msr & 0x100000) {
                /* IEEE FP exception */
 
index 3fda8922323ba104285afcf1af6b54bbe43601da..183c3e40025881daab3b80ec360a47f2d380af1e 100644 (file)
@@ -43,39 +43,12 @@ GSETSPR(274, sprg2)
 GSETSPR(275, sprg3)
 GSETSPR(282, ear)
 GSETSPR(287, pvr)
-GSETSPR(528, bat0u)
-GSETSPR(529, bat0l)
-GSETSPR(530, bat1u)
-GSETSPR(531, bat1l)
-GSETSPR(532, bat2u)
-GSETSPR(533, bat2l)
-GSETSPR(534, bat3u)
-GSETSPR(535, bat3l)
 GSETSPR(1008, hid0)
 GSETSPR(1009, hid1)
 GSETSPR(1010, iabr)
 GSETSPR(1013, dabr)
 GSETSPR(1023, pir)
 
-static inline int get_sr(int n)
-{
-       int ret;
-
-#if 0
-       // DRENG does not assemble 
-       asm (" mfsrin %0,%1" : "=r" (ret) : "r" (n << 28));
-#endif
-       return ret;
-}
-
-static inline void set_sr(int n, int val)
-{
-#if 0
-       // DRENG does not assemble 
-       asm ("mtsrin %0,%1" : : "r" (val), "r" (n << 28));
-#endif
-}
-
 static inline void store_inst(void *p)
 {
        asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
@@ -90,4 +63,3 @@ static inline void cinval(void *p)
 {
        asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
 }
-
index 52cd2c8210a7312c54b7754a7ab5f0a90723e49f..16ebf3dccc6609b00d3108a79fb69c1a804c6a54 100644 (file)
@@ -115,10 +115,7 @@ static void cpu_cmd(void);
 #endif /* CONFIG_SMP */
 static void csum(void);
 static void bootcmds(void);
-static void mem_translate(void);
-static void mem_check(void);
-static void mem_find_real(void);
-static void mem_find_vsid(void);
+void dump_segments(void);
 
 static void debug_trace(void);
 
@@ -149,7 +146,15 @@ Commands:\n\
   b    show breakpoints\n\
   bd   set data breakpoint\n\
   bi   set instruction breakpoint\n\
-  bc   clear breakpoint\n\
+  bc   clear breakpoint\n"
+#ifdef CONFIG_SMP
+  "\
+  c    print cpus stopped in xmon\n\
+  ci   send xmon interrupt to all other cpus\n\
+  c#   try to switch to cpu number h (in hex)\n"
+#endif
+  "\
+  C    checksum\n\
   d    dump bytes\n\
   di   dump instructions\n\
   df   dump float values\n\
@@ -162,7 +167,6 @@ Commands:\n\
   md   compare two blocks of memory\n\
   ml   locate a block of memory\n\
   mz   zero a block of memory\n\
-  mx   translation information for an effective address\n\
   mi   show information about memory allocation\n\
   p    show the task list\n\
   r    print registers\n\
@@ -171,7 +175,14 @@ Commands:\n\
   t    print backtrace\n\
   T    Enable/Disable PPCDBG flags\n\
   x    exit monitor\n\
-";
+  u    dump segment table or SLB\n\
+  ?    help\n"
+#ifndef CONFIG_PPC_ISERIES
+  "\
+  zr   reboot\n\
+  zh   halt\n"
+#endif
+;
 
 static int xmon_trace[NR_CPUS];
 #define SSTEP  1               /* stepping because of 's' command */
@@ -308,6 +319,7 @@ xmon(struct pt_regs *excp)
 #endif /* CONFIG_SMP */
        remove_bpts();
        disable_surveillance();
+       printf("press ? for help ");
        cmd = cmds(excp);
        if (cmd == 's') {
                xmon_trace[smp_processor_id()] = SSTEP;
@@ -332,17 +344,6 @@ xmon(struct pt_regs *excp)
        set_msrd(msr);          /* restore interrupt enable */
 }
 
-void
-xmon_irq(int irq, void *d, struct pt_regs *regs)
-{
-       unsigned long flags;
-       local_save_flags(flags);
-       local_irq_disable();
-       printf("Keyboard interrupt\n");
-       xmon(regs);
-       local_irq_restore(flags);
-}
-
 int
 xmon_bpt(struct pt_regs *regs)
 {
@@ -524,18 +525,6 @@ cmds(struct pt_regs *excp)
                        case 'z':
                                memzcan();
                                break;
-                       case 'x':
-                               mem_translate();
-                               break;
-                       case 'c':
-                               mem_check();
-                               break;
-                       case 'f':
-                               mem_find_real();
-                               break;
-                       case 'e':
-                               mem_find_vsid();
-                               break;
                        case 'i':
                                show_mem();
                                break;
@@ -587,11 +576,16 @@ cmds(struct pt_regs *excp)
                        cpu_cmd();
                        break;
 #endif /* CONFIG_SMP */
+#ifndef CONFIG_PPC_ISERIES
                case 'z':
                        bootcmds();
+#endif
                case 'T':
                        debug_trace();
                        break;
+               case 'u':
+                       dump_segments();
+                       break;
                default:
                        printf("Unrecognized command: ");
                        do {
@@ -1057,14 +1051,23 @@ cacheflush(void)
                termch = 0;
        nflush = 1;
        scanhex(&nflush);
-       nflush = (nflush + 31) / 32;
-       if (cmd != 'i') {
-               for (; nflush > 0; --nflush, adrs += 0x20)
-                       cflush((void *) adrs);
-       } else {
-               for (; nflush > 0; --nflush, adrs += 0x20)
-                       cinval((void *) adrs);
+       nflush = (nflush + L1_CACHE_BYTES - 1) / L1_CACHE_BYTES;
+       if( setjmp(bus_error_jmp) == 0 ) {
+               debugger_fault_handler = handle_fault;
+               sync();
+
+               if (cmd != 'i') {
+                       for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
+                               cflush((void *) adrs);
+               } else {
+                       for (; nflush > 0; --nflush, adrs += L1_CACHE_BYTES)
+                               cinval((void *) adrs);
+               }
+               sync();
+               /* wait a little while to see if we get a machine check */
+               __delay(200);
        }
+       debugger_fault_handler = 0;
 }
 
 unsigned long
@@ -1073,6 +1076,7 @@ read_spr(int n)
        unsigned int instrs[2];
        unsigned long (*code)(void);
        unsigned long opd[3];
+       unsigned long ret = -1UL;
 
        instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
        instrs[1] = 0x4e800020;
@@ -1083,7 +1087,22 @@ read_spr(int n)
        store_inst(instrs+1);
        code = (unsigned long (*)(void)) opd;
 
-       return code();
+       if (setjmp(bus_error_jmp) == 0) {
+               debugger_fault_handler = handle_fault;
+               sync();
+
+               ret = code();
+
+               sync();
+               /* wait a little while to see if we get a machine check */
+               __delay(200);
+       } else {
+               printf("*** Error reading spr %x\n", n);
+       }
+
+       debugger_fault_handler = 0;
+
+       return ret;
 }
 
 void
@@ -1102,7 +1121,20 @@ write_spr(int n, unsigned long val)
        store_inst(instrs+1);
        code = (unsigned long (*)(unsigned long)) opd;
 
-       code(val);
+       if (setjmp(bus_error_jmp) == 0) {
+               debugger_fault_handler = handle_fault;
+               sync();
+
+               code(val);
+
+               sync();
+               /* wait a little while to see if we get a machine check */
+               __delay(200);
+       } else {
+               printf("*** Error writing spr %x\n", n);
+       }
+
+       debugger_fault_handler = 0;
 }
 
 static unsigned long regno;
@@ -1112,11 +1144,14 @@ extern char dec_exc;
 void
 super_regs()
 {
-       int i, cmd;
+       int cmd;
        unsigned long val;
-       struct paca_struct*  ptrPaca = NULL;
-       struct ItLpPaca*  ptrLpPaca = NULL;
-       struct ItLpRegSave*  ptrLpRegSave = NULL;
+#ifdef CONFIG_PPC_ISERIES
+       int i;
+       struct paca_struct *ptrPaca = NULL;
+       struct ItLpPaca *ptrLpPaca = NULL;
+       struct ItLpRegSave *ptrLpRegSave = NULL;
+#endif
 
        cmd = skipbl();
        if (cmd == '\n') {
@@ -1130,10 +1165,7 @@ super_regs()
                printf("sp   = %.16lx  sprg3= %.16lx\n", sp, get_sprg3());
                printf("toc  = %.16lx  dar  = %.16lx\n", toc, get_dar());
                printf("srr0 = %.16lx  srr1 = %.16lx\n", get_srr0(), get_srr1());
-               printf("asr  = %.16lx\n", mfasr());
-               for (i = 0; i < 8; ++i)
-                       printf("sr%.2ld = %.16lx  sr%.2ld = %.16lx\n", i, get_sr(i), i+8, get_sr(i+8));
-
+#ifdef CONFIG_PPC_ISERIES
                // Dump out relevant Paca data areas.
                printf("Paca: \n");
                ptrPaca = get_paca();
@@ -1149,7 +1181,8 @@ super_regs()
                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
+
                return;
        }
 
@@ -1163,11 +1196,6 @@ super_regs()
        case 'r':
                printf("spr %lx = %lx\n", regno, read_spr(regno));
                break;
-       case 's':
-               val = get_sr(regno);
-               scanhex(&val);
-               set_sr(regno, val);
-               break;
        case 'm':
                val = get_msr();
                scanhex(&val);
@@ -1924,240 +1952,8 @@ void __xmon_print_symbol(const char *fmt, unsigned long address)
        }
 }
 
-void
-mem_translate()
-{
-       int c;
-       unsigned long ea, va, vsid, vpn, page, hpteg_slot_primary, hpteg_slot_secondary, primary_hash, i, *steg, esid, stabl;
-       HPTE *  hpte;
-       struct mm_struct * mm;
-       pte_t  *ptep = NULL;
-       void * pgdir;
-       c = inchar();
-       if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
-               termch = c;
-       scanhex((void *)&ea);
-  
-       if ((ea >= KRANGE_START) && (ea <= (KRANGE_START + (1UL<<60)))) {
-               ptep = 0;
-               vsid = get_kernel_vsid(ea);
-               va = ( vsid << 28 ) | ( ea & 0x0fffffff );
-       } else {
-               // if in vmalloc range, use the vmalloc page directory
-               if ( ( ea >= VMALLOC_START ) && ( ea <= VMALLOC_END ) ) {
-                       mm = &init_mm;
-                       vsid = get_kernel_vsid( ea );
-               }
-               // if in ioremap range, use the ioremap page directory
-               else if ( ( ea >= IMALLOC_START ) && ( ea <= IMALLOC_END ) ) {
-                       mm = &ioremap_mm;
-                       vsid = get_kernel_vsid( ea );
-               }
-               // if in user range, use the current task's page directory
-               else if ( ( ea >= USER_START ) && ( ea <= USER_END ) ) {
-                       mm = current->mm;
-                       vsid = get_vsid(mm->context, ea );
-               }
-               pgdir = mm->pgd;
-               va = ( vsid << 28 ) | ( ea & 0x0fffffff );
-               ptep = find_linux_pte( pgdir, ea );
-       }
-
-       vpn = ((vsid << 28) | (((ea) & 0xFFFF000))) >> 12;
-       page = vpn & 0xffff;
-       esid = (ea >> 28)  & 0xFFFFFFFFF;
-
-  // Search the primary group for an available slot
-       primary_hash = ( vsid & 0x7fffffffff ) ^ page;
-       hpteg_slot_primary = ( primary_hash & htab_data.htab_hash_mask ) * HPTES_PER_GROUP;
-       hpteg_slot_secondary = ( ~primary_hash & htab_data.htab_hash_mask ) * HPTES_PER_GROUP;
-
-       printf("ea             : %.16lx\n", ea);
-       printf("esid           : %.16lx\n", esid);
-       printf("vsid           : %.16lx\n", vsid);
-
-       printf("\nSoftware Page Table\n-------------------\n");
-       printf("ptep           : %.16lx\n", ((unsigned long *)ptep));
-       if(ptep) {
-               printf("*ptep          : %.16lx\n", *((unsigned long *)ptep));
-       }
-
-       hpte  = htab_data.htab  + hpteg_slot_primary;
-       printf("\nHardware Page Table\n-------------------\n");
-       printf("htab base      : %.16lx\n", htab_data.htab);
-       printf("slot primary   : %.16lx\n", hpteg_slot_primary);
-       printf("slot secondary : %.16lx\n", hpteg_slot_secondary);
-       printf("\nPrimary Group\n");
-       for (i=0; i<8; ++i) {
-               if ( hpte->dw0.dw0.v != 0 ) {
-                       printf("%d: (hpte)%.16lx %.16lx\n", i, hpte->dw0.dword0, hpte->dw1.dword1);
-                       printf("          vsid: %.13lx   api: %.2lx  hash: %.1lx\n", 
-                              (hpte->dw0.dw0.avpn)>>5, 
-                              (hpte->dw0.dw0.avpn) & 0x1f,
-                              (hpte->dw0.dw0.h));
-                       printf("          rpn: %.13lx \n", (hpte->dw1.dw1.rpn));
-                       printf("           pp: %.1lx \n", 
-                              ((hpte->dw1.dw1.pp0)<<2)|(hpte->dw1.dw1.pp));
-                       printf("        wimgn: %.2lx  reference: %.1lx  change: %.1lx\n", 
-                              ((hpte->dw1.dw1.w)<<4)|
-                              ((hpte->dw1.dw1.i)<<3)|
-                              ((hpte->dw1.dw1.m)<<2)|
-                              ((hpte->dw1.dw1.g)<<1)|
-                              ((hpte->dw1.dw1.n)<<0),
-                              hpte->dw1.dw1.r, hpte->dw1.dw1.c);
-               }
-               hpte++;
-       }
-
-       printf("\nSecondary Group\n");
-       // Search the secondary group
-       hpte  = htab_data.htab  + hpteg_slot_secondary;
-       for (i=0; i<8; ++i) {
-               if(hpte->dw0.dw0.v) {
-                       printf("%d: (hpte)%.16lx %.16lx\n", i, hpte->dw0.dword0, hpte->dw1.dword1);
-                       printf("          vsid: %.13lx   api: %.2lx  hash: %.1lx\n", 
-                              (hpte->dw0.dw0.avpn)>>5, 
-                              (hpte->dw0.dw0.avpn) & 0x1f,
-                              (hpte->dw0.dw0.h));
-                       printf("          rpn: %.13lx \n", (hpte->dw1.dw1.rpn));
-                       printf("           pp: %.1lx \n", 
-                              ((hpte->dw1.dw1.pp0)<<2)|(hpte->dw1.dw1.pp));
-                       printf("        wimgn: %.2lx  reference: %.1lx  change: %.1lx\n", 
-                              ((hpte->dw1.dw1.w)<<4)|
-                              ((hpte->dw1.dw1.i)<<3)|
-                              ((hpte->dw1.dw1.m)<<2)|
-                              ((hpte->dw1.dw1.g)<<1)|
-                              ((hpte->dw1.dw1.n)<<0),
-                              hpte->dw1.dw1.r, hpte->dw1.dw1.c);
-               }
-               hpte++;
-       }
-
-       printf("\nHardware Segment Table\n-----------------------\n");
-       stabl = (unsigned long)(KERNELBASE+(_ASR&0xFFFFFFFFFFFFFFFE));
-       steg = (unsigned long *)((stabl) | ((esid & 0x1f) << 7));
-
-       printf("stab base      : %.16lx\n", stabl);
-       printf("slot           : %.16lx\n", steg);
-
-       for (i=0; i<8; ++i) {
-               printf("%d: (ste) %.16lx %.16lx\n", i,
-                      *((unsigned long *)(steg+i*2)),*((unsigned long *)(steg+i*2+1)) );
-       }
-}
-
-void mem_check()
-{
-       unsigned long htab_size_bytes;
-       unsigned long htab_end;
-       unsigned long last_rpn;
-       HPTE *hpte1, *hpte2;
-
-       htab_size_bytes = htab_data.htab_num_ptegs * 128; // 128B / PTEG
-       htab_end = (unsigned long)htab_data.htab + htab_size_bytes;
-       // last_rpn = (naca->physicalMemorySize-1) >> PAGE_SHIFT;
-       last_rpn = 0xfffff;
-
-       printf("\nHardware Page Table Check\n-------------------\n");
-       printf("htab base      : %.16lx\n", htab_data.htab);
-       printf("htab size      : %.16lx\n", htab_size_bytes);
-
-#if 1
-       for(hpte1 = htab_data.htab; hpte1 < (HPTE *)htab_end; hpte1++) {
-               if ( hpte1->dw0.dw0.v != 0 ) {
-                       if ( hpte1->dw1.dw1.rpn <= last_rpn ) {
-                               for(hpte2 = hpte1+1; hpte2 < (HPTE *)htab_end; hpte2++) {
-                                       if ( hpte2->dw0.dw0.v != 0 ) {
-                                               if(hpte1->dw1.dw1.rpn == hpte2->dw1.dw1.rpn) {
-                                                       printf(" Duplicate rpn: %.13lx \n", (hpte1->dw1.dw1.rpn));
-                                                       printf("   hpte1: %16.16lx  *hpte1: %16.16lx %16.16lx\n",
-                                                              hpte1, hpte1->dw0.dword0, hpte1->dw1.dword1);
-                                                       printf("   hpte2: %16.16lx  *hpte2: %16.16lx %16.16lx\n",
-                                                              hpte2, hpte2->dw0.dword0, hpte2->dw1.dword1);
-                                               }
-                                       }
-                               }
-                       } else {
-                               printf(" Bogus rpn: %.13lx \n", (hpte1->dw1.dw1.rpn));
-                               printf("   hpte: %16.16lx  *hpte: %16.16lx %16.16lx\n",
-                                      hpte1, hpte1->dw0.dword0, hpte1->dw1.dword1);
-                       }
-               }
-       }
-#endif
-       printf("\nDone -------------------\n");
-}
-
-void mem_find_real()
+static void debug_trace(void)
 {
-       unsigned long htab_size_bytes;
-       unsigned long htab_end;
-       unsigned long last_rpn;
-       HPTE *hpte1;
-       unsigned long pa, rpn;
-       int c;
-
-       c = inchar();
-       if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
-               termch = c;
-       scanhex((void *)&pa);
-       rpn = pa >> 12;
-  
-       htab_size_bytes = htab_data.htab_num_ptegs * 128; // 128B / PTEG
-       htab_end = (unsigned long)htab_data.htab + htab_size_bytes;
-       // last_rpn = (naca->physicalMemorySize-1) >> PAGE_SHIFT;
-       last_rpn = 0xfffff;
-
-       printf("\nMem Find RPN\n-------------------\n");
-       printf("htab base      : %.16lx\n", htab_data.htab);
-       printf("htab size      : %.16lx\n", htab_size_bytes);
-
-       for(hpte1 = htab_data.htab; hpte1 < (HPTE *)htab_end; hpte1++) {
-               if ( hpte1->dw0.dw0.v != 0 ) {
-                       if ( hpte1->dw1.dw1.rpn == rpn ) {
-                               printf(" Found rpn: %.13lx \n", (hpte1->dw1.dw1.rpn));
-                               printf("      hpte: %16.16lx  *hpte1: %16.16lx %16.16lx\n",
-                                      hpte1, hpte1->dw0.dword0, hpte1->dw1.dword1);
-                       }
-               }
-       }
-       printf("\nDone -------------------\n");
-}
-
-void mem_find_vsid()
-{
-       unsigned long htab_size_bytes;
-       unsigned long htab_end;
-       HPTE *hpte1;
-       unsigned long vsid;
-       int c;
-
-       c = inchar();
-       if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
-               termch = c;
-       scanhex((void *)&vsid);
-  
-       htab_size_bytes = htab_data.htab_num_ptegs * 128; // 128B / PTEG
-       htab_end = (unsigned long)htab_data.htab + htab_size_bytes;
-
-       printf("\nMem Find VSID\n-------------------\n");
-       printf("htab base      : %.16lx\n", htab_data.htab);
-       printf("htab size      : %.16lx\n", htab_size_bytes);
-
-       for(hpte1 = htab_data.htab; hpte1 < (HPTE *)htab_end; hpte1++) {
-               if ( hpte1->dw0.dw0.v != 0 ) {
-                       if ( ((hpte1->dw0.dw0.avpn)>>5) == vsid ) {
-                               printf(" Found vsid: %.16lx \n", ((hpte1->dw0.dw0.avpn) >> 5));
-                               printf("       hpte: %16.16lx  *hpte1: %16.16lx %16.16lx\n",
-                                      hpte1, hpte1->dw0.dword0, hpte1->dw1.dword1);
-                       }
-               }
-       }
-       printf("\nDone -------------------\n");
-}
-
-static void debug_trace(void) {
         unsigned long val, cmd, on;
 
        cmd = skipbl();
@@ -2204,3 +2000,47 @@ static void debug_trace(void) {
                cmd = skipbl();
        }
 }
+
+static void dump_slb(void)
+{
+       int i;
+       unsigned long tmp;
+
+       printf("SLB contents of cpu %d\n", smp_processor_id());
+
+       for (i = 0; i < naca->slb_size; 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);
+       }
+}
+
+static void dump_stab(void)
+{
+       int i;
+       unsigned long *tmp = (unsigned long *)get_paca()->xStab_data.virt;
+
+       printf("Segment table contents of cpu %d\n", smp_processor_id());
+
+       for (i = 0; i < PAGE_SIZE/16; i++) {
+               unsigned long a, b;
+
+               a = *tmp++;
+               b = *tmp++;
+
+               if (a || b) {
+                       printf("%03d %016lx ", i, a);
+                       printf("%016lx\n", b);
+               }
+       }
+}
+
+void dump_segments(void)
+{
+       if (cur_cpu_spec->cpu_features & CPU_FTR_SLB)
+               dump_slb();
+       else
+               dump_stab();
+}