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

📄 kn02ba.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
		} else {		    kn02ba_logesrpkt(EL_PRISEVERE, ep, ssr, sir, sirm);		    kn02ba_consprint(KN02BA_ESRPKT, ep, 0, 0, ssr, sir, sirm);		    panic("bus timeout");		}		break;	      case EXC_CPU:		kn02ba_logesrpkt(EL_PRISEVERE, ep, ssr, sir, sirm);		kn02ba_consprint(KN02BA_ESRPKT, ep, 0, 0, ssr, sir, sirm);		panic("coprocessor unusable");		break;	      case EXC_RADE:	      case EXC_WADE:		kn02ba_logesrpkt(EL_PRISEVERE, ep, ssr, sir, sirm);		kn02ba_consprint(KN02BA_ESRPKT, ep, 0, 0, ssr, sir, sirm);		panic("unaligned access");		break;	      default:		kn02ba_logesrpkt(EL_PRISEVERE, ep, ssr, sir, sirm);		kn02ba_consprint(KN02BA_ESRPKT, ep, 0, 0, ssr, sir, sirm);		panic("trap");		break;	    }	}	/*	 * Default user-mode action is to terminate the process	 */	*signo = SIGBUS;	return(0);}kn02ba_intr(ep, code, sr, cause)u_int *ep;u_int code, sr, cause;{	register u_int req, sir, tmp_cause;        register int nintr = 1, current_ipl;	extern int nstrays;	u_int current_sirm = *(u_int *)PHYS_TO_K1(KN02BA_SIRM_ADDR);		CURRENT_CPUDATA->cpu_inisr++;		/* remove any pending intr's that are masked */	tmp_cause = cause & sr;		req = ffintr(tmp_cause);	switch (req) {	  case CR_HALT:	    /* loop until the halt button is released */            while (get_cause() & SR_IBIT7) ;	    kn02ba_halt(ep);	    break;	    	  case CR_FPU:	    splx(SPLFPU);	    fpuintr(ep);	    break;	    	  case CR_SYSTEM:	    sir = *(u_int *)PHYS_TO_K1(KN02BA_SIR_ADDR);	    	    /* mask out bits that we don't want */	    sir &= current_sirm;	    	    if (sir & CPU_IO_TIMEOUT) {		splx(SPLMEM);		kn02ba_errintr(ep);	    } else if (sir & TOY_INTR) {		splx(SPLCLOCK);		hardclock(ep);	    } else if (sir & SLU_INTR) {		splx(SPLIO);		(*(tc_slot[KN02BA_SCC_INDEX].intr))();	    } else if (sir & LANCE_INTR) {		splx(SPLIO);		(*(tc_slot[KN02BA_LN_INDEX].intr))();	    } else if (sir & SCSI_INTR) {		splx(SPLIO);		(*(tc_slot[KN02BA_SCSI_INDEX].intr))();	    } else {		nintr--;		nstrays++;		/* rpbfix: downgrade to a printf after debugging */		cprintf("Stray interrupt from System Interrupt Register");	    }	    break;	    	  case CR_OPTION_2:	    splx(SPLIO);	    (*(tc_slot[2].intr))(tc_slot[2].unit);	    break;	    	  case CR_OPTION_1:	    splx(SPLIO);	    (*(tc_slot[1].intr))(tc_slot[1].unit);	    break;	    	  case CR_OPTION_0:	    splx(SPLIO);	    (*(tc_slot[0].intr))(tc_slot[0].unit);	    break;	    	  case CR_SOFTNET:	    splx(SPLNET);	    softnet(ep);	    break;	    	  case CR_SOFTCLOCK:	    splx(SPLSOFTC);	    softclock(ep);	    break;	    	  case CR_NONE:	    /* rpbfix: downgrade to printf later */	    nintr--;	    nstrays++;	    /*	    panic("no interrupt pending");*/	    cprintf("no interrupt pending, cause = %x, sr = %x\n", cause, sr);	    break;	}		CURRENT_CPUDATA->cpu_intr += nintr;	CURRENT_CPUDATA->cpu_inisr--;}kn02ba_getspl(){    return (ipllevel);}/* On 3min, the value returned by getspl is the actual ipllevel */kn02ba_whatspl(ipl)u_int ipl;{    return (ipl);}kn02ba_errintr(ep)    register u_int *ep;		/* exception frame ptr */{        register unsigned cpu_addr_err;	register unsigned ssr;	register unsigned sir;	register unsigned sirm;	struct kn02ba_consinfo_t kn02ba_consinfo, *p;		ssr = *(u_int *)(PHYS_TO_K1(KN02BA_SSR_ADDR));	sir = *(u_int *)(PHYS_TO_K1(KN02BA_SIR_ADDR));	sirm = *(u_int *)(PHYS_TO_K1(KN02BA_SIRM_ADDR));		cpu_addr_err = *(u_int *)PHYS_TO_K1(KN02BA_ADDR_ERR);	ep[EF_BADVADDR] = cpu_addr_err;	/*	 * if we are still processing an previous interrupt	 * then simply crash. we don't queue these interrupts.	 */	if (CURRENT_CPUDATA->cpu_wto_event) {	    kn02ba_logesrpkt(EL_PRISEVERE, ep, ssr, sir, sirm);	    kn02ba_consprint(KN02BA_ESRPKT, ep, 0, 0, ssr, sir, sirm);	    *(u_int *)PHYS_TO_K1(KN02BA_INTR_REG) = 0;	    wbflush();	    panic("CPU write timeout");	}	else {	    /*	     *	capture error information in kn02consinfo.	     *	softnet() interrupt will print this info	     *	if panicing on the console.	     */	    p = &kn02ba_consinfo;	    /*	     *	capture log information in kn02log_errinfo.	     *	softnet() interrupt will log this info	     *	if panicing in the error log buffer.	     */	    p->pkt_type 		= KN02BA_ESRPKT;	    p->pkt.esrp.cause		= ep[EF_CAUSE];		    p->pkt.esrp.epc		= ep[EF_EPC];	    p->pkt.esrp.status		= ep[EF_SR];		    p->pkt.esrp.badva		= ep[EF_BADVADDR];	    p->pkt.esrp.sp		= ep[EF_SP];		    p->pkt.esrp.ssr		= ssr;	    p->pkt.esrp.sir		= sir;	    p->pkt.esrp.sirm		= sirm;	    CURRENT_CPUDATA->cpu_consinfo	= (char *) &kn02ba_consinfo;	    CURRENT_CPUDATA->cpu_log_errinfo	= (char *) &kn02ba_consinfo;	    CURRENT_CPUDATA->cpu_wto_pfn    	= btop(cpu_addr_err);	    CURRENT_CPUDATA->cpu_wto_event 		= 1;	    *(u_int *)PHYS_TO_K1(KN02BA_INTR_REG) 	= 0;	    wbflush();	    setsoftnet();	}}/* * * Tested from 5 seconds down to 4,000 usecs (4 mSec clock accuracy). * */kn02ba_delay(n)	int n;{	register int N = kn02ba_delay_mult*(n); 	while (--N > 0); 	return(0);}kn02ba_stray(){        /* rpbfix: downgrade to printf */        panic("Received stray interrupt");}halt_cnt = 0;kn02ba_halt(ep)u_int *ep;{    /* print out value of PC, SP, and EP with labels */    rex_printf("\nPC:\t0x%x\nSP:\t0x%x\nEP:\t0x%x\n\n", ep[EF_EPC], ep[EF_SP], ep);    rex_halt(0,0);}kn02ba_enable_option(index)    register int index;{        register int i;		switch (index) {	  case KN02BA_SCC_INDEX:	    for (i = 0; i < SPLIO; i++)		kn02ba_sim[i] |= (SLU_INTR);	    break;	    	  case KN02BA_LN_INDEX:	    for (i = 0; i < SPLIO; i++)		kn02ba_sim[i] |= (LANCE_INTR);	    break;	    	  case KN02BA_SCSI_INDEX:	    /* rpbfix: reenable when scsi is really turned on */	    for (i = 0; i < SPLIO; i++)		kn02ba_sim[i] |= (SCSI_INTR);	    break;	    	  case TC_OPTION_SLOT_0:	    for (i = 0; i < SPLIO; i++)		splm[i] |= SR_IBIT3;	    sr_usermask |= SR_IBIT3;	    break;	    	  case TC_OPTION_SLOT_1:	    for (i = 0; i < SPLIO; i++)		splm[i] |= SR_IBIT4;	    sr_usermask |= SR_IBIT4;	    break;	    	  case TC_OPTION_SLOT_2:	    for (i = 0; i < SPLIO; i++)		splm[i] |= SR_IBIT5;	    sr_usermask |= SR_IBIT5;	    break;	    	  default:	    /* rpbfix: downgrade to printf */	    panic("Enable_option call to non existent slot");	    break;	}		/* load the registers with the new values */	splx(ipllevel);}kn02ba_disable_option(index)    register int index;{        register int i;	switch (index) {	  case KN02BA_SCC_INDEX:	    for (i = 0; i < SPLIO; i++)		kn02ba_sim[i] &= ~(SLU_INTR);	    break;	    	  case KN02BA_LN_INDEX:	    for (i = 0; i < SPLIO; i++)		kn02ba_sim[i] &= ~(LANCE_INTR);	    break;	    	  case KN02BA_SCSI_INDEX:	    for (i = 0; i < SPLIO; i++)		kn02ba_sim[i] &= ~(SCSI_INTR);	    break;	    	  case TC_OPTION_SLOT_0:	    for (i = 0; i < SPLIO; i++)		splm[i] &= ~(SR_IBIT3);	    sr_usermask &= ~(SR_IBIT3);	    break;	    	  case TC_OPTION_SLOT_1:	    for (i = 0; i < SPLIO; i++)		splm[i] &= ~(SR_IBIT4);	    sr_usermask &= ~(SR_IBIT4);	    break;	    	  case TC_OPTION_SLOT_2:	    for (i = 0; i < SPLIO; i++)		splm[i] &= ~(SR_IBIT5);	    sr_usermask &= ~(SR_IBIT5);	    break;	    	  default:	    /* rpbfix: downgrade to printf */	    panic("disable_option call to non existent slot");	    break;	}		/* load the registers with the new values */	splx(ipllevel);}kn02ba_clear_errors(){}#define KN02BA_LOG_ESRPKT(elrp, cause,epc,sr,badva,sp,ssr,sir,sirm)	\	elrp->el_body.elesr.elesr.el_esrkn02ba.esr_cause = cause;	\	elrp->el_body.elesr.elesr.el_esrkn02ba.esr_epc = epc;		\	elrp->el_body.elesr.elesr.el_esrkn02ba.esr_status = sr;		\	elrp->el_body.elesr.elesr.el_esrkn02ba.esr_badva = badva;	\	elrp->el_body.elesr.elesr.el_esrkn02ba.esr_sp = sp;		\	elrp->el_body.elesr.elesr.el_esrkn02ba.esr_ssr = ssr;		\	elrp->el_body.elesr.elesr.el_esrkn02ba.esr_sir = sir;		\	elrp->el_body.elesr.elesr.el_esrkn02ba.esr_sirm = sirm;		\/* * Log Error & Status Registers to the error log buffer */kn02ba_logesrpkt(priority, ep, ssr, sir, sirm)	int priority;		/* for pkt priority */	register u_int *ep;	/* exception frame ptr */	u_int ssr;	u_int sir;	u_int sirm;{	struct el_rec *elrp;		elrp = ealloc(sizeof(struct el_esr), priority);	if (elrp != NULL) {	    LSUBID(elrp,ELCT_ESR,ELESR_KN02BA,EL_UNDEF,EL_UNDEF,EL_UNDEF,EL_UNDEF);	    KN02BA_LOG_ESRPKT(elrp, ep[EF_CAUSE], ep[EF_EPC], ep[EF_SR], ep[EF_BADVADDR], 			      ep[EF_SP], ssr, sir, sirm);	    	    EVALID(elrp);	}}/* * Log a memory error packet, so uerf can find it as a main memory error. */kn02ba_logmempkt(priority, ep, memreg, pa)	int priority;		/* pkt priority: panic: severe; else: high */	register u_int *ep;	/* exception frame ptr */	unsigned memreg;	/* assorted parity error info */	int pa;			/* physical addr where memory err occured */{	struct el_rec *elrp;	register struct el_mem *mrp;		elrp = ealloc(EL_MEMSIZE, priority);	if (elrp != NULL) {	    LSUBID(elrp,ELCT_MEM,EL_UNDEF,ELMCNTR_KN02BA,EL_UNDEF,EL_UNDEF,EL_UNDEF);	    mrp = &elrp->el_body.elmem;	    mrp->elmem_cnt = 1;	    mrp->elmemerr.cntl = 1;	    mrp->elmemerr.type = ELMETYP_PAR;	    mrp->elmemerr.numerr = 1;	    mrp->elmemerr.regs[0] = memreg;	    mrp->elmemerr.regs[1] = pa;	    mrp->elmemerr.regs[2] = ep[EF_EPC];;	    mrp->elmemerr.regs[3] = ep[EF_BADVADDR];;	    EVALID(elrp);	}}/* * 	Logs error information to the error log buffer. *	Exported through the cpu switch. */kn02ba_log_errinfo(p)struct kn02ba_consinfo_t *p;{	struct el_rec *elrp;	struct kn02ba_consinfo_esr_t *esrp;		switch (p->pkt_type) {	    	  case KN02BA_ESRPKT:	    esrp = &(p->pkt.esrp);	    elrp = ealloc(sizeof(struct el_esr), EL_PRISEVERE);	    if (elrp != NULL) {		LSUBID(elrp,ELCT_ESR,ELESR_KN02BA,EL_UNDEF,EL_UNDEF,EL_UNDEF,EL_UNDEF);		KN02BA_LOG_ESRPKT(elrp, esrp->cause, esrp->epc, esrp->status, esrp->badva, 				  esrp->sp, esrp->ssr, esrp->sir, esrp->sirm);		EVALID(elrp);	    }	    break;	    	  default: 	    cprintf("bad pkt type\n");	    return;	}}/* * Print error packet to the console. * This is only done when we are about to panic on the error. * It calls kn02_print_consinfo to actually print the information. * */kn02ba_consprint(pkt, ep, memreg, pa, ssr, sir, sirm)	int pkt;		/* error pkt: Error & Stat Regs / memory pkt */	register u_int *ep;	/* exception frame ptr */	unsigned memreg;	/* For MEMPKT: assorted parity error info */	unsigned pa;		/* For MEMPKT: physical addr of error */		unsigned ssr;	unsigned sir;	unsigned sirm;{	register int i;	struct kn02ba_consinfo_t p;			p.pkt_type = pkt;	switch (pkt) {	  case KN02BA_ESRPKT:	    p.pkt.esrp.cause	= ep[EF_CAUSE];	    p.pkt.esrp.epc		= ep[EF_EPC];	    p.pkt.esrp.status	= ep[EF_SR];	    p.pkt.esrp.badva	= ep[EF_BADVADDR];	    p.pkt.esrp.sp		= ep[EF_SP];	    p.pkt.esrp.ssr		= ssr;	    p.pkt.esrp.sir		= sir;	    p.pkt.esrp.sirm		= sirm;	    break;	    	  case KN02BA_MEMPKT:	    p.pkt.memp.epc		= ep[EF_EPC];	    p.pkt.memp.badva	= ep[EF_BADVADDR];	    p.pkt.memp.memreg	= memreg;	    p.pkt.memp.pa		= pa;	    break;	    	  default:	    cprintf("bad consprint\n");	    return;	}	kn02ba_print_consinfo(&p);	}/* *	This routine is similar to kn02consprint(). *	This is exported through the cpusw structure.  *	

⌨️ 快捷键说明

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