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

📄 ka420.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
					cache_state &= ~(CVAX_SEN2);					/*					 * Set I & D stream for 2nd level					 * cache operation.					 */					mtpr (CADR, cache_state);					printf("1st Level Cache Completely DISABLED by software on mchk\n");					cache_errcnt.cache_last = 0;					time = 0;					break;				case SET_NONE:					recover = 0;	/* don't recover */					ka420consprint(2,type,mcf);					printf("Got a 1st Level Cache Parity Error with the 1st Level Cache Disabled!\n");					break;				default:					cache_state = (CVAX_CEND | CVAX_CENI | CVAX_SEN1 | CVAX_SEN2);					mtpr (CADR, cache_state);					break;				}			} else {				/*				 * Fewer than 3 errs in 1 time period,				 * reenable whichever cache sets were on.				 */				switch (cache_state & CADR_SETMASK) {				case SET_BOTH:					mtpr (CADR, cache_state);					mprintf("1st Level Cache, Re-enabled by software on mchk\n");					break;				case SET_ONE:					mtpr (CADR, cache_state);					mprintf("1st Level Cache, Set 1 Re-enabled, Set 2 left Disabled by software on mchk\n");					break;				case SET_TWO:					mtpr (CADR, cache_state);					mprintf("1st Level Cache, Set 2 Re-enabled, Set 1 left Disabled by software on mchk\n");					break;				case SET_NONE:					recover = 0;	/* don't recover */					ka420consprint(2,type,mcf);					printf("Got a 1st Level Cache Parity Error with the 1st Level Cache Disabled!\n");					break;				default:					cache_state = (CVAX_CEND | CVAX_CENI | CVAX_SEN1 | CVAX_SEN2);					mtpr (CADR, cache_state);					mprintf("1st Level Cache, Re-enabled by software on mchk\n");					break;				}			}			/*			 * Since we can recover update the times,			 */			cache_errcnt.cache_prev = cache_errcnt.cache_last;			cache_errcnt.cache_last = time;		} else {			/*			 * Undefined Machine check 0x80, 0x81.			 * Log the mcheck & ESR Packet.			 * We can't recover so print errors on the console.		 	 * todo: if in user-mode only crash the user process.			 */			logmck((int *)cmcf, ELMCKT_CVAX,  cpunum, recover);			mprintf("No primary error flag - unspecified error type\n");			ka420logesrpkt(recover);			ka420consprint(2,type,mcf);			cprintf("No primary error flag - unspecified error type\n");			ka420consprint(3,0,0);		}		break;	case 0x82:	case 0x83:		/*		 *   Re-enable (after flushing) the 2nd level cache if cache		 *   was enabled before we entered mcheck (to log it in the		 *   state it was in when mcheck occured).		 */		if (cache2_state) {			nb_regs->nb_cacr |= CACR_CPE;			for (i=0; i<CVS_CACHE_SIZE; i++)				cdp->nb_cvscache[i] = (u_long)0;			nb_regs->nb_cacr |= CACR_CEN;		}		/*		 * We can't recover so print errors on the console.		 * Last, clear the error bits.		 */		logmck((int *)cmcf, ELMCKT_CVAX,  cpunum, recover);		ka420logesrpkt(recover);		ka420consprint(2,type,mcf);		ka420consprint(3,0,0);		break;	default:		/*		 *   Re-enable (after flushing) the 2nd level cache if cache		 *   was enabled before we entered mcheck (this is so we		 *   log it in the state it was in when mcheck occured).		 */		if (cache2_state) {			nb_regs->nb_cacr |= CACR_CPE;			for (i=0; i<CVS_CACHE_SIZE; i++)				cdp->nb_cvscache[i] = (u_long)0;			nb_regs->nb_cacr |= CACR_CEN;		}		/*		 * Unrecognized mcheck: these are non-recoverable.		 * Log the mcheck & ESR packet.		 * Also print to the console.		 */		logmck((int *)cmcf, ELMCKT_CVAX,  cpunum, recover);		ka420logesrpkt(recover);		type = 0;		ka420consprint(2,type,mcf);		ka420consprint(3,0,0);		break;	}	if (!recover)		panic ("ka420 mchk");	ka420_mchkprog = 0;	return(0);}/* * Get the Physical Addr where the memory parity error occured so we can log it. * * For mcheck 0x80, virtual (+4) is given in mcheck frame, convert to physical. * For mcheck 0x81, physical (+4) is given in mcheck frame. * * The macro to determine if an address is in system space may appear in *     vmmac.h in a future version of ULTRIX. */#define SYSADDR(v) (v & 0x80000000)ka420getpa(mcf, type)	register struct mcCVAXSTARframe *mcf;	int type;{	struct pte *pte;	/* PTE ptr to obtain physical addr */	int pa;			/* the physical address where mem err occured */	if (type == 0x80) {		if (SYSADDR (mcf->mc1_vap -4)) {			pte = &(Sysmap[btop((int)(mcf->mc1_vap -4) & ~VA_SYS)]);		} else {			/*			 * user space address			 */			pte = vtopte(u.u_procp, btop(mcf->mc1_vap -4));		}		/*		 * Validity check the pte before picking up the page address		 */		if ((!SYSADDR((int)pte)) || (!pte->pg_v))			pa = -1;		else			pa = (int)ptob(pte->pg_pfnum);	} else		pa = mcf->mc1_vap -4;	return (pa);}/* * Log 2nd level cache tag parity error. * Log packet 3 (error status registers). * * Traps through SCB vector 54: correctable memory errors. * * These errors are recoverable. */ka420crderr(){	register struct nb_regs *nb_regs = (struct nb_regs *)nexus;	register struct nb6_regs *cdp = (struct nb6_regs *)cvscachemem;	register int i;	int recover;	/* set to 1 if we can recover from this error */	u_int time;	recover = 0;	time = ka420readtodr();	if (nb_regs->nb_cacr & CACR_CPE) {		/*		 * Cache Tag Parity error (Cache automatically disabled):		 * Will cause a cache miss so a memory read will be done		 *   after we REI from the interrupt.		 * Action depends on prior 2nd level cache state:		 *    was on:  Recover		 *    was off: Panic		 */		if (cache2_state) {			/*			 * Second Level Cache was on:			 * Action depends on number of errors:			 *    3 within 1 time period:   Leave Cache disabled			 *    < 3 within 1 time period: Flush Cache & re-enable			 */			mprintf("Tag parity interrupt: 2nd level cache tag parity\n");			recover = 1;			if (time - tag_errcnt.tag_prev <= TIME_THRESH_C2) {				/*				 * Cache was on, 3 errs in 1 time period				 */				printf("2nd Level Cache DISABLED by software on tag parity\n");				ka420logesrpkt(recover);				nb_regs->nb_cacr |= CACR_CPE;				cache2_state = 0;				tag_errcnt.tag_last = 0;				time = 0;			} else {				/*				 * Cache was on, < 3 errs in 1 time period				 * Flush and re-enable cache				 */				ka420logesrpkt(recover);				nb_regs->nb_cacr |= CACR_CPE;				for (i=0; i<CVS_CACHE_SIZE; i++)					cdp->nb_cvscache[i] = (u_long)0;				nb_regs->nb_cacr |= CACR_CEN;				mprintf("2nd Level Cache re-enabled by software\n");			}			tag_errcnt.tag_prev = tag_errcnt.tag_last;			tag_errcnt.tag_last = time;		} else {			/*			 * Cache was off: no recover.			 * NOTE: consprint() sets up display for cprintf here!			 */			ka420logesrpkt(recover);			ka420consprint(3,0,0);			printf("2nd Level Cache Tag Parity Error occured with Cache Disabled!\n");			nb_regs->nb_cacr |= CACR_CPE;			panic("ka420 Cache Tag Parity error");		}	} else {		/*		 * Catch-all: vector 54 interrupt without CACR-CPE bit set.		 * Dismiss the error and REI.		 */		mprintf("Tag parity interrupt without tag parity bit\n");	}	return(0);}/* * 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, ioctl is done to force kernel printfs *	directly to the screen. */ka420consprint(pkt, type, mcf)	int pkt;	/* error pkt desired:	2 = mcheck frame			   			3 = error status registers			   			4 = memory error packet */	int type;				/* machine check type */	register struct mcCVAXSTARframe *mcf;	/* mcheck frame pointer */{	register struct nb_regs *nb_regs = (struct nb_regs *)nexus;	register int i;	int ws_disp;	/*	 * If console is a graphics device,	 * force printf messages directly to screen.	 */	if (ws_display_type) {	    ws_disp = ws_display_type << 8;	    (*cdevsw[ws_display_type].d_ioctl)(ws_disp, QD_KERN_UNLOOP, 0, 0);	}	switch (pkt) {	case 2:		cprintf("\nmachine check %x: ", type);		/*		 * Types are disjoint. Have to convert some to linear range.		 */		if (type >= 0x80)			type = type - 0x80 + MCcVAXSTARDISJ;		cprintf("%s\n", mcCVAXSTAR[type]);		cprintf("\tcode\t= %x\n", mcf->mc1_summary);		cprintf("\tmost recent virtual addr\t=%x\n", mcf->mc1_vap);		cprintf("\tinternal state 1\t=%x\n", mcf->mc1_internal_state1);		cprintf("\tinternal state 2\t=%x\n", mcf->mc1_internal_state2);		cprintf("\tpc\t= %x\n", mcf->mc1_pc);		cprintf("\tpsl\t= %x\n\n", mcf->mc1_psl);		break;	case 3:		cprintf("\tcacr\t= %x\n", nb_regs->nb_cacr);		cprintf("\tcadr\t= %x\n", mfpr(CADR));		cprintf("\tmser\t= %x\n", mfpr(MSER));		break;	case 4:		cprintf("\tcacr\t= %x\n", nb_regs->nb_cacr);		cprintf("\tcadr\t= %x\n", mfpr(CADR));		cprintf("\tmser\t= %x\n", mfpr(MSER));		cprintf("\tphys addr\t= 0x%x\n", ka420getpa(mcf, type));		break;	default:		cprintf("bogus ka420consprint\n");		break;	}}/* * Log Error & Status Registers */ka420logesrpkt(priority)	int priority;		/* for pkt priority */{	struct el_rec *elrp;	register struct nb_regs *nb_regs = (struct nb_regs *)nexus;	switch (priority) {	case 0:	/* non-recoverable mchecks */		priority = EL_PRISEVERE;		break;	case 1:	/* recoverable mchecks */		priority = EL_PRIHIGH;		break;	case 2:	/* recoverable CRDs (cache tag parity errors) */		priority = EL_PRILOW;		break;	}	elrp = ealloc(sizeof(struct el_esr420), priority);	if (elrp != NULL) {		LSUBID(elrp,ELCT_ESR420,EL_UNDEF,EL_UNDEF,EL_UNDEF,EL_UNDEF,EL_UNDEF);		elrp->el_body.elesr420.esr_cacr = nb_regs->nb_cacr;		elrp->el_body.elesr420.esr_cadr = mfpr(CADR);		elrp->el_body.elesr420.esr_mser = mfpr(MSER);		EVALID(elrp);	}}/* * Log Error & Status Registers (and physical address where error occured) * as a memory error packet, so uerf can find it as a main memory error. */ka420logmempkt(recover, pa)	int recover;		/* for pkt priority */	int pa;			/* physical addr where memory err occured */{	struct el_rec *elrp;	register struct el_mem *mrp;	elrp = ealloc(EL_MEMSIZE,recover ? EL_PRIHIGH : EL_PRISEVERE);	if (elrp != NULL) {		LSUBID(elrp,ELCT_MEM,EL_UNDEF,ELMCNTR_420,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] = ((struct nb_regs *)nexus)->nb_cacr;		mrp->elmemerr.regs[1] = mfpr(CADR);		mrp->elmemerr.regs[2] = mfpr(MSER) ;		mrp->elmemerr.regs[3] = pa;		EVALID(elrp);	}}ka420readtodr(){	u_int s,todr;	struct tm tm;	register struct nb_regs *nb_regs = (struct nb_regs *)nexus;	/*	 * All CVAXstar toy clock registers (including NVR)	 * read/write bits 2 - 9 instead of 0 - 7.	 */	/*	 * Copy the toy register contents into tm so that we can	 * work with. The toy must be completely read in 2.5 millisecs.	 *	 *	 * Wait for update in progress to be done.	 */	while( nb_regs->nb_toycsra & (QBT_UIP << 2) )			;	s = spl7();	tm.tm_sec = ((nb_regs->nb_toysecs >> 2) & 0xff);	tm.tm_min = ((nb_regs->nb_toymins >> 2) & 0xff);	tm.tm_hour = ((nb_regs->nb_toyhours >> 2) & 0xff);	tm.tm_mday = ((nb_regs->nb_toyday >> 2) & 0xff);	tm.tm_mon = ((nb_regs->nb_toymonth >> 2) & 0xff);	tm.tm_year = ((nb_regs->nb_toyyear >> 2) & 0xff);	splx( s );	todr = toyread_convert(tm);	return(todr);}ka420writetodr(yrtime)u_int yrtime;{	struct tm xtime;	int s;	register struct nb_regs *nb_regs = (struct nb_regs *)nexus;	toywrite_convert(&xtime,yrtime);	nb_regs->nb_toycsrb = (QBT_SETUP << 2);	s = spl7();	nb_regs->nb_toysecs = (xtime.tm_sec << 2);	nb_regs->nb_toymins = (xtime.tm_min << 2);	nb_regs->nb_toyhours = (xtime.tm_hour << 2);	nb_regs->nb_toyday = (xtime.tm_mday << 2);	nb_regs->nb_toymonth = (xtime.tm_mon << 2);	nb_regs->nb_toyyear = (xtime.tm_year << 2);	/* 	 * Start the clock again. 	 */	nb_regs->nb_toycsra = (QBT_SETA << 2);	nb_regs->nb_toycsrb = (QBT_SETB << 2);	splx( s );}

⌨️ 快捷键说明

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