📄 xmon.c
字号:
int delta = stack[2]-tab.funcstart; if (delta < 0) printf(" <unknown code>"); else printf(" %s+0x%x", tab.name, delta); } printf("\n"); } if (stack[0] && stack[0] <= sp) { if ((stack[0] & 0xffffffff00000000UL) == 0) printf("<Stack drops into 32-bit userspace %.16lx>\n", stack[0]); else printf("<Corrupt stack. Next backchain is %.16lx>\n", stack[0]); break; } } if (framecount >= MAXFRAMECOUNT) printf("<Punt. Too many stack frames>\n");}intgetsp(){ int x; asm("mr %0,1" : "=r" (x) :); return x;}spinlock_t exception_print_lock = SPIN_LOCK_UNLOCKED;voidexcprint(struct pt_regs *fp){ struct task_struct *c; struct tbtable tab; unsigned long flags; spin_lock_irqsave(&exception_print_lock, flags);#ifdef CONFIG_SMP printf("cpu %d: ", smp_processor_id());#endif /* CONFIG_SMP */ printf("Vector: %lx %s at [%lx]\n", fp->trap, getvecname(fp->trap), fp); printf(" pc: %lx", fp->nip); if (find_tb_table(fp->nip, &tab) && tab.name[0]) { /* Got a nice name for it */ int delta = fp->nip - tab.funcstart; printf(" (%s+0x%x)", tab.name, delta); } printf("\n"); printf(" lr: %lx", fp->link); if (find_tb_table(fp->link, &tab) && tab.name[0]) { /* Got a nice name for it */ int delta = fp->link - tab.funcstart; printf(" (%s+0x%x)", tab.name, delta); } printf("\n"); printf(" sp: %lx\n", fp->gpr[1]); printf(" msr: %lx\n", fp->msr); if (fp->trap == 0x300 || fp->trap == 0x600) { printf(" dar: %lx\n", fp->dar); printf(" dsisr: %lx\n", fp->dsisr); } /* XXX: need to copy current or we die. Why? */ c = current; printf(" current = 0x%lx\n", c); printf(" paca = 0x%lx\n", get_paca()); if (c) { printf(" current = %lx, pid = %ld, comm = %s\n", c, c->pid, c->comm); } spin_unlock_irqrestore(&exception_print_lock, flags);}voidprregs(struct pt_regs *fp){ int n; unsigned long base; if (scanhex((void *)&base)) fp = (struct pt_regs *) base; for (n = 0; n < 16; ++n) printf("R%.2ld = %.16lx R%.2ld = %.16lx\n", n, fp->gpr[n], n+16, fp->gpr[n+16]); printf("pc = %.16lx msr = %.16lx\nlr = %.16lx cr = %.16lx\n", fp->nip, fp->msr, fp->link, fp->ccr); printf("ctr = %.16lx xer = %.16lx trap = %8lx\n", fp->ctr, fp->xer, fp->trap);}voidcacheflush(void){ int cmd; unsigned long nflush; cmd = inchar(); if (cmd != 'i') termch = cmd; scanhex((void *)&adrs); if (termch != '\n') 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); }}unsigned longread_spr(int n){ unsigned int instrs[2]; unsigned long (*code)(void); unsigned long opd[3]; instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6); instrs[1] = 0x4e800020; opd[0] = (unsigned long)instrs; opd[1] = 0; opd[2] = 0; store_inst(instrs); store_inst(instrs+1); code = (unsigned long (*)(void)) opd; return code();}voidwrite_spr(int n, unsigned long val){ unsigned int instrs[2]; unsigned long (*code)(unsigned long); unsigned long opd[3]; instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6); instrs[1] = 0x4e800020; opd[0] = (unsigned long)instrs; opd[1] = 0; opd[2] = 0; store_inst(instrs); store_inst(instrs+1); code = (unsigned long (*)(unsigned long)) opd; code(val);}static unsigned long regno;extern char exc_prolog;extern char dec_exc;voidprint_sysmap(void){ extern char *sysmap; if ( sysmap ) printf("System.map: \n%s", sysmap);}voidsuper_regs(){ int i, cmd; unsigned long val; struct paca_struct* ptrPaca = NULL; struct ItLpPaca* ptrLpPaca = NULL; struct ItLpRegSave* ptrLpRegSave = NULL; cmd = skipbl(); if (cmd == '\n') { unsigned long sp, toc; asm("mr %0,1" : "=r" (sp) :); asm("mr %0,2" : "=r" (toc) :); printf("msr = %.16lx sprg0= %.16lx\n", get_msr(), get_sprg0()); printf("pvr = %.16lx sprg1= %.16lx\n", get_pvr(), get_sprg1()); printf("dec = %.16lx sprg2= %.16lx\n", get_dec(), get_sprg2()); 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)); // Dump out relevant Paca data areas. printf("Paca: \n"); ptrPaca = get_paca(); printf(" Local Processor Control Area (LpPaca): \n"); ptrLpPaca = ptrPaca->xLpPacaPtr; printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n", ptrLpPaca->xSavedSrr0, ptrLpPaca->xSavedSrr1); printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n", ptrLpPaca->xSavedGpr3, ptrLpPaca->xSavedGpr4); printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->xSavedGpr5); printf(" Local Processor Register Save Area (LpRegSave): \n"); ptrLpRegSave = ptrPaca->xLpRegSavePtr; 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); return; } scanhex(®no); switch (cmd) { case 'w': val = read_spr(regno); scanhex(&val); write_spr(regno, val); /* fall through */ 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); set_msrd(val); break; } scannl();}#if 0static voidopenforth(){ int c; char *p; char cmd[1024]; int args[5]; extern int (*prom_entry)(int *); p = cmd; c = skipbl(); while (c != '\n') { *p++ = c; c = inchar(); } *p = 0; args[0] = (int) "interpret"; args[1] = 1; args[2] = 1; args[3] = (int) cmd; (*prom_entry)(args); printf("\n"); if (args[4] != 0) printf("error %x\n", args[4]);}#endif#ifndef CONFIG_PPC64BRIDGEstatic voiddump_hash_table_seg(unsigned seg, unsigned start, unsigned end){ extern void *Hash; extern unsigned long Hash_size; unsigned *htab = Hash; unsigned hsize = Hash_size; unsigned v, hmask, va, last_va; int found, last_found, i; unsigned *hg, w1, last_w2, last_va0; last_found = 0; hmask = hsize / 64 - 1; va = start; start = (start >> 12) & 0xffff; end = (end >> 12) & 0xffff; for (v = start; v < end; ++v) { found = 0; hg = htab + (((v ^ seg) & hmask) * 16); w1 = 0x80000000 | (seg << 7) | (v >> 10); for (i = 0; i < 8; ++i, hg += 2) { if (*hg == w1) { found = 1; break; } } if (!found) { w1 ^= 0x40; hg = htab + ((~(v ^ seg) & hmask) * 16); for (i = 0; i < 8; ++i, hg += 2) { if (*hg == w1) { found = 1; break; } } } if (!(last_found && found && (hg[1] & ~0x180) == last_w2 + 4096)) { if (last_found) { if (last_va != last_va0) printf(" ... %x", last_va); printf("\n"); } if (found) { printf("%x to %x", va, hg[1]); last_va0 = va; } last_found = found; } if (found) { last_w2 = hg[1] & ~0x180; last_va = va; } va += 4096; } if (last_found) printf(" ... %x\n", last_va);}#else /* CONFIG_PPC64BRIDGE */static voiddump_hash_table_seg(unsigned seg, unsigned start, unsigned end){ extern void *Hash; extern unsigned long Hash_size; unsigned *htab = Hash; unsigned hsize = Hash_size; unsigned v, hmask, va, last_va; int found, last_found, i; unsigned *hg, w1, last_w2, last_va0; last_found = 0; hmask = hsize / 128 - 1; va = start; start = (start >> 12) & 0xffff; end = (end >> 12) & 0xffff; for (v = start; v < end; ++v) { found = 0; hg = htab + (((v ^ seg) & hmask) * 32); w1 = 1 | (seg << 12) | ((v & 0xf800) >> 4); for (i = 0; i < 8; ++i, hg += 4) { if (hg[1] == w1) { found = 1; break; } } if (!found) { w1 ^= 2; hg = htab + ((~(v ^ seg) & hmask) * 32); for (i = 0; i < 8; ++i, hg += 4) { if (hg[1] == w1) { found = 1; break; } } } if (!(last_found && found && (hg[3] & ~0x180) == last_w2 + 4096)) { if (last_found) { if (last_va != last_va0) printf(" ... %x", last_va); printf("\n"); } if (found) { printf("%x to %x", va, hg[3]); last_va0 = va; } last_found = found; } if (found) { last_w2 = hg[3] & ~0x180; last_va = va; } va += 4096; } if (last_found) printf(" ... %x\n", last_va);}#endif /* CONFIG_PPC64BRIDGE */static unsigned long hash_ctx;static unsigned long hash_start;static unsigned long hash_end;static voiddump_hash_table(){ int seg; unsigned seg_start, seg_end; hash_ctx = 0; hash_start = 0; hash_end = 0xfffff000; scanhex(&hash_ctx); scanhex(&hash_start); scanhex(&hash_end); printf("Mappings for context %x\n", hash_ctx); seg_start = hash_start; for (seg = hash_start >> 28; seg <= hash_end >> 28; ++seg) { seg_end = (seg << 28) | 0x0ffff000; if (seg_end > hash_end) seg_end = hash_end; dump_hash_table_seg((hash_ctx << 4) + seg, seg_start, seg_end); seg_start = seg_end + 0x1000; }}intmread(unsigned long adrs, void *buf, int size){ volatile int n; char *p, *q; n = 0; if( setjmp(bus_error_jmp) == 0 ){ debugger_fault_handler = handle_fault; sync(); p = (char *) adrs; q = (char *) buf; switch (size) { case 2: *(short *)q = *(short *)p; break; case 4: *(int *)q = *(int *)p; break; default: for( ; n < size; ++n ) { *q++ = *p++; sync(); } } sync(); /* wait a little while to see if we get a machine check */ __delay(200); n = size; } debugger_fault_handler = 0; return n;}intmwrite(unsigned long adrs, void *buf, int size){ volatile int n; char *p, *q; n = 0; if( setjmp(bus_error_jmp) == 0 ){ debugger_fault_handler = handle_fault; sync(); p = (char *) adrs; q = (char *) buf; switch (size) { case 2: *(short *)p = *(short *)q; break; case 4: *(int *)p = *(int *)q; break; default: for( ; n < size; ++n ) { *p++ = *q++; sync(); } } sync(); /* wait a little while to see if we get a machine check */ __delay(200); n = size; } else { printf("*** Error writing address %x\n", adrs + n); } debugger_fault_handler = 0; return n;}static int fault_type;static char *fault_chars[] = { "--", "**", "##" };static voidhandle_fault(struct pt_regs *regs){ fault_type = regs->trap == 0x200? 0: regs->trap == 0x300? 1: 2; longjmp(bus_error_jmp, 1);}#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))voidbyterev(unsigned char *val, int size){ int t; switch (size) { case 2: SWAP(val[0], val[1], t); break; case 4: SWAP(val[0], val[3], t); SWAP(val[1], val[2], t); break; case 8: /* is there really any use for this? */ SWAP(val[0], val[7], t); SWAP(val[1], val[6], t); SWAP(val[2], val[5], t); SWAP(val[3], val[4], t); break; }}static int brev;static int mnoread;static char *memex_help_string = "Memory examine command usage:\n" "m [addr] [flags] examine/change memory\n" " addr is optional. will start where left off.\n" " flags may include chars from this set:\n" " b modify by bytes (default)\n" " w modify by words (2 byte)\n" " l modify by longs (4 byte)\n" " d modify by doubleword (8 byte)\n" " r toggle reverse byte order mode\n" " n do not read memory (for i/o spaces)\n" " . ok to read (default)\n" "NOTE: flags are saved as defaults\n" "";static char *memex_subcmd_help_string = "Memory examine subcommands:\n" " hexval write this val to current location\n" " 'string' write chars from string to this location\n" " ' increment address\n" " ^ decrement address\n" " / increment addr by 0x10. //=0x100, ///=0x1000, etc\n" " \\ decrement addr by 0x10. \\\\=0x100, \\\\\\=0x1000, etc\n" " ` clear no-read flag\n" " ; stay at this addr\n" " v change to byte mode\n" " w change to word (2 byte) mode\n"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -