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

📄 kn210.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
 */kn210harderrintr(ep)int	*ep;{int	isr;	/* Content of ISR */u_long	pa;	/* Physical address */u_long	dser;	isr = *(int *)ISR;	/* Read content of ISR */	/*	 * Log DMA system error register, error address register, ..etc.	 */	esr[0].esr_wear = * (u_long *)KN210WEAR;	esr[0].esr_dser = * (u_long *)KN210DSER;	esr[0].esr_qbear = * (u_long *)KN210QBEAR;	esr[0].esr_dear = * (u_long *)KN210DEAR;	esr[0].esr_cbtcr = * (u_long *)KN210CBTCR;	esr[0].esr_isr = isr;	/* Clear the error bits */	*(u_long *)KN210DSER = 0xc0bd;	*(u_long *)KN210CBTCR = 0xc0000000 | esr[0].esr_cbtcr;	*(int *)ISR = 0;	/* Acknowledge all error interrupts */	if (isr & ISR_WEAR) {		/* Write error interrupt */		/* physical address is in WEAR */				pa = esr[0].esr_wear;		if (btop((int)pa) < physmem) {			/* was writing to main memory */			kn210logmempkt(EL_PRISEVERE, ep, pa);			kn210consprint(MEMPKT, ep, pa, 0);			panic("Memory write error");		}		else	{			kn210logesrpkt(ep, esr, EL_PRISEVERE);			kn210consprint(ESRPKT, ep, pa, 0);			panic("Bus write error");		}	}	if (isr & ISR_CERR) {		/* CQBIC or CMCTL error interrupt */		/* compute physical address */		dser = esr[0].esr_dser;		if (dser & 0xa0) {			/*			 * Q22 bus write cycle timeout after 10uS,			 * or Q22 bus parity error.			 * QBEAR contains Qbus physical address.			 */			pa = esr[0].esr_qbear << 9;			kn210logesrpkt(ep, esr, EL_PRISEVERE);			kn210consprint(ESRPKT, ep, pa, 1);			panic("Q22 bus error");		}		else if (dser & 0x11) {			/*			 * DMA transfer to non-existent main memory location,			 * or main memory error.			 * DEAR contains physical address.			 */			pa = esr[0].esr_dear << 9;			/* was writing to main memory */			kn210logmempkt(EL_PRISEVERE, ep, pa);			kn210consprint(MEMPKT, ep, pa, 0);			panic("Memory error");		}	}	if (isr & ISR_PWF) {		/* Powerfail interrupt */		powerfail_intr(ep);	}}/* * Pending powerfail, currently ULTRIX has no handling * strategy on VAX and MIPS.  Further, there is no restart * parameter block on MIPS.   * */powerfail_intr(ep)int *ep;{	printf("Power fail..\n");	DELAY(1000000);	/* Delay 1 second, if we are still alive, continue */}/* * Interrupts from Qbus level 7 or 10mS clock.  Level 7 is reserved for * Qbus real-time devices.  Currently not used in ULTRIX. */kn210hardintr2(ep)int *ep;{extern int (*(scb[]))();register int vrr;	vrr = read_nofault(VRR3);	/* Read interrupt vector */					/* 0 = passive release	*/	vrr &= 0xffff;	(*(scb[vrr/4]))(ep,vrr);	/* Call the interrupt handler 	*/}/* * Interrupts from NI, DSSI, or Qbus level 6. */kn210hardintr1(ep)int *ep;{extern int (*(scb[]))();register int vrr;	vrr = read_nofault(VRR2);	/* Read interrupt vector */					/* 0 = passive release	*/	vrr &= 0xffff;	(*(scb[vrr/4]))(ep,vrr);	/* Call the interrupt handler 	*/}/* * Interrupts from the Qbus level 5 and 4, * and from the SSC chip (programmable timers, console). * * VRR0 contains vector for Qbus level 4 & 5, don't read VRR1 for * reason I don't understand. */kn210hardintr0(ep)int *ep;{extern int (*(scb[]))();register int vrr;	vrr = read_nofault(VRR0);	/* Read interrupt vector */					/* 0 = passive release	*/	vrr &= 0xffff;	(*(scb[vrr/4]))(ep,vrr);	/* Call the interrupt handler 	*/}/* * Routine to handle trap errors: user-mode ibe & dbe, & all kernel mode traps. * We try to recover from user-mode errors and panic on kernel mode errors. */kn210trap_error(ep, code, sr, cause, signo)register u_int *ep;		/* exception frame ptr */register u_int code;		/* trap code (trap type) */u_int sr, cause;		/* status and cause regs */int *signo;			/* set if we want to kill process */{	caddr_t pa;			/* the physical addr of the error */		int epc;			/* the EPC of the error */		int pagetype;          		/* type of page */	int vaddr;			/* virt addr of error */	register struct proc *p;	/* ptr to current proc struct */		/*	 * Log DMA system error register, error address register, ..etc.	 */	esr[0].esr_wear = * (u_long *)KN210WEAR;	esr[0].esr_dser = * (u_long *)KN210DSER;	esr[0].esr_qbear = * (u_long *)KN210QBEAR;	esr[0].esr_dear = * (u_long *)KN210DEAR;	esr[0].esr_cbtcr = * (u_long *)KN210CBTCR;	/* Clear the error bits */	*(u_long *)KN210DSER = 0xc0bd;	*(u_long *)KN210CBTCR = 0xc0000000 | esr[0].esr_cbtcr;	p = u.u_procp;	if (USERMODE(sr)) {		/*		 * It is a memory read error:		 *    a) on a private process page, terminate the process		 *	 (by setting signo = SIGBUS)		 *    b) on a shared page, crash the system.		 * TBD: on a non-modified page, re-read the page (page fault),		 *	and continue the process.		 * TBD: on a shared page terminate all proc's sharing the page,		 *	instead of crash system.		 * TBD: on hard errors map out the page.		 */		pa = (caddr_t)vatophys(ep[EF_BADVADDR]);		if ( (int)pa != -1 && (btop((int)pa) < physmem) ) {			pagetype = cmap[pgtocm(btop(pa))].c_type;			if (SHAREDPG(pagetype)) {				kn210logmempkt(EL_PRISEVERE, ep,pa);				kn210consprint(MEMPKT, ep, pa, 0);				panic("memory read error in shared page");			} else {				kn210logmempkt(EL_PRIHIGH, ep, pa);				printf("pid %d (%s) was killed on memory read error\n",					p->p_pid, u.u_comm);				uprintf("pid %d (%s) was killed on memory read error\n",					p->p_pid, u.u_comm);			}		} else {			uprintf("pid %d (%s) was killed on bus read error\n",				p->p_pid, u.u_comm);		}	} else {		/*		 * Kernel mode errors.		 * They all panic, its just a matter of what we log		 * and what panic message we issue.		 */		switch (code) {		case EXC_DBE:		case EXC_IBE:			/*			 * Figure out if its a memory parity error			 *     or a read bus timeout error			 */			pa = (caddr_t)vatophys(ep[EF_BADVADDR]);			if ( (int)pa != -1 && (btop((int)pa) < physmem) ) {				kn210logmempkt(EL_PRISEVERE, ep, pa);				kn210consprint(MEMPKT, ep, pa, 0);				panic("memory read error in kernel mode");			} else {				kn210logesrpkt(ep, esr, EL_PRISEVERE);				kn210consprint(ESRPKT, ep, 0, 0);				panic("read bus timeout");			}			break;		case EXC_CPU:			kn210logesrpkt(ep, esr, EL_PRISEVERE);			kn210consprint(ESRPKT, ep, 0, 0);			panic("coprocessor unusable");			break;		case EXC_RADE:		case EXC_WADE:			kn210logesrpkt(ep, esr, EL_PRISEVERE);			kn210consprint(ESRPKT, ep, 0, 0);			panic("unaligned access");			break;		default:			kn210logesrpkt(ep, esr, EL_PRISEVERE);			kn210consprint(ESRPKT, ep, 0, 0);			panic("trap");			break;		}	}	/*	 * Default user-mode action is to terminate the process	 */	*signo = SIGBUS;	return(0);}/* * Log Error & Status Registers to the error log buffer. */kn210logesrpkt(ep, ptr, priority)register u_int *ep;	/* exception frame ptr */struct esr *ptr;	/* pointer to esr */int priority;		/* for pkt priority */{	struct el_rec *elrp;	elrp = ealloc(sizeof(struct el_esr), priority);	if (elrp != NULL) {		LSUBID(elrp,ELCT_ESR,ELESR_5400,EL_UNDEF,EL_UNDEF,EL_UNDEF,EL_UNDEF);		elrp->el_body.elesr.elesr.el_esr5400.esr_cause = ep[EF_CAUSE];		elrp->el_body.elesr.elesr.el_esr5400.esr_epc = ep[EF_EPC];		elrp->el_body.elesr.elesr.el_esr5400.esr_status = ep[EF_SR];		elrp->el_body.elesr.elesr.el_esr5400.esr_badva = ep[EF_BADVADDR];		elrp->el_body.elesr.elesr.el_esr5400.esr_sp = ep[EF_SP];		elrp->el_body.elesr.elesr.el_esr5400.esr_wear = ptr->esr_wear;		elrp->el_body.elesr.elesr.el_esr5400.esr_dser = ptr->esr_dser;		elrp->el_body.elesr.elesr.el_esr5400.esr_qbear = ptr->esr_qbear;		elrp->el_body.elesr.elesr.el_esr5400.esr_dear = ptr->esr_dear;		elrp->el_body.elesr.elesr.el_esr5400.esr_cbtcr = ptr->esr_cbtcr;		elrp->el_body.elesr.elesr.el_esr5400.esr_isr = ptr->esr_isr;		EVALID(elrp);	}}/* * Log a memory error packet, so uerf can find it as a main memory error. * Determine the type of memory error by reading MEMCSR16. * * Side effect: clear error bits in MEMCSR16. */kn210logmempkt(priority, ep, pa)int priority;		/* pkt priority: panic: severe; else: high */register u_int *ep;	/* exception frame ptr */int pa;			/* physical addr where memory err occured */{	struct el_rec *elrp;	register struct el_mem *mrp;	struct memcsr *memcsrptr = (struct memcsr *)MEMCSR;/* Pointer to memory csr */	elrp = ealloc(EL_MEMSIZE, priority);	if (elrp != NULL) {		LSUBID(elrp,ELCT_MEM,EL_UNDEF,ELMCNTR_5400,EL_UNDEF,EL_UNDEF,EL_UNDEF);		mrp = &elrp->el_body.elmem;		mrp->elmem_cnt = 1;		mrp->elmemerr.cntl = 1;				mrp->elmemerr.numerr = 1;		mrp->elmemerr.regs[0] = memcsrptr->memcsr16;		if (mrp->elmemerr.regs[0] & 0xc0000000)			mrp->elmemerr.type = ELMETYP_RDS;		else if (mrp->elmemerr.regs[0] & 0x20000000)			mrp->elmemerr.type = ELMETYP_CRD;		else if (mrp->elmemerr.regs[0] & 0x100)			mrp->elmemerr.type = ELMETYP_CNTL;		else				mrp->elmemerr.type = 0;		memcsrptr->memcsr16 = mrp->elmemerr.regs[0]; /* Clear errors*/		mrp->elmemerr.regs[1] = pa;		mrp->elmemerr.regs[2] = ep[EF_EPC];;		mrp->elmemerr.regs[3] = ep[EF_BADVADDR];;		EVALID(elrp);	}}/* * Print error packet to the console. * This is only done when we are about to panic on the error. * * Note: side-effect. *	If console is a graphics device, printstate is changed  to force *	kernel printfs directly to the screen. */kn210consprint(pkt, ep, pa, qbus)int pkt;		/* error pkt: Error & Stat Regs / memory pkt */register u_int *ep;	/* exception frame ptr */unsigned pa;		/* For MEMPKT: physical addr of error */	int	qbus;		/* 1 if pa is a qbus address, 0 otherwise */{	/*	 * If console is a graphics device,	 * force printf messages directly to screen.	 * Note: DS_5400 currently does not support qdss, 	 * but just in case...	 */        printstate |= PANICPRINT;	switch (pkt) {	case ESRPKT:		cprintf("\nException condition\n");		break;	case MEMPKT:		cprintf("\nMemory Error\n");		break;	default:		cprintf("bad consprint\n");		break;	}	cprintf("\tCause reg\t= 0x%x\n", ep[EF_CAUSE]);	cprintf("\tException PC\t= 0x%x\n", ep[EF_EPC]);	cprintf("\tStatus reg\t= 0x%x\n", ep[EF_SR]);	cprintf("\tBad virt addr\t= 0x%x\n", ep[EF_BADVADDR]);	if (pa) {		if (qbus) {			cprintf("\tQ22 Bus physical address of error: 0x%x\n",			pa);		}		else {			cprintf("\tPhysical address of error: 0x%x\n",pa);		}	}	return;}

⌨️ 快捷键说明

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