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

📄 vbainit.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic char *sccsid = "@(#)vbainit.c	4.9	(ULTRIX)	4/4/91";#endif lint/************************************************************************ *									* *			Copyright (c) 1990 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//* * * Abstract: *	This module contains the routines which are used to initialize *	VMEbus adapters and to perform configuration of VMEbus devices. * * Revision History * *	18-Mar-91	map -- Mark A. Parenti *		Fix initialization of I/O space address maps. * *	26-Feb-91	map -- Mark A. Parenti *		Check return value from rmalloc in vme_map_csr() and return *		if unable to allocate map registers. *		Modify check of address space to account for boundary *		conditions. * *	19-Feb-91	map -- Mark A. Parenti *		Enable/disable block mode DMA based on the board rev *		level. See comment for more information. * *	22-Jan-91	map -- Mark A. Parenti *		Make selection of address space mapping dependent on *		setting in vbadata structure.  The DMA PMRs can be mapped *		into either the 1st or 2nd GB of VMEbus address space. * *	03-Jan-91	map -- Mark A. Parenti *		Fix initialization of ui_ and um_priority levels(used for *		splx). * *	15-Nov-90	Ron Bruckman, DEIC *		Changes to initialization logic *		1) Check clock for MVIB *		2) Clear interrupts from CSR during init *		3) Initialize "B" board registers *		4) Enable interrupts * *	12-Oct-90	map -- Mark A. Parenti *		Fix various hardware initialization bugs. *		Use correct data size definitions for hardware registers. *		Add priority to config print message. *		Add various startup error messages. * *	31-Aug-90	map -- Mark A. Parenti *		Add vba_get_vmeaddr() routine. *		Complete interrupt initialization. *		Various fixes from debug. * *	10-Apr-90	map -- Mark A. Parenti *		Change getvba() and insvba() to work with vba_hd pointers. *		Added initialization of various registers. *		Restructured module layout. * *	14-Nov-89	map -- Mark A. Parenti *		Original Version *************************************************************************/#include "../machine/pte.h"#include "../h/param.h"#include "../h/systm.h"#include "../h/map.h"#include "../h/buf.h"#include "../h/time.h"#include "../h/kernel.h"#include "../h/errlog.h"#include "../../machine/common/cpuconf.h"#include "../h/dk.h"#include "../h/config.h"#include "../h/kmalloc.h"#include "../h/vmmac.h"#include "../machine/cpu.h"#ifdef vax#include "../machine/mtpr.h"#endif /* vax */#include "../machine/nexus.h"#include "../machine/scb.h"#include "../io/xmi/xmireg.h"#include "../io/xmi/xbireg.h"#include "../io/vme/xviareg.h"#include "../io/vme/xvibreg.h"#include "../io/vme/vbareg.h"#include "../io/vme/vbavar.h"#include "../io/uba/ubavar.h"extern int (*VMEvec[])();#ifdef vaxextern int catcher[256];#endif /* vax */#ifdef mipsextern int	stray();#endif /* mips */extern int nNVBA;int vecvme = 0;int nvme_config = 0;extern struct cpusw *cpup;	/* pointer to cpusw entry */extern	int		cpu;extern	int		splm[];extern	struct vba_hd *head_vba;extern	struct	vbadata	vbadata;extern	int	vbavec;extern struct config_adpt config_adpt[];extern	int	MVIBerrors(), XBIAerrors();extern struct bus_dispatch vbaerr_dispatch[];extern	int	passive_release();extern	int	dkn;int	vme_init_maps();u_long	vme_map_csr();extern int	vmedebug;		/* Used to trigger debug printf's	*//* Define debugging stuff. */#define DEBUG#ifdef DEBUG#define Cprintf if(vmedebug)cprintf#define Dprintf if( vmedebug >= 2 )cprintf#else#define Cprintf ;#define Dprintf ;#endif#ifdef mips#define WBFLUSH	wbflush()		/* Flush write buffer on mips */#else#define WBFLUSH ;			/* NOP for vax	*/#endif /* mips */#define	DELAY200MS	200		/* Delay 200MS with a 1MS loop */char	*vme_spaces[3][3] = {	{"vmea16d08", "vmea24d08", "vmea32d08"},	{"vmea16d16", "vmea24d16", "vmea32d16"},	{"vmea16d32", "vmea24d32", "vmea32d32"}};struct vba_hd *get_vba(vbanumber) int vbanumber;{	register struct vba_hd *vhp;	vhp = head_vba;	while(vhp) {		if(vhp->vbanum == vbanumber) {			return(vhp);		}		vhp = vhp->next;	}	panic("vba: no vba_hd");	/*NOTREACHED*/}int	ins_vba(vhp)struct vba_hd	*vhp;{struct	vba_hd	*vhp_ptr;	vhp_ptr = head_vba;	while(vhp_ptr) {		if(vhp_ptr->next == 0)			break;		vhp_ptr = vhp_ptr->next;	}        if(vhp_ptr) {		vhp_ptr->next = vhp;	}        else {		head_vba = vhp;	}}probevba(vhp)struct vba_hd *vhp;{	register int i;	register struct uba_ctlr *um;	register struct uba_device *ui;	register struct uba_driver *udp;	register struct xbi_reg *xbireg;        register struct config_adpt *p_adpt;	register int (**vecaddr)(), (**ivec)(), (**intr_dispatch)();	struct xmidata *xmidata;	int ser, vbatype, vec, intr_bit, vecidx;	unsigned long map_addr, map_addr2, vdcr, vvor, vcsr, viacsr, csr;	volatile unsigned char *reg;	int alive, savectlr, pmrsize, rev;	u_short addr;	int 	*io;	Cprintf("probevba: Entered vhp = 0x%x\n", vhp);	vhp->adptnum = nvme_config;	vhp->vbavec_page = VMEvec + (nvme_config * 0x400);	vbatype = vhp->vba_type;	switch(vbatype) {	      case VBA_3VIA:		vhp->vba_err = MVIBerrors;		viacsr = (VIACSR_ENAB_ADP | VBA_ADPT_VEC | VIACSR_MVIB_RST);		if (cpu == DS_5000_100)			viacsr |= (VIACSR_32MB_IO | VIACSR_MODEL100);		if (BADADDR(Xviaregs.viacsr, 4)) {			printf("vba%d not configured: Unable to access 3VIA\n",			       vhp->vbanum);			return(0);		}		/* check MVIB clock */		vcsr = *Xviaregs.viacsr;		if (vcsr & VIACSR_YAB_NCLK)			{			printf("vba%d not configured: No clock, check cable\n",			       vhp->vbanum);			return(0);			}				*Xviaregs.viacsr = viacsr;		WBFLUSH;		if (BADADDR(Xviaregs.csr, 4)) {			printf("vba%d not configured: Unable to access MVIB\n",			       vhp->vbanum);			return(0);		}		for(i=0; i < DELAY200MS; i++) {			DELAY(1000)    			csr = *Xviaregs.csr;			if(csr & CSR_VME_SYSRST)				break;		}		if (i == DELAY200MS) {			printf("vba%d not configured: SYSRST Timeout\n",			       vhp->vbanum);			return(0);		}		if (csr & CSR_VME_ACLOW)			printf("vba%d: AC LOW Indicated - check backplane\n",			       vhp->vbanum);		/* check VIA CSR for errors */		vcsr = *Xviaregs.viacsr;				if (vcsr & VIACSR_ERR_MSK)		{		/* clear status register of interrupts */		*Xviaregs.viaclr = VIACLR_CLR_ALL;		WBFLUSH;		/* check if it worked */		DELAY(1000)		vcsr = *Xviaregs.viacsr;		if (vcsr & VIACSR_ERR_MSK);			{			printf("vba%d not configured: CSR Error\n",vhp->vbanum);			return(0);			} 		}		/*setup B board here */		csr = (CSR_DMA | CSR_VME_RESET	| CSR_MVIB_RST);		if(vbadata.asc)			csr |= CSR_SEL_UDMA;		else			csr |= CSR_SEL_LDMA;		*Xviaregs.csr = csr;		*Xviaregs.arcr = (u_char)(vbadata.vme_brl << ARCR_BR_SHIFT);		*Xviaregs.ttr = (u_char)(vbadata.arb_to << TTR_VMETO_SHIFT) |			(vbadata.arb_to << TTR_LBTO_SHIFT);		*Xviaregs.rcr = (u_char)(vbadata.release);		*Xviaregs.lvb = (u_char)0x08;		*Xviaregs.besr = (u_char)0x00;		*Xviaregs.icfr = (u_char)0x04;  /*metastability interval*/		/* Read B-board revision from CSR		*/		csr = *Xviaregs.csr;		rev = (csr & CSR_REV) >> 16;		/* Revisions 0-3 have special meaning.  Due to a bug in */		/* the VIC chip, block mode DMA can only be enabled for */		/* one address space.  A later revision of the VIC is   */		/* expected to fix the problem.  If the rev is 0, both  */		/* address spaces are disabled. This shouldn't be set   */		/* so print a message and enable both.			*/		/* If revision is 1, then enable A24 block mode.  If 	*/		/* revision is 2, then enable A32 block mode.  If 	*/		/* revision is 3 or greater then enable both.		*/		/* The revision is set via jumpers on the B-board.	*/		/* If a jumper is installed, the bit will be read as	*/		/* a 0 (typical hardware backwards logic!!).		*/		switch (rev) {		      case 0:			printf("vba%d: Invalid block mode jumper settings\n",			       vhp->vbanum);			printf("\tA24 and A32 block mode DMA enabled\n");			*Xviaregs.s0c0 = (u_char)0x16;	/*enables A24 blk */			*Xviaregs.s1c0 = (u_char)0x12;  /*enables A32 blk */			break;		      case 1:			*Xviaregs.s0c0 = (u_char)0x16;	/*enables A24 blk */			*Xviaregs.s1c0 = (u_char)0x10;  /*disables A32 blk*/			break;		      case 2:			*Xviaregs.s0c0 = (u_char)0x14;	/*disables A24 blk*/			*Xviaregs.s1c0 = (u_char)0x12;  /*enables A32 blk */			break;		      default:			*Xviaregs.s0c0 = (u_char)0x16; /*enables A24 blk */			*Xviaregs.s1c0 = (u_char)0x12;  /*enables A32 blk */		}		/* Initialize vector table to stray() catcher */		for(i=0; i < NVME_VECS; i++)			*(int (**)())_3VIA_VEC_ADDR(vhp, i) = stray;		/* Setup vector 0 as passive release */		intr_dispatch = (int (**)())_3VIA_VEC_ADDR(vhp, 0);		*intr_dispatch = passive_release;		/* Setup to handle 3VIA generated interrupts */		for(vecidx=0; vbaerr_dispatch[vecidx].bus_num != 		    vhp->vbanum ; vecidx++) {			if (vbaerr_dispatch[vecidx].bus_num == -1) 				panic("vba: no adapter error vector");		}		intr_dispatch = (int (**)())_3VIA_VEC_ADDR(vhp, 					   VBA_ADPT_VEC);		*intr_dispatch = (int (*)())vbaerr_dispatch[vecidx].bus_vec;		/* Setup to handle MVIB generated interrupts */		for(i = 0x9; i <= 0xF; i++) {		       intr_dispatch = (int (**)())_3VIA_VEC_ADDR(vhp, 					   i);		       *intr_dispatch = (int (*)())vbaerr_dispatch[vecidx].bus_vec;	       }						/* Initialize map registers to invalid  */		io = (int *)(Xviaregs.dma_pmr);		for (i=0; i < vhp->n32dmapmr; i++)			*(int *)io++ = 0;		/* Setup interrupt handling.  If IPL level set in vbadata */		/* then enable the corresponding register		  */		reg = Xviaregs.icr;		intr_bit = 1;		for(i = 0; i < 7; i++) {			if(intr_bit & vbadata.intr_mask)				*reg = (u_char)ICR_IPL_2;			reg += 4;  /* Can't just ++ here because registers */			           /* are 8-bits on 32-bit boundaries.     */			intr_bit <<= 1;		}	/* set local interrupts for parity, transaction pio and dma faults */		reg = Xviaregs.licr;		/* Enable local interrupts 1 - 3 */		for(i = 0; i < 3; i++) {  			*reg = (u_char) (ICR_IPL_2 | LICR_EDGE | LICR_VECTOR); 			reg += 4; /* Can't just ++ here because registers */			           /* are 8-bits on 32-bit boundaries.     */		}		/* Don't enable DMA Page Map error. Just let VMEbus */		/* timeout occur.				    */		*reg = (u_char)LICR_DISABLE;		reg +=4;		/* Enable local interrupts 5 - 7 */		for(i = 5; i < 8; i++) { 			*reg = (u_char) (ICR_IPL_2 | LICR_EDGE | LICR_VECTOR);			reg +=4; /* Can't just ++ here because registers */			         /* are 8-bits on 32-bit boundaries      */		}		*Xviaregs.errgi = (u_char)(ERRGI_ENABLE | ICR_IPL_2);		WBFLUSH;		/* initialize interrupts */		vcsr = *Xviaregs.viacsr;		*Xviaregs.viacsr = (vcsr | VIACSR_ENAB_INT);		WBFLUSH;		break;	      case VBA_XBIA:		vhp->vba_err = XBIAerrors;		xbireg = (struct xbi_reg *)vhp->vbavirt;		Cprintf("probevba: xbireg = 0x%x\n", xbireg);		ser = xbireg->xbi_aesr;		vdcr = *Xvibregs.vdcr;    	        if (((ser & XBIA_IB_OK) == 0) || (vdcr & VDCR_ERR_SUM)) {			return(0);		}	        /* clear out any errors generated during XBIA init */		/* and setup XBIA+ registers			   */	        xbireg->xbi_aesr = xbireg->xbi_aesr;	        xbireg->xbi_xbe = xbireg->xbi_xbe & ~XMI_XBAD; /* write 1 to clear */	        xbireg->xbi_besr = xbireg->xbi_besr; 		xmidata = vhp->adapt_info.xbia_info.xmidata; 	        xbireg->xbi_aimr = (XBIA_ENABLE_IVINTR |				  XBIA_ENABLE_CC | /* corrected confirmaiton*/				  XBIA_ENABLE_PE | /* parity error */				  XBIA_ENABLE_WSE| /* write seq error */				  XBIA_ENABLE_RDN| /* read data noack */				  XBIA_ENABLE_WDN | /* write data noack */				  XBIA_ENABLE_NRR | /* No read response */				  XBIA_ENABLE_RSE | /* Read seq error */				  XBIA_ENABLE_RER | /* Read error response */				  XBIA_ENABLE_IBUS_APE |				  XBIA_ENABLE_IBUS_BPE |				  XBIA_ENABLE_IBUS_DPE |				  XBIA_ENABLE_NXM); /* non-exist memory */		xbireg->xbi_aivintr = xmidata->xmiintr_dst; 		/* Setup PMR page size 	*/#ifdef mips		switch(cpu) {		      case DS_5800:		      default:			pmrsize = XBIAP_DMA_4K;			break;		}#endif /* mips */#ifdef vax		pmrsize = XBIAP_DMA_512;#endif /* vax */		xbireg->xbi_autlr |= pmrsize; 				/* Setup XVIB registers		*/		*Xvibregs.vcar = (VCAR_WRITE | ADSEL_ADD_ENAB | VCAR_ADD_SEL);		vdcr = (vbadata.syscon) | 			(vbadata.vme_brl << VDCR_BR_SHIFT) | 				VDCR_PSIZE_8K;		*Xvibregs.vdcr = vdcr;		*Xvibregs.vicr = VICR_INIT_SET |			(vbadata.intr_mask << VICR_IRQ_SHIFT);#ifdef vax		vvor =  ( ( ((int)vhp->vbavec_page) & ~VA_SYS)			- ((int)&scb.scb_stray & ~ VA_SYS));#endif /* vax */#ifdef mips		vvor = ( ((int)vhp->vbavec_page )			- ((int)&scb.scb_stray));#endif /* mips */		*Xvibregs.vvor = vvor | (xmidata->xmiintr_dst << 16);		*Xvibregs.vevr = (xmidata->xmiintr_dst << 16); 		/* initialize SCB to catcher */		for ( i=0 ; i < 256; i++)			*(SCB_VME_ADDR(vhp->vbavec_page) + i) =#ifdef vax			    scbentry(&catcher[i*2], SCB_ISTACK);#endif /* vax */#ifdef mips			    scbentry(stray, 0);#endif /* mips */		vecaddr = (int (**)())SCB_VME_VEC_ADDR(vhp->vbavec_page, 0); 		*vecaddr = scbentry(passive_release, SCB_ISTACK);		for(vecidx=0; vbaerr_dispatch[vecidx].bus_num != 		    vhp->vbanum ; vecidx++) {			if (vbaerr_dispatch[vecidx].bus_num == -1) 				panic("vba: no adapter error vector");		}		vecaddr = (int (**)())SCB_VME_VEC_ADDR(vhp->vbavec_page, VBA_ADPT_VEC << 2); 		*vecaddr = scbentry(vbaerr_dispatch[vecidx].bus_vec, SCB_ISTACK);			break;	      default:		printf("vba%d: Unsupported adapter type\n", vhp->vbanum);		return(0);		break;	}	Cprintf("probevba: Init maps\n");	/* Initialize resource maps for DMA, PIO, and VME memory space */	if(vme_init_maps(vhp) == 0) {		printf("vba%d not configured: Map initialization failed\n", 		       vhp->vbanum);		return(0);	}			/*	 * Search controller table for VMEbus controller devices,	 * see if it is really there, and if it is record it and	 * then go looking for slaves.	 */	for (um = ubminit; udp = um->um_driver; um++) {			if((um->um_alive) ||		   (um->um_adpt != vhp->vbanum) ||		   (um->um_vbanum == '?')) continue;                for(p_adpt = &config_adpt[0]; p_adpt->p_name; p_adpt++) {			if(strcmp("vba", p_adpt->p_name)==0 &&                       		(char *)udp == p_adpt->c_name &&                       		p_adpt->c_num == um->um_ctlr) break;		}		if (p_adpt->p_name == 0)			continue;		map_addr = 0;		map_addr2 = 0;	        vec = um->um_ivnum;		if((vec < 0x40) || (vec > 0xFF)) {			printf("%s%d not configured: Invalid vector 0x%x\n", um->um_ctlrname, um->um_ctlr, vec);			continue;		}		Cprintf("probevba: Found device\n");		Cprintf("probevba: name = %s%d Addr1 = 0x%x  Addr2 = 0x%x\n",			um->um_ctlrname, um->um_ctlr, 

⌨️ 快捷键说明

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