📄 xmon.c
字号:
unsigned a; int mode, i; struct bpt *bp; cmd = inchar(); switch (cmd) {#if !defined(CONFIG_8xx) && !defined(CONFIG_POWER4) case 'd': mode = 7; cmd = inchar(); if (cmd == 'r') mode = 5; else if (cmd == 'w') mode = 6; else termch = cmd; dabr.address = 0; dabr.count = 0; dabr.enabled = scanhex(&dabr.address); scanhex(&dabr.count); if (dabr.enabled) dabr.address = (dabr.address & ~7) | mode; break; case 'i': iabr.address = 0; iabr.count = 0; iabr.enabled = scanhex(&iabr.address); if (iabr.enabled) iabr.address |= 3; scanhex(&iabr.count); break;#endif case 'c': if (!scanhex(&a)) { /* clear all breakpoints */ for (i = 0; i < NBPTS; ++i) bpts[i].enabled = 0; iabr.enabled = 0; dabr.enabled = 0; printf("All breakpoints cleared\n"); } else { bp = at_breakpoint(a); if (bp == 0) { printf("No breakpoint at %x\n", a); } else { bp->enabled = 0; } } break; default: termch = cmd; if (!scanhex(&a)) { /* print all breakpoints */ printf("type address count\n"); if (dabr.enabled) { printf("data %.8x %8x [", dabr.address & ~7, dabr.count); if (dabr.address & 1) printf("r"); if (dabr.address & 2) printf("w"); printf("]\n"); } if (iabr.enabled) printf("inst %.8x %8x\n", iabr.address & ~3, iabr.count); for (bp = bpts; bp < &bpts[NBPTS]; ++bp) if (bp->enabled) printf("trap %.8x %8x\n", bp->address, bp->count); break; } bp = at_breakpoint(a); if (bp == 0) { for (bp = bpts; bp < &bpts[NBPTS]; ++bp) if (!bp->enabled) break; if (bp >= &bpts[NBPTS]) { printf("Sorry, no free breakpoints\n"); break; } } bp->enabled = 1; bp->address = a; bp->count = 0; scanhex(&bp->count); break; }}static voidbacktrace(struct pt_regs *excp){ unsigned sp; unsigned stack[2]; struct pt_regs regs; extern char ret_from_intercept, ret_from_syscall_1, ret_from_syscall_2; extern char lost_irq_ret, do_bottom_half_ret, do_signal_ret; extern char ret_from_except; printf("backtrace:\n"); if (excp != NULL) sp = excp->gpr[1]; else sp = getsp(); scanhex(&sp); scannl(); for (; sp != 0; sp = stack[0]) { if (mread(sp, stack, sizeof(stack)) != sizeof(stack)) break; printf("%x ", stack[1]); if (stack[1] == (unsigned) &ret_from_intercept || stack[1] == (unsigned) &ret_from_except || stack[1] == (unsigned) &ret_from_syscall_1 || stack[1] == (unsigned) &ret_from_syscall_2 || stack[1] == (unsigned) &lost_irq_ret || stack[1] == (unsigned) &do_bottom_half_ret || stack[1] == (unsigned) &do_signal_ret) { if (mread(sp+16, ®s, sizeof(regs)) != sizeof(regs)) break; printf("\nexception:%x [%x] %x ", regs.trap, sp+16, regs.nip); sp = regs.gpr[1]; if (mread(sp, stack, sizeof(stack)) != sizeof(stack)) break; } } printf("\n");}intgetsp(){ int x; asm("mr %0,1" : "=r" (x) :); return x;}voidexcprint(struct pt_regs *fp){#ifdef CONFIG_SMP printf("cpu %d: ", smp_processor_id());#endif /* CONFIG_SMP */ printf("vector: %x at pc = %x", fp->trap, fp->nip); printf(", lr = %x, msr = %x, sp = %x [%x]\n", fp->link, fp->msr, fp->gpr[1], fp); if (fp->trap == 0x300 || fp->trap == 0x600) printf("dar = %x, dsisr = %x\n", fp->dar, fp->dsisr); if (current) printf("current = %x, pid = %d, comm = %s\n", current, current->pid, current->comm);}voidprregs(struct pt_regs *fp){ int n; unsigned base; if (scanhex(&base)) fp = (struct pt_regs *) base; for (n = 0; n < 32; ++n) printf("R%.2d = %.8x%s", n, fp->gpr[n], (n & 3) == 3? "\n": " "); printf("pc = %.8x msr = %.8x lr = %.8x cr = %.8x\n", fp->nip, fp->msr, fp->link, fp->ccr); printf("ctr = %.8x xer = %.8x trap = %4x\n", fp->ctr, fp->xer, fp->trap);}voidcacheflush(void){ int cmd; unsigned nflush; cmd = inchar(); if (cmd != 'i') termch = cmd; scanhex(&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 intread_spr(int n){ unsigned int instrs[2]; int (*code)(void); instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6); instrs[1] = 0x4e800020; store_inst(instrs); store_inst(instrs+1); code = (int (*)(void)) instrs; return code();}voidwrite_spr(int n, unsigned int val){ unsigned int instrs[2]; int (*code)(unsigned int); instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6); instrs[1] = 0x4e800020; store_inst(instrs); store_inst(instrs+1); code = (int (*)(unsigned int)) instrs; code(val);}static unsigned int 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 val; cmd = skipbl(); if (cmd == '\n') { printf("msr = %x, pvr = %x\n", get_msr(), get_pvr()); printf("sprg0-3 = %x %x %x %x\n", get_sprg0(), get_sprg1(), get_sprg2(), get_sprg3()); printf("srr0 = %x, srr1 = %x\n", get_srr0(), get_srr1()); printf("sr0-15 ="); for (i = 0; i < 16; ++i) printf(" %x", get_sr(i)); printf("\n"); asm("mr %0,1" : "=r" (i) :); printf("sp = %x ", i); asm("mr %0,2" : "=r" (i) :); printf("toc = %x\n", i); return; } scanhex(®no); switch (cmd) { case 'w': val = read_spr(regno); scanhex(&val); write_spr(regno, val); /* fall through */ case 'r': printf("spr %x = %x\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_msr(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 hash_ctx;static unsigned hash_start;static unsigned 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; }}/* * Stuff for reading and writing memory safely */extern inline void sync(void){ asm volatile("sync; isync");}extern inline void __delay(unsigned int loops){ if (loops != 0) __asm__ __volatile__("mtctr %0; 1: bdnz 1b" : : "r" (loops) : "ctr");}intmread(unsigned 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 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(); 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; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -