xmon.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 2,009 行 · 第 1/3 页

C
2,009
字号
	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;		pretty_print_addr(stack[1]);		printf(" ");		if (stack[1] == (unsigned) &ret_from_except		    || stack[1] == (unsigned) &ret_from_except_full		    || stack[1] == (unsigned) &ret_from_syscall) {			if (mread(sp+16, &regs, 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(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);	pretty_print_addr(fp->nip);	printf(", lr = ");	pretty_print_addr(fp->link);	printf("\nmsr = %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;voidprint_sysmap(void){	extern char *sysmap;	if ( sysmap ) {		printf("System.map: \n");		if( setjmp(bus_error_jmp) == 0 ) {			debugger_fault_handler = handle_fault;			sync();			xmon_puts(sysmap);			sync();		}		debugger_fault_handler = NULL;	}	else		printf("No System.map\n");}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(&regno);	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;	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(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))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;	}}static int brev;static int mnoread;voidmemex(void){    int cmd, inc, i, nslash;    unsigned n;    unsigned char val[4];    last_cmd = "m\n";    scanhex(&adrs);    while ((cmd = skipbl()) != '\n') {	switch( cmd ){	case 'b':	size = 1;	break;	case 'w':	size = 2;	break;	case 'l':	size = 4;	break;	case 'r': 	brev = !brev;	break;	case 'n':	mnoread = 1;	break;	case '.':	mnoread = 0;	break;	}    }    if( size <= 0 )	size = 1;    else if( size > 4 )	size = 4;    for(;;){	if (!mnoread)	    n = mread(adrs, val, size);	printf("%.8x%c", adrs, brev? 'r': ' ');	if (!mnoread) {	    if (brev)		byterev(val, size);	    putchar(' ');	    for (i = 0; i < n; ++i)		printf("%.2x", val[i]);	    for (; i < size; ++i)		printf("%s", fault_chars[fault_type]);	}	putchar(' ');	inc = size;	nslash = 0;	for(;;){	    if( scanhex(&n) ){		for (i = 0; i < size; ++i)		    val[i] = n >> (i * 8);		if (!brev)		    byterev(val, size);		mwrite(adrs, val, size);		inc = size;	    }	    cmd = skipbl();	    if (cmd == '\n')		break;	    inc = 0;	    switch (cmd) {	    case '\'':		for(;;){		    n = inchar();		    if( n == '\\' )			n = bsesc();		    else if( n == '\'' )			break;		    for (i = 0; i < size; ++i)			val[i] = n >> (i * 8);		    if (!brev)			byterev(val, size);		    mwrite(adrs, val, size);		    adrs += size;		}		adrs -= size;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?