if ((frame->tf_iir & 0xfffffe00) == 0x10000200) { frame_regmap(frame, frame->tf_iir & 0x1f) = 0;
if ((opcode & 0xfffffe00) == 0x10000200) { frame_regmap(frame, opcode & 0x1f) = 0;
trap(type, frame)	int type;	struct trapframe *frame;{	struct proc *p = curproc;	vaddr_t va;	struct vm_map *map;	struct vmspace *vm;	register vm_prot_t vftype;	register pa_space_t space;	union sigval sv;	u_int opcode;	int ret, trapnum;	const char *tts;	vm_fault_t fault = VM_FAULT_INVALID;#ifdef DIAGNOSTIC	int oldcpl = cpl;#endif	trapnum = type & ~T_USER;	opcode = frame->tf_iir;	if (trapnum == T_ITLBMISS ||	    trapnum == T_EXCEPTION || trapnum == T_EMULATION) {		va = frame->tf_iioq_head;		space = frame->tf_iisq_head;		vftype = UVM_PROT_EXEC;	} else {		va = frame->tf_ior;		space = frame->tf_isr;		/* what is the vftype for the T_ITLBMISSNA ??? XXX */		if (va == frame->tf_iioq_head)			vftype = UVM_PROT_EXEC;		else if (inst_store(opcode))			vftype = UVM_PROT_WRITE;		else			vftype = UVM_PROT_READ;	}	if (frame->tf_flags & TFF_LAST)		p->p_md.md_regs = frame;	if (trapnum > trap_types)		tts = "reserved";	else		tts = trap_type[trapnum];#ifdef TRAPDEBUG	if (trapnum != T_INTERRUPT && trapnum != T_IBREAK)		db_printf("trap: %x, %s for %x:%x at %x:%x, fl=%x, fp=%p\n",		    type, tts, space, va, frame->tf_iisq_head,		    frame->tf_iioq_head, frame->tf_flags, frame);	else if (trapnum  == T_IBREAK)		db_printf("trap: break instruction %x:%x at %x:%x, fp=%p\n",		    break5(opcode), break13(opcode),		    frame->tf_iisq_head, frame->tf_iioq_head, frame);	{		extern int etext;		if (frame < (struct trapframe *)&etext) {			printf("trap: bogus frame ptr %p\n", frame);			goto dead_end;		}	}#endif	if (trapnum != T_INTERRUPT) {		uvmexp.traps++;		mtctl(frame->tf_eiem, CR_EIEM);	} else		uvmexp.intrs++;	switch (type) {	case T_NONEXIST:	case T_NONEXIST | T_USER:		/* we've got screwed up by the central scrutinizer */		printf("trap: elvis has just left the building!\n");		goto dead_end;	case T_RECOVERY:	case T_RECOVERY | T_USER:		/* XXX will implement later */		printf("trap: handicapped");		goto dead_end;#ifdef DIAGNOSTIC	case T_EXCEPTION:		panic("FPU/SFU emulation botch");		/* these just can't happen ever */	case T_PRIV_OP:	case T_PRIV_REG:		/* these just can't make it to the trap() ever */	case T_HPMC:	case T_HPMC | T_USER:#endif	case T_IBREAK:	case T_DATALIGN:	case T_DBREAK:	dead_end:#ifdef DDB		if (kdb_trap (type, va, frame)) {			if (type == T_IBREAK) {				/* skip break instruction */				frame->tf_iioq_head = frame->tf_iioq_tail;				frame->tf_iioq_tail += 4;			}			return;		}#else		if (type == T_DATALIGN)			panic ("trap: %s at 0x%x", tts, va);		else			panic ("trap: no debugger for \"%s\" (%d)", tts, type);#endif		break;	case T_IBREAK | T_USER:	case T_DBREAK | T_USER:		/* pass to user debugger */		trapsignal(p, SIGTRAP, type &~ T_USER, TRAP_BRKPT, sv);		break;	case T_EXCEPTION | T_USER: {		u_int64_t *fpp = (u_int64_t *)frame->tf_cr30;		u_int32_t *pex;		int i, flt;		pex = (u_int32_t *)&fpp[0];		for (i = 0, pex++; i < 7 && !*pex; i++, pex++);		flt = 0;		if (i < 7) {			u_int32_t stat = HPPA_FPU_OP(*pex);			if (stat & HPPA_FPU_UNMPL)				flt = FPE_FLTINV;			else if (stat & (HPPA_FPU_V << 1))				flt = FPE_FLTINV;			else if (stat & (HPPA_FPU_Z << 1))				flt = FPE_FLTDIV;			else if (stat & (HPPA_FPU_I << 1))				flt = FPE_FLTRES;			else if (stat & (HPPA_FPU_O << 1))				flt = FPE_FLTOVF;			else if (stat & (HPPA_FPU_U << 1))				flt = FPE_FLTUND;			/* still left: under/over-flow w/ inexact */			*pex = 0;		}		/* reset the trap flag, as if there was none */		fpp[0] &= ~(((u_int64_t)HPPA_FPU_T) << 32);		/* flush out, since load is done from phys, only 4 regs */		fdcache(HPPA_SID_KERNEL, (vaddr_t)fpp, 8 * 4);		sv.sival_int = va;		trapsignal(p, SIGFPE, type &~ T_USER, flt, sv);		}		break;	case T_EMULATION:		panic("trap: emulation trap in the kernel");		break;	case T_EMULATION | T_USER:		sv.sival_int = va;		trapsignal(p, SIGILL, type &~ T_USER, ILL_COPROC, sv);		break;	case T_OVERFLOW | T_USER:		sv.sival_int = va;		trapsignal(p, SIGFPE, type &~ T_USER, FPE_INTOVF, sv);		break;	case T_CONDITION | T_USER:		sv.sival_int = va;		trapsignal(p, SIGFPE, type &~ T_USER, FPE_INTDIV, sv);		break;	case T_PRIV_OP | T_USER:		sv.sival_int = va;		trapsignal(p, SIGILL, type &~ T_USER, ILL_PRVOPC, sv);		break;	case T_PRIV_REG | T_USER:		sv.sival_int = va;		trapsignal(p, SIGILL, type &~ T_USER, ILL_PRVREG, sv);		break;		/* these should never got here */	case T_HIGHERPL | T_USER:	case T_LOWERPL | T_USER:		sv.sival_int = va;		trapsignal(p, SIGSEGV, vftype, SEGV_ACCERR, sv);		break;	case T_IPROT | T_USER:	case T_DPROT | T_USER:		sv.sival_int = va;		trapsignal(p, SIGSEGV, vftype, SEGV_ACCERR, sv);		break;	case T_DATACC:	case T_DATACC | T_USER:		fault = VM_FAULT_PROTECT;	case T_ITLBMISS:	case T_ITLBMISS | T_USER:	case T_DTLBMISS:	case T_DTLBMISS | T_USER:	case T_ITLBMISSNA:	case T_ITLBMISSNA | T_USER:	case T_DTLBMISSNA:	case T_DTLBMISSNA | T_USER:	case T_TLB_DIRTY:	case T_TLB_DIRTY | T_USER:		/*		 * user faults out of user addr space are always a fail,		 * this happens on va >= VM_MAXUSER_ADDRESS, where		 * space id will be zero and therefore cause		 * a misbehave lower in the code.		 */		if (type & T_USER && va >= VM_MAXUSER_ADDRESS) {			sv.sival_int = va;			trapsignal(p, SIGSEGV, vftype, SEGV_ACCERR, sv);			break;		}		/*		 * it could be a kernel map for exec_map faults		 */		if (space == HPPA_SID_KERNEL)			map = kernel_map;		else {			vm = p->p_vmspace;			map = &vm->vm_map;		}		if (type & T_USER && map->pmap->pm_space != space) {			sv.sival_int = va;			trapsignal(p, SIGSEGV, vftype, SEGV_MAPERR, sv);			break;		}		ret = uvm_fault(map, hppa_trunc_page(va), fault, vftype);		/* dig probe insn */		if (ret && trapnum == T_DTLBMISSNA &&		    (frame->tf_iir & 0xfc001f80) == 0x04001180) {			frame_regmap(frame, frame->tf_iir & 0x1f) = 0;			frame->tf_ipsw |= PSL_N;			break;		}		/*		 * If this was a stack access we keep track of the maximum		 * accessed stack size.  Also, if uvm_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 (space != HPPA_SID_KERNEL &&		    va < (vaddr_t)vm->vm_minsaddr &&		    va >= (vaddr_t)vm->vm_maxsaddr + ctob(vm->vm_ssize)) {			if (ret == 0) {				vsize_t nss = btoc(va - USRSTACK + NBPG - 1);				if (nss > vm->vm_ssize)					vm->vm_ssize = nss;			} else if (ret == EACCES)				ret = EFAULT;		}		if (ret != 0) {			if (type & T_USER) {				sv.sival_int = va;				trapsignal(p, SIGSEGV, vftype,				    ret == EACCES? SEGV_ACCERR : SEGV_MAPERR,				    sv);			} else {				if (p && p->p_addr->u_pcb.pcb_onfault) {					frame->tf_iioq_tail = 4 +					    (frame->tf_iioq_head =						p->p_addr->u_pcb.pcb_onfault);#ifdef DDB					frame->tf_iir = 0;#endif				} else {					panic("trap: "					    "uvm_fault(%p, %lx, %d, %d): %d",					    map, va, 0, vftype, ret);				}			}		}		break;	case T_DATALIGN | T_USER:		sv.sival_int = va;		trapsignal(p, SIGBUS, vftype, BUS_ADRALN, sv);		break;	case T_INTERRUPT:	case T_INTERRUPT | T_USER:		cpu_intr(frame);		break;	case T_CONDITION:		panic("trap: divide by zero in the kernel");		break;	case T_ILLEGAL:	case T_ILLEGAL | T_USER:		/* see if it's a SPOP1,,0 */		if ((frame->tf_iir & 0xfffffe00) == 0x10000200) {			frame_regmap(frame, frame->tf_iir & 0x1f) = 0;			frame->tf_ipsw |= PSL_N;			break;		}		if (type & T_USER) {			sv.sival_int = va;			trapsignal(p, SIGILL, type &~ T_USER, ILL_ILLOPC, sv);			break;		}		/* FALLTHROUGH */	case T_LOWERPL:	case T_DPROT:	case T_IPROT:	case T_OVERFLOW:	case T_HIGHERPL:	case T_TAKENBR:	case T_POWERFAIL:	case T_LPMC:	case T_PAGEREF:	case T_DATAPID:	case T_DATAPID | T_USER:		if (0 /* T-chip */) {			break;		}		/* FALLTHROUGH to unimplemented */	default:#if 0if (kdb_trap (type, va, frame))	return;#endif		panic("trap: unimplemented \'%s\' (%d)", tts, trapnum);	}#ifdef DIAGNOSTIC	if (cpl != oldcpl)		printf("WARNING: SPL (%d) NOT LOWERED ON "		    "TRAP (%d) EXIT\n", cpl, trapnum);#endif	if (trapnum != T_INTERRUPT)		splx(cpl);	/* process softints */	/*	 * in case we were interrupted from the syscall gate page	 * treat this as we were not realy running user code no more	 * for weird things start to happen on return to the userland	 * and also see a note in locore.S:TLABEL(all)	 */	if ((type & T_USER) &&	    (frame->tf_iioq_head & ~PAGE_MASK) != SYSCALLGATE)		userret(p, frame->tf_iioq_head, 0);}