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

📄 uba.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifndef lintstatic char *sccsid = "@(#)uba.c	4.2      (ULTRIX)        11/9/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1985,86,87 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.	* *									* ************************************************************************ * Modification History: * * 23-Feb-90 -- sekhar * 	Merged Joe Martin's fix for 3.1 cld. When copying user PTEs,  *	check for page crossing and reevaluate vtopte. * * 15-Oct-89	Robin Lewis *	patched the qbus map register assignment to set the High bit on vax's * * 20-Jul-89	Mark Parenti *	Add code for reset of KDM70. * * 15-Apr-89	Kong *	Fixed bug in qbasetup so that the magic cookie returned is *	in the format defined in the routine block comment. *	 * 05-Nov-88	Robin Lewis *	Changed the Q22-Bus map register allocation to return registers *	in clicks of 8.  This is necessary because there are insuficient *	bits in the int to pass back the offset in the page, the starting *	map register and the number of map registers allocated.  Nine *	bit are needed to have a 512 offset value and that can not change. *	The remainint bits return the starting map register with a max *	of 8K and the number of registers which can also be 8K ..? *	Passing back clicks of 8 registers allows this to work but *	does waste registers (but only until they are released.) * * 12-11-87	Robin L. and Larry C. *	Added portclass support to the system. * * 15-Sep-87  -- darrell *	Removed unnecessary consistency checks in vs_bufctl. * * 19-May-87  -- darrell *	Fixed a hole in vs_bufctl that was causing a panic during the *	installation on VAXstation/MicroVAX 2000.  *	 * 12-May-87  -- darrell *	Added a temporary variable to vs_bufctl to keep track of a  * 	pointer to the vsdev structure for the driver that is active. *	This fixes several panics. * * 23-Apr-87  -- darrell *	vs_bufctl has been changed to accpet a pointer to structure *	that contains the the ID of the device calling it, the action *	to be performed, and a pointer to the routine to call back *	into to driver. (stc.c or sdc.c) * * 29-Sep-86  -- darrell *	Space for vsbuf is now allocated here instead of in  *	../data/sdc_data.c. * * 26-Sep-86  -- darrell *	Fixed a bug in vs_bufctl that caused the vaxstar tape/disk *	buffer to be allocated incorrectly. * * 05-Sep-86  -- darrell *	Added a panic. vs_bufctl will now panic if called by the *	owner of the buffer. * * 30-Aug-86  -- darrell (Darrell Dunnuck) *	Fix bugs in VAXstar data buffer interlock code, which *	allows TZK50 and disk to share a common DMA data buffer. * *  5-Aug-86   -- gmm (George Mathew) and darrell (Darrell Dunnuck) *	Added routines to allow sharing the common disk data buffer *	between the VAXstar disk and TZK50 drivers. * * 13-Jun-86   -- jaw 	fix to uba reset and drivers. * * 14-May-86 -- bjg *	Move uba# field in subid when logging uba errors * * 16-Apr-86 -- afd *	Changed UMEMmap to QMEMmap and umem to qmem for QBUS reset. * * 19-feb-86 -- bjg  add uba error logging * * 04-feb-86 -- jaw  get rid of biic.h. * * 15-jul-85 -- jaw *	VAX8800 support * * 11 Nov 85   depp *	Removed System V conditional compiles. * * 08-Aug-85	darrell *	Zero vectors are now timed.  If we get too many, a message is  *	printed into the message buffer reporting the rate at which they *	are accuring.  The routine "ubatimer" was added. * * 11-jul-85 -- jaw *	fix bua/bda map registers. * * 19-Jun-85 -- jaw *	VAX8200 name change. * * 06 Jun 85 -- jaw *	add in the BDA support. * *  7 May 85 -- rjl *	Turned on Q-bus map as part of bus init.  *  * 22 Mar 85 -- depp *	Added Sys V Shared memory support * * 13-MAR-85 -jaw *	Changes for support of the VAX8200 were merged in. * * 27-Feb-85 -tresvik *	Changes for support of the VAX8600 were merged in. * * 12 Nov 84 -- rjl *	Added support for MicroVAX-II notion of a q-bus adapter. */#include "../machine/pte.h"#include "../h/param.h"#include "../h/systm.h"#include "../h/map.h"#include "../h/vmmac.h"#include "../h/buf.h"#include "../h/vm.h"#include "../h/dir.h"#include "../h/user.h"#include "../h/proc.h"#include "../h/conf.h"#include "../h/dk.h"#include "../h/kernel.h"#include "../h/clist.h"#include "../h/ipc.h"#include "../h/shm.h"#include "../h/errlog.h"#include "../machine/cpu.h"#ifdef vax#include "../machine/mtpr.h"#endif vax#ifdef mips#include "../machine/ssc.h"#endif mips#include "../machine/nexus.h"#include "../io/uba/ubareg.h"#include "../io/uba/ubavar.h"#include "../io/bi/buareg.h"#define QIPCR 0x1f40			/* Q-bus Inter-processor csr	*/#define LMEA 0x20			/* Local memory access enable	*/#define QMCIA 0x4000			/* Invalidate all cached map regs*/#ifdef mips#define WBFLUSH	wbflush()		/* Flush write buffer on mips */#else#define WBFLUSH ;			/* NOP for vax	*/#endif mips/* *  For zero vector timer -- should really be in a data.c file, but *  but there isn't one for uba.c */int	ubatimer();int	zvintvl = ZVINTVL;	/* zero vector timer interval in seconds */int	zvthresh = ZVTHRESH;	/* zero vector timer threhsold for reporting */char	ubasr_bits[] = UBASR_BITS;/* * Do transfer on device argument.  The controller * and uba involved are implied by the device. * We queue for resource wait in the uba code if necessary. * We return 1 if the transfer was started, 0 if it was not. * If you call this routine with the head of the queue for a * UBA, it will automatically remove the device from the UBA * queue before it returns.  If some other device is given * as argument, it will be added to the request queue if the * request cannot be started immediately.  This means that * passing a device which is on the queue but not at the head * of the request queue is likely to be a disaster. */ubago(ui)	register struct uba_device *ui;{	register struct uba_ctlr *um = ui->ui_mi;	register struct uba_hd *uh;	register int s, unit;	uh = &uba_hd[um->um_ubanum];	s = spl6();	if (um->um_driver->ud_xclu && uh->uh_users > 0 || uh->uh_xclu)		goto rwait;	um->um_ubinfo = ubasetup(um->um_ubanum, um->um_tab.b_actf->b_actf,	    UBA_NEEDBDP|UBA_CANTWAIT);	if (um->um_ubinfo == 0)		goto rwait;	uh->uh_users++;	if (um->um_driver->ud_xclu)		uh->uh_xclu = 1;	splx(s);	if (ui->ui_dk >= 0) {		unit = ui->ui_dk;		dk_busy |= 1<<unit;		dk_xfer[unit]++;		dk_wds[unit] += um->um_tab.b_actf->b_actf->b_bcount>>6;	}	if (uh->uh_actf == ui)		uh->uh_actf = ui->ui_forw;	(*um->um_driver->ud_dgo)(um);	return (1);rwait:	if (uh->uh_actf != ui) {		ui->ui_forw = NULL;		if (uh->uh_actf == NULL)			uh->uh_actf = ui;		else			uh->uh_actl->ui_forw = ui;		uh->uh_actl = ui;	}	splx(s);	return (0);}ubadone(um)	register struct uba_ctlr *um;{	register struct uba_hd *uh = &uba_hd[um->um_ubanum];	if (um->um_driver->ud_xclu)		uh->uh_xclu = 0;	uh->uh_users--;	/* already released map registers if it's a MicroVAX I */	if( (uh->uba_type & UBAUVI) ==0)		ubarelse(um->um_ubanum, &um->um_ubinfo);}/* * Allocate and setup UBA map registers, and bdp's * Flags says whether bdp is needed, whether the caller can't * wait (e.g. if the caller is at interrupt level). * * Return value: *	Bits 0-8	Byte offset *	Bits 9-17	Start map reg. no. *	Bits 18-27	No. mapping reg's *	Bits 28-31	BDP no. */ubasetup(uban, bp, flags)	struct buf *bp;{	register struct uba_hd *uh = &uba_hd[uban];	register int temp;	int npf, reg, bdp;	unsigned v;	register struct pte *pte, *io;	struct proc *rp;	int a, o, ubinfo, vax_pfn;	int user_addr = 0;#ifdef mips	int	mips_of;		  /* offset within a mips page	*/	int	mips_pfn;		  /* PFN of a mips pte		*/#endif mips	if (uh->uba_type & (UBA730|UBAUVI|UBAUVII))		flags &= ~UBA_NEEDBDP;	v = btop(bp->b_un.b_addr);	o = (int)bp->b_un.b_addr & 0x1ff; /* offset within a VAX page, even for					   mips based systesm where PGOFFSET is					   different - DO NOT replace 0x1ff with					   PGOFFSET */#ifdef mips	/* offset within a mips page */	mips_of = (int)bp->b_un.b_addr & PGOFSET;#endif	/* 	 * Number of VAX pages spanned by the buffer + 1(hence number of	 * map registers needed since we need one guard page)	 */	npf = (((unsigned)(bp->b_bcount + o)+0x1ff) >> 9) + 1; 	a = spl6();	while ((reg = rmalloc(uh->uh_map, (long)npf)) == 0) {		if (flags & UBA_CANTWAIT) {			splx(a);			return (0);		}		uh->uh_mrwant++;		sleep((caddr_t)&uh->uh_mrwant, PSWP);	}	bdp = 0;	if (flags & UBA_NEEDBDP) {		while ((bdp = ffs(uh->uh_bdpfree)) == 0) {			if (flags & UBA_CANTWAIT) {				rmfree(uh->uh_map, (long)npf, (long)reg);				splx(a);				return (0);			}			uh->uh_bdpwant++;			sleep((caddr_t)&uh->uh_bdpwant, PSWP);		}		uh->uh_bdpfree &= ~(1 << (bdp-1));	} else if (flags & UBA_HAVEBDP)		bdp = (flags >> 28) & 0xf;	splx(a);	reg--;	ubinfo = (bdp << 28) | (npf << 18) | (reg << 9) | o;	temp = (bdp << 21) | UBAMR_MRV;	if (bdp && (o & 01))		temp |= UBAMR_BO;	rp = bp->b_flags&B_DIRTY ? &proc[2] : bp->b_proc;	pte = 0;	if ((bp->b_flags & B_PHYS) == 0) {#ifdef vax		pte = &Sysmap[btop(((int)bp->b_un.b_addr)&0x7fffffff)];#else   			/* mips KSEG Addressing */	        if(IS_KSEG0(bp->b_un.b_addr)){ 			/* unmapped KSEG areas */                	mips_pfn = btop(K0_TO_PHYS(bp->b_un.b_addr));	        } else if(IS_KSEG1(bp->b_un.b_addr)){			/* unmapped KSEG areas */                	mips_pfn = btop(K1_TO_PHYS(bp->b_un.b_addr));	        } else if(IS_KSEG2(bp->b_un.b_addr)){			/* mapped KSEG areas */	                pte = &Sysmap[btop(bp->b_un.b_addr - K2BASE)];        	}#endif vax	}	else if (bp->b_flags & B_UAREA)		pte = &rp->p_addr[v];	else if (bp->b_flags & B_PAGET)		pte = &Usrptmap[btokmx((struct pte *)bp->b_un.b_addr)];	else if ((bp->b_flags & B_SMEM)  &&	/* SHMEM */					((bp->b_flags & B_DIRTY) == 0))		pte = ((struct smem *)rp)->sm_ptaddr + v;	else {		pte = vtopte(rp, v);		user_addr++;	}	if ((uh->uba_type & UBAUVI) ==0 || (flags&UBA_MAPANYWAY)) {		/* get address of starting UNIBUS map register */		io = &uh->uh_uba->uba_map[reg];                /* Loop to load all the map registers with pte information.                 * For a mips we need to simulate vax pte structures.		 *		 * On a VAX, we have npf map registers to fill, each		 * map register is to be filled by a VAX pte.		 *		 * On a mips, we have npf map registers to fill, but		 * each mips page is 4KB, so we have fewer mips ptes		 * to use.		 *		 * The following loop iterates for each map register.                 */		while (--npf != 0) {#ifdef mips			if(pte != 0)			{	/* pte points to the mips pte */				if (pte->pg_pfnum == 0)					panic("uba zero uentry");				vax_pfn = (pte->pg_pfnum << 3) + 					  (mips_of / 0x200);			} else {				/* There are no pte's, use pfn's				 */				vax_pfn = (mips_pfn << 3) +					  (mips_of / 0x200);			}			*(int *)io++ = vax_pfn | UBAMR_MRV;			mips_of += 0x200; /* next vax page */			if (mips_of >= 0x1000) {				/* Crossing mips page boundary */				/* Go on to next mips page */				mips_of -= 0x1000;

⌨️ 快捷键说明

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