X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fppc64%2Fxmon%2Fxmon.c;h=8ff281b995089c15c5459f181770855d86540d61;hb=f1227cd3e0e73c48b93368800aa89f4341103a00;hp=3c0ccb2623aeba4e89e9b43c439bf0c4ceafe1cd;hpb=340e2b1a4c74f653454348914c408420d5d3c28a;p=linux-2.6.git diff --git a/arch/ppc64/xmon/xmon.c b/arch/ppc64/xmon/xmon.c index 3c0ccb262..8ff281b99 100644 --- a/arch/ppc64/xmon/xmon.c +++ b/arch/ppc64/xmon/xmon.c @@ -26,13 +26,12 @@ #include #include #include +#include #include #include #include #include #include -#include -#include #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 [cnt] set breakpoint at given instr addr\n" "bc clear all breakpoints\n" "bc clear breakpoint number n or at addr\n" - "bi [cnt] set hardware instr breakpoint (POWER3/RS64 only)\n" - "bd [cnt] set hardware data breakpoint\n" + "bi [cnt] set hardware instr breakpoint (broken?)\n" + "bd [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') + if( termch != '\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();