📄 xmon.c
字号:
}#endif /* CONFIG_SMP */#ifdef CONFIG_BOOTX_TEXTextern boot_infos_t disp_bi;static void vidcmds(void){ int c = inchar(); unsigned int val, w; extern int boot_text_mapped; if (!boot_text_mapped) return; if (c != '\n' && scanhex(&val)) { switch (c) { case 'd': w = disp_bi.dispDeviceRowBytes / (disp_bi.dispDeviceDepth >> 3); disp_bi.dispDeviceDepth = val; disp_bi.dispDeviceRowBytes = w * (val >> 3); return; case 'p': disp_bi.dispDeviceRowBytes = val; return; case 'w': disp_bi.dispDeviceRect[2] = val; return; case 'h': disp_bi.dispDeviceRect[3] = val; return; } } printf("W = %d (0x%x) H = %d (0x%x) D = %d (0x%x) P = %d (0x%x)\n", disp_bi.dispDeviceRect[2], disp_bi.dispDeviceRect[2], disp_bi.dispDeviceRect[3], disp_bi.dispDeviceRect[3], disp_bi.dispDeviceDepth, disp_bi.dispDeviceDepth, disp_bi.dispDeviceRowBytes, disp_bi.dispDeviceRowBytes);}#endif /* CONFIG_BOOTX_TEXT */static unsigned short fcstab[256] = { 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78};#define FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff])static voidcsum(void){ unsigned int i; unsigned short fcs; unsigned char v; if (!scanhex(&adrs)) return; if (!scanhex(&ncsum)) return; fcs = 0xffff; for (i = 0; i < ncsum; ++i) { if (mread(adrs+i, &v, 1) == 0) { printf("csum stopped at %x\n", adrs+i); break; } fcs = FCS(fcs, v); } printf("%x\n", fcs);}static voidbpt_cmds(void){ int cmd; unsigned a; int mode, i; struct bpt *bp; cmd = inchar(); switch (cmd) {#if !defined(CONFIG_8xx) case 'd': mode = 7; cmd = inchar(); if (cmd == 'r') mode = 5; else if (cmd == 'w') mode = 6; else termch = cmd; cmd = inchar(); if (cmd == 'p') mode &= ~4; 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': cmd = inchar(); if (cmd == 'p') mode = 2; else mode = 3; iabr.address = 0; iabr.count = 0; iabr.enabled = scanhex(&iabr.address); if (iabr.enabled) iabr.address |= mode; 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"); if (!(dabr.address & 4)) printf("p"); 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_except, ret_from_except_full, ret_from_syscall; 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("[%.8lx] ", stack); xmon_print_symbol(stack[1], " ", "\n"); if (stack[1] == (unsigned) &ret_from_except || stack[1] == (unsigned) &ret_from_except_full || stack[1] == (unsigned) &ret_from_syscall) { if (mread(sp+16, ®s, sizeof(regs)) != sizeof(regs)) break; printf("exception:%x [%x] %x\n", regs.trap, sp+16, regs.nip); sp = regs.gpr[1]; if (mread(sp, stack, sizeof(stack)) != sizeof(stack)) break; } }}intgetsp(void){ int x; asm("mr %0,1" : "=r" (x) :); return x;}voidexcprint(struct pt_regs *fp){ int trap;#ifdef CONFIG_SMP printf("cpu %d: ", smp_processor_id());#endif /* CONFIG_SMP */ printf("vector: %x at pc=", fp->trap); xmon_print_symbol(fp->nip, ": ", ", lr="); xmon_print_symbol(fp->link, ": ", "\n"); printf("msr = %x, sp = %x [%x]\n", fp->msr, fp->gpr[1], fp); trap = TRAP(fp); if (trap == 0x300 || 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": " "); if (n == 12 && !FULL_REGS(fp)) { printf("\n"); break; } } 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;voidsuper_regs(void){ 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());#ifdef CONFIG_PPC_STD_MMU printf("sr0-15 ="); for (i = 0; i < 16; ++i) printf(" %x", get_sr(i)); printf("\n");#endif 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();}#ifndef CONFIG_PPC_STD_MMUstatic voiddump_hash_table(void){ printf("This CPU doesn't have a hash table.\n");}#else#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 = 0; int found, last_found, i; unsigned *hg, w1, last_w2 = 0, last_va0 = 0; 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(void){ 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 * 0x111), seg_start, seg_end); seg_start = seg_end + 0x1000; }}#endif /* CONFIG_PPC_STD_MMU *//* * Stuff for reading and writing memory safely */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 = NULL; 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 = NULL; return n;}static int fault_type;static int fault_except;static char *fault_chars[] = { "--", "**", "##" };static voidhandle_fault(struct pt_regs *regs){ fault_except = TRAP(regs); fault_type = TRAP(regs) == 0x200? 0: TRAP(regs) == 0x300? 1: 2; longjmp(bus_error_jmp, 1);}#define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -