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

📄 kn220.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
		{			esr[0].esr_mesr = 0xffffffff;		}	} else {					/* R3000 Cycle	*/		pa = esr[0].esr_mear;		if((((esr[0].esr_mear & BIT29) == 1)&&((esr[0].esr_mear & BIT28) == 0))		|| (((esr[0].esr_mear & BIT29) == 0)&&((esr[0].esr_mear & BIT28) == 1)))		{					/* I/O Cycle	*/			esr[0].esr_mesr = 0xffffffff; 	/* Zap mesr to make ECC Ok*/		} else {				/* Memory Cycle	*/			if((esr[0].esr_mear & KN220_NXM) == 1)				esr[0].esr_mesr = 0xffffffff;		}	}	/* Its a Kernel space error	 *	 * Look in the Memory Error Syndrome Register and if the error	 * is a single bit error (LER or HER bit set to zero) then	 * we will not panic.	 */	if( (( esr[0].esr_mesr & KN220_LER ) == 0) ||		(( esr[0].esr_mesr & KN220_HER) == 0)) 	{		/* Single bit error case-		 * Look in the Sbit_error array to see if the		 * error has hapened in the last 15 min.  If it		 * has the address will be in here and we 		 * will not log the error.		 */		for (i=0;i < SBIT_SIZE;i++)		{			/* Return here because it was only a single bit			 * memory error and we don't want to panic the system.			 * But first check for multri bit first just 			 * in case both single and multi were 			 * set (no a valid case but who knows)			 */			if(Sbit_error[i] == esr[0].esr_mear)				if( (( esr[0].esr_mesr & KN220_LME ) == 1) &&				(( esr[0].esr_mesr & KN220_HME) == 1)) 					return;		}		/* The address is not there so load it and go on		 * to log the error.		 */		for (i=0;i < SBIT_SIZE;i++)		{			if ((Sbit_error[i] != 0) &&				(i != SBIT_SIZE))				 continue;			if(i == (SBIT_SIZE - 1))				break;			Sbit_error[i] = esr[0].esr_mear;			kn220logmempkt(EL_PRISEVERE, ep, pa);		}		/* Return here because it was only a single bit		 * memory error and we don't want to panic the system.		 * But first check for multri bit first just 		 * in case both single and multi were 		 * set (no a valid case but who knows)		 */		if( (( esr[0].esr_mesr & KN220_LME ) == 1) &&			(( esr[0].esr_mesr & KN220_HME) == 1)) 				return;	}	/* 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 error */		kn220logesrpkt(ep, esr, EL_PRISEVERE);		kn220consprint(ESRPKT, ep, pa, 0);		panic("Memory multi bit parity error");	}	/*	 * if the low bit in the address is high its a NXM	 */	if( (esr[0].esr_mear & KN220_NXM) == 1 ){		/*		 * if we are still processing a previous interrupt		 * then simply crash. we don't queue these interrupts.		 */		if (CURRENT_CPUDATA->cpu_wto_event) {			kn220logesrpkt(ep, esr, EL_PRISEVERE);			kn220consprint(MEMPKT, ep, pa, 0);			panic("nonexistant memory access");		}		else {			/* 			 *	capture error information in kn220consinfo.			 *	softnet() interrupt will print this info			 *	if panicing on the console.			 */			pcons = &kn220consinfo;			pcons->pkt_type 	= ESRPKT;			pcons->qbus		= 0;			pcons->pkt.cause	= ep[EF_CAUSE];				pcons->pkt.epc		= ep[EF_EPC];			pcons->pkt.sr		= ep[EF_SR];				pcons->pkt.badvaddr 	= ep[EF_BADVADDR];			pcons->pkt.pa		= pa;			/* 			 *	capture log information in kn220log_errinfo.			 *	softnet() interrupt will log this info			 *	if panicing in the error log buffer.			 */			plog = &kn220log_errinfo;			plog->pkt_type		= ESRPKT;			plog->cause		= ep[EF_CAUSE];				plog->epc		= ep[EF_EPC];					plog->sr		= ep[EF_SR];			plog->badvaddr		= ep[EF_BADVADDR];			plog->sp		= ep[EF_SP];			plog->logesr.esr_dser	= esr[0].esr_dser;			plog->logesr.esr_qbear	= esr[0].esr_qbear;			plog->logesr.esr_dear	= esr[0].esr_dear;			plog->logesr.esr_cbtcr	= esr[0].esr_cbtcr;			plog->logesr.esr_isr	= esr[0].esr_isr;			plog->logesr.esr_ipcr	= esr[0].esr_ipcr;			plog->logesr.esr_mesr	= esr[0].esr_mesr;			plog->logesr.esr_mear	= esr[0].esr_mear;			CURRENT_CPUDATA->cpu_consinfo	    = (char *) &kn220consinfo;			CURRENT_CPUDATA->cpu_log_errinfo    = (char *) &kn220log_errinfo;			CURRENT_CPUDATA->cpu_wto_pfn        = btop(pa);			CURRENT_CPUDATA->cpu_wto_event 	    = 1;			setsoftnet();		}	}}/* Every 15 min. we want to "zap" the array that keeps track * of single bit ECC memory errors.  We do this so that a location * which generates a single bit error does not flood the error log * if it stays in memory and get hit many, many times.  This array * tries to limit the amount entries.  After this array is zeroed * any new single bit errors will get logged. */kn220_ZSbit(){	int i;	extern timeout();	extern int hz;	for (i=0;i < SBIT_SIZE;i++)	{		Sbit_error[i] = 0;	}	/* Reschedule this routine to run in 15 min.	 */	timeout(kn220_ZSbit,0,15*60*hz);}/* In the DS_5500 we need to write to a memory location * to clear memory interrupts.  This routine seems the best * way to do this? */int kn220badaddr(addr,len)caddr_t addr;int len;{	register int foo,s;		#ifdef lint	len=len;#endif lint	s = splextreme();	*(int *)ISR = 0;	foo = bbadaddr(addr,len);	*(int *)PHYS_TO_K1(CLEAR_MEM_INTR) = 0;	wbflush();	splx(s);	return(foo);}/* The CQBIC can generate a memory type error interrupts.  This routine checks * for the error and will crash the system.  This routine is called from interrupt * if and only if the ISR bit 1 is set.  Bit 1 of the ISR indicates a Qbus * posted memory error.  The nofault code must clear this bit. */kn220_qbus_memerr(ep)register u_int *ep;{	u_long pa;	int	isr;	/* Content of ISR 				*/	int 	dser;	/* Read content of Interrupt Status Register */	isr = *(int *)ISR;	*(int *)ISR = 0;			   /* Acknowledge all error */	wbflush();	/*	 * 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  */	*(u_long *)KN220DSER = 0xc0bd;	*(u_long *)KN220CBTCR = 0xc0000000 | esr[0].esr_cbtcr;	/* If the CQBIC reports nogrant or nxm then the address in 	 * the dear is valid	 */	if (isr & ISR_CERR) {		/* if the CQBIC reports a Q22 bus parity error OR bus time out the		 * Q22 bus the address is in the QBEAR (but left shift it 9).		 */		if( (esr[0].esr_dser & DSER_PARITY ) || 		  ( esr[0].esr_dser  & DSER_MEMTO ))			pa = esr[0].esr_qbear << 9;		if( (esr[0].esr_dser & DSER_NOGRNT ) || ( esr[0].esr_dser  & DSER_NXM ))			pa = esr[0].esr_dear << 9;		/* Log a error log packet */		kn220logmempkt(EL_PRISEVERE, ep, pa);		kn220consprint(MEMPKT, ep, pa, ITS_A_QBUS);		/*		 * Q22 bus write cycle timeout after 10uS,		 * or Q22 bus parity error.		 * QBEAR contains Qbus physical address.		 */		dser = esr[0].esr_dser;		if ( dser & DSER_PARITY ) 			panic("Q22 bus memory parity error");		if ( dser & DSER_MEMTO ) 			panic("Read bus timeout");		if ((dser & DSER_NXM)||(dser & DSER_MME)) {			/*			 * DMA transfer to non-existent main 			 * memory location.			*/			panic("DMA memory error");			}	       if (dser & DSER_NOGRNT) {			/*			 * Q22 Bus does not return a bus grant			 * within the 10ms of the Bus request for a CPU			 * read or write cycle.			 */			panic("Q22 Bus Grant Timeout");		}		/* Default case */		panic("Qbus Memory error");	/* END of CQBIC error code 	*/	}}kn220_battery_status(){	register int i, *memid;	int B1, B2;	int iopres;	/*	 * This routine is called by presto software	 * periodically. 	 *	 * See h/presto.h for comments on the data structures involved. 	 * 	 * For DS5500 the NVRAM battery is the primary	 * and the H3602 battery is the secondary.	 * Both batteries must be operational for normal Prestoserve	 * operation.	 *	 * Get the battery status for the primary on the fly, the console	 * gives me the secondary status as it was at boot time.	 */	memid =(int *) KN220MIDR;  	nvram_batteries0.nv_nbatteries = 2;	   /* two batteries */	nvram_batteries0.nv_minimum_ok = 2;	   /* both must be good */	nvram_batteries0.nv_primary_mandatory = 1; /* primary must be good */	nvram_batteries0.nv_test_retries = 3;	   /* call this routine 3 times						    * for each "test" */	ssc_ptr = (struct ssc_regs *)PHYS_TO_K1(DEFAULT_SSC_PHYS);	*memid = KN220BLOAD;		/* Get old state */	wbflush();	DELAY(kn220_battdelay);	iopres = *(int *)KN220IOPRES;	/* Read content of IOPRES */	B1 = iopres & KN220_BOK;	*memid = KN220JUMPER & KN220BLOAD;	/* Update state	*/	wbflush();	DELAY(kn220_battdelay);	iopres = *(int *)KN220IOPRES;	/* Read content of IOPRES */	B2 = iopres & KN220_BOK;  	nvram_batteries0.nv_status[0] = BATT_OK; /* assume OK */	*memid = 0;			/* Turn it off battery load*/	wbflush();	if (B1 == B2)			/* check for NVRAM battery low */	{		if (B1 != KN220_BOK)			/* "DS5500 NVRAM battery backup disabled" */			/* battery will not back RAM */		  	nvram_batteries0.nv_status[0] = BATT_NONE; 	} else {		/* "DS5500 NVRAM lost battery backup" */		/* low battery */  		nvram_batteries0.nv_status[0] = BATT_ENABLED;	}	/* Bit 31 high is low H3602 	 * battery, zero is battery OK	 */  	if (ssc_ptr->ssc_ssccr & 0x80000000)		  	nvram_batteries0.nv_status[1] = BATT_ENABLED;	else  		nvram_batteries0.nv_status[1] = BATT_OK;	return(0);}int kn220_fakestatus = 0; /* set to 1 for old, bad ROMs */intkn220_nvram_status(){	int i;	/* Status of NVRAM diagnostics 	* NVRAM_BAD	0	 either read/write or read-only diagnostics	*			 	run unsuccessfully 	* NVRAM_RDWR	1	 read/write diagnostics run successfully 	* NVRAM_RDONLY	2	 read-only diagnostics run successfully 	* If the reply is NVRAM_RDONLY, then presto will attempt recovery, but	* not allow normal operation. If the reply is NVRAM_BAD, presto will	* offer the console operator a "halt or continue" choice.	*	*/	if (kn220_fakestatus)		return(NVRAM_RDWR); /* HACK UNTIL THE CONSOLE ROMS ARE UP TO DATE */	else {		i = NVRAMSTATUS;		return (i);	}}#include "../h/socket.h"#include "../net/net/if.h"/* * Get the hardware E_net address for on-board ne0 and use it * to build a poor man's version of a unique processor ID. */u_intkn220_machineid(){	register struct ifnet *ifp = ifnet;	struct ifdevea ifr;	u_int i = 0;	int error;	if (ifnet == NULL) {		printf("kn220: ifnet NULL\n");		return (i);	}	while (ifp != NULL) {		if (ifp->if_name[0] == 'n' && ifp->if_name[1] == 'e' &&		    ifp->if_unit == 0) {	/* found ne0 */			error = (*ifp->if_ioctl)(ifp, SIOCRPHYSADDR, &ifr);			if (error)				return (i);			i = (u_int)ifr.default_pa[2];			i = i << 8;			i += (u_int)ifr.default_pa[3];			i = i << 8;			i += (u_int)ifr.default_pa[4];			i = i << 8;			i += (u_int)ifr.default_pa[5];			return (i);		}		ifp = ifp->if_next;	}	return (i);}

⌨️ 快捷键说明

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