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

📄 rtl-stub.c

📁 fsmlabs的real time linux的内核
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (!f) {		spin_unlock (&bp_lock);		return EINVAL;	}	spin_unlock (&bp_lock);	return 0;}int remove_bp (char *mem){	struct bp_cache_entry *e = cache_start;	struct bp_cache_entry *f = 0;	char buf[10];	if (!e) {		return EINVAL;	}	if (e->mem == mem) {		cache_start = e->next;		f = e;	} else {		for (; e->next; e = e->next) {			if (e->next->mem == mem) {				f = e->next;				e->next = f->next;				break;			}		}	}	if (!f) {		return EINVAL;	}	sprintf(buf, "%08x", (unsigned) f->val);	hex2mem(buf, f->mem, 4);	debugpr("removed %x, restored %s (real) %x\n", f->mem, buf, *((unsigned long *) (f->mem)));		kgdb_flush_cache_all();	flush_icache_range((unsigned) f->mem, (unsigned)( f->mem)+4);	return 0;}static int send_exception_info = 0;struct module *mod;static void kgdb_fault_handler(struct pt_regs *regs){	kgdb_longjmp((long*)fault_jmp_buf, 1);}/* Convert the SPARC hardware trap type code to a unix signal number. *//* * This table contains the mapping between PowerPC hardware trap types, and * signals, which are primarily what GDB understands. */static struct hard_trap_info{	unsigned int tt;		/* Trap type code for powerpc */	unsigned char signo;		/* Signal that we map this trap into */} hard_trap_info[] = {	{ 0x200, SIGSEGV },			/* machine check */	{ 0x300, SIGSEGV },			/* address error (store) */	{ 0x400, SIGBUS },			/* instruction bus error */	{ 0x500, SIGINT },			/* interrupt */	{ 0x600, SIGBUS },			/* alingment */	{ 0x700, SIGTRAP },			/* breakpoint trap */	{ 0x800, SIGFPE },			/* fpu unavail */	{ 0x900, SIGALRM },			/* decrementer */	{ 0xa00, SIGILL },			/* reserved */	{ 0xb00, SIGILL },			/* reserved */	{ 0xc00, SIGCHLD },			/* syscall */	{ 0xd00, SIGTRAP },			/* single-step/watch */	{ 0xe00, SIGFPE },			/* fp assist */	{ 0, 0}				/* Must be last */};static int computeSignal(unsigned int tt){	struct hard_trap_info *ht;	for (ht = hard_trap_info; ht->tt && ht->signo; ht++)		if (ht->tt == tt)			return ht->signo;	return SIGHUP;         /* default for things we don't know about */}#define PC_REGNUM 64#define SP_REGNUM 1  /* * This function does all command processing for interfacing to gdb. */static inthandle_exception (struct pt_regs *regs){	int signo;	int addr;	int length;	char *ptr;/* 	unsigned long nip = regs->nip; */	unsigned int msr;	int exceptionVector = regs->trap;  unsigned long flags;#ifdef CONFIG_RTL_DEBUGGER_THREADS  pthread_t current_thread = pthread_self();#endif  if (user_mode(regs) && !(rtl_is_psc_active())) {    return(0);  }  	if (debugger_fault_handler) {		debugger_fault_handler(regs);	}	if (debugger_fault_handler) {		debugger_fault_handler(regs);		panic("kgdb longjump failed!\n");	}	rtl_hard_savef_and_cli(flags);#ifdef KGDB_DEBUG	printk("kgdb: entering handle_exception; trap [0x%x]\n",	       (unsigned int)regs->trap);#endif	msr = get_msr();	signo = computeSignal(exceptionVector);	if (rtl_running_linux() && exceptionVector != 0x700  && exceptionVector != 0xd00) {		rtl_hard_restore_flags(flags) ;		return 0; /* let linux handle it's own faults */	}	/*   debugpr("exception: %x\n", exceptionVector); */	debugpr("exception: %x regs->nip=%x regs->msr=%x msr=%x MSR_EE=%x\n",			exceptionVector, regs->nip, regs->msr, msr, MSR_EE);	/* can't trace with interrupts disabled or in Linux mode */	if (exceptionVector == 0xd00 && (!(regs->msr & MSR_EE) || rtl_running_linux())) {		regs->msr &= ~MSR_SE; /* clear trace bit */		debugpr("can't single step");		kgdb_flush_cache_all();		set_msr(msr);		rtl_hard_restore_flags(flags) ;		return(1) ;	}	if (exceptionVector == 0x700) {		/* disable breakpoints if they're hit with interrupts disabled or in Linux mode */		if ((!(regs->msr & MSR_EE) || rtl_running_linux())) {			spin_lock (&bp_lock);			if (remove_bp (((char *) regs->nip))) {				debugpr("advancing");				regs->nip += 4; /* there's no cached breakpoint, so nothing to retry */			}			spin_unlock (&bp_lock);			debugpr("can't breakpoint");			regs->msr |= MSR_SE;			kgdb_flush_cache_all();			set_msr(msr);			rtl_hard_restore_flags(flags) ;			return(1) ;		}		if (*((unsigned long *)regs->nip) == BPCODE && search_bp((char *)regs->nip)) {			/* Skip over breakpoint trap insn */			regs->nip += 4;		}	}  /* ok, here we know pthread_self() is an RT-thread */  pthread_cleanup_push (&rtl_exit_debugger, 0);  rtl_enter_debugger(exceptionVector, (void *) regs->nip);  /* reply to host that an exception has occurred */  set_bit(0, &send_exception_info);	while (1) {	    remcomOutBuffer[0] = 0;	    if (test_and_clear_bit(0, &send_exception_info)) {		strcpy(remcomInBuffer, "?");	    } else {		    getpacket(remcomInBuffer);	    }	    switch (remcomInBuffer[0]) {		case 'q' : 			if (!strcmp(remcomInBuffer, "qOffsets") && text && data && bss && !rtl_is_psc_active()) {				sprintf(remcomOutBuffer, "Text=%x;Data=%x;Bss=%x",				(unsigned )text, (unsigned )data, (unsigned )bss);			}#ifdef CONFIG_RTL_DEBUGGER_THREADS	 if (!strcmp(remcomInBuffer, "qC")) {		 sprintf(remcomOutBuffer, "QC%x", (unsigned )(pthread_self()));	 } else if (!strncmp(remcomInBuffer, "qL", 2)) {		 /* we assume we have a limit of 31 threads -- to fit in one packet */		 char packethead[17];		 pthread_t task;		 int ntasks = 0;		 int i;		 strcpy(remcomOutBuffer, remcomInBuffer);		for (i = 0; i < rtl_num_cpus(); i++) {			 int cpu_id = cpu_logical_map (i);			 schedule_t *s = &rtl_sched [cpu_id];			 spin_lock (&s->rtl_tasks_lock);			 task = s->rtl_tasks;			 while (task != &s->rtl_linux_task && ntasks < 31) {				 sprintf((remcomOutBuffer) + strlen(remcomOutBuffer),						 "00000000%08x", (unsigned) task);				 task = task->next;				 ntasks++;			 }			 spin_unlock (&s->rtl_tasks_lock);		}		sprintf(packethead, "qM%02x%01x", ntasks, 1 /* done */);		memcpy(remcomOutBuffer, packethead, strlen(packethead));	 }#endif	 break;#ifdef CONFIG_RTL_DEBUGGER_THREADS      case 'H': if (/* remcomInBuffer[1] == 'c' ||*/ remcomInBuffer[1] == 'g') {		       if (remcomInBuffer[2] == '-') {			current_thread = (pthread_t) -strtoul(remcomInBuffer + 3, 0, 16);		       } else  {			current_thread = (pthread_t) strtoul(remcomInBuffer + 2, 0, 16);		       }			strcpy(remcomOutBuffer, "OK");		}		break;      case 'T':{		       pthread_t thread;		       if (remcomInBuffer[1] == '-') {			thread = (pthread_t) -strtoul(remcomInBuffer + 2, 0, 16);		       } else  {			thread = (pthread_t) strtoul(remcomInBuffer + 1, 0, 16);		       }		       if (!pthread_kill(thread, 0)) {			       strcpy(remcomOutBuffer, "OK");		       } else {			       strcpy(remcomOutBuffer, "ERROR");		       }		}		break;#endif#ifdef CONFIG_RTL_DEBUGGER_Z_PROTOCOL      case 'Z': case 'z' :		{			int type = remcomInBuffer[1] - '0';			unsigned address = strtoul(remcomInBuffer + 3, 0, 16);			int res;			if (type != 0) {				strcpy(remcomOutBuffer, "ERROR");				break;			}			spin_lock (&bp_lock);			if (remcomInBuffer[0] == 'Z') {				res = insert_bp((char *)address);			} else {				remove_bp((char *)address);				res = 0;			}			spin_unlock (&bp_lock);			if (res) {				strcpy(remcomOutBuffer, "ERROR");			} else {				strcpy(remcomOutBuffer, "OK");			}		}		break;#endif      case '?' :#ifdef CONFIG_RTL_DEBUGGER_THREADS		sprintf(remcomOutBuffer, "T%02xthread:%x;", signo, (unsigned) pthread_self());#else		remcomOutBuffer[0] = 'S';                   remcomOutBuffer[1] =  hexchars[signo >> 4];                   remcomOutBuffer[2] =  hexchars[signo % 16];                   remcomOutBuffer[3] = 0;#endif                 break;		case 'd':			/* toggle debug flag */			kdebug ^= 1;			break;		case 'g':	/* return the value of the CPU registers.				 * some of them are non-PowerPC names :(				 * they are stored in gdb like:				 * struct {				 *     u32 gpr[32];				 *     f64 fpr[32];				 *     u32 pc, ps, cnd, lr; (ps=msr)				 *     u32 cnt, xer, mq;				 * }				 */		{			int i;			struct pt_regs *t_regs = regs;#ifdef CONFIG_RTL_DEBUGGER_THREADS			struct pt_regs r = *regs;			if (current_thread != pthread_self()) {				t_regs = &r;/*				rtl_printf("thread %x\n", current_thread);				rtl_printf("stack=%x\n", current_thread->stack);				for (i=0; i < 10; i++) {					rtl_printf("%d: %#x    ", i, *(current_thread->stack + i));				}				rtl_printf("\n"); */				for(i=0; i<32; i++) {					t_regs->gpr[i] = *(current_thread->stack + 5 + i);/* 					rtl_printf("%d: %#x    ", i, t_regs->gpr[i]); */				}				t_regs->msr = *(current_thread->stack + 0);				t_regs->nip = *(current_thread->stack + 4);			}#endif			ptr = remcomOutBuffer;			/* General Purpose Regs */			ptr = mem2hex((char *)t_regs, ptr, 32 * 4);			/* Floating Point Regs - FIXME */			/*ptr = mem2hex((char *), ptr, 32 * 8);*/			for(i=0; i<(32*8*2); i++) { /* 2chars/byte */				ptr[i] = '0';			}			ptr += 32*8*2;			/* pc, msr, cr, lr, ctr, xer, (mq is unused) *//* 			ptr = mem2hex((char *)&nip, ptr, 4); */			ptr = mem2hex((char *)&t_regs->nip, ptr, 4);			ptr = mem2hex((char *)&t_regs->msr, ptr, 4);			ptr = mem2hex((char *)&t_regs->ccr, ptr, 4);			ptr = mem2hex((char *)&t_regs->link, ptr, 4);			ptr = mem2hex((char *)&t_regs->ctr, ptr, 4);			ptr = mem2hex((char *)&t_regs->xer, ptr, 4);		}			break;		case 'G':   /* set the value of the CPU registers */		{			ptr = &remcomInBuffer[1];			/*			 * If the stack pointer has moved, you should pray.			 * (cause only god can help you).			 */			/* General Purpose Regs */			hex2mem(ptr, (char *)regs, 32 * 4);			/* Floating Point Regs - FIXME?? */			/*ptr = hex2mem(ptr, ??, 32 * 8);*/			ptr += 32*8*2;			/* pc, msr, cr, lr, ctr, xer, (mq is unused) */			ptr = hex2mem(ptr, (char *)&regs->nip, 4);			ptr = hex2mem(ptr, (char *)&regs->msr, 4);			ptr = hex2mem(ptr, (char *)&regs->ccr, 4);			ptr = hex2mem(ptr, (char *)&regs->link, 4);			ptr = hex2mem(ptr, (char *)&regs->ctr, 4);			ptr = hex2mem(ptr, (char *)&regs->xer, 4);			strcpy(remcomOutBuffer,"OK");		}			break;		case 'm':	/* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */				/* Try to read %x,%x.  */			ptr = &remcomInBuffer[1];			if (hexToInt(&ptr, &addr)			    && *ptr++ == ','			    && hexToInt(&ptr, &length))	{				if (mem2hex((char *)addr, remcomOutBuffer,length))					break;				strcpy (remcomOutBuffer, "E03");			} else {				strcpy(remcomOutBuffer,"E01");			}			break;		case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */			/* Try to read '%x,%x:'.  */			ptr = &remcomInBuffer[1];			if (hexToInt(&ptr, &addr)			    && *ptr++ == ','			    && hexToInt(&ptr, &length)			    && *ptr++ == ':') {#ifdef CONFIG_RTL_DEBUG_BP_HACK				debugpr("addr=%x, length=%x, ptr=%s\n", addr,length, ptr);				if (length == 4) { /* maybe breakpoint stuff */					if (!strncmp(ptr, STR_BPCODE, strlen(STR_BPCODE))) {						spin_lock (&bp_lock);						insert_bp((char *)addr);						spin_unlock (&bp_lock);					} else {						spin_lock (&bp_lock);						remove_bp((char *)addr);						spin_unlock (&bp_lock);					}				}#endif				if (hex2mem(ptr, (char *)addr, length)) {					strcpy(remcomOutBuffer, "OK");				} else {					strcpy(remcomOutBuffer, "E03");				}				flush_icache_range(addr, addr+length);			} else {				strcpy(remcomOutBuffer, "E02");			}			break;		case 'k':    /* kill the program, actually just continue */		case 'c':    /* cAA..AA  Continue; address AA..AA optional */			/* try to read optional parameter, pc unchanged if no parm */			ptr = &remcomInBuffer[1];			if (hexToInt(&ptr, &addr)) {				regs->nip = addr;			}/* Need to flush the instruction cache here, 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. */			kgdb_flush_cache_all();			regs->msr &= ~MSR_SE;			set_msr(msr);			kgdb_active = 0;			goto cleanup;		case 's':			kgdb_flush_cache_all();			regs->msr |= MSR_SE;#if 0			set_msr(msr | MSR_SE);#endif			kgdb_active = 0;			goto cleanup;		case 'r':		/* Reset (if user process..exit ???)*/			panic("kgdb reset.");			break;		}			/* switch */		if (remcomOutBuffer[0] && kdebug) {			printk("remcomInBuffer: %s\n", remcomInBuffer);			printk("remcomOutBuffer: %s\n", remcomOutBuffer);		}		/* reply to the request */		putpacket(remcomOutBuffer);	} /* while(1) */cleanup: pthread_cleanup_pop(1);  rtl_hard_restore_flags(flags) ;  debugpr("cleanup");  return(1) ;}/* Output string in GDB O-packet format if GDB has connected. If nothing   output, returns 0 (caller must then handle output). *//*intkgdb_output_string (const char* s, unsigned int count){	char buffer[512];        if (!kgdb_started)            return 0;	count = (count <= (sizeof(buffer) / 2 - 2)) 		? count : (sizeof(buffer) / 2 - 2);	buffer[0] = 'O';	mem2hex (s, &buffer[1], count);	putpacket(buffer);        return 1; } */#ifndef CONFIG_8xx/* I don't know why other platforms don't need this.  The function for * the 8xx is found in arch/ppc/8xx_io/uart.c.  -- Dan */voidkgdb_map_scc(void){}#endif

⌨️ 快捷键说明

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