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

📄 mem.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
字号:
#ifndef lintstatic char *sccsid = "@(#)mem.c	4.3	ULTRIX	3/13/91";#endif lint/************************************************************************ *									* *			Copyright (c) 1986 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.	* *									* ************************************************************************//*	mem.c	6.1	83/07/29	*//* * Modification History * * 13-Mar-91 jaa *	keep the proc in core during the uiomove().  Because we  *	use forkmap, and when uiomove() completes a page fault  *	we could be swapped out which also uses forkmap. * * 14-Feb-91	jaa *	when reading/writing kernel memory on machine that's paging *	and/or swapping, double map the kernel virtual address to *	forkmap incase it goes away while using it.  you might get *	garbage but the machine won't panic. * * 09-Nov-89 	jaw *	make /dev/mem use pte 2 in the forkutl map.  this is so we *	don't conflict with pagein. * * 30-May-89	darrell *	Added include of ../../machine/common/cpuconf.h -- cpu types *	were moved there. * * 10-Oct-88 -- jaw *	replace switch_to_master with general routine switch_affinity * * 06-Aug-86 -- jaw	fixed baddaddr to work on running system. * * tresvik - 13-Jun-86 *	Changed UNIcopy to test the address before reading or writing. *	Uses BADADDR. *//* * Memory special file */#include "../machine/pte.h"#include "../h/param.h"#include "../h/dir.h"#include "../h/user.h"#include "../h/conf.h"#include "../h/buf.h"#include "../h/systm.h"#include "../h/vm.h"#include "../h/cmap.h"#include "../h/uio.h"#include "../h/proc.h"#include "../machine/mtpr.h"#include "../../machine/common/cpuconf.h"extern int boot_cpu_mask;mmread(dev, uio)	dev_t dev;	struct uio *uio;{	return (mmrw(dev, uio, UIO_READ));}mmwrite(dev, uio)	dev_t dev;	struct uio *uio;{	return (mmrw(dev, uio, UIO_WRITE));}mmrw(dev, uio, rw)	dev_t dev;	struct uio *uio;	enum uio_rw rw;{	register int o;	register u_int c, v;	register struct iovec *iov;	struct proc *p = u.u_procp;	int error = 0;	struct pte *upte;	extern int umbabeg, umbaend;	while (uio->uio_resid > 0 && error == 0) {		iov = uio->uio_iov;		if (iov->iov_len == 0) {			uio->uio_iov++;			uio->uio_iovcnt--;			if (uio->uio_iovcnt < 0)				panic("mmrw");			continue;		}		switch (minor(dev)) {/* minor device 0 is physical memory */		case 0:			v = btop(uio->uio_offset);			if (v >= physmem)				goto fault;			*((int *)Forkmap+ CLSIZE ) = v | PG_V |				(rw == UIO_READ ? PG_KR : PG_KW);			mtpr(TBIS, ((caddr_t)&forkutl + (NBPG*CLSIZE)));			o = (int)uio->uio_offset & PGOFSET;			c = min((u_int)(NBPG - o), (u_int)iov->iov_len);			c = min(c, (u_int)(NBPG - ((int)iov->iov_base&PGOFSET)));			SET_P_VM(p, SKEEP);			error = uiomove(((caddr_t)&forkutl)+o+(NBPG*CLSIZE), (int)c, rw, uio);			CLEAR_P_VM(p, SKEEP);			continue;/* minor device 1 is kernel memory */		case 1:			if ((caddr_t)uio->uio_offset < (caddr_t)&umbabeg &&			    (caddr_t)uio->uio_offset + uio->uio_resid >= (caddr_t)&umbabeg)				goto fault;			if ((caddr_t)uio->uio_offset >= (caddr_t)&umbabeg &&			    (caddr_t)uio->uio_offset < (caddr_t)&umbaend)				goto fault;			if ((int)uio->uio_offset & VA_SYS)  {				o = (int)uio->uio_offset & PGOFSET;				c = min((u_int)(NBPG - o), (u_int)iov->iov_len);				c = min(c, (u_int)(NBPG - ((int)iov->iov_base&PGOFSET)));                        	if (!kernacc((caddr_t)uio->uio_offset, c, 					rw == UIO_READ ? B_READ : B_WRITE))					goto fault;				upte = svtopte(uio->uio_offset);				if(upte->pg_pfnum > physmem)					goto fault;				*((int *)Forkmap+ CLSIZE ) = upte->pg_pfnum | PG_V |					(rw == UIO_READ ? PG_KR : PG_KW);				mtpr(TBIS, ((caddr_t)&forkutl + (NBPG*CLSIZE)));				SET_P_VM(p, SKEEP);				error = uiomove(((caddr_t)&forkutl)+o+(NBPG*CLSIZE), 					(int)c, rw, uio);						CLEAR_P_VM(p, SKEEP);			} else {				c = iov->iov_len;				if (!kernacc((caddr_t)uio->uio_offset, c, 					     rw == UIO_READ ? B_READ : B_WRITE))					goto fault;				error = uiomove((caddr_t)uio->uio_offset, 						(int)c, rw, uio);			}			continue;/* minor device 2 is EOF/RATHOLE */		case 2:			if (rw == UIO_READ)				return (0);			c = iov->iov_len;			break;/* minor device 3 is unibus memory (addressed by shorts) */		case 3:			c = iov->iov_len;			if (!kernacc((caddr_t)uio->uio_offset, c, rw == UIO_READ ? B_READ : B_WRITE))				goto fault;			if (!useracc(iov->iov_base, c, rw == UIO_READ ? B_WRITE : B_READ))				goto fault;			error = UNIcpy((caddr_t)uio->uio_offset, iov->iov_base,			    (int)c, rw);			break;		}		if (error)			break;		iov->iov_base += c;		iov->iov_len -= c;		uio->uio_offset += c;		uio->uio_resid -= c;	}	return (error);fault:	return (EFAULT);}/* * UNIBUS Address Space <--> User Space transfer */UNIcpy(uniadd, usradd, n, rw)	caddr_t uniadd, usradd;	register int n;	enum uio_rw rw;{	register short *from, *to;	extern char Sysbase[];	unsigned int saveaffinity;  	/* BADADDR is NOT mpsafe */	saveaffinity = switch_affinity(boot_cpu_mask);	if (rw == UIO_READ) {		from = (short *)uniadd;		to = (short *)usradd;	} else {		from = (short *)usradd;		to = (short *)uniadd;	}	for (n >>= 1; n > 0; n--) {		int bad;		extern	int cpu; 		bad = BADADDR((rw == UIO_READ) ? from : to, 2);		if (bad) {			u.u_procp->p_affinity=saveaffinity;			return (EFAULT);		}		*to++ = *from++;	}	(void) switch_affinity(saveaffinity);	return (0);}

⌨️ 快捷键说明

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