This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / arch / ppc64 / xmon / xmon.c
index 3c0ccb2..8ff281b 100644 (file)
 #include <asm/pgtable.h>
 #include <asm/mmu.h>
 #include <asm/mmu_context.h>
+#include <asm/naca.h>
 #include <asm/paca.h>
 #include <asm/ppcdebug.h>
 #include <asm/cputable.h>
 #include <asm/rtas.h>
 #include <asm/sstep.h>
-#include <asm/bug.h>
-#include <asm/hvcall.h>
 
 #include "nonstdio.h"
 #include "privinst.h"
@@ -51,7 +50,6 @@ static unsigned long in_xmon = 0;
 
 static unsigned long adrs;
 static int size = 1;
-#define MAX_DUMP (128 * 1024)
 static unsigned long ndump = 64;
 static unsigned long nidump = 16;
 static unsigned long ncsum = 4096;
@@ -148,6 +146,8 @@ extern int setjmp(long *);
 extern void longjmp(long *, int);
 extern unsigned long _ASR;
 
+pte_t *find_linux_pte(pgd_t *pgdir, unsigned long va); /* from htab.c */
+
 #define GETWORD(v)     (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
 
 #define isxdigit(c)    (('0' <= (c) && (c) <= '9') \
@@ -228,6 +228,17 @@ extern inline void sync(void)
  no functions have been called from the current function.
  */
 
+/*
+ * We don't allow single-stepping an mtmsrd that would clear
+ * MSR_RI, since that would make the exception unrecoverable.
+ * Since we need to single-step to proceed from a breakpoint,
+ * we don't allow putting a breakpoint on an mtmsrd instruction.
+ * Similarly we don't allow breakpoints on rfid instructions.
+ * These macros tell us if an instruction is a mtmsrd or rfid.
+ */
+#define IS_MTMSRD(instr)       (((instr) & 0xfc0007fe) == 0x7c000164)
+#define IS_RFID(instr)         (((instr) & 0xfc0007fe) == 0x4c000024)
+
 /*
  * Disable surveillance (the service processor watchdog function)
  * while we are in xmon.
@@ -625,19 +636,6 @@ int xmon_fault_handler(struct pt_regs *regs)
        return 0;
 }
 
-/* On systems with a hypervisor, we can't set the DABR
-   (data address breakpoint register) directly. */
-static void set_controlled_dabr(unsigned long val)
-{
-#ifdef CONFIG_PPC_PSERIES
-       if (systemcfg->platform == PLATFORM_PSERIES_LPAR) {
-               int rc = plpar_hcall_norets(H_SET_DABR, val);
-               if (rc != H_Success)
-                       xmon_printf("Warning: setting DABR failed (%d)\n", rc);
-       } else
-#endif
-               set_dabr(val);
-}
 
 static struct bpt *at_breakpoint(unsigned long pc)
 {
@@ -725,8 +723,8 @@ static void insert_bpts(void)
 static void insert_cpu_bpts(void)
 {
        if (dabr.enabled)
-               set_controlled_dabr(dabr.address | (dabr.enabled & 7));
-       if (iabr && cpu_has_feature(CPU_FTR_IABR))
+               set_dabr(dabr.address | (dabr.enabled & 7));
+       if (iabr && (cur_cpu_spec->cpu_features & CPU_FTR_IABR))
                set_iabr(iabr->address
                         | (iabr->enabled & (BP_IABR|BP_IABR_TE)));
 }
@@ -753,8 +751,8 @@ static void remove_bpts(void)
 
 static void remove_cpu_bpts(void)
 {
-       set_controlled_dabr(0);
-       if (cpu_has_feature(CPU_FTR_IABR))
+       set_dabr(0);
+       if ((cur_cpu_spec->cpu_features & CPU_FTR_IABR))
                set_iabr(0);
 }
 
@@ -1063,8 +1061,8 @@ static char *breakpoint_help_string =
     "b <addr> [cnt]   set breakpoint at given instr addr\n"
     "bc               clear all breakpoints\n"
     "bc <n/addr>      clear breakpoint number n or at addr\n"
-    "bi <addr> [cnt]  set hardware instr breakpoint (POWER3/RS64 only)\n"
-    "bd <addr> [cnt]  set hardware data breakpoint\n"
+    "bi <addr> [cnt]  set hardware instr breakpoint (broken?)\n"
+    "bd <addr> [cnt]  set hardware data breakpoint (broken?)\n"
     "";
 
 static void
@@ -1101,7 +1099,7 @@ bpt_cmds(void)
                break;
 
        case 'i':       /* bi - hardware instr breakpoint */
-               if (!cpu_has_feature(CPU_FTR_IABR)) {
+               if (!(cur_cpu_spec->cpu_features & CPU_FTR_IABR)) {
                        printf("Hardware instruction breakpoint "
                               "not supported on this cpu\n");
                        break;
@@ -1334,26 +1332,6 @@ static void backtrace(struct pt_regs *excp)
        scannl();
 }
 
-static void print_bug_trap(struct pt_regs *regs)
-{
-       struct bug_entry *bug;
-       unsigned long addr;
-
-       if (regs->msr & MSR_PR)
-               return;         /* not in kernel */
-       addr = regs->nip;       /* address of trap instruction */
-       if (addr < PAGE_OFFSET)
-               return;
-       bug = find_bug(regs->nip);
-       if (bug == NULL)
-               return;
-       if (bug->line & BUG_WARNING_TRAP)
-               return;
-
-       printf("kernel BUG in %s at %s:%d!\n",
-              bug->function, bug->file, (unsigned int)bug->line);
-}
-
 void excprint(struct pt_regs *fp)
 {
        unsigned long trap;
@@ -1385,9 +1363,6 @@ void excprint(struct pt_regs *fp)
                printf("    pid   = %ld, comm = %s\n",
                       current->pid, current->comm);
        }
-
-       if (trap == 0x700)
-               print_bug_trap(fp);
 }
 
 void prregs(struct pt_regs *fp)
@@ -1480,17 +1455,7 @@ read_spr(int n)
        store_inst(instrs+1);
        code = (unsigned long (*)(void)) opd;
 
-       if (setjmp(bus_error_jmp) == 0) {
-               catch_memory_errors = 1;
-               sync();
-
-               ret = code();
-
-               sync();
-               /* wait a little while to see if we get a machine check */
-               __delay(200);
-               n = size;
-       }
+       ret = code();
 
        return ret;
 }
@@ -1511,17 +1476,7 @@ write_spr(int n, unsigned long val)
        store_inst(instrs+1);
        code = (unsigned long (*)(unsigned long)) opd;
 
-       if (setjmp(bus_error_jmp) == 0) {
-               catch_memory_errors = 1;
-               sync();
-
-               code(val);
-
-               sync();
-               /* wait a little while to see if we get a machine check */
-               __delay(200);
-               n = size;
-       }
+       code(val);
 }
 
 static unsigned long regno;
@@ -1535,7 +1490,7 @@ super_regs(void)
        unsigned long val;
 #ifdef CONFIG_PPC_ISERIES
        struct paca_struct *ptrPaca = NULL;
-       struct lppaca *ptrLpPaca = NULL;
+       struct ItLpPaca *ptrLpPaca = NULL;
        struct ItLpRegSave *ptrLpRegSave = NULL;
 #endif
 
@@ -1559,10 +1514,10 @@ super_regs(void)
                printf("  Local Processor Control Area (LpPaca): \n");
                ptrLpPaca = ptrPaca->lppaca_ptr;
                printf("    Saved Srr0=%.16lx  Saved Srr1=%.16lx \n",
-                      ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
+                      ptrLpPaca->xSavedSrr0, ptrLpPaca->xSavedSrr1);
                printf("    Saved Gpr3=%.16lx  Saved Gpr4=%.16lx \n",
-                      ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
-               printf("    Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
+                      ptrLpPaca->xSavedGpr3, ptrLpPaca->xSavedGpr4);
+               printf("    Saved Gpr5=%.16lx \n", ptrLpPaca->xSavedGpr5);
     
                printf("  Local Processor Register Save Area (LpRegSave): \n");
                ptrLpRegSave = ptrPaca->reg_save_ptr;
@@ -1940,22 +1895,18 @@ dump(void)
        if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
                termch = c;
        scanhex((void *)&adrs);
-       if (termch != '\n')
+       iftermch != '\n')
                termch = 0;
-       if (c == 'i') {
+       if( c == 'i' ){
                scanhex(&nidump);
-               if (nidump == 0)
+               if( nidump == 0 )
                        nidump = 16;
-               else if (nidump > MAX_DUMP)
-                       nidump = MAX_DUMP;
                adrs += ppc_inst_dump(adrs, nidump, 1);
                last_cmd = "di\n";
        } else {
                scanhex(&ndump);
-               if (ndump == 0)
+               if( ndump == 0 )
                        ndump = 64;
-               else if (ndump > MAX_DUMP)
-                       ndump = MAX_DUMP;
                prdump(adrs, ndump);
                adrs += ndump;
                last_cmd = "d\n";
@@ -2409,9 +2360,9 @@ static void debug_trace(void)
        if (cmd == '\n') {
                /* show current state */
                unsigned long i;
-               printf("ppc64_debug_switch = 0x%lx\n", ppc64_debug_switch);
+               printf("naca->debug_switch = 0x%lx\n", naca->debug_switch);
                for (i = 0; i < PPCDBG_NUM_FLAGS ;i++) {
-                       on = PPCDBG_BITVAL(i) & ppc64_debug_switch;
+                       on = PPCDBG_BITVAL(i) & naca->debug_switch;
                        printf("%02x %s %12s   ", i, on ? "on " : "off",  trace_names[i] ? trace_names[i] : "");
                        if (((i+1) % 3) == 0)
                                printf("\n");
@@ -2425,7 +2376,7 @@ static void debug_trace(void)
                        on = (cmd == '+');
                        cmd = inchar();
                        if (cmd == ' ' || cmd == '\n') {  /* Turn on or off based on + or - */
-                               ppc64_debug_switch = on ? PPCDBG_ALL:PPCDBG_NONE;
+                               naca->debug_switch = on ? PPCDBG_ALL:PPCDBG_NONE;
                                printf("Setting all values to %s...\n", on ? "on" : "off");
                                if (cmd == '\n') return;
                                else cmd = skipbl(); 
@@ -2440,10 +2391,10 @@ static void debug_trace(void)
                        return;
                }
                if (on) {
-                       ppc64_debug_switch |= PPCDBG_BITVAL(val);
+                       naca->debug_switch |= PPCDBG_BITVAL(val);
                        printf("enable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
                } else {
-                       ppc64_debug_switch &= ~PPCDBG_BITVAL(val);
+                       naca->debug_switch &= ~PPCDBG_BITVAL(val);
                        printf("disable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");
                }
                cmd = skipbl();
@@ -2499,7 +2450,7 @@ void xmon_init(void)
 
 void dump_segments(void)
 {
-       if (cpu_has_feature(CPU_FTR_SLB))
+       if (cur_cpu_spec->cpu_features & CPU_FTR_SLB)
                dump_slb();
        else
                dump_stab();