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

📄 gdb-stub.c

📁 底层驱动开发
💻 C
📖 第 1 页 / 共 4 页
字号:
#define __get_ibar(X) ({ unsigned long x; asm volatile("movsg ibar"#X",%0" : "=r"(x)); x; })		if (__debug_regs->dcr & DCR_IBE0 && __get_ibar(0) == addr) {			//gdbstub_printk("clear h/w break 0: %08lx\n", addr);			__debug_regs->dcr &= ~DCR_IBE0;			asm volatile("movgs gr0,ibar0");			return 0;		}		if (__debug_regs->dcr & DCR_IBE1 && __get_ibar(1) == addr) {			//gdbstub_printk("clear h/w break 1: %08lx\n", addr);			__debug_regs->dcr &= ~DCR_IBE1;			asm volatile("movgs gr0,ibar1");			return 0;		}		if (__debug_regs->dcr & DCR_IBE2 && __get_ibar(2) == addr) {			//gdbstub_printk("clear h/w break 2: %08lx\n", addr);			__debug_regs->dcr &= ~DCR_IBE2;			asm volatile("movgs gr0,ibar2");			return 0;		}		if (__debug_regs->dcr & DCR_IBE3 && __get_ibar(3) == addr) {			//gdbstub_printk("clear h/w break 3: %08lx\n", addr);			__debug_regs->dcr &= ~DCR_IBE3;			asm volatile("movgs gr0,ibar3");			return 0;		}		return -EINVAL;		/* clear data read/write/access watchpoint */	case 2:	case 3:	case 4:		if ((addr & ~7) != ((addr + len - 1) & ~7))			return -EINVAL;		tmp = addr & 7;		memset(dbmr.bytes, 0xff, sizeof(dbmr.bytes));		for (loop = 0; loop < len; loop++)			dbmr.bytes[tmp + loop] = 0;		addr &= ~7;#define __get_dbar(X) ({ unsigned long x; asm volatile("movsg dbar"#X",%0" : "=r"(x)); x; })#define __get_dbmr0(X) ({ unsigned long x; asm volatile("movsg dbmr"#X"0,%0" : "=r"(x)); x; })#define __get_dbmr1(X) ({ unsigned long x; asm volatile("movsg dbmr"#X"1,%0" : "=r"(x)); x; })		/* consider DBAR 0 */		tmp = type==2 ? DCR_DWBE0 : type==3 ? DCR_DRBE0 : DCR_DRBE0|DCR_DWBE0;		if ((__debug_regs->dcr & (DCR_DRBE0|DCR_DWBE0)) != tmp ||		    __get_dbar(0) != addr ||		    __get_dbmr0(0) != dbmr.mask0 ||		    __get_dbmr1(0) != dbmr.mask1)			goto skip_dbar0;		//gdbstub_printk("clear h/w watchpoint 0 type %ld: %08lx\n", type, addr);		__debug_regs->dcr &= ~(DCR_DRBE0|DCR_DWBE0);		asm volatile("	movgs	gr0,dbar0	\n"			     "	movgs	gr0,dbmr00	\n"			     "	movgs	gr0,dbmr01	\n"			     "	movgs	gr0,dbdr00	\n"			     "	movgs	gr0,dbdr01	\n");		return 0;	skip_dbar0:		/* consider DBAR 0 */		tmp = type==2 ? DCR_DWBE1 : type==3 ? DCR_DRBE1 : DCR_DRBE1|DCR_DWBE1;		if ((__debug_regs->dcr & (DCR_DRBE1|DCR_DWBE1)) != tmp ||		    __get_dbar(1) != addr ||		    __get_dbmr0(1) != dbmr.mask0 ||		    __get_dbmr1(1) != dbmr.mask1)			goto skip_dbar1;		//gdbstub_printk("clear h/w watchpoint 1 type %ld: %08lx\n", type, addr);		__debug_regs->dcr &= ~(DCR_DRBE1|DCR_DWBE1);		asm volatile("	movgs	gr0,dbar1	\n"			     "	movgs	gr0,dbmr10	\n"			     "	movgs	gr0,dbmr11	\n"			     "	movgs	gr0,dbdr10	\n"			     "	movgs	gr0,dbdr11	\n");		return 0;	skip_dbar1:		return -ENOSPC;	default:		return -EINVAL;	}} /* end gdbstub_clear_breakpoint() *//*****************************************************************************//* * check a for an internal software breakpoint, and wind the PC back if necessary */static void gdbstub_check_breakpoint(void){	unsigned long addr = __debug_frame->pc - 4;	int bkpt;	for (bkpt = 255; bkpt >= 0; bkpt--)		if (gdbstub_bkpts[bkpt].addr == addr)			break;	if (bkpt >= 0)		__debug_frame->pc = addr;	//gdbstub_printk("alter pc [%d] %08lx\n", bkpt, __debug_frame->pc);} /* end gdbstub_check_breakpoint() *//*****************************************************************************//* * */static void __attribute__((unused)) gdbstub_show_regs(void){	uint32_t *reg;	int loop;	gdbstub_printk("\n");	gdbstub_printk("Frame: @%p [%s]\n",		       __debug_frame,		       __debug_frame->psr & PSR_S ? "kernel" : "user");	reg = (uint32_t *) __debug_frame;	for (loop = 0; loop < REG__END; loop++) {		printk("%s %08x", regnames[loop + 0], reg[loop + 0]);		if (loop == REG__END - 1 || loop % 5 == 4)			printk("\n");		else			printk(" | ");	}	gdbstub_printk("Process %s (pid: %d)\n", current->comm, current->pid);} /* end gdbstub_show_regs() *//*****************************************************************************//* * dump debugging regs */static void __attribute__((unused)) gdbstub_dump_debugregs(void){	unsigned long x;	x = __debug_regs->dcr;	gdbstub_printk("DCR    %08lx  ", x);	x = __debug_regs->brr;	gdbstub_printk("BRR %08lx\n", x);	gdbstub_printk("IBAR0  %08lx  ", __get_ibar(0));	gdbstub_printk("IBAR1  %08lx  ", __get_ibar(1));	gdbstub_printk("IBAR2  %08lx  ", __get_ibar(2));	gdbstub_printk("IBAR3  %08lx\n", __get_ibar(3));	gdbstub_printk("DBAR0  %08lx  ", __get_dbar(0));	gdbstub_printk("DBMR00 %08lx  ", __get_dbmr0(0));	gdbstub_printk("DBMR01 %08lx\n", __get_dbmr1(0));	gdbstub_printk("DBAR1  %08lx  ", __get_dbar(1));	gdbstub_printk("DBMR10 %08lx  ", __get_dbmr0(1));	gdbstub_printk("DBMR11 %08lx\n", __get_dbmr1(1));	gdbstub_printk("\n");} /* end gdbstub_dump_debugregs() *//*****************************************************************************//* * dump the MMU state into a structure so that it can be accessed with GDB */void gdbstub_get_mmu_state(void){	asm volatile("movsg hsr0,%0" : "=r"(__debug_mmu.regs.hsr0));	asm volatile("movsg pcsr,%0" : "=r"(__debug_mmu.regs.pcsr));	asm volatile("movsg esr0,%0" : "=r"(__debug_mmu.regs.esr0));	asm volatile("movsg ear0,%0" : "=r"(__debug_mmu.regs.ear0));	asm volatile("movsg epcr0,%0" : "=r"(__debug_mmu.regs.epcr0));	/* read the protection / SAT registers */	__debug_mmu.iamr[0].L  = __get_IAMLR(0);	__debug_mmu.iamr[0].P  = __get_IAMPR(0);	__debug_mmu.iamr[1].L  = __get_IAMLR(1);	__debug_mmu.iamr[1].P  = __get_IAMPR(1);	__debug_mmu.iamr[2].L  = __get_IAMLR(2);	__debug_mmu.iamr[2].P  = __get_IAMPR(2);	__debug_mmu.iamr[3].L  = __get_IAMLR(3);	__debug_mmu.iamr[3].P  = __get_IAMPR(3);	__debug_mmu.iamr[4].L  = __get_IAMLR(4);	__debug_mmu.iamr[4].P  = __get_IAMPR(4);	__debug_mmu.iamr[5].L  = __get_IAMLR(5);	__debug_mmu.iamr[5].P  = __get_IAMPR(5);	__debug_mmu.iamr[6].L  = __get_IAMLR(6);	__debug_mmu.iamr[6].P  = __get_IAMPR(6);	__debug_mmu.iamr[7].L  = __get_IAMLR(7);	__debug_mmu.iamr[7].P  = __get_IAMPR(7);	__debug_mmu.iamr[8].L  = __get_IAMLR(8);	__debug_mmu.iamr[8].P  = __get_IAMPR(8);	__debug_mmu.iamr[9].L  = __get_IAMLR(9);	__debug_mmu.iamr[9].P  = __get_IAMPR(9);	__debug_mmu.iamr[10].L = __get_IAMLR(10);	__debug_mmu.iamr[10].P = __get_IAMPR(10);	__debug_mmu.iamr[11].L = __get_IAMLR(11);	__debug_mmu.iamr[11].P = __get_IAMPR(11);	__debug_mmu.iamr[12].L = __get_IAMLR(12);	__debug_mmu.iamr[12].P = __get_IAMPR(12);	__debug_mmu.iamr[13].L = __get_IAMLR(13);	__debug_mmu.iamr[13].P = __get_IAMPR(13);	__debug_mmu.iamr[14].L = __get_IAMLR(14);	__debug_mmu.iamr[14].P = __get_IAMPR(14);	__debug_mmu.iamr[15].L = __get_IAMLR(15);	__debug_mmu.iamr[15].P = __get_IAMPR(15);	__debug_mmu.damr[0].L  = __get_DAMLR(0);	__debug_mmu.damr[0].P  = __get_DAMPR(0);	__debug_mmu.damr[1].L  = __get_DAMLR(1);	__debug_mmu.damr[1].P  = __get_DAMPR(1);	__debug_mmu.damr[2].L  = __get_DAMLR(2);	__debug_mmu.damr[2].P  = __get_DAMPR(2);	__debug_mmu.damr[3].L  = __get_DAMLR(3);	__debug_mmu.damr[3].P  = __get_DAMPR(3);	__debug_mmu.damr[4].L  = __get_DAMLR(4);	__debug_mmu.damr[4].P  = __get_DAMPR(4);	__debug_mmu.damr[5].L  = __get_DAMLR(5);	__debug_mmu.damr[5].P  = __get_DAMPR(5);	__debug_mmu.damr[6].L  = __get_DAMLR(6);	__debug_mmu.damr[6].P  = __get_DAMPR(6);	__debug_mmu.damr[7].L  = __get_DAMLR(7);	__debug_mmu.damr[7].P  = __get_DAMPR(7);	__debug_mmu.damr[8].L  = __get_DAMLR(8);	__debug_mmu.damr[8].P  = __get_DAMPR(8);	__debug_mmu.damr[9].L  = __get_DAMLR(9);	__debug_mmu.damr[9].P  = __get_DAMPR(9);	__debug_mmu.damr[10].L = __get_DAMLR(10);	__debug_mmu.damr[10].P = __get_DAMPR(10);	__debug_mmu.damr[11].L = __get_DAMLR(11);	__debug_mmu.damr[11].P = __get_DAMPR(11);	__debug_mmu.damr[12].L = __get_DAMLR(12);	__debug_mmu.damr[12].P = __get_DAMPR(12);	__debug_mmu.damr[13].L = __get_DAMLR(13);	__debug_mmu.damr[13].P = __get_DAMPR(13);	__debug_mmu.damr[14].L = __get_DAMLR(14);	__debug_mmu.damr[14].P = __get_DAMPR(14);	__debug_mmu.damr[15].L = __get_DAMLR(15);	__debug_mmu.damr[15].P = __get_DAMPR(15);#ifdef CONFIG_MMU	do {		/* read the DAT entries from the TLB */		struct __debug_amr *p;		int loop;		asm volatile("movsg tplr,%0" : "=r"(__debug_mmu.regs.tplr));		asm volatile("movsg tppr,%0" : "=r"(__debug_mmu.regs.tppr));		asm volatile("movsg tpxr,%0" : "=r"(__debug_mmu.regs.tpxr));		asm volatile("movsg cxnr,%0" : "=r"(__debug_mmu.regs.cxnr));		p = __debug_mmu.tlb;		/* way 0 */		asm volatile("movgs %0,tpxr" :: "r"(0 << TPXR_WAY_SHIFT));		for (loop = 0; loop < 64; loop++) {			asm volatile("tlbpr %0,gr0,#1,#0" :: "r"(loop << PAGE_SHIFT));			asm volatile("movsg tplr,%0" : "=r"(p->L));			asm volatile("movsg tppr,%0" : "=r"(p->P));			p++;		}		/* way 1 */		asm volatile("movgs %0,tpxr" :: "r"(1 << TPXR_WAY_SHIFT));		for (loop = 0; loop < 64; loop++) {			asm volatile("tlbpr %0,gr0,#1,#0" :: "r"(loop << PAGE_SHIFT));			asm volatile("movsg tplr,%0" : "=r"(p->L));			asm volatile("movsg tppr,%0" : "=r"(p->P));			p++;		}		asm volatile("movgs %0,tplr" :: "r"(__debug_mmu.regs.tplr));		asm volatile("movgs %0,tppr" :: "r"(__debug_mmu.regs.tppr));		asm volatile("movgs %0,tpxr" :: "r"(__debug_mmu.regs.tpxr));	} while(0);#endif} /* end gdbstub_get_mmu_state() *//*****************************************************************************//* * handle event interception and GDB remote protocol processing * - on entry: *	PSR.ET==0, PSR.S==1 and the CPU is in debug mode *	__debug_frame points to the saved registers *	__frame points to the kernel mode exception frame, if it was in kernel *      mode when the break happened */void gdbstub(int sigval){	unsigned long addr, length, loop, dbar, temp, temp2, temp3;	uint32_t zero;	char *ptr;	int flush_cache = 0;	LEDS(0x5000);	if (sigval < 0) {#ifndef CONFIG_GDBSTUB_IMMEDIATE		/* return immediately if GDB immediate activation option not set */		return;#else		sigval = SIGINT;#endif	}	save_user_regs(&__break_user_context);#if 0	gdbstub_printk("--> gdbstub() %08x %p %08x %08x\n",		       __debug_frame->pc,		       __debug_frame,		       __debug_regs->brr,		       __debug_regs->bpsr);//	gdbstub_show_regs();#endif	LEDS(0x5001);	/* if we were interrupted by input on the serial gdbstub serial port,	 * restore the context prior to the interrupt so that we return to that	 * directly	 */	temp = (unsigned long) __entry_kerneltrap_table;	temp2 = (unsigned long) __entry_usertrap_table;	temp3 = __debug_frame->pc & ~15;	if (temp3 == temp + TBR_TT_INTERRUPT_15 ||	    temp3 == temp2 + TBR_TT_INTERRUPT_15	    ) {		asm volatile("movsg pcsr,%0" : "=r"(__debug_frame->pc));		__debug_frame->psr |= PSR_ET;		__debug_frame->psr &= ~PSR_S;		if (__debug_frame->psr & PSR_PS)			__debug_frame->psr |= PSR_S;		__debug_regs->brr = (__debug_frame->tbr & TBR_TT) << 12;		__debug_regs->brr |= BRR_EB;		sigval = SIGINT;	}	/* handle the decrement timer going off (FR451 only) */	if (temp3 == temp + TBR_TT_DECREMENT_TIMER ||	    temp3 == temp2 + TBR_TT_DECREMENT_TIMER	    ) {		asm volatile("movgs %0,timerd" :: "r"(10000000));		asm volatile("movsg pcsr,%0" : "=r"(__debug_frame->pc));		__debug_frame->psr |= PSR_ET;		__debug_frame->psr &= ~PSR_S;		if (__debug_frame->psr & PSR_PS)			__debug_frame->psr |= PSR_S;		__debug_regs->brr = (__debug_frame->tbr & TBR_TT) << 12;		__debug_regs->brr |= BRR_EB;		sigval = SIGXCPU;;	}	LEDS(0x5002);	/* after a BREAK insn, the PC lands on the far side of it */	if (__debug_regs->brr & BRR_SB)		gdbstub_check_breakpoint();	LEDS(0x5003);	/* handle attempts to write console data via GDB "O" commands */	if (__debug_frame->pc == (unsigned long) gdbstub_console_write + 4) {		__gdbstub_console_write((struct console *) __debug_frame->gr8,					(const char *) __debug_frame->gr9,					(unsigned) __debug_frame->gr10);		goto done;	}	if (gdbstub_rx_unget) {		sigval = SIGINT;		goto packet_waiting;	}	if (!sigval)		sigval = gdbstub_compute_signal(__debug_regs->brr);	LEDS(0x5004);	/* send a message to the debugger's user saying what happened if it may	 * not be clear cut (we can't map exceptions onto signals properly)	 */	if (sigval != SIGINT && sigval != SIGTRAP && sigval != SIGILL) {		static const char title[] = "Break ";		static const char crlf[] = "\r\n";		unsigned long brr = __debug_regs->brr;		char hx;		ptr = output_buffer;		*ptr++ = 'O';		ptr = mem2hex(title, ptr, sizeof(title) - 1,0);		hx = hexchars[(brr & 0xf0000000) >> 28];		*ptr++ = hexchars[hx >> 4];	*ptr++ = hexchars[hx & 0xf];		hx = hexchars[(brr & 0x0f000000) >> 24];		*ptr++ = hexchars[hx >> 4];	*ptr++ = hexchars[hx & 0xf];		hx = hexchars[(brr & 0x00f00000) >> 20];		*ptr++ = hexchars[hx >> 4];	*ptr++ = hexchars[hx & 0xf];		hx = hexchars[(brr & 0x000f0000) >> 16];		*ptr++ = hexchars[hx >> 4];	*ptr++ = hexchars[hx & 0xf];		hx = hexchars[(brr & 0x0000f000) >> 12];		*ptr++ = hexchars[hx >> 4];	*ptr++ = hexchars[hx & 0xf];		hx = hexchars[(brr & 0x00000f00) >> 8];		*ptr++ = hexchars[hx >> 4];	*ptr++ = hexchars[hx & 0xf];		hx = hexchars[(brr & 0x000000f0) >> 4];		*ptr++ = hexchars[hx >> 4];	*ptr++ = hexchars[hx & 0xf];		hx = hexchars[(brr & 0x0000000f)];		*ptr++ = hexchars[hx >> 4];	*ptr++ = hexchars[hx & 0xf];		ptr = mem2hex(crlf, ptr, sizeof(crlf) - 1, 0);		*ptr = 0;		gdbstub_send_packet(output_buffer);	/* send it off... */	}	LEDS(0x5005);	/* tell the debugger that an exception has occurred */	ptr = output_buffer;	/* Send trap type (converted to signal) */	*ptr++ = 'T';	*ptr++ = hexchars[sigval >> 4];	*ptr++ = hexchars[sigval & 0xf];	/* Send Error PC */	*ptr++ = hexchars[GDB_REG_PC >> 4];	*ptr++ = hexchars[GDB_REG_PC & 0xf];	*ptr++ = ':';	ptr = mem2hex(&__debug_frame->pc, ptr, 4, 0);	*ptr++ = ';';	/*	 * Send frame pointer	 */	*ptr++ = hexchars[GDB_REG_FP >> 4];	*ptr++ = hexchars[GDB_REG_FP & 0xf];	*ptr++ = ':';	ptr = mem2hex(&__debug_frame->fp, ptr, 4, 0);	*ptr++ = ';';	/*	 * Send stack pointer	 */	*ptr++ = hexchars[GDB_REG_SP >> 4];	*ptr++ = hexchars[GDB_REG_SP & 0xf];	*ptr++ = ':';	ptr = mem2hex(&__debug_frame->sp, ptr, 4, 0);	*ptr++ = ';';	*ptr++ = 0;	gdbstub_send_packet(output_buffer);	/* send it off... */	LEDS(0x5006); packet_waiting:	gdbstub_get_mmu_state();	/* wait for input from remote GDB */	while (1) {		output_buffer[0] = 0;		LEDS(0x5007);		gdbstub_recv_packet(input_buffer);		LEDS(0x5600 | input_buffer[0]);		switch (input_buffer[0]) {			/* request repeat of last signal number */		case '?':			output_buffer[0] = 'S';			output_buffer[1] = hexchars[sigval >> 4];			output_buffer[2] = hexchars[sigval & 0xf];			output_buffer[3] = 0;			break;		case 'd':			/* toggle debug flag */			break;			/* return the value of the CPU registers			 * - GR0,  GR1,  GR2,  GR3,  GR4,  GR5,  GR6,  GR7,			 * - GR8,  GR9,  GR10, GR11, GR12, GR13, GR14, GR15,			 * - GR16, GR17, GR18, GR19, GR20, GR21, GR22, GR23,			 * - GR24, GR25, GR26, GR27, GR28, GR29, GR30, GR31,			 * - GR32, GR33, GR34, GR35, GR36, GR37, GR38, GR39,			 * - GR40, GR41, GR42, GR43, GR44, GR45, GR46, GR47,			 * - GR48, GR49, GR50, GR51, GR52, GR53, GR54, GR55,			 * - GR56, GR57, GR58, GR59, GR60, GR61, GR62, GR63,			 * - FP0,  FP1,  FP2,  FP3,  FP4,  FP5,  FP6,  FP7,			 * - FP8,  FP9,  FP10, FP11, FP12, FP13, FP14, FP15,			 * - FP16, FP17, FP18, FP19, FP20, FP21, FP22, FP23,			 * - FP24, FP25, FP26, FP27, FP28, FP29, FP30, FP31,			 * - FP32, FP33, FP34, FP35, FP36, FP37, FP38, FP39,			 * - FP40, FP41, FP42, FP43, FP44, FP45, FP46, FP47,			 * - FP48, FP49, FP50, FP51, FP52, FP53, FP54, FP55,			 * - FP56, FP57, FP58, FP59, FP60, FP61, FP62, FP63,			 * - PC, PSR, CCR, CCCR,			 * - _X132, _X133, _X134			 * - TBR, BRR, DBAR0, DBAR1, DBAR2, DBAR3,			 * - _X141, _X142, _X143, _X144,			 * - LR, LCR			 */		case 'g':			zero = 0;			ptr = output_buffer;			/* deal with GR0, GR1-GR27, GR28-GR31, GR32-GR63 */			ptr = mem2hex(&zero, ptr, 4, 0);

⌨️ 快捷键说明

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