map = &vm->vm_map;
map = vm ? &vm->vm_map : kernel_map;
trap(type, code, v, frame)	int type;	unsigned code;	register unsigned v;	struct frame frame;{	extern char fubail[], subail[];#ifdef DDB	extern char trap0[], trap1[], trap2[], trap12[], trap15[], illinst[];#endif	register struct proc *p;	register int i;	u_int ucode;	u_quad_t sticks;	cnt.v_trap++;	p = curproc;	ucode = 0;	if (USERMODE(frame.f_sr)) {		type |= T_USER;		sticks = p->p_sticks;		p->p_md.md_regs = frame.f_regs;	}	switch (type) {	default:dopanic:		printf("trap type %d, code = %x, v= %x\n", type, code, v);#ifdef DDB		if (kdb_trap(type, (db_regs_t *) &frame))			return;#endif		regdump(&frame, 128);		type &= ~T_USER;		if ((unsigned)type < trap_types)			panic(trap_type[type]);		panic("trap");	case T_BUSERR:		/* Kernel bus error */		if (!p->p_addr->u_pcb.pcb_onfault)			goto dopanic;		/*		 * If we have arranged to catch this fault in any of the		 * copy to/from user space routines, set PC to return to		 * indicated location and set flag informing buserror code		 * that it may need to clean up stack frame.		 */copyfault:		frame.f_stackadj = exframesize[frame.f_format];		frame.f_format = frame.f_vector = 0;		frame.f_pc = (int) p->p_addr->u_pcb.pcb_onfault;		return;	case T_BUSERR|T_USER:	/* Bus error */	case T_ADDRERR|T_USER:	/* Address error */		ucode = v;		i = SIGBUS;		break;	case T_ILLINST|T_USER:	/* Illegal instruction fault */	case T_PRIVINST|T_USER:	/* Privileged instruction fault */		ucode = frame.f_format;	/* XXX was ILL_PRIVIN_FAULT */		i = SIGILL;		break;	/*	 * divde by zero, CHK/TRAPV inst 	 */	case T_ZERODIV|T_USER:		/* Divide by zero trap */	case T_CHKINST|T_USER:		/* CHK instruction trap */	case T_TRAPVINST|T_USER:	/* TRAPV instruction trap */		ucode = frame.f_format;		i = SIGFPE;		break;	/* 	 * User coprocessor violation	 */	case T_COPERR|T_USER:		ucode = 0;		i = SIGFPE;	/* XXX What is a proper response here? */		break;	/* 	 * 6888x exceptions 	 */	case T_FPERR|T_USER:		/*		 * We pass along the 68881 status register which locore		 * stashed in code for us.  Note that there is a		 * possibility that the bit pattern of this register		 * will conflict with one of the FPE_* codes defined		 * in signal.h.  Fortunately for us, the only such		 * codes we use are all in the range 1-7 and the low		 * 3 bits of the status register are defined as 0 so		 * there is no clash.		 */		ucode = code;		i = SIGFPE;		break;	/*	 * FPU faults in supervisor mode.	 */	case T_ILLINST:	/* fnop generates this, apparently. */	case T_FPEMULI:	case T_FPEMULD: {		extern int	*nofault;		if (nofault)	/* If we're probing. */			longjmp((label_t *) nofault);		if (type == T_ILLINST)			printf("Kernel Illegal Instruction trap.\n");		else			printf("Kernel FPU trap.\n");		goto dopanic;	}	/*	 * Unimplemented FPU instructions/datatypes.	 */	case T_FPEMULI|T_USER:	case T_FPEMULD|T_USER:#ifdef FPU_EMULATE		i = fpu_emulate(&frame, &p->p_addr->u_pcb.pcb_fpregs);		/* XXX -- deal with tracing? (frame.f_sr & PSL_T) */#else		uprintf("pid %d killed: no floating point support.\n",			p->p_pid);		i = SIGILL;#endif		break;	case T_COPERR:		/* Kernel coprocessor violation */	case T_FMTERR:		/* Kernel format error */	case T_FMTERR|T_USER:	/* User format error */		/*		 * The user has most likely trashed the RTE or FP state info		 * in the stack frame of a signal handler.		 */		printf("pid %d: kernel %s exception\n", p->p_pid,		    type==T_COPERR ? "coprocessor" : "format");		type |= T_USER;		p->p_sigacts->ps_sigact[SIGILL] = SIG_DFL;		i = sigmask(SIGILL);		p->p_sigignore &= ~i;		p->p_sigcatch &= ~i;		p->p_sigmask &= ~i;		i = SIGILL;		ucode = frame.f_format;	/* XXX was ILL_RESAD_FAULT */		break;	/*	 * Trace traps.	 *	 * M68k NetBSD uses trap #2,	 * SUN 3.x uses trap #15,	 * KGDB uses trap #15 (for kernel breakpoints; handled elsewhere).	 *	 * M68k NetBSD traps get mapped by locore.s into T_TRACE.	 * SUN 3.x traps get passed through as T_TRAP15 and are not really	 * supported yet.	 */	case T_TRACE:		/* Kernel trace trap */	case T_TRAP15:		/* SUN trace trap */#ifdef DDB		if (type == T_TRAP15 ||		    ((caddr_t) frame.f_pc != trap0 &&		     (caddr_t) frame.f_pc != trap1 &&		     (caddr_t) frame.f_pc != trap2 &&		     (caddr_t) frame.f_pc != trap12 &&		     (caddr_t) frame.f_pc != trap15 &&		     (caddr_t) frame.f_pc != illinst)) {			if (kdb_trap(type, (db_regs_t *) &frame))				return;		}#endif		frame.f_sr &= ~PSL_T;		i = SIGTRAP;		break;	case T_TRACE|T_USER:	/* user trace trap */	case T_TRAP15|T_USER:	/* Sun user trace trap */#ifdef COMPAT_SUNOS		/*		 * XXX This comment/code is not consistent XXX		 * SunOS seems to use Trap #2 for some obscure 		 * fpu operations.  So far, just ignore it, but		 * DONT trap on it.. 		 */		if (p->p_emul == &emul_sunos) {			userret(p, &frame, sticks, v, 1); 			return;		}#endif		frame.f_sr &= ~PSL_T;		i = SIGTRAP;		break;	case T_ASTFLT:		/* System async trap, cannot happen */		goto dopanic;	case T_ASTFLT|T_USER:	/* User async trap. */		astpending = 0;		/*		 * We check for software interrupts first.  This is because		 * they are at a higher level than ASTs, and on a VAX would		 * interrupt the AST.  We assume that if we are processing		 * an AST that we must be at IPL0 so we don't bother to		 * check.  Note that we ensure that we are at least at SIR		 * IPL while processing the SIR.		 */		spl1();		/* fall into... */	case T_SSIR:		/* Software interrupt */	case T_SSIR|T_USER:		if (ssir & SIR_SERIAL) {			void zssoft __P((int));			siroff(SIR_SERIAL);			cnt.v_soft++;			zssoft(0);		}		if (ssir & SIR_NET) {			void netintr __P((void));			siroff(SIR_NET);			cnt.v_soft++;			netintr();		}		if (ssir & SIR_CLOCK) {			void softclock __P((void));			siroff(SIR_CLOCK);			cnt.v_soft++;			softclock();		}		/*		 * If this was not an AST trap, we are all done.		 */		if (type != (T_ASTFLT|T_USER)) {			cnt.v_trap--;			return;		}		spl0();		if (p->p_flag & P_OWEUPC) {			p->p_flag &= ~P_OWEUPC;			ADDUPROF(p);		}		goto out;	case T_MMUFLT:		/* Kernel mode page fault */		/*		 * If we were doing profiling ticks or other user mode		 * stuff from interrupt code, Just Say No.		 */		if (p->p_addr->u_pcb.pcb_onfault == fubail ||		    p->p_addr->u_pcb.pcb_onfault == subail)			goto copyfault;		/* fall into... */	case T_MMUFLT|T_USER:	/* page fault */	    {		register vm_offset_t va;		register struct vmspace *vm = p->p_vmspace;		register vm_map_t map;		int rv;		vm_prot_t ftype;		extern vm_map_t kernel_map;#ifdef DEBUG		if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid))		printf("trap: T_MMUFLT pid=%d, code=%x, v=%x, pc=%x, sr=%x\n",			p->p_pid, code, v, frame.f_pc, frame.f_sr);#endif		/*		 * It is only a kernel address space fault iff:		 *	1. (type & T_USER) == 0 and		 *	2. pcb_onfault not set or		 *	3. pcb_onfault set but supervisor data fault		 * The last can occur during an exec() copyin where the		 * argument space is lazy-allocated.		 */		if (type == T_MMUFLT &&		    (!p->p_addr->u_pcb.pcb_onfault || KDFAULT(code)))			map = kernel_map;		else			map = &vm->vm_map;		if (WRFAULT(code))			ftype = VM_PROT_READ | VM_PROT_WRITE;		else			ftype = VM_PROT_READ;		va = trunc_page((vm_offset_t) v);#ifdef DEBUG		if (map == kernel_map && va == 0) {			printf("trap: bad kernel access at %x\n", v);			goto dopanic;		}#endif		rv = vm_fault(map, va, ftype, FALSE);#ifdef DEBUG		if (rv && MDB_ISPID(p->p_pid))			printf("vm_fault(%x, %x, %x, 0) -> %x\n",				map, va, ftype, rv);#endif		/*		 * If this was a stack access, we keep track of the maximum		 * accessed stack size.  Also, if vm_fault gets a protection		 * failure, it is due to accessing the stack region outside		 * the current limit and we need to reflect that as an access		 * error.		 */		if ((caddr_t)va >= vm->vm_maxsaddr && map != kernel_map) {			if (rv == KERN_SUCCESS) {				unsigned nss;				nss = clrnd(btoc(USRSTACK-(unsigned)va));				if (nss > vm->vm_ssize)					vm->vm_ssize = nss;			} else if (rv == KERN_PROTECTION_FAILURE)				rv = KERN_INVALID_ADDRESS;		}		if (rv == KERN_SUCCESS) {			if (type == T_MMUFLT) {#if defined(M68040)				if (mmutype == MMU_68040)					(void) writeback(&frame, 1);#endif				return;			}			goto out;		}		if (type == T_MMUFLT) {			if (p->p_addr->u_pcb.pcb_onfault)				goto copyfault;			printf("vm_fault(%x, %x, %x, 0) -> %x\n",				(unsigned) map, (unsigned) va, ftype, rv);			printf("  type %x, code [mmu,,ssw]: %x\n",				type, code);			goto dopanic;		}		ucode = v;		i = SIGSEGV;		break;	    }	}	if (i) trapsignal(p, i, ucode);	if ((type & T_USER) == 0)		return;out:	userret(p, &frame, sticks, v, 1); }