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

📄 kn220.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
			if (SHAREDPG(pa)) {				kn220logmempkt(EL_PRISEVERE, ep,pa);				kn220consprint(MEMPKT, ep, pa, 0);				panic("memory read error in shared page");			} else {				kn220logmempkt(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:		/* Data Bus Error	 */		case EXC_IBE:		/* Instruction Bus Error */			/*			 * Figure out if its a memory parity error			 *     or a read bus timeout error			 */			/* If the bits in the dser are set its a CQBIC			 * reported problem.			 */			if (isr & ISR_CERR) 			{				kn220_qbus_memerr(ep);			} else {					/* A memory controller reported				 * problem.  Trap is caused on multi bit errors				 * on read or bus timeouts.				 * Look for Multi bit ECC errors.  If it is a multi bit error				 * bits (HME or LME) will be zero in the memory error syndrome				 * reister.				 */				if( (( esr[0].esr_mesr & KN220_LME ) == 0) ||					(( esr[0].esr_mesr & KN220_HME) == 0)) 				{					/* Multi bit ECC error */					kn220logmempkt(EL_PRISEVERE, ep, pa);					kn220consprint(MEMPKT, ep, pa, 0);					panic("memory read error in kernel mode");				}				/* To get here it was not a parity error				 * so it must have been a memory timeout.				 */				kn220logesrpkt(ep, esr, EL_PRISEVERE);				kn220consprint(ESRPKT, ep, pa, 0);				panic("read bus timeout");			}			break;		case EXC_CPU:		/* CoProcessor Unusable */			kn220logesrpkt(ep, esr, EL_PRISEVERE);			kn220consprint(ESRPKT, ep, 0, 0);			panic("coprocessor unusable");			break;		case EXC_RADE:		/* Read Address Error	*/		case EXC_WADE:		/* Write Address Error 	*/			kn220logesrpkt(ep, esr, EL_PRISEVERE);			kn220consprint(ESRPKT, ep, 0, 0);			panic("unaligned access");			break;		case SEXC_SEGV: /* This can be because we were in TLBMIS code				 * and to a SEGV.  That causes us to get to this				 * routine with a SEXC_SEGV and I want a better				 * panic message than "trap".				 */			kn220logesrpkt(ep, esr, EL_PRISEVERE);			kn220consprint(ESRPKT, ep, 0, 0);			panic("segmentation violation");			break;		default:			kn220logesrpkt(ep, esr, EL_PRISEVERE);			kn220consprint(ESRPKT, ep, 0, 0);			panic("trap");			break;		}	}	/*	 * Default user-mode action is to terminate the process	 */	*signo = SIGBUS;	return(0);}#define KN220_LOG_ESRPKT(elrp, cause, epc, sr, badva, sp)		\	elrp->el_body.elesr.elesr.el_esr5500.esr_cause  = cause;	\	elrp->el_body.elesr.elesr.el_esr5500.esr_epc    = epc;		\	elrp->el_body.elesr.elesr.el_esr5500.esr_status = sr;		\	elrp->el_body.elesr.elesr.el_esr5500.esr_badva  = badva;	\	elrp->el_body.elesr.elesr.el_esr5500.esr_sp 	= sp;		\/* *	Copy the information from the error registers to the  *	the error log buffer area. */kn220copy_esrinfo(elrp, esrp)struct el_rec *elrp;struct esr *esrp;	/* pointer to esrs */{	elrp->el_body.elesr.elesr.el_esr5500.esr_dser  = esrp->esr_dser;	elrp->el_body.elesr.elesr.el_esr5500.esr_qbear = esrp->esr_qbear;	elrp->el_body.elesr.elesr.el_esr5500.esr_dear  = esrp->esr_dear;	elrp->el_body.elesr.elesr.el_esr5500.esr_cbtcr = esrp->esr_cbtcr;	elrp->el_body.elesr.elesr.el_esr5500.esr_isr   = esrp->esr_isr;	elrp->el_body.elesr.elesr.el_esr5500.esr_mser  = esrp->esr_mesr;	elrp->el_body.elesr.elesr.el_esr5500.esr_mear  = esrp->esr_mear;	elrp->el_body.elesr.elesr.el_esr5500.esr_ipcr  = esrp->esr_ipcr;}/* * Log Error & Status Registers to the error log buffer. */kn220logesrpkt(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_5500,EL_UNDEF,EL_UNDEF,EL_UNDEF,EL_UNDEF);		KN220_LOG_ESRPKT(elrp, ep[EF_CAUSE], ep[EF_EPC], ep[EF_SR], ep[EF_BADVADDR],			    ep[EF_SP]);		kn220copy_esrinfo(elrp, ptr);		EVALID(elrp);	}}/* * kn220_log_errinfo: *	Exported through the cpusw and used to log error information to  *	the error log buffer. */kn220_log_errinfo(p)struct kn220log_errinfo_t *p;{	struct el_rec *elrp;	switch (p->pkt_type) {		case ESRPKT:		elrp = ealloc(sizeof(struct el_esr), EL_PRISEVERE);		if (elrp != NULL) {			LSUBID(elrp,ELCT_ESR,ELESR_5500,EL_UNDEF,EL_UNDEF,EL_UNDEF,EL_UNDEF);			KN220_LOG_ESRPKT(elrp, p->cause, p->epc, p->sr, p->badvaddr, p->sp);			kn220copy_esrinfo(elrp, (struct esr *) &(p->logesr));			EVALID(elrp);		}		break;	default:		cprintf("bad pkt type");		return;	}}		/* * 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. */kn220logmempkt(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;	int slot, sum_addr;	/* compute which memory board the pa is on.	 * Walk through each of the four slots and find which slot the PA	 * is on.  Memory_slot[slot] has the size of the memory board so	 * we loop through each until the pa boundry is found.	 */	slot=0;	for(; slot < 4; slot++)	{		if(memory_slot[slot] != 0)		{			if((sum_addr + memory_slot[slot]) < pa)				sum_addr = sum_addr + memory_slot[slot];			else			{				/* the sum of the address exceeds the pa so				 * we have found the board!				 */				break;			}		} else			/* An empty slot so we have reached the end of memory			 * and can stop now.			 */			break;	}	slot++;	/* because we want to start counting from 1 when we log it */	/* Allocate an error log packet.	 */	elrp = ealloc(EL_MEMSIZE, priority);	if (elrp != NULL) {		LSUBID(elrp,ELCT_MEM,EL_UNDEF,ELMCNTR_5500,EL_UNDEF,EL_UNDEF,EL_UNDEF);		mrp = &elrp->el_body.elmem;		mrp->elmem_cnt = 1;		mrp->elmemerr.cntl = 1;		mrp->elmemerr.numerr = 1;		/* Check for MULTI bit errors in both the 		 * High and Low ECC checks.  Bits are zero		 * if an error was detected.		 * Address of location in error is in esr_mear		 */		if( ((esr[0].esr_mesr & KN220_HME) == 0)		      || ((esr[0].esr_mesr & KN220_LME) == 0))			mrp->elmemerr.type = ELMETYP_RDS;		else 		    /* Check for SINGLE bit errors in both the 		     * High and Low ECC checks.  Bits are zero		     * if an error was detected.		     * Address of location in error is in esr_mear		     */		    if( ((esr[0].esr_mesr & KN220_HER) == 0)		      || ((esr[0].esr_mesr & KN220_LER) == 0))				mrp->elmemerr.type = ELMETYP_CRD;		    else			/* Check for PARITY error			 */			if (esr[0].esr_dser & DSER_PARITY){				mrp->elmemerr.type = ELMETYP_PAR;			}		        else				    /* Check if its a Non-existant memory access.			     */			    if (esr[0].esr_dser & DSER_NXM){			    	mrp->elmemerr.type = ELMETYP_NXM;			    }		    	    else			    		    mrp->elmemerr.type = 0;		mrp->elmemerr.regs[0] = esr[0].esr_mesr;		mrp->elmemerr.regs[1] = pa;		mrp->elmemerr.regs[2] = ep[EF_EPC];		mrp->elmemerr.regs[3] = ep[EF_BADVADDR];		mrp->elmemerr.regs[4] = slot;		/* We are done...validate the error log packet.  This puts		 * it back on the available list and closes the error log		 * task.		 */		EVALID(elrp);	}}/* * Print error packet to the console. * This is only done when we are about to panic on the error. * Uses kn220_print_consinfo to do the actual printing. * */kn220consprint(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 */{	struct kn220consinfo_t p;	p.pkt_type 	= pkt;	p.pkt.cause	= ep[EF_CAUSE];	p.pkt.epc	= ep[EF_EPC];	p.pkt.sr	= ep[EF_SR];	p.pkt.badvaddr	= ep[EF_BADVADDR];	p.pkt.pa	= pa;	p.qbus		= qbus;	kn220_print_consinfo(&p);}/* *	This routine is similar to kn220consprint(). *	This is exported through the cpusw structure.  * * 	N.B.: side-effect. *	If console is a graphics device, printstate is changed   *	to force kernel printfs directly to the screen. */kn220_print_consinfo(p)struct kn220consinfo_t *p;{	/*	 * If console is a graphics device,	 * force printf messages directly to screen.	 * Note: DS_5500 currently does not support qdss, 	 * but just in case...	 */	printstate |= PANICPRINT;	switch (p->pkt_type) {	case ESRPKT:		cprintf("\nException condition\n");		break;	case MEMPKT:		cprintf("\nMemory Error\n");		break;	default:		cprintf("bad consprint\n");		return;	}	cprintf("\tCause reg\t= 0x%x\n", p->pkt.cause);	cprintf("\tException PC\t= 0x%x\n", p->pkt.epc);	cprintf("\tStatus reg\t= 0x%x\n", p->pkt.sr);	cprintf("\tBad virt addr\t= 0x%x\n", p->pkt.badvaddr);	if (p->pkt.pa) {		if (p->qbus) {			cprintf("\tQ22 Bus physical address of error: 0x%x\n",			p->pkt.pa);		}		else {			cprintf("\tPhysical address of error: 0x%x\n",p->pkt.pa);		}	}	return;}/* * Log memory errors in kernel buffer * We get memory interupts for ECC errors on writes * but single bit errors; data is fixed which makes single bit errors * generated informational only. */kn220memerr(ep)register u_int *ep;	/* exception frame ptr 				*/{	register struct proc *p;	/* ptr to current proc struct 	*/	u_long	dser;	u_long	pa;	/* Physical address 				*/	int	isr;	/* Content of ISR 				*/	int     i;	/* counter for Single bit array scan 		*/        struct kn220consinfo_t *pcons;    /* pointer to console info */        struct kn220log_errinfo_t *plog;  /* pointer to log info */	/* Read content of Interrupt Status Register */	isr = *(int *)ISR;	/*	 * Log DMA system error register, error address register, ..etc.	 */	esr[0].esr_dser  = * (u_long *)KN220DSER;  /* DMA Sys error register*/	esr[0].esr_qbear = * (u_long *)KN220QBEAR; /* Qbus error addr reg.  */	esr[0].esr_dear  = * (u_long *)KN220DEAR;  /* DMA error addr reg.   */	esr[0].esr_cbtcr = * (u_long *)KN220CBTCR; /* CDAL Bus Timeout	    */	esr[0].esr_mesr  = * (u_long *)KN220MESR;  /* Memory Error Syndrom Reg.*/	esr[0].esr_mear  = * (u_long *)KN220MEAR;  /* Memory Error Address Reg.*/	esr[0].esr_isr   = isr;			   /* Interupt Status Reg.  */						   /* Clear the error bits  */	/* Compute the physical address. 	 * pa that is load by the R3000 in the execption frame will	 * be the default address to use.	 */	pa = vatophys(ep[EF_BADVADDR]);	/* If the problem was a memeory error problem the address will be	 * found in the MEAR register.	 * 	 * Check the high two bit of the MEAR; if one and only one	 * of them is set the DESR is invalid but the  MESR is valid.	 * Set the mesr to a valid value to stop us from processing	 * bad data.	 *	 * bit 28 & 29 value meanings	 *	00	memory space	 *	11	memory space	 *	01	I/O space	 *	10	I/O space	 *	 * Also, if bit 1 is set, the address in MEAR is valid.  This bit is	 * needed by the hardware to indicate what kind of cycle it was	 * processing ... if the contents of the reg. is OK or not.	 */	if ((esr[0].esr_mear & GOOD_ADDR) == 0)		/* DMA Cycle 	*/	{		pa = esr[0].esr_mear;		if((esr[0].esr_mear & KN220_NXM) == 1)

⌨️ 快捷键说明

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