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

📄 trap.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
		/* restore original instruction and clear BP  */		i = suiword((caddr_t)va, p->p_md.md_ss_instr);		if (i < 0) {			vm_offset_t sa, ea;			int rv;			sa = trunc_page((vm_offset_t)va);			ea = round_page((vm_offset_t)va+sizeof(int)-1);			rv = vm_map_protect(&p->p_vmspace->vm_map, sa, ea,				VM_PROT_DEFAULT, FALSE);			if (rv == KERN_SUCCESS) {				i = suiword((caddr_t)va, p->p_md.md_ss_instr);				(void) vm_map_protect(&p->p_vmspace->vm_map,					sa, ea, VM_PROT_READ|VM_PROT_EXECUTE,					FALSE);			}		}		if (i < 0)			printf("Warning: can't restore instruction at %x: %x\n",				p->p_md.md_ss_addr, p->p_md.md_ss_instr);		p->p_md.md_ss_addr = 0;		i = SIGTRAP;		break;	    }	case T_RES_INST+T_USER:		i = SIGILL;		break;	case T_COP_UNUSABLE+T_USER:		if ((causeReg & MACH_CR_COP_ERR) != 0x10000000) {			i = SIGILL;	/* only FPU instructions allowed */			break;		}		MachSwitchFPState(machFPCurProcPtr, p->p_md.md_regs);		machFPCurProcPtr = p;		p->p_md.md_regs[PS] |= MACH_SR_COP_1_BIT;		p->p_md.md_flags |= MDP_FPUSED;		goto out;	case T_OVFLOW+T_USER:		i = SIGFPE;		break;	case T_ADDR_ERR_LD:	/* misaligned access */	case T_ADDR_ERR_ST:	/* misaligned access */	case T_BUS_ERR_LD_ST:	/* BERR asserted to cpu */		if (i = ((struct pcb *)UADDR)->pcb_onfault) {			((struct pcb *)UADDR)->pcb_onfault = 0;			return (onfault_table[i]);		}		/* FALLTHROUGH */	default:	err:#ifdef KADB	    {		extern struct pcb kdbpcb;		if (USERMODE(statusReg))			kdbpcb = p->p_addr->u_pcb;		else {			kdbpcb.pcb_regs[ZERO] = 0;			kdbpcb.pcb_regs[AST] = ((int *)&args)[2];			kdbpcb.pcb_regs[V0] = ((int *)&args)[3];			kdbpcb.pcb_regs[V1] = ((int *)&args)[4];			kdbpcb.pcb_regs[A0] = ((int *)&args)[5];			kdbpcb.pcb_regs[A1] = ((int *)&args)[6];			kdbpcb.pcb_regs[A2] = ((int *)&args)[7];			kdbpcb.pcb_regs[A3] = ((int *)&args)[8];			kdbpcb.pcb_regs[T0] = ((int *)&args)[9];			kdbpcb.pcb_regs[T1] = ((int *)&args)[10];			kdbpcb.pcb_regs[T2] = ((int *)&args)[11];			kdbpcb.pcb_regs[T3] = ((int *)&args)[12];			kdbpcb.pcb_regs[T4] = ((int *)&args)[13];			kdbpcb.pcb_regs[T5] = ((int *)&args)[14];			kdbpcb.pcb_regs[T6] = ((int *)&args)[15];			kdbpcb.pcb_regs[T7] = ((int *)&args)[16];			kdbpcb.pcb_regs[T8] = ((int *)&args)[17];			kdbpcb.pcb_regs[T9] = ((int *)&args)[18];			kdbpcb.pcb_regs[RA] = ((int *)&args)[19];			kdbpcb.pcb_regs[MULLO] = ((int *)&args)[21];			kdbpcb.pcb_regs[MULHI] = ((int *)&args)[22];			kdbpcb.pcb_regs[PC] = pc;			kdbpcb.pcb_regs[SR] = statusReg;			bzero((caddr_t)&kdbpcb.pcb_regs[F0], 33 * sizeof(int));		}		if (kdb(causeReg, vadr, p, !USERMODE(statusReg)))			return (kdbpcb.pcb_regs[PC]);	    }#else#ifdef DEBUG		trapDump("trap");#endif#endif		panic("trap");	}	trapsignal(p, i, ucode);out:	/*	 * Note: we should only get here if returning to user mode.	 */	/* take pending signals */	while ((i = CURSIG(p)) != 0)		postsig(i);	p->p_priority = p->p_usrpri;	astpending = 0;	if (want_resched) {		int s;		/*		 * Since we are curproc, clock will normally just change		 * our priority without moving us from one queue to another		 * (since the running process is not on a queue.)		 * If that happened after we put ourselves on the run queue		 * but before we switched, we might not be on the queue		 * indicated by our priority.		 */		s = splstatclock();		setrunqueue(p);		p->p_stats->p_ru.ru_nivcsw++;		mi_switch();		splx(s);		while ((i = CURSIG(p)) != 0)			postsig(i);	}	/*	 * If profiling, charge system time to the trapped pc.	 */	if (p->p_flag & P_PROFIL) {		extern int psratio;		addupc_task(p, pc, (int)(p->p_sticks - sticks) * psratio);	}	curpriority = p->p_priority;	return (pc);}/* * Handle an interrupt. * Called from MachKernIntr() or MachUserIntr() * Note: curproc might be NULL. */interrupt(statusReg, causeReg, pc)	unsigned statusReg;	/* status register at time of the exception */	unsigned causeReg;	/* cause register at time of exception */	unsigned pc;		/* program counter where to continue */{	register unsigned mask;	struct clockframe cf;#ifdef DEBUG	trp->status = statusReg;	trp->cause = causeReg;	trp->vadr = 0;	trp->pc = pc;	trp->ra = 0;	trp->code = 0;	if (++trp == &trapdebug[TRAPSIZE])		trp = trapdebug;#endif	cnt.v_intr++;	mask = causeReg & statusReg;	/* pending interrupts & enable mask */	if (pmax_hardware_intr)		splx((*pmax_hardware_intr)(mask, pc, statusReg, causeReg));	if (mask & MACH_INT_MASK_5) {		if (!USERMODE(statusReg)) {#ifdef DEBUG			trapDump("fpintr");#else			printf("FPU interrupt: PC %x CR %x SR %x\n",				pc, causeReg, statusReg);#endif		} else			MachFPInterrupt(statusReg, causeReg, pc);	}	if (mask & MACH_SOFT_INT_MASK_0) {		clearsoftclock();		cnt.v_soft++;		softclock();	}	/* process network interrupt if we trapped or will very soon */	if ((mask & MACH_SOFT_INT_MASK_1) ||	    netisr && (statusReg & MACH_SOFT_INT_MASK_1)) {		clearsoftnet();		cnt.v_soft++;#ifdef INET		if (netisr & (1 << NETISR_ARP)) {			netisr &= ~(1 << NETISR_ARP);			arpintr();		}		if (netisr & (1 << NETISR_IP)) {			netisr &= ~(1 << NETISR_IP);			ipintr();		}#endif#ifdef NS		if (netisr & (1 << NETISR_NS)) {			netisr &= ~(1 << NETISR_NS);			nsintr();		}#endif#ifdef ISO		if (netisr & (1 << NETISR_ISO)) {			netisr &= ~(1 << NETISR_ISO);			clnlintr();		}#endif	}}/* * Handle pmax (DECstation 2100/3100) interrupts. */pmax_intr(mask, pc, statusReg, causeReg)	unsigned mask;	unsigned pc;	unsigned statusReg;	unsigned causeReg;{	register volatile struct chiptime *c = Mach_clock_addr;	struct clockframe cf;	int temp;	/* handle clock interrupts ASAP */	if (mask & MACH_INT_MASK_3) {		temp = c->regc;	/* XXX clear interrupt bits */		cf.pc = pc;		cf.sr = statusReg;		hardclock(&cf);		/* keep clock interrupts enabled */		causeReg &= ~MACH_INT_MASK_3;	}	/* Re-enable clock interrupts */	splx(MACH_INT_MASK_3 | MACH_SR_INT_ENA_CUR);#if NSII > 0	if (mask & MACH_INT_MASK_0)		siiintr(0);#endif#if NLE > 0	if (mask & MACH_INT_MASK_1)		leintr(0);#endif#if NDC > 0	if (mask & MACH_INT_MASK_2)		dcintr(0);#endif	if (mask & MACH_INT_MASK_4)		pmax_errintr();	return ((statusReg & ~causeReg & MACH_HARD_INT_MASK) |		MACH_SR_INT_ENA_CUR);}/* * Handle hardware interrupts for the KN02. (DECstation 5000/200) * Returns spl value. */kn02_intr(mask, pc, statusReg, causeReg)	unsigned mask;	unsigned pc;	unsigned statusReg;	unsigned causeReg;{	register unsigned i, m;	register volatile struct chiptime *c = Mach_clock_addr;	register unsigned csr;	int temp;	struct clockframe cf;	static int warned = 0;	/* handle clock interrupts ASAP */	if (mask & MACH_INT_MASK_1) {		csr = *(unsigned *)MACH_PHYS_TO_UNCACHED(KN02_SYS_CSR);		if ((csr & KN02_CSR_PSWARN) && !warned) {			warned = 1;			printf("WARNING: power supply is overheating!\n");		} else if (warned && !(csr & KN02_CSR_PSWARN)) {			warned = 0;			printf("WARNING: power supply is OK again\n");		}		temp = c->regc;	/* XXX clear interrupt bits */		cf.pc = pc;		cf.sr = statusReg;		hardclock(&cf);		/* keep clock interrupts enabled */		causeReg &= ~MACH_INT_MASK_1;	}	/* Re-enable clock interrupts */	splx(MACH_INT_MASK_1 | MACH_SR_INT_ENA_CUR);	if (mask & MACH_INT_MASK_0) {		csr = *(unsigned *)MACH_PHYS_TO_UNCACHED(KN02_SYS_CSR);		m = csr & (csr >> KN02_CSR_IOINTEN_SHIFT) & KN02_CSR_IOINT;#if 0		*(unsigned *)MACHPHYS_TO_UNCACHED(KN02_SYS_CSR) =			(csr & ~(KN02_CSR_WRESERVED | 0xFF)) |			(m << KN02_CSR_IOINTEN_SHIFT);#endif		for (i = 0; m; i++, m >>= 1) {			if (!(m & 1))				continue;			if (tc_slot_info[i].intr)				(*tc_slot_info[i].intr)(tc_slot_info[i].unit);			else				printf("spurious interrupt %d\n", i);		}#if 0		*(unsigned *)MACH_PHYS_TO_UNCACHED(KN02_SYS_CSR) =			csr & ~(KN02_CSR_WRESERVED | 0xFF);#endif	}	if (mask & MACH_INT_MASK_3)		kn02_errintr();	return ((statusReg & ~causeReg & MACH_HARD_INT_MASK) |		MACH_SR_INT_ENA_CUR);}/* * 3min hardware interrupts. (DECstation 5000/1xx) */kmin_intr(mask, pc, statusReg, causeReg)	unsigned mask;	unsigned pc;	unsigned statusReg;	unsigned causeReg;{	register u_int intr;	register volatile struct chiptime *c = Mach_clock_addr;	volatile u_int *imaskp =		(volatile u_int *)MACH_PHYS_TO_UNCACHED(KMIN_REG_IMSK);	volatile u_int *intrp =		(volatile u_int *)MACH_PHYS_TO_UNCACHED(KMIN_REG_INTR);	unsigned int old_mask;	struct clockframe cf;	int temp;	static int user_warned = 0;	old_mask = *imaskp & kmin_tc3_imask;	*imaskp = old_mask;	if (mask & MACH_INT_MASK_4)		(*callv->halt)((int *)0, 0);	if (mask & MACH_INT_MASK_3) {		intr = *intrp;		/* masked interrupts are still observable */		intr &= old_mask;			if (intr & KMIN_INTR_SCSI_PTR_LOAD) {			*intrp &= ~KMIN_INTR_SCSI_PTR_LOAD;#ifdef notdef			asc_dma_intr();#endif		}			if (intr & (KMIN_INTR_SCSI_OVRUN | KMIN_INTR_SCSI_READ_E))			*intrp &= ~(KMIN_INTR_SCSI_OVRUN | KMIN_INTR_SCSI_READ_E);		if (intr & KMIN_INTR_LANCE_READ_E)			*intrp &= ~KMIN_INTR_LANCE_READ_E;		if (intr & KMIN_INTR_TIMEOUT)			kn02ba_errintr();			if (intr & KMIN_INTR_CLOCK) {			temp = c->regc;	/* XXX clear interrupt bits */			cf.pc = pc;			cf.sr = statusReg;			hardclock(&cf);		}			if ((intr & KMIN_INTR_SCC_0) &&			tc_slot_info[KMIN_SCC0_SLOT].intr)			(*(tc_slot_info[KMIN_SCC0_SLOT].intr))			(tc_slot_info[KMIN_SCC0_SLOT].unit);			if ((intr & KMIN_INTR_SCC_1) &&			tc_slot_info[KMIN_SCC1_SLOT].intr)			(*(tc_slot_info[KMIN_SCC1_SLOT].intr))			(tc_slot_info[KMIN_SCC1_SLOT].unit);			if ((intr & KMIN_INTR_SCSI) &&			tc_slot_info[KMIN_SCSI_SLOT].intr)			(*(tc_slot_info[KMIN_SCSI_SLOT].intr))			(tc_slot_info[KMIN_SCSI_SLOT].unit);			if ((intr & KMIN_INTR_LANCE) &&			tc_slot_info[KMIN_LANCE_SLOT].intr)			(*(tc_slot_info[KMIN_LANCE_SLOT].intr))			(tc_slot_info[KMIN_LANCE_SLOT].unit);			if (user_warned && ((intr & KMIN_INTR_PSWARN) == 0)) {			printf("%s\n", "Power supply ok now.");			user_warned = 0;		}		if ((intr & KMIN_INTR_PSWARN) && (user_warned < 3)) {			user_warned++;			printf("%s\n", "Power supply overheating");		}	}	if ((mask & MACH_INT_MASK_0) && tc_slot_info[0].intr)		(*tc_slot_info[0].intr)(tc_slot_info[0].unit);	if ((mask & MACH_INT_MASK_1) && tc_slot_info[1].intr)		(*tc_slot_info[1].intr)(tc_slot_info[1].unit);	if ((mask & MACH_INT_MASK_2) && tc_slot_info[2].intr)		(*tc_slot_info[2].intr)(tc_slot_info[2].unit);	return ((statusReg & ~causeReg & MACH_HARD_INT_MASK) |		MACH_SR_INT_ENA_CUR);}/* * Maxine hardware interrupts. (Personal DECstation 5000/xx) */xine_intr(mask, pc, statusReg, causeReg)	unsigned mask;	unsigned pc;	unsigned statusReg;	unsigned causeReg;{	register u_int intr;	register volatile struct chiptime *c = Mach_clock_addr;	volatile u_int *imaskp = (volatile u_int *)		MACH_PHYS_TO_UNCACHED(XINE_REG_IMSK);	volatile u_int *intrp = (volatile u_int *)		MACH_PHYS_TO_UNCACHED(XINE_REG_INTR);	u_int old_mask;	struct clockframe cf;	int temp;	old_mask = *imaskp & xine_tc3_imask;	*imaskp = old_mask;	if (mask & MACH_INT_MASK_4)		(*callv->halt)((int *)0, 0);	/* handle clock interrupts ASAP */	if (mask & MACH_INT_MASK_1) {		temp = c->regc;	/* XXX clear interrupt bits */		cf.pc = pc;		cf.sr = statusReg;		hardclock(&cf);		causeReg &= ~MACH_INT_MASK_1;		/* reenable clock interrupts */		splx(MACH_INT_MASK_1 | MACH_SR_INT_ENA_CUR);	}	if (mask & MACH_INT_MASK_3) {		intr = *intrp;		/* masked interrupts are still observable */		intr &= old_mask;		if (intr & XINE_INTR_SCSI_PTR_LOAD) {			*intrp &= ~XINE_INTR_SCSI_PTR_LOAD;#ifdef notdef			asc_dma_intr();#endif		}			if (intr & (XINE_INTR_SCSI_OVRUN | XINE_INTR_SCSI_READ_E))			*intrp &= ~(XINE_INTR_SCSI_OVRUN | XINE_INTR_SCSI_READ_E);		if (intr & XINE_INTR_LANCE_READ_E)			*intrp &= ~XINE_INTR_LANCE_READ_E;		if ((intr & XINE_INTR_SCC_0) &&			tc_slot_info[XINE_SCC0_SLOT].intr)			(*(tc_slot_info[XINE_SCC0_SLOT].intr))			(tc_slot_info[XINE_SCC0_SLOT].unit);			if ((intr & XINE_INTR_DTOP_RX) &&			tc_slot_info[XINE_DTOP_SLOT].intr)			(*(tc_slot_info[XINE_DTOP_SLOT].intr))			(tc_slot_info[XINE_DTOP_SLOT].unit);			if ((intr & XINE_INTR_FLOPPY) &&			tc_slot_info[XINE_FLOPPY_SLOT].intr)			(*(tc_slot_info[XINE_FLOPPY_SLOT].intr))			(tc_slot_info[XINE_FLOPPY_SLOT].unit);			if ((intr & XINE_INTR_TC_0) &&			tc_slot_info[0].intr)			(*(tc_slot_info[0].intr))			(tc_slot_info[0].unit);			if ((intr & XINE_INTR_TC_1) &&			tc_slot_info[1].intr)			(*(tc_slot_info[1].intr))			(tc_slot_info[1].unit);			if ((intr & XINE_INTR_ISDN) &&			tc_slot_info[XINE_ISDN_SLOT].intr)			(*(tc_slot_info[XINE_ISDN_SLOT].intr))			(tc_slot_info[XINE_ISDN_SLOT].unit);			if ((intr & XINE_INTR_SCSI) &&			tc_slot_info[XINE_SCSI_SLOT].intr)			(*(tc_slot_info[XINE_SCSI_SLOT].intr))			(tc_slot_info[XINE_SCSI_SLOT].unit);			if ((intr & XINE_INTR_LANCE) &&			tc_slot_info[XINE_LANCE_SLOT].intr)			(*(tc_slot_info[XINE_LANCE_SLOT].intr))			(tc_slot_info[XINE_LANCE_SLOT].unit);		}	if (mask & MACH_INT_MASK_2)		kn02ba_errintr();	return ((statusReg & ~causeReg & MACH_HARD_INT_MASK) |		MACH_SR_INT_ENA_CUR);}#ifdef DS5000_240/* * 3Max+ hardware interrupts. (DECstation 5000/240) UNTESTED!! */kn03_intr(mask, pc, statusReg, causeReg)	unsigned mask;	unsigned pc;	unsigned statusReg;	unsigned causeReg;{	register u_int intr;	register volatile struct chiptime *c = Mach_clock_addr;	volatile u_int *imaskp = (volatile u_int *)		MACH_PHYS_TO_UNCACHED(KN03_REG_IMSK);	volatile u_int *intrp = (volatile u_int *)		MACH_PHYS_TO_UNCACHED(KN03_REG_INTR);	u_int old_mask;	struct clockframe cf;	int temp;	static int user_warned = 0;	old_mask = *imaskp & kn03_tc3_imask;	*imaskp = old_mask;	if (mask & MACH_INT_MASK_4)		(*callv->halt)((int *)0, 0);	/* handle clock interrupts ASAP */	if (mask & MACH_INT_MASK_1) {		temp = c->regc;	/* XXX clear interrupt bits */		cf.pc = pc;		cf.sr = statusReg;		hardclock(&cf);		causeReg &= ~MACH_INT_MASK_1;		/* reenable clock interrupts */		splx(MACH_INT_MASK_1 | MACH_SR_INT_ENA_CUR);	}	if (mask & MACH_INT_MASK_0) {		intr = *intrp;		/* masked interrupts are still observable */		intr &= old_mask;		if (intr & KN03_INTR_SCSI_PTR_LOAD) {			*intrp &= ~KN03_INTR_SCSI_PTR_LOAD;#ifdef notdef			asc_dma_intr();#endif		}			if (intr & (KN03_INTR_SCSI_OVRUN | KN03_INTR_SCSI_READ_E))			*intrp &= ~(KN03_INTR_SCSI_OVRUN | KN03_INTR_SCSI_READ_E);		if (intr & KN03_INTR_LANCE_READ_E)			*intrp &= ~KN03_INTR_LANCE_READ_E;		if ((intr & KN03_INTR_SCC_0) &&			tc_slot_info[KN03_SCC0_SLOT].intr)			(*(tc_slot_info[KN03_SCC0_SLOT].intr))			(tc_slot_info[KN03_SCC0_SLOT].unit);			if ((intr & KN03_INTR_SCC_1) &&			tc_slot_info[KN03_SCC1_SLOT].intr)			(*(tc_slot_info[KN03_SCC1_SLOT].intr))			(tc_slot_info[KN03_SCC1_SLOT].unit);			if ((intr & KN03_INTR_TC_0) &&			tc_slot_info[0].intr)			(*(tc_slot_info[0].intr))			(tc_slot_info[0].unit);			if ((intr & KN03_INTR_TC_1) &&			tc_slot_info[1].intr)			(*(tc_slot_info[1].intr))			(tc_slot_info[1].unit);			if ((intr & KN03_INTR_TC_2) &&			tc_slot_info[2].intr)

⌨️ 快捷键说明

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