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

📄 gdb-stub.c

📁 底层驱动开发
💻 C
📖 第 1 页 / 共 4 页
字号:
			for (loop = 1; loop <= 27; loop++)				ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(loop),					      ptr, 4, 0);			temp = (unsigned long) __frame;			ptr = mem2hex(&temp, ptr, 4, 0);			ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(29), ptr, 4, 0);			ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(30), ptr, 4, 0);#ifdef CONFIG_MMU			ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(31), ptr, 4, 0);#else			temp = (unsigned long) __debug_frame;			ptr = mem2hex(&temp, ptr, 4, 0);#endif			for (loop = 32; loop <= 63; loop++)				ptr = mem2hex((unsigned long *)__debug_frame + REG_GR(loop),					      ptr, 4, 0);			/* deal with FR0-FR63 */			for (loop = 0; loop <= 63; loop++)				ptr = mem2hex((unsigned long *)&__break_user_context +					      __FPMEDIA_FR(loop),					      ptr, 4, 0);			/* deal with special registers */			ptr = mem2hex(&__debug_frame->pc,    ptr, 4, 0);			ptr = mem2hex(&__debug_frame->psr,   ptr, 4, 0);			ptr = mem2hex(&__debug_frame->ccr,   ptr, 4, 0);			ptr = mem2hex(&__debug_frame->cccr,  ptr, 4, 0);			ptr = mem2hex(&zero, ptr, 4, 0);			ptr = mem2hex(&zero, ptr, 4, 0);			ptr = mem2hex(&zero, ptr, 4, 0);			ptr = mem2hex(&__debug_frame->tbr,   ptr, 4, 0);			ptr = mem2hex(&__debug_regs->brr ,   ptr, 4, 0);			asm volatile("movsg dbar0,%0" : "=r"(dbar));			ptr = mem2hex(&dbar, ptr, 4, 0);			asm volatile("movsg dbar1,%0" : "=r"(dbar));			ptr = mem2hex(&dbar, ptr, 4, 0);			asm volatile("movsg dbar2,%0" : "=r"(dbar));			ptr = mem2hex(&dbar, ptr, 4, 0);			asm volatile("movsg dbar3,%0" : "=r"(dbar));			ptr = mem2hex(&dbar, ptr, 4, 0);			asm volatile("movsg scr0,%0" : "=r"(dbar));			ptr = mem2hex(&dbar, ptr, 4, 0);			asm volatile("movsg scr1,%0" : "=r"(dbar));			ptr = mem2hex(&dbar, ptr, 4, 0);			asm volatile("movsg scr2,%0" : "=r"(dbar));			ptr = mem2hex(&dbar, ptr, 4, 0);			asm volatile("movsg scr3,%0" : "=r"(dbar));			ptr = mem2hex(&dbar, ptr, 4, 0);			ptr = mem2hex(&__debug_frame->lr, ptr, 4, 0);			ptr = mem2hex(&__debug_frame->lcr, ptr, 4, 0);			ptr = mem2hex(&__debug_frame->iacc0, ptr, 8, 0);			ptr = mem2hex(&__break_user_context.f.fsr[0], ptr, 4, 0);			for (loop = 0; loop <= 7; loop++)				ptr = mem2hex(&__break_user_context.f.acc[loop], ptr, 4, 0);			ptr = mem2hex(&__break_user_context.f.accg, ptr, 8, 0);			for (loop = 0; loop <= 1; loop++)				ptr = mem2hex(&__break_user_context.f.msr[loop], ptr, 4, 0);			ptr = mem2hex(&__debug_frame->gner0, ptr, 4, 0);			ptr = mem2hex(&__debug_frame->gner1, ptr, 4, 0);			ptr = mem2hex(&__break_user_context.f.fner[0], ptr, 4, 0);			ptr = mem2hex(&__break_user_context.f.fner[1], ptr, 4, 0);			break;			/* set the values of the CPU registers */		case 'G':			ptr = &input_buffer[1];			/* deal with GR0, GR1-GR27, GR28-GR31, GR32-GR63 */			ptr = hex2mem(ptr, &temp, 4);			for (loop = 1; loop <= 27; loop++)				ptr = hex2mem(ptr, (unsigned long *)__debug_frame + REG_GR(loop),					      4);			ptr = hex2mem(ptr, &temp, 4);			__frame = (struct pt_regs *) temp;			ptr = hex2mem(ptr, &__debug_frame->gr29, 4);			ptr = hex2mem(ptr, &__debug_frame->gr30, 4);#ifdef CONFIG_MMU			ptr = hex2mem(ptr, &__debug_frame->gr31, 4);#else			ptr = hex2mem(ptr, &temp, 4);#endif			for (loop = 32; loop <= 63; loop++)				ptr = hex2mem(ptr, (unsigned long *)__debug_frame + REG_GR(loop),					      4);			/* deal with FR0-FR63 */			for (loop = 0; loop <= 63; loop++)				ptr = mem2hex((unsigned long *)&__break_user_context +					      __FPMEDIA_FR(loop),					      ptr, 4, 0);			/* deal with special registers */			ptr = hex2mem(ptr, &__debug_frame->pc,  4);			ptr = hex2mem(ptr, &__debug_frame->psr, 4);			ptr = hex2mem(ptr, &__debug_frame->ccr, 4);			ptr = hex2mem(ptr, &__debug_frame->cccr,4);			for (loop = 132; loop <= 140; loop++)				ptr = hex2mem(ptr, &temp, 4);			ptr = hex2mem(ptr, &temp, 4);			asm volatile("movgs %0,scr0" :: "r"(temp));			ptr = hex2mem(ptr, &temp, 4);			asm volatile("movgs %0,scr1" :: "r"(temp));			ptr = hex2mem(ptr, &temp, 4);			asm volatile("movgs %0,scr2" :: "r"(temp));			ptr = hex2mem(ptr, &temp, 4);			asm volatile("movgs %0,scr3" :: "r"(temp));			ptr = hex2mem(ptr, &__debug_frame->lr,  4);			ptr = hex2mem(ptr, &__debug_frame->lcr, 4);			ptr = hex2mem(ptr, &__debug_frame->iacc0, 8);			ptr = hex2mem(ptr, &__break_user_context.f.fsr[0], 4);			for (loop = 0; loop <= 7; loop++)				ptr = hex2mem(ptr, &__break_user_context.f.acc[loop], 4);			ptr = hex2mem(ptr, &__break_user_context.f.accg, 8);			for (loop = 0; loop <= 1; loop++)				ptr = hex2mem(ptr, &__break_user_context.f.msr[loop], 4);			ptr = hex2mem(ptr, &__debug_frame->gner0, 4);			ptr = hex2mem(ptr, &__debug_frame->gner1, 4);			ptr = hex2mem(ptr, &__break_user_context.f.fner[0], 4);			ptr = hex2mem(ptr, &__break_user_context.f.fner[1], 4);			gdbstub_strcpy(output_buffer,"OK");			break;			/* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */		case 'm':			ptr = &input_buffer[1];			if (hexToInt(&ptr, &addr) &&			    *ptr++ == ',' &&			    hexToInt(&ptr, &length)			    ) {				if (mem2hex((char *)addr, output_buffer, length, 1))					break;				gdbstub_strcpy (output_buffer, "E03");			}			else {				gdbstub_strcpy(output_buffer,"E01");			}			break;			/* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */		case 'M':			ptr = &input_buffer[1];			if (hexToInt(&ptr, &addr) &&			    *ptr++ == ',' &&			    hexToInt(&ptr, &length) &&			    *ptr++ == ':'			    ) {				if (hex2mem(ptr, (char *)addr, length)) {					gdbstub_strcpy(output_buffer, "OK");				}				else {					gdbstub_strcpy(output_buffer, "E03");				}			}			else				gdbstub_strcpy(output_buffer, "E02");			flush_cache = 1;			break;			/* PNN,=RRRRRRRR: Write value R to reg N return OK */		case 'P':			ptr = &input_buffer[1];			if (!hexToInt(&ptr, &addr) ||			    *ptr++ != '=' ||			    !hexToInt(&ptr, &temp)			    ) {				gdbstub_strcpy(output_buffer, "E01");				break;			}			temp2 = 1;			switch (addr) {			case GDB_REG_GR(0):				break;			case GDB_REG_GR(1) ... GDB_REG_GR(63):				__break_user_context.i.gr[addr - GDB_REG_GR(0)] = temp;				break;			case GDB_REG_FR(0) ... GDB_REG_FR(63):				__break_user_context.f.fr[addr - GDB_REG_FR(0)] = temp;				break;			case GDB_REG_PC:				__break_user_context.i.pc = temp;				break;			case GDB_REG_PSR:				__break_user_context.i.psr = temp;				break;			case GDB_REG_CCR:				__break_user_context.i.ccr = temp;				break;			case GDB_REG_CCCR:				__break_user_context.i.cccr = temp;				break;			case GDB_REG_BRR:				__debug_regs->brr = temp;				break;			case GDB_REG_LR:				__break_user_context.i.lr = temp;				break;			case GDB_REG_LCR:				__break_user_context.i.lcr = temp;				break;			case GDB_REG_FSR0:				__break_user_context.f.fsr[0] = temp;				break;			case GDB_REG_ACC(0) ... GDB_REG_ACC(7):				__break_user_context.f.acc[addr - GDB_REG_ACC(0)] = temp;				break;			case GDB_REG_ACCG(0):				*(uint32_t *) &__break_user_context.f.accg[0] = temp;				break;			case GDB_REG_ACCG(4):				*(uint32_t *) &__break_user_context.f.accg[4] = temp;				break;			case GDB_REG_MSR(0) ... GDB_REG_MSR(1):				__break_user_context.f.msr[addr - GDB_REG_MSR(0)] = temp;				break;			case GDB_REG_GNER(0) ... GDB_REG_GNER(1):				__break_user_context.i.gner[addr - GDB_REG_GNER(0)] = temp;				break;			case GDB_REG_FNER(0) ... GDB_REG_FNER(1):				__break_user_context.f.fner[addr - GDB_REG_FNER(0)] = temp;				break;			default:				temp2 = 0;				break;			}			if (temp2) {				gdbstub_strcpy(output_buffer, "OK");			}			else {				gdbstub_strcpy(output_buffer, "E02");			}			break;			/* cAA..AA    Continue at address AA..AA(optional) */		case 'c':			/* try to read optional parameter, pc unchanged if no parm */			ptr = &input_buffer[1];			if (hexToInt(&ptr, &addr))				__debug_frame->pc = addr;			goto done;			/* kill the program */		case 'k' :			goto done;	/* just continue */			/* reset the whole machine (FIXME: system dependent) */		case 'r':			break;			/* step to next instruction */		case 's':			__debug_regs->dcr |= DCR_SE;			goto done;			/* set baud rate (bBB) */		case 'b':			ptr = &input_buffer[1];			if (!hexToInt(&ptr, &temp)) {				gdbstub_strcpy(output_buffer,"B01");				break;			}			if (temp) {				/* ack before changing speed */				gdbstub_send_packet("OK");				gdbstub_set_baud(temp);			}			break;			/* set breakpoint */		case 'Z':			ptr = &input_buffer[1];			if (!hexToInt(&ptr,&temp) || *ptr++ != ',' ||			    !hexToInt(&ptr,&addr) || *ptr++ != ',' ||			    !hexToInt(&ptr,&length)			    ) {				gdbstub_strcpy(output_buffer,"E01");				break;			}			if (temp >= 5) {				gdbstub_strcpy(output_buffer,"E03");				break;			}			if (gdbstub_set_breakpoint(temp, addr, length) < 0) {				gdbstub_strcpy(output_buffer,"E03");				break;			}			if (temp == 0)				flush_cache = 1; /* soft bkpt by modified memory */			gdbstub_strcpy(output_buffer,"OK");			break;			/* clear breakpoint */		case 'z':			ptr = &input_buffer[1];			if (!hexToInt(&ptr,&temp) || *ptr++ != ',' ||			    !hexToInt(&ptr,&addr) || *ptr++ != ',' ||			    !hexToInt(&ptr,&length)			    ) {				gdbstub_strcpy(output_buffer,"E01");				break;			}			if (temp >= 5) {				gdbstub_strcpy(output_buffer,"E03");				break;			}			if (gdbstub_clear_breakpoint(temp, addr, length) < 0) {				gdbstub_strcpy(output_buffer,"E03");				break;			}			if (temp == 0)				flush_cache = 1; /* soft bkpt by modified memory */			gdbstub_strcpy(output_buffer,"OK");			break;		default:			gdbstub_proto("### GDB Unsupported Cmd '%s'\n",input_buffer);			break;		}		/* reply to the request */		LEDS(0x5009);		gdbstub_send_packet(output_buffer);	} done:	restore_user_regs(&__break_user_context);	//gdbstub_dump_debugregs();	//gdbstub_printk("<-- gdbstub() %08x\n", __debug_frame->pc);	/* need to flush the instruction cache before resuming, as we may have	 * deposited a breakpoint, and the icache probably has no way of	 * knowing that a data ref to some location may have changed something	 * that is in the instruction cache.  NB: We flush both caches, just to	 * be sure...	 */	/* note: flushing the icache will clobber EAR0 on the FR451 */	if (flush_cache)		gdbstub_purge_cache();	LEDS(0x5666);} /* end gdbstub() *//*****************************************************************************//* * initialise the GDB stub */void __init gdbstub_init(void){#ifdef CONFIG_GDBSTUB_IMMEDIATE	unsigned char ch;	int ret;#endif	gdbstub_printk("%s", gdbstub_banner);	gdbstub_printk("DCR: %x\n", __debug_regs->dcr);	gdbstub_io_init();	/* try to talk to GDB (or anyone insane enough to want to type GDB protocol by hand) */	gdbstub_proto("### GDB Tx ACK\n");	gdbstub_tx_char('+'); /* 'hello world' */#ifdef CONFIG_GDBSTUB_IMMEDIATE	gdbstub_printk("GDB Stub waiting for packet\n");	/*	 * In case GDB is started before us, ack any packets	 * (presumably "$?#xx") sitting there.	 */	do { gdbstub_rx_char(&ch, 0); } while (ch != '$');	do { gdbstub_rx_char(&ch, 0); } while (ch != '#');	do { ret = gdbstub_rx_char(&ch, 0); } while (ret != 0); /* eat first csum byte */	do { ret = gdbstub_rx_char(&ch, 0); } while (ret != 0); /* eat second csum byte */	gdbstub_proto("### GDB Tx NAK\n");	gdbstub_tx_char('-'); /* nak it */#else	gdbstub_printk("GDB Stub set\n");#endif#if 0	/* send banner */	ptr = output_buffer;	*ptr++ = 'O';	ptr = mem2hex(gdbstub_banner, ptr, sizeof(gdbstub_banner) - 1, 0);	gdbstub_send_packet(output_buffer);#endif#if defined(CONFIG_GDBSTUB_CONSOLE) && defined(CONFIG_GDBSTUB_IMMEDIATE)	register_console(&gdbstub_console);#endif} /* end gdbstub_init() *//*****************************************************************************//* * register the console at a more appropriate time */#if defined (CONFIG_GDBSTUB_CONSOLE) && !defined(CONFIG_GDBSTUB_IMMEDIATE)static int __init gdbstub_postinit(void){	printk("registering console\n");	register_console(&gdbstub_console);	return 0;} /* end gdbstub_postinit() */__initcall(gdbstub_postinit);#endif/*****************************************************************************//* * send an exit message to GDB */void gdbstub_exit(int status){	unsigned char checksum;	int count;	unsigned char ch;	sprintf(output_buffer,"W%02x",status&0xff);	gdbstub_tx_char('$');	checksum = 0;	count = 0;	while ((ch = output_buffer[count]) != 0) {		gdbstub_tx_char(ch);		checksum += ch;		count += 1;	}	gdbstub_tx_char('#');	gdbstub_tx_char(hexchars[checksum >> 4]);	gdbstub_tx_char(hexchars[checksum & 0xf]);	/* make sure the output is flushed, or else RedBoot might clobber it */	gdbstub_tx_char('-');	gdbstub_tx_flush();} /* end gdbstub_exit() *//*****************************************************************************//* * GDB wants to call malloc() and free() to allocate memory for calling kernel * functions directly from its command line */static void *malloc(size_t size) __attribute__((unused));static void *malloc(size_t size){	return kmalloc(size, GFP_ATOMIC);}static void free(void *p) __attribute__((unused));static void free(void *p){	kfree(p);}static uint32_t ___get_HSR0(void) __attribute__((unused));static uint32_t ___get_HSR0(void){	return __get_HSR(0);}static uint32_t ___set_HSR0(uint32_t x) __attribute__((unused));static uint32_t ___set_HSR0(uint32_t x){	__set_HSR(0, x);	return __get_HSR(0);}

⌨️ 快捷键说明

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