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

📄 traps.c

📁 microwindows移植到S3C44B0的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#endif	if (fp->ptregs.sr & PS_S) {		/* kernel fault must be a data fault to user space */		if (! ((ssw & DF) && ((ssw & DFC) == USER_DATA))) {			/* instruction fault or kernel data fault! */			if (ssw & (FC | FB))				printk ("Instruction fault at %#010lx\n",					fp->ptregs.pc);			if (ssw & DF) {				printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",					ssw & RW ? "read" : "write",					fp->un.fmtb.daddr,					space_names[ssw & DFC], fp->ptregs.pc);			}			printk ("BAD KERNEL BUSERR\n");			die_if_kernel("Oops",&fp->ptregs,0);			force_sig(SIGKILL, current);			return;		}	} else {		/* user fault */		if (!(ssw & (FC | FB)) && !(ssw & DF))			/* not an instruction fault or data fault! BAD */			panic ("USER BUSERR w/o instruction or data fault");		user_space_fault = 1;#if DEBUG		printk("User space bus-error\n");#endif	}	/* ++andreas: If a data fault and an instruction fault happen	   at the same time map in both pages.  */	/* First handle the data fault, if any.  */	if (ssw & DF)	  {	    addr = fp->un.fmtb.daddr;	    mmusr = MMU_I;	    if (user_space_fault) {#if DEBUG		    asm volatile ("ptestr #1,%2@,#7,%0\n\t"				  "pmove %/psr,%1@"				  : "=a&" (desc)				  : "a" (&temp), "a" (addr));#else		    asm volatile ("ptestr #1,%1@,#7\n\t"				  "pmove %/psr,%0@"				  : : "a" (&temp), "a" (addr));#endif		    mmusr = temp;	    }      #if DEBUG	    printk ("mmusr is %#x for addr %#lx in task %p\n",		    mmusr, addr, current);	    printk ("descriptor address is %#lx, contents %#lx\n",		    mm_ptov(desc), *(unsigned long *)mm_ptov(desc));#endif	    errorcode = (mmusr & MMU_I) ? 0 : 1;	    if (!(ssw & RW) || (ssw & RM))		    errorcode |= 2;	    if (mmusr & (MMU_I | MMU_WP)) {		/* Don't try to do anything further if an exception was		   handled. */		if (do_page_fault (&fp->ptregs, addr, errorcode) < 0)			return;	    } else if (mmusr & (MMU_B|MMU_L|MMU_S)) {		    printk ("invalid %s access at %#lx from pc %#lx\n",			    !(ssw & RW) ? "write" : "read", addr,			    fp->ptregs.pc);		    die_if_kernel("Oops",&fp->ptregs,mmusr);		    force_sig(SIGSEGV, current);		    return;	    } else {#if 0		    static volatile long tlong;#endif		    printk ("weird %s access at %#lx from pc %#lx (ssw is %#x)\n",			    !(ssw & RW) ? "write" : "read", addr,			    fp->ptregs.pc, ssw);		    asm volatile ("ptestr #1,%1@,#0\n\t"				  "pmove %/psr,%0@"				  : /* no outputs */				  : "a" (&temp), "a" (addr));		    mmusr = temp;		    printk ("level 0 mmusr is %#x\n", mmusr);#if 0		    asm volatile ("pmove %/tt0,%0@"				  : /* no outputs */				  : "a" (&tlong));		    printk ("tt0 is %#lx, ", tlong);		    asm volatile ("pmove %/tt1,%0@"				  : /* no outputs */				  : "a" (&tlong));		    printk ("tt1 is %#lx\n", tlong);#endif#if DEBUG		    printk("Unknown SIGSEGV - 1\n");#endif		    die_if_kernel("Oops",&fp->ptregs,mmusr);		    force_sig(SIGSEGV, current);		    return;	    }	    /* setup an ATC entry for the access about to be retried */	    if (!(ssw & RW))		    asm volatile ("ploadw %1,%0@" : /* no outputs */				  : "a" (addr), "d" (ssw));	    else		    asm volatile ("ploadr %1,%0@" : /* no outputs */				  : "a" (addr), "d" (ssw));	  }	/* Now handle the instruction fault. */	if (!(ssw & (FC|FB)))		return;	/* get the fault address */	if (fp->ptregs.format == 10)		addr = fp->ptregs.pc + 4;	else		addr = fp->un.fmtb.baddr;	if (ssw & FC)		addr -= 2;	if ((ssw & DF) && ((addr ^ fp->un.fmtb.daddr) & PAGE_MASK) == 0)		/* Insn fault on same page as data fault.  But we		   should still create the ATC entry.  */		goto create_atc_entry;	mmusr = MMU_I;	if (user_space_fault) {#if DEBUG		asm volatile ("ptestr #1,%2@,#7,%0\n\t"			      "pmove %/psr,%1@"			      : "=a&" (desc)			      : "a" (&temp), "a" (addr));#else		asm volatile ("ptestr #1,%1@,#7\n\t"			      "pmove %/psr,%0@"			      : : "a" (&temp), "a" (addr));#endif		mmusr = temp;	}      #ifdef DEBUG	printk ("mmusr is %#x for addr %#lx in task %p\n",		mmusr, addr, current);	printk ("descriptor address is %#lx, contents %#lx\n",		mm_ptov(desc), *(unsigned long *)mm_ptov(desc));#endif	if (mmusr & MMU_I)		do_page_fault (&fp->ptregs, addr, 0);	else if (mmusr & (MMU_B|MMU_L|MMU_S)) {		printk ("invalid insn access at %#lx from pc %#lx\n",			addr, fp->ptregs.pc);#if DEBUG		printk("Unknown SIGSEGV - 2\n");#endif		die_if_kernel("Oops",&fp->ptregs,mmusr);		force_sig(SIGSEGV, current);		return;	}create_atc_entry:	/* setup an ATC entry for the access about to be retried */	asm volatile ("ploadr #2,%0@" : /* no outputs */		      : "a" (addr));}#endif /* CPU_M68020_OR_M68030 */#endif /* !CONFIG_SUN3 */asmlinkage void buserr_c(struct frame *fp){	/* Only set esp0 if coming from user mode */	if (user_mode(&fp->ptregs))		current->thread.esp0 = (unsigned long) fp;#if DEBUG	printk ("*** Bus Error *** Format is %x\n", fp->ptregs.format);#endif	switch (fp->ptregs.format) {#if defined (CONFIG_M68060)	case 4:				/* 68060 access error */	  access_error060 (fp);	  break;#endif#if defined (CONFIG_M68040)	case 0x7:			/* 68040 access error */	  access_error040 (fp);	  break;#endif#if defined (CPU_M68020_OR_M68030)	case 0xa:	case 0xb:	  bus_error030 (fp);	  break;#endif	default:	  die_if_kernel("bad frame format",&fp->ptregs,0);#if DEBUG	  printk("Unknown SIGSEGV - 4\n");#endif	  force_sig(SIGSEGV, current);	}}int kstack_depth_to_print = 48;/* MODULE_RANGE is a guess of how much space is likely to be   vmalloced.  */#define MODULE_RANGE (8*1024*1024)static void dump_stack(struct frame *fp){	unsigned long *stack, *endstack, addr;#if DAVIDM	unsigned long module_start, module_end;#endif	extern char _start, _etext;	int i;	addr = (unsigned long)&fp->un;	printk("Frame format=%X ", fp->ptregs.format);	switch (fp->ptregs.format) {	case 0x2:	    printk("instr addr=%08lx\n", fp->un.fmt2.iaddr);	    addr += sizeof(fp->un.fmt2);	    break;	case 0x3:	    printk("eff addr=%08lx\n", fp->un.fmt3.effaddr);	    addr += sizeof(fp->un.fmt3);	    break;	case 0x4:#if DAVIDM /* fixme */	    printk((CPU_IS_060 ? "fault addr=%08lx fslw=%08lx\n"		    : "eff addr=%08lx pc=%08lx\n"),		   fp->un.fmt4.effaddr, fp->un.fmt4.pc);#endif	    addr += sizeof(fp->un.fmt4);	    break;	case 0x7:	    printk("eff addr=%08lx ssw=%04x faddr=%08lx\n",		   fp->un.fmt7.effaddr, fp->un.fmt7.ssw, fp->un.fmt7.faddr);	    printk("wb 1 stat/addr/data: %04x %08lx %08lx\n",		   fp->un.fmt7.wb1s, fp->un.fmt7.wb1a, fp->un.fmt7.wb1dpd0);	    printk("wb 2 stat/addr/data: %04x %08lx %08lx\n",		   fp->un.fmt7.wb2s, fp->un.fmt7.wb2a, fp->un.fmt7.wb2d);	    printk("wb 3 stat/addr/data: %04x %08lx %08lx\n",		   fp->un.fmt7.wb3s, fp->un.fmt7.wb3a, fp->un.fmt7.wb3d);	    printk("push data: %08lx %08lx %08lx %08lx\n",		   fp->un.fmt7.wb1dpd0, fp->un.fmt7.pd1, fp->un.fmt7.pd2,		   fp->un.fmt7.pd3);	    addr += sizeof(fp->un.fmt7);	    break;	case 0x9:	    printk("instr addr=%08lx\n", fp->un.fmt9.iaddr);	    addr += sizeof(fp->un.fmt9);	    break;	case 0xa:	    printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",		   fp->un.fmta.ssw, fp->un.fmta.isc, fp->un.fmta.isb,		   fp->un.fmta.daddr, fp->un.fmta.dobuf);	    addr += sizeof(fp->un.fmta);	    break;	case 0xb:	    printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",		   fp->un.fmtb.ssw, fp->un.fmtb.isc, fp->un.fmtb.isb,		   fp->un.fmtb.daddr, fp->un.fmtb.dobuf);	    printk("baddr=%08lx dibuf=%08lx ver=%x\n",		   fp->un.fmtb.baddr, fp->un.fmtb.dibuf, fp->un.fmtb.ver);	    addr += sizeof(fp->un.fmtb);	    break;	default:	    printk("\n");	}	stack = (unsigned long *)addr;	endstack = (unsigned long *)PAGE_ALIGN(addr);	printk("Stack from %08lx:", (unsigned long)stack);	for (i = 0; i < kstack_depth_to_print; i++) {		if (stack + 1 > endstack)			break;		if (i % 8 == 0)			printk("\n       ");		printk(" %08lx", *stack++);	}	printk ("\nCall Trace:");	stack = (unsigned long *) addr;	i = 0;#if 0 /* DAVIDM */	module_start = VMALLOC_START;	module_end = module_start + MODULE_RANGE;#endif	while (stack + 1 <= endstack) {		addr = *stack++;		/*		 * If the address is either in the text segment of the		 * kernel, or in the region which contains vmalloc'ed		 * memory, it *may* be the address of a calling		 * routine; if so, print it so that someone tracing		 * down the cause of the crash will be able to figure		 * out the call path that was taken.		 */		if (((addr >= (unsigned long) &_start) &&		     (addr <= (unsigned long) &_etext))#if 0 /* DAVIDM */			 || ((addr >= module_start) && (addr <= module_end))#endif			) {			if (i % 4 == 0)				printk("\n       ");			printk(" [<%08lx>]", addr);			i++;		}	}	printk("\nCode: ");	for (i = 0; i < 10; i++)		printk("%04x ", 0xffff & ((short *) fp->ptregs.pc)[i]);	printk ("\n");}void bad_super_trap (struct frame *fp){	console_verbose();	if (fp->ptregs.vector < 4*sizeof(vec_names)/sizeof(vec_names[0]))		printk ("*** %s ***   FORMAT=%X\n",			vec_names[(fp->ptregs.vector) >> 2],			fp->ptregs.format);	else		printk ("*** Exception %d ***   FORMAT=%X\n",			(fp->ptregs.vector) >> 2, 			fp->ptregs.format);#if 0 /* DAVIDM */	if (fp->ptregs.vector >> 2 == VEC_ADDRERR && CPU_IS_020_OR_030) {		unsigned short ssw = fp->un.fmtb.ssw;		printk ("SSW=%#06x  ", ssw);		if (ssw & RC)			printk ("Pipe stage C instruction fault at %#010lx\n",				(fp->ptregs.format) == 0xA ?				fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2);		if (ssw & RB)			printk ("Pipe stage B instruction fault at %#010lx\n",				(fp->ptregs.format) == 0xA ?				fp->ptregs.pc + 4 : fp->un.fmtb.baddr);		if (ssw & DF)			printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",				ssw & RW ? "read" : "write",				fp->un.fmtb.daddr, space_names[ssw & DFC],				fp->ptregs.pc);	}#endif	printk ("Current process id is %d\n", current->pid);	die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0);}asmlinkage void trap_c(struct frame *fp){	int sig;	siginfo_t info;	if (fp->ptregs.sr & PS_S) {		if ((fp->ptregs.vector >> 2) == VEC_TRACE) {			/* traced a trapping instruction */			current->ptrace |= PT_DTRACE;		} else			bad_super_trap(fp);		return;	}	/* send the appropriate signal to the user program */	switch ((fp->ptregs.vector) >> 2) {	    case VEC_ADDRERR:		info.si_code = BUS_ADRALN;		sig = SIGBUS;		break;	    case VEC_ILLEGAL:	    case VEC_LINE10:	    case VEC_LINE11:		info.si_code = ILL_ILLOPC;		sig = SIGILL;		break;	    case VEC_PRIV:		info.si_code = ILL_PRVOPC;		sig = SIGILL;		break;	    case VEC_COPROC:		info.si_code = ILL_COPROC;		sig = SIGILL;		break;	    case VEC_TRAP1: /* gdbserver breakpoint */		fp->ptregs.pc -= 2;		info.si_code = TRAP_TRACE;		sig = SIGTRAP;		break;	    case VEC_TRAP2:	    case VEC_TRAP3:	    case VEC_TRAP4:	    case VEC_TRAP5:	    case VEC_TRAP6:	    case VEC_TRAP7:	    case VEC_TRAP8:	    case VEC_TRAP9:	    case VEC_TRAP10:	    case VEC_TRAP11:	    case VEC_TRAP12:	    case VEC_TRAP13:	    case VEC_TRAP14:		info.si_code = ILL_ILLTRP;		sig = SIGILL;		break;	    case VEC_FPBRUC:	    case VEC_FPOE:	    case VEC_FPNAN:		info.si_code = FPE_FLTINV;		sig = SIGFPE;		break;	    case VEC_FPIR:		info.si_code = FPE_FLTRES;		sig = SIGFPE;		break;	    case VEC_FPDIVZ:		info.si_code = FPE_FLTDIV;		sig = SIGFPE;		break;	    case VEC_FPUNDER:		info.si_code = FPE_FLTUND;		sig = SIGFPE;		break;	    case VEC_FPOVER:		info.si_code = FPE_FLTOVF;		sig = SIGFPE;		break;	    case VEC_ZERODIV:		info.si_code = FPE_INTDIV;		sig = SIGFPE;		break;	    case VEC_CHK:	    case VEC_TRAP:		info.si_code = FPE_INTOVF;		sig = SIGFPE;		break;	    case VEC_TRACE:		/* ptrace single step */		info.si_code = TRAP_TRACE;		sig = SIGTRAP;		break;	    case VEC_TRAP15:		/* breakpoint */		info.si_code = TRAP_BRKPT;		sig = SIGTRAP;		break;	    default:		info.si_code = ILL_ILLOPC;		sig = SIGILL;		break;	}	info.si_signo = sig;	info.si_errno = 0;	switch (fp->ptregs.format) {	    default:		info.si_addr = (void *) fp->ptregs.pc;		break;	    case 2:		info.si_addr = (void *) fp->un.fmt2.iaddr;		break;	    case 7:		info.si_addr = (void *) fp->un.fmt7.effaddr;		break;	    case 9:		info.si_addr = (void *) fp->un.fmt9.iaddr;		break;	    case 10:		info.si_addr = (void *) fp->un.fmta.daddr;		break;	    case 11:		info.si_addr = (void *) fp->un.fmtb.daddr;		break;	}	force_sig_info (sig, &info, current);}asmlinkage void set_esp0 (unsigned long ssp){	current->thread.esp0 = ssp;}void show_trace_task(struct task_struct *tsk){	/* DAVIDM: we can do better, need a proper stack dump */	printk("STACK ksp=0x%lx, usp=0x%lx\n", tsk->thread.ksp, tsk->thread.usp);}void die_if_kernel (char *str, struct pt_regs *fp, int nr){	if (!(fp->sr & PS_S))		return;	console_verbose();	printk("%s: %08x\n",str,nr);	printk("PC: [<%08lx>]\nSR: %04x  SP: %p  a2: %08lx\n",	       fp->pc, fp->sr, fp, fp->a2);	printk("d0: %08lx    d1: %08lx    d2: %08lx    d3: %08lx\n",	       fp->d0, fp->d1, fp->d2, fp->d3);	printk("d4: %08lx    d5: %08lx    a0: %08lx    a1: %08lx\n",	       fp->d4, fp->d5, fp->a0, fp->a1);	printk("Process %s (pid: %d, stackpage=%08lx)\n",		current->comm, current->pid, PAGE_SIZE+(unsigned long)current);	dump_stack((struct frame *)fp);	do_exit(SIGSEGV);}/* * This function is called if an error occur while accessing * user-space from the fpsp040 code. */asmlinkage void fpsp040_die(void){	do_exit(SIGSEGV);}#ifdef CONFIG_M68KFPU_EMUasmlinkage void fpemu_signal(int signal, int code, void *addr){	siginfo_t info;	info.si_signo = signal;	info.si_errno = 0;	info.si_code = code;	info.si_addr = addr;	force_sig_info(signal, &info, current);}#endif

⌨️ 快捷键说明

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