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

📄 kn220.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
		 * needs to be before the ib_config_.... calls which load the		 * scb; don't want unifind to stomp on the entries after they 		 * are set.		 */		unifind(qb_ptr,KN220QBUSREG,qmem,			0x14000000,512*8192,0x10000000,QMEMmap,0,0,0);	} 	/*	 * Configure all the devices.  I/O devices include	 * an on-board Ethernet interface, an on-board DSSI interface, 	 * and a Q22 Bus.	 *	 * On board devices sit on a virtual bus called the "ibus".	 */	config_set_alive("ibus",0,0,0);	/* Configure on-board ethernet */	ib_config_dev(PHYS_TO_K1(KN220SGEC_ADDR), 		KN220SGEC_ADDR,0,"ne",(int)scb+SGEC_OFFSET);	/* Initialize NVRAM pseudo-driver */	/* 3rd arg is: mapped?; 4th arg is cached? */	/* Use un-mapped, cached NVRAM */	if (kn220_usenvram)		presto_init(NVRAM_ADDR, NVRAM_SIZE, kn220_nvram_mapped,			    kn220_cache_nvram, kn220_machineid());	/* We need a test nNASC but nNASC is not set up in autoconf_data.c yet * NEED FIXING OR fix the alive bit in the SCSI driver. */	/* Configure on-board SCSI */	ib_config_cont(PHYS_TO_K1(KN220_53C94_REG_ADDR),		KN220_53C94_REG_ADDR,0,"asc",(int)scb+SCSI_OFFSET);	/* Configure on-board DSSI */	if (nNMSI) {		extern int (*msiintv[])();		scb[MSI_OFFSET/4] = msiintv[nummsi];	/* Stuff the SCB */		if (msi_probe(nummsi,PHYS_TO_K1(KN220MSIREG_ADDR),			PHYS_TO_K1(KN220SIIBUF_ADDR))) {			config_set_alive("msi",0,0,0);			printf("msi%d\n",nummsi);			}	}	/* Now is a good time to check the VME bus 	 * to see if it there.  If we find the VME, all	 * its devices should be pulled in now.	 *	 * Read content of IOPRES bit to see if a VME is present.	 */	vmepres = *(int *)KN220IOPRES;		if ((vmepres) & KN220_VMEP)	{		/* We have one slot that can have a VME or a FDDI cadr		 * but not both.		 */		if(BADADDR(PHYS_TO_K1(VME_BASE_ADDR),4)){			/* Search adapter table to see if VME is configured.			 * Compare must be hardwired to "vba" because there			 * is no configuration database for the RIO like			 * there is for the TURBOchannel.			 * If the VME adapter is configured then call the			 * configuration routine.			 * 			 */		  found = 0;		  for (i = 0; config_adpt[i].p_name != NULL; i++) {		    if ((!(strcmp ("vba",  config_adpt[i].c_name))) &&			(config_adpt[i].c_type == 'A')) {		      xviaconf(PHYS_TO_K1(VME_BASE_ADDR), 			   VME_BASE_ADDR,			   0,			   config_adpt[i].c_num,			   0);		      found = 1;		      break;		    }		  }		  if(!found)		    printf("VME not configured\n");		} else		if(BADADDR(PHYS_TO_K1(FDDI_BASE_ADDR),4)){			/* Call FDDI config routine 			 * when we have one.  For now we will do a print			 * statement that we found one?			 */			printf("FDDI\n");		}	} 	/* Now we will work on the Configure of the Q22 bus.	 * We need to find all devices that are in the config	 * file and that are on the BUS.	 */	/* Clear boot flag	 */	cold = 0;	/* Startup the code that clears the Single Bit ECC error	 * log array every 15 min.	 */	timeout(kn220_ZSbit,0,15*60*hz);	return(0);}/* * Initialization routine for kn220 processor (MIPSFAIR2). */kn220init(){	extern int c0vec_tblsize;	extern int (*c0vec_tbl[])();	extern int iplmask[];	extern int splm[];	extern int hz;	extern int tick;	extern int tickadj;	extern struct cpusw *cpup;	 /* Points to unibus adaptor regs	 */	qb_ptr = (struct qbm_regs *)(PHYS_TO_K1(KN220QBUSREG));	/*	 * bcopy()'s  must be done very early and must	 * be done before any interrupt is allowed.	 */	/* Initialize the interrupt dispatch table c0vec_tbl.	 */	bcopy((int *)kn220intr_vec, c0vec_tbl, c0vec_tblsize);	/* Initialize the spl table for the system we are running on.	 */	bcopy(kn220iplmask, iplmask, IPLSIZE * sizeof(int));	/* Initialize the interrupt masks for the system we are running on.	 */	bcopy(kn220splm, splm, (SPLMSIZE) * sizeof(int));	/* Initialize the spl dispatch table and the intr dispatch routine */	spl_init();	/* Change over from console to kernel trap handling; this	 * is done by changing the BEV bit in the Status Register.	 */	clear_bev();	/*	 * Set up the system specific value for "hz", the number of clock	 * interrupts per second; and corresponding tick and tickadj values.	 */	hz	= cpup->HZ;	tick	= 1000000 / hz;	tickadj = 240000 / (60 * hz);	return (0);}/* * Routine to start the 10mS hardclock running. * This is simply to start up the 10mS interval timer so * that it interrupts every 10mS.  The interval timer * on KN220 interrupts the R3000 cpu at hardware line 2 (0 being * lowest priority, 5 being highest).  When the interrupt handler * reads the vector, the interval timer returns a vector of 0xc0. */kn220startrtclock(){int *tcsr;	tcsr	= (int *)TCSR;	*tcsr	= TCSR_IE;	return(0);}/* * Routine to stop the 10mS hardclock from interrupting. */kn220stopclocks(){int *tcsr;	tcsr	= (int *)TCSR;	*tcsr	= 0;	return(0);}/* * The MIPSFAIR2 special register in physical address 0x10084000 * can be read to determine which error condition occurred.  Format * of ISR: *	bit<3> set if halt requset is posted, *	bit<2> set if powerfail, *	bit<1> set if CQBIC posts a memory error. *	bit<0> Always reads as 1. * * The ISR must have the proper bit cleared to enable subsequent interrupts. * A halt condition is received.  This is an interrupt * handler. * */kn220haltintr(ep)int *ep;{	prom_halt(ep);}/* *	1. Memory error by CQBIC or MEM_CTL. * * * Note that multiple bits can be set.  For now, arbitrarily handle * the error with the following priority (from high to low): *	CQBIC & memory error. * * Parameter: *	ep		Pointer to exception frame. * */kn220memintr(ep)int	*ep;{	int	s;	/* To clear the memory interrupt we need to write to	 * locoation 1610005c.  The logic on what to do based	 * on the kind of error is in the general memory error	 * handler.	 */	*(int *)PHYS_TO_K1(CLEAR_MEM_INTR) = 0;	*(int *)ISR = 0;	/* Acknowledge all error 	*/	wbflush();	kn220memerr(ep);	/* Clear ISR after returning here */}/* * Pending powerfail, currently ULTRIX has no handling * strategy on VAX and MIPS.  Further, there is no restart * parameter block on MIPS.   * */kn220powerfail_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. */kn220hardintr2(ep)int *ep;{extern int (*(scb[]))();register int vrr;int	isr;	isr = *(int *)ISR;		/* Read content of ISR 		*/	if (isr & ISR_CERR) 		/* Test for CQBIC mem error	*/	{		kn220_qbus_memerr(ep);	}	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. */kn220hardintr1(ep)int *ep;{extern int (*(scb[]))();register int vrr;int	isr;	isr = *(int *)ISR;		/* Read content of ISR 		*/	if (isr & ISR_CERR) 		/* Test for CQBIC mem error	*/		kn220_qbus_memerr(ep);	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. */kn220hardintr0(ep)int *ep;{extern int (*(scb[]))();register int vrr;int	isr;				isr = *(int *)ISR;		/* Read content of ISR 		*/	if (isr & ISR_CERR) 		/* Test for CQBIC mem errors	*/		kn220_qbus_memerr(ep);	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. *  * A read to non-existent memory will generate an * exception which we need to handle.  A write to non-existent  * memory location will generate an interupt which we  * will need to handle in the interupt routine. */kn220trap_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 */{	unsigned long pa;		/* the physical addr of the error */		int epc;			/* the EPC of the error 	*/		int vaddr;			/* virt addr of error 		*/	register struct proc *p;	/* ptr to current proc struct 	*/	u_long	dser;	int i;	int	isr;			/* Content of ISR */	isr = *(int *)ISR;		/* Read content of ISR		*/	/*	 * Log DMA system error register, error address register, ..etc.	 */	esr[0].esr_dser = * (u_long *)KN220DSER;	esr[0].esr_dear = * (u_long *)KN220DEAR;	esr[0].esr_qbear = * (u_long *)KN220QBEAR;	esr[0].esr_cbtcr = * (u_long *)KN220CBTCR;	esr[0].esr_mesr = * (u_long *)KN220MESR;	esr[0].esr_mear = * (u_long *)KN220MEAR;	/* Clear the error bits 	*/	*(u_long *)KN220DSER = 0xc0bd;	*(u_long *)KN220CBTCR = 0xc0000000 | esr[0].esr_cbtcr;	/* 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)		{			esr[0].esr_mesr = 0xffffffff;		}	} else {					/* R3000 Cycle	*/		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;		}	}	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.		 */		p = u.u_procp;		if ( (int)pa != -1 && (btop((int)pa) < physmem) ) {

⌨️ 快捷键说明

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