⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmon.c

📁 底层驱动开发
💻 C
📖 第 1 页 / 共 4 页
字号:
			case '<':				n = size;				scanhex(&n);				adrs -= n;				break;			case '>':				n = size;				scanhex(&n);				adrs += n;				break;			case '?':				printf(memex_subcmd_help_string);				break;			}		}		adrs += inc;	}}intbsesc(void){	int c;	c = inchar();	switch( c ){	case 'n':	c = '\n';	break;	case 'r':	c = '\r';	break;	case 'b':	c = '\b';	break;	case 't':	c = '\t';	break;	}	return c;}#define isxdigit(c)	(('0' <= (c) && (c) <= '9') \			 || ('a' <= (c) && (c) <= 'f') \			 || ('A' <= (c) && (c) <= 'F'))voiddump(void){	int c;	c = inchar();	if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')		termch = c;	scanhex((void *)&adrs);	if (termch != '\n')		termch = 0;	if (c == 'i') {		scanhex(&nidump);		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)			ndump = 64;		else if (ndump > MAX_DUMP)			ndump = MAX_DUMP;		prdump(adrs, ndump);		adrs += ndump;		last_cmd = "d\n";	}}voidprdump(unsigned long adrs, long ndump){	long n, m, c, r, nr;	unsigned char temp[16];	for (n = ndump; n > 0;) {		printf("%.16lx", adrs);		putchar(' ');		r = n < 16? n: 16;		nr = mread(adrs, temp, r);		adrs += nr;		for (m = 0; m < r; ++m) {		        if ((m & 7) == 0 && m > 0)			    putchar(' ');			if (m < nr)				printf("%.2x", temp[m]);			else				printf("%s", fault_chars[fault_type]);		}		if (m <= 8)			printf(" ");		for (; m < 16; ++m)			printf("  ");		printf("  |");		for (m = 0; m < r; ++m) {			if (m < nr) {				c = temp[m];				putchar(' ' <= c && c <= '~'? c: '.');			} else				putchar(' ');		}		n -= r;		for (; m < 16; ++m)			putchar(' ');		printf("|\n");		if (nr < r)			break;	}}intppc_inst_dump(unsigned long adr, long count, int praddr){	int nr, dotted;	unsigned long first_adr;	unsigned long inst, last_inst = 0;	unsigned char val[4];	dotted = 0;	for (first_adr = adr; count > 0; --count, adr += 4) {		nr = mread(adr, val, 4);		if (nr == 0) {			if (praddr) {				const char *x = fault_chars[fault_type];				printf("%.16lx  %s%s%s%s\n", adr, x, x, x, x);			}			break;		}		inst = GETWORD(val);		if (adr > first_adr && inst == last_inst) {			if (!dotted) {				printf(" ...\n");				dotted = 1;			}			continue;		}		dotted = 0;		last_inst = inst;		if (praddr)			printf("%.16lx  %.8x", adr, inst);		printf("\t");		print_insn_powerpc(inst, adr, 0);	/* always returns 4 */		printf("\n");	}	return adr - first_adr;}voidprint_address(unsigned long addr){	xmon_print_symbol(addr, "\t# ", "");}/* * Memory operations - move, set, print differences */static unsigned long mdest;		/* destination address */static unsigned long msrc;		/* source address */static unsigned long mval;		/* byte value to set memory to */static unsigned long mcount;		/* # bytes to affect */static unsigned long mdiffs;		/* max # differences to print */voidmemops(int cmd){	scanhex((void *)&mdest);	if( termch != '\n' )		termch = 0;	scanhex((void *)(cmd == 's'? &mval: &msrc));	if( termch != '\n' )		termch = 0;	scanhex((void *)&mcount);	switch( cmd ){	case 'm':		memmove((void *)mdest, (void *)msrc, mcount);		break;	case 's':		memset((void *)mdest, mval, mcount);		break;	case 'd':		if( termch != '\n' )			termch = 0;		scanhex((void *)&mdiffs);		memdiffs((unsigned char *)mdest, (unsigned char *)msrc, mcount, mdiffs);		break;	}}voidmemdiffs(unsigned char *p1, unsigned char *p2, unsigned nb, unsigned maxpr){	unsigned n, prt;	prt = 0;	for( n = nb; n > 0; --n )		if( *p1++ != *p2++ )			if( ++prt <= maxpr )				printf("%.16x %.2x # %.16x %.2x\n", p1 - 1,					p1[-1], p2 - 1, p2[-1]);	if( prt > maxpr )		printf("Total of %d differences\n", prt);}static unsigned mend;static unsigned mask;voidmemlocate(void){	unsigned a, n;	unsigned char val[4];	last_cmd = "ml";	scanhex((void *)&mdest);	if (termch != '\n') {		termch = 0;		scanhex((void *)&mend);		if (termch != '\n') {			termch = 0;			scanhex((void *)&mval);			mask = ~0;			if (termch != '\n') termch = 0;			scanhex((void *)&mask);		}	}	n = 0;	for (a = mdest; a < mend; a += 4) {		if (mread(a, val, 4) == 4			&& ((GETWORD(val) ^ mval) & mask) == 0) {			printf("%.16x:  %.16x\n", a, GETWORD(val));			if (++n >= 10)				break;		}	}}static unsigned long mskip = 0x1000;static unsigned long mlim = 0xffffffff;voidmemzcan(void){	unsigned char v;	unsigned a;	int ok, ook;	scanhex(&mdest);	if (termch != '\n') termch = 0;	scanhex(&mskip);	if (termch != '\n') termch = 0;	scanhex(&mlim);	ook = 0;	for (a = mdest; a < mlim; a += mskip) {		ok = mread(a, &v, 1);		if (ok && !ook) {			printf("%.8x .. ", a);			fflush(stdout);		} else if (!ok && ook)			printf("%.8x\n", a - mskip);		ook = ok;		if (a + mskip < a)			break;	}	if (ook)		printf("%.8x\n", a - mskip);}/* Input scanning routines */intskipbl(void){	int c;	if( termch != 0 ){		c = termch;		termch = 0;	} else		c = inchar();	while( c == ' ' || c == '\t' )		c = inchar();	return c;}#define N_PTREGS	44static char *regnames[N_PTREGS] = {	"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",	"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",	"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",	"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",	"pc", "msr", "or3", "ctr", "lr", "xer", "ccr", "softe",	"trap", "dar", "dsisr", "res"};intscanhex(unsigned long *vp){	int c, d;	unsigned long v;	c = skipbl();	if (c == '%') {		/* parse register name */		char regname[8];		int i;		for (i = 0; i < sizeof(regname) - 1; ++i) {			c = inchar();			if (!isalnum(c)) {				termch = c;				break;			}			regname[i] = c;		}		regname[i] = 0;		for (i = 0; i < N_PTREGS; ++i) {			if (strcmp(regnames[i], regname) == 0) {				if (xmon_regs == NULL) {					printf("regs not available\n");					return 0;				}				*vp = ((unsigned long *)xmon_regs)[i];				return 1;			}		}		printf("invalid register name '%%%s'\n", regname);		return 0;	}	/* skip leading "0x" if any */	if (c == '0') {		c = inchar();		if (c == 'x') {			c = inchar();		} else {			d = hexdigit(c);			if (d == EOF) {				termch = c;				*vp = 0;				return 1;			}		}	} else if (c == '$') {		int i;		for (i=0; i<63; i++) {			c = inchar();			if (isspace(c)) {				termch = c;				break;			}			tmpstr[i] = c;		}		tmpstr[i++] = 0;		*vp = 0;		if (setjmp(bus_error_jmp) == 0) {			catch_memory_errors = 1;			sync();			*vp = kallsyms_lookup_name(tmpstr);			sync();		}		catch_memory_errors = 0;		if (!(*vp)) {			printf("unknown symbol '%s'\n", tmpstr);			return 0;		}		return 1;	}	d = hexdigit(c);	if (d == EOF) {		termch = c;		return 0;	}	v = 0;	do {		v = (v << 4) + d;		c = inchar();		d = hexdigit(c);	} while (d != EOF);	termch = c;	*vp = v;	return 1;}voidscannl(void){	int c;	c = termch;	termch = 0;	while( c != '\n' )		c = inchar();}inthexdigit(int c){	if( '0' <= c && c <= '9' )		return c - '0';	if( 'A' <= c && c <= 'F' )		return c - ('A' - 10);	if( 'a' <= c && c <= 'f' )		return c - ('a' - 10);	return EOF;}voidgetstring(char *s, int size){	int c;	c = skipbl();	do {		if( size > 1 ){			*s++ = c;			--size;		}		c = inchar();	} while( c != ' ' && c != '\t' && c != '\n' );	termch = c;	*s = 0;}static char line[256];static char *lineptr;voidflush_input(void){	lineptr = NULL;}intinchar(void){	if (lineptr == NULL || *lineptr == 0) {		if (fgets(line, sizeof(line), stdin) == NULL) {			lineptr = NULL;			return EOF;		}		lineptr = line;	}	return *lineptr++;}voidtake_input(char *str){	lineptr = str;}static voidsymbol_lookup(void){	int type = inchar();	unsigned long addr;	static char tmp[64];	switch (type) {	case 'a':		if (scanhex(&addr))			xmon_print_symbol(addr, ": ", "\n");		termch = 0;		break;	case 's':		getstring(tmp, 64);		if (setjmp(bus_error_jmp) == 0) {			catch_memory_errors = 1;			sync();			addr = kallsyms_lookup_name(tmp);			if (addr)				printf("%s: %lx\n", tmp, addr);			else				printf("Symbol '%s' not found.\n", tmp);			sync();		}		catch_memory_errors = 0;		termch = 0;		break;	}}/* Print an address in numeric and symbolic form (if possible) */static void xmon_print_symbol(unsigned long address, const char *mid,			      const char *after){	char *modname;	const char *name = NULL;	unsigned long offset, size;	printf("%.16lx", address);	if (setjmp(bus_error_jmp) == 0) {		catch_memory_errors = 1;		sync();		name = kallsyms_lookup(address, &size, &offset, &modname,				       tmpstr);		sync();		/* wait a little while to see if we get a machine check */		__delay(200);	}	catch_memory_errors = 0;	if (name) {		printf("%s%s+%#lx/%#lx", mid, name, offset, size);		if (modname)			printf(" [%s]", modname);	}	printf("%s", after);}static void debug_trace(void){        unsigned long val, cmd, on;	cmd = skipbl();	if (cmd == '\n') {		/* show current state */		unsigned long i;		printf("ppc64_debug_switch = 0x%lx\n", ppc64_debug_switch);		for (i = 0; i < PPCDBG_NUM_FLAGS ;i++) {			on = PPCDBG_BITVAL(i) & ppc64_debug_switch;			printf("%02x %s %12s   ", i, on ? "on " : "off",  trace_names[i] ? trace_names[i] : "");			if (((i+1) % 3) == 0)				printf("\n");		}		printf("\n");		return;	}	while (cmd != '\n') {		on = 1;	/* default if no sign given */		while (cmd == '+' || cmd == '-') {			on = (cmd == '+');			cmd = inchar();			if (cmd == ' ' || cmd == '\n') {  /* Turn on or off based on + or - */				ppc64_debug_switch = on ? PPCDBG_ALL:PPCDBG_NONE;				printf("Setting all values to %s...\n", on ? "on" : "off");				if (cmd == '\n') return;				else cmd = skipbl(); 			}			else				termch = cmd;		}		termch = cmd;	/* not +/- ... let scanhex see it */		scanhex((void *)&val);		if (val >= 64) {			printf("Value %x out of range:\n", val);			return;		}		if (on) {			ppc64_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);			printf("disable debug %x %s\n", val, trace_names[val] ? trace_names[val] : "");		}		cmd = skipbl();	}}static void dump_slb(void){	int i;	unsigned long tmp;	printf("SLB contents of cpu %x\n", smp_processor_id());	for (i = 0; i < SLB_NUM_ENTRIES; i++) {		asm volatile("slbmfee  %0,%1" : "=r" (tmp) : "r" (i));		printf("%02d %016lx ", i, tmp);		asm volatile("slbmfev  %0,%1" : "=r" (tmp) : "r" (i));		printf("%016lx\n", tmp);	}}static void dump_stab(void){	int i;	unsigned long *tmp = (unsigned long *)get_paca()->stab_addr;	printf("Segment table contents of cpu %x\n", smp_processor_id());	for (i = 0; i < PAGE_SIZE/16; i++) {		unsigned long a, b;		a = *tmp++;		b = *tmp++;		if (a || b) {			printf("%03d %016lx ", i, a);			printf("%016lx\n", b);		}	}}void xmon_init(int enable){	if (enable) {		__debugger = xmon;		__debugger_ipi = xmon_ipi;		__debugger_bpt = xmon_bpt;		__debugger_sstep = xmon_sstep;		__debugger_iabr_match = xmon_iabr_match;		__debugger_dabr_match = xmon_dabr_match;		__debugger_fault_handler = xmon_fault_handler;	} else {		__debugger = NULL;		__debugger_ipi = NULL;		__debugger_bpt = NULL;		__debugger_sstep = NULL;		__debugger_iabr_match = NULL;		__debugger_dabr_match = NULL;		__debugger_fault_handler = NULL;	}}void dump_segments(void){	if (cpu_has_feature(CPU_FTR_SLB))		dump_slb();	else		dump_stab();}

⌨️ 快捷键说明

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