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

📄 xmiinit.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic char *sccsid = "@(#)xmiinit.c	4.7    ULTRIX  12/6/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1988,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.	* *									* ************************************************************************//* * Revision History * * 03-Dec-90	Joe Szczypek *	Added return() to get_xmi() to silence LINT. * * 29-Aug-90	stuarth (Stuart Hollander) *	Fixed bug in xmisst when determining which xmi a node is on. *	Added comments explaining xmiconf structure. * * 17-Aug-90	rafiey (Ali Rafieymehr) *	Made the following changes for Stuart Hollander. *	Split xmiconf() into xmiconf_reset() and xmiconf_conf(). *	Allows, per xmi bus, to reset all nodes, then wait as they *	all perform self-test in parallel, instead of resetting and *	waiting for each device, one-by-one. *	Also, handles multiple xmi s. * * 03-Aug-90	rafiey (Ali Rafieymehr) *	Changed xmi_io_space for VAX9000. Defined numxmi for multiple *	XMI support. * * 02-May-90    Joe Szczypek *      Modified error routines for xbi+ support. * * 13-Mar-90	rafiey (Ali Rafieymehr) *	Removed unnecessary check for invalid slot of xmi node from xmi_io_space(). * * 11-Dec-89    Paul Grist *      Modified xmierrors to call panic using status returned from *      xbi_check_errs(). Added new routine log_xmi_bierrors() to  *      to log pending VAXBI errors and log_xmierrors to just log pending *      xbi errors. They will be used by exception handlers looking for *      more error information. * * 08-Dec-89 	Pete Keilty *	Modified nxaccess() in xmiconf() routine to use XMINODE_SIZE *	as node space size define in xmireg.h for VAX. * * 08-Dec-89 	jaw *	make printf use decimal for printing node and bus numbers.   * * 13-Nov-89	burns *	Made xmi_io_space consistent over vax/mips platforms. Trickery *      now performed in nxaccess(). * * 09-Nov-89	jaw *	fix bug where hooking xna to wrong bus. * * 20-Jul-89	rafiey (Ali Rafieymehr) *	Added support for XMI devices. * * 24-May-89	darrell *	Changed the #include for cpuconf.h to find it in it's new home -- *	sys/machine/common/cpuconf.h * * 24-May-89	darrell *	Removed the v_ prefix from all cpusw fields, removed cpup from any *	arguments being passed in function args.  cpup is now defined *	globally -- as part of the new cpusw. * *************************************************************************/#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/uba/ubavar.h"#ifdef vax#define XMI_START_PHYS 0x21800000#endif vax#ifdef mips#define XMI_START_PHYS 0x11800000#endif mipsextern int dkn;         /* number of iostat dk numbers assigned so far */extern int nNUBA;#ifdef vaxextern int catcher[256];#endif vax#ifdef mipsextern int	stray();#endif mipsextern int nNXMI;extern int vecbi;extern int cpu;			/* Ultrix internal System type */extern struct bus_dispatch xmierr_dispatch[];extern struct cpusw *cpup;	/* pointer to cpusw entry */extern struct config_adpt  *ni_port_adpt;extern struct bidata bidata[];int	numxmi;xmisetvec(xminumber)int xminumber;{	int i;	struct xmidata *xmidata;	xmidata = get_xmi(xminumber);	for(i=0; xmierr_dispatch[i].bus_num != xminumber ; i++) {		if (xmierr_dispatch[i].bus_num == -1) panic("no vector");	}		*(xmidata->xmivec_page+(XMIEINT_XMIVEC/4))=				scbentry(xmierr_dispatch[i].bus_vec,SCB_ISTACK);}struct xmidata *get_xmi(xminumber) int xminumber;{	register struct xmidata *xmidata;		xmidata = head_xmidata;	while(xmidata) {		if(xmidata->xminum == xminumber)			return(xmidata);		xmidata = xmidata->next;	}	panic("no bus data");	/*NOTREACHED*/}extern struct xmi_reg xmi_start[];	/* Instead of being simply one large function,	   xmiconf is structured as three subfunctions so that	   one could easily write a function to initialize multiple	   xmis in parallel by calling xmiconf_reset for each xmi,	   then calling xmiconf_wait for each, and then calling	   xmiconf_conf for each.	   We keep xmiconf as a function that initializes	   only one xmi so that existing code can remain unchanged. 	*/xmiconf(xminumber)int xminumber;{	int s;    	s = spl5();	xmiconf_reset(xminumber); /* Reset all nodes on the xmi */	xmiconf_wait(xminumber); /* Wait for all initializations to complete */	splx(s);	xmiconf_conf(xminumber); /* Configure each node */}xmiconf_reset(xminumber)int xminumber;{	struct xmi_reg	*nxv;	/* virtual pointer to XMI node */	struct xmi_reg	*nxp;	/* physical pointer to XMI node */	register int xminode;	register struct xmisw *pxmisw;	register struct xmidata *xmidata;	register struct xmi_reg *cpunode=0;	register int i;	xmidata = get_xmi(xminumber);	/* set xmi alive in adpter struct */	config_set_alive("xmi",xminumber);	nxp = xmidata->xmiphys;		/* see if we need to allocate pte's */	/*	 * Set up initial virtual address for xmi node space.	 * This is a bit of a misnomer. On Vaxes XMI node space is mapped	 * and thus accesses via real virtual addresses. On mips XMI node	 * is accessible vis KSEG0 and KSEG1, so we use a KSEG1 "virtual"	 * address which really is a direct translation of the physical.	 */#ifdef vax	nxv = xmi_start;	nxv += (xminumber * 16);#endif vax#ifdef mips	nxv = (struct xmi_reg *)PHYS_TO_K1(XMI_START_PHYS);#endif mips	xmidata->xmivirt = nxv;	printf("xmi %d at address 0x%x\n",xminumber,nxp);	xmidata->xminodes_alive =0;	/* figure out cpu node from xmi interrupt dst. reg */	xmidata->cpu_xmi_addr = nxv + (ffs(xmidata->xmiintr_dst) -1);		/* If on first page of scb, do not change the first 64		 * vectors, as these are the standard arch defined vectors.		 * On other pages, initialize all vectors.		 */	if (xmidata->xmivec_page == &scb.scb_stray) i=64;	else i=0;		/* initialize SCB to catcher */	for ( ; i < 128; i++)		*(SCB_XMI_ADDR(xmidata) + i) =#ifdef vax		    scbentry(&catcher[i*2], SCB_ISTACK);#endif vax#ifdef mips		    scbentry(stray, 0);#endif mips	/* set error interrupt vector */	xmisetvec(xminumber);	for(xminode = 0; xminode < MAX_XMI_NODE; xminode++,nxv++) {	    /* get physical address to map */	    nxp = (struct xmi_reg *) cpup->nexaddr(xminumber,xminode);#ifdef vax	    /* map xmi node space */	    nxaccess(nxp,&Sysmap[btop((int)(nxv) & ~VA_SYS)],XMINODE_SIZE);#endif vax#ifdef mips	    /* 	     * XMI node space is not mapped on mips.	     */#endif mips	    /* xmi node alive ??? */	    if (BADADDR((caddr_t) nxv,sizeof(long))) continue;	    for (pxmisw = xmisw ; pxmisw->xmi_type ; pxmisw++) {			if (pxmisw->xmi_type == (short)(nxv->xmi_dtype)) {	    	    xmidata->xmierr[xminode].pxmisw= pxmisw;		    xmidata->xminodes_alive |= (1 << xminode);                    if (pxmisw->xmi_flags&XMIF_SST) {			nxv->xmi_xbe = (nxv->xmi_xbe & ~XMI_XBAD) | XMI_NRST;                    }                    break;		}	    }	    if (pxmisw->xmi_type ==0)		printf ("xmi %d node %d, unsupported device type 0x%x\n",			xminumber,xminode, (unsigned short) nxv->xmi_dtype);	}	DELAY(10000);	/* need to give time for XMI bad line to be set */}	/* Wait for reset of xmi nodes to take effect. */xmiconf_wait(xminumber)int xminumber;{	struct xmi_reg	*nxv;	/* virtual pointer to XMI node */	struct xmi_reg	*nxp;	/* physical pointer to XMI node */	register int xminode;	register struct xmisw *pxmisw;	register struct xmidata *xmidata;	register struct xmi_reg *cpunode=0;	register int i;	int broke;	int alive;	int totaldelay;	/* Wait cumulative up to 20 seconds.	   For extra safety, this is double the spec value. */	totaldelay = 2000;	xmidata = get_xmi(xminumber);	nxv = xmidata->xmivirt;	for(xminode = 0; xminode < MAX_XMI_NODE; xminode++,nxv++) {	    if( !(xmidata->xminodes_alive & (1 << xminode)))		continue;	    pxmisw = xmidata->xmierr[xminode].pxmisw;		/* wait here for up to remaining count time		   or until device is reset.  */            if (pxmisw->xmi_flags&XMIF_SST) {	    	cpunode = xmidata->cpu_xmi_addr;		while((cpunode->xmi_xbe & XMI_XBAD) && (totaldelay-- > 0))			DELAY(10000);		while((nxv->xmi_xbe&(XMI_ETF|XMI_STF)) && (totaldelay-- > 0))			DELAY(10000);		nxv->xmi_xbe = nxv->xmi_xbe & ~(XMI_XBAD | XMI_NRST);	    }	}}	/* Do config of nodes. */xmiconf_conf(xminumber)int xminumber;{	struct xmi_reg	*nxv;	/* virtual pointer to XMI node */	struct xmi_reg	*nxp;	/* physical pointer to XMI node */	register int xminode;	register struct xmisw *pxmisw;	register struct xmidata *xmidata;	register struct xmi_reg *cpunode=0;	register int i;	int broke;	int alive;	int totaldelay;	xmidata = get_xmi(xminumber);	/* do config of devices, adapters, controllers, etc. */	nxv = xmidata->xmivirt;	for(xminode = 0; xminode < MAX_XMI_NODE; xminode++,nxv++) {	    if( !(xmidata->xminodes_alive & (1 << xminode)))		continue;	    pxmisw = xmidata->xmierr[xminode].pxmisw;	    nxp = (struct xmi_reg *) cpup->nexaddr(xminumber,xminode);	    broke = (nxv->xmi_xbe & XMI_ETF) ||			(nxv->xmi_xbe & XMI_STF);	    alive = 0;	    if (pxmisw->xmi_flags&XMIF_DEVICE)		alive |= xmi_config_dev(nxv,nxp,xminumber,xminode,xmidata);	    if (pxmisw->xmi_flags&XMIF_CONTROLLER);		alive |= xmi_config_con(nxv,nxp,xminumber,xminode,xmidata);	    if (pxmisw->xmi_flags&XMIF_ADAPTER){	    	(**pxmisw->probes)(nxv,nxp,xminumber,xminode,xmidata);		alive = 1;	    }            if (pxmisw->xmi_flags&XMIF_NOCONF) {		printf ("%s at xmi%d node %d",                        pxmisw->xmi_name,xminumber,xminode);                if (broke == 0)                        printf("\n");                else                        printf(" is broken, continuing!\n");	 	(**pxmisw->probes)(nxv,nxp,xminumber,xminode,xmidata);                alive=1;            }            if (alive==0) xminotconf(nxv,nxp,xminumber,xminode,xmidata);	}	/* The following loop cleans up any errors that might	   have gotten set when we probed the XMI */	nxv = xmidata->xmivirt;	for(xminode = 0; xminode < MAX_XMI_NODE; xminode++,nxv++) {		if (xmidata->xminodes_alive & (1<<xminode)) {			nxv->xmi_xbe = nxv->xmi_xbe & ~XMI_XBAD;		}		}}struct uba_ctlr *xmifindum();xmi_config_con(nxv,nxp,xminumber,xminode,xmidata)struct	xmi_reg *nxv;char	*nxp;register int    xminumber;register int    xminode;register struct xmidata *xmidata;{

⌨️ 快捷键说明

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