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

📄 pt_machdep.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic	char	*sccsid = "@(#)pt_machdep.c	4.1	(ULTRIX)	7/2/90";#endif lint/*********************************************************************** *									* *			Copyright (c) 1984, 1986, 1988 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 * * 19-Jun-90 -- jmartin *	Fixes for "panic: vrelvm rssize" * * 05 Mar 90 jaw *	IPL level lowered when text lock is released in vinitpt. * * 06 Feb 90 gmm *	Get lk_text if vinitpt() returns with value 0. The calling routine *	expects lk_text to be held on return. * * 11 Dec 89 jaa *	fixed mips to round from clicks to pt's in vinitpt * * 24 Jul 89 -- jmartin *	Don't call swapout; just ask the swapper and sleep. * * 06-Jun-89  -- jaa *    Creation date *    split machdep routines from ../vm_pt.c  */#include "../h/param.h"#include "../h/systm.h"#include "../h/dir.h"#include "../h/user.h"#include "../h/proc.h"#include "../h/map.h"#include "../h/cmap.h"#include "../h/vm.h"#include "../h/buf.h"#include "../h/text.h"#include "../h/mount.h"#include "../h/gnode.h"#include "../h/kernel.h"#include "../machine/pte.h"#include "../machine/cpu.h"#include "../h/ipc.h"#include "../h/shm.h"#include "../h/cpudata.h"extern struct sminfo sminfo;extern int swapfrag;/* * Get data and stack page tables for process p.  Allocator * for memory is argument; process must be locked * from swapping if vmemall is used; if memall is * used, call will return w/o waiting for memory. * In any case an error return results if no user * page table space is available. */vgetpt(p, pmemall, pmemfree)	register struct proc *p;	int (*pmemall)();	int (*pmemfree)();{	register long ad = 0;	register long as = 0;	register int i, s, takelock;	extern int memfree();#ifdef CACHETRICKS	register struct cmap *c;	register unsigned pf;#endif CACHETRICKSXPRINTF(XPR_VM,"enter vgetpt",0,0,0,0);	/*	 * Must take MP lock for memfree during error path frees.	 */	takelock = (pmemfree == memfree);	/*	 * Allocate space in the kernel map for this process.	 * Then allocate page table pages, and initialize the	 * process' base registers and addr pointers to be the kernel	 * virtual addresses of the base of the page tables and	 * the pte for the process pcb (at the base of the u.).	 */	if (p->p_datapt) {		if ((ad = rmalloc(kernelmap, (long)p->p_datapt)) == 0)			return (0);		if ((*pmemall)(&Usrptmap[ad], p->p_datapt, p, 				     CSYS, NULL, V_NOOP) == 0) {			rmfree(kernelmap, (long)p->p_datapt, ad);			return (0);		}	}	if (p->p_stakpt) {		if ((as = rmalloc(kernelmap, (long)p->p_stakpt)) == 0) {			if (p->p_datapt) {				if (takelock) {					s = splimp();					smp_lock(&lk_cmap, LK_RETRY);				}				(*pmemfree)(&Usrptmap[ad], p->p_datapt);				if (takelock) {					smp_unlock(&lk_cmap);					(void) splx(s);				}				rmfree(kernelmap, (long)p->p_datapt, ad);			}			return (0);		}		if ((*pmemall)(&Usrptmap[as], p->p_stakpt, p, 				     CSYS, NULL, V_NOOP) == 0) {			if (p->p_datapt) {				if (takelock) {					s = splimp();					smp_lock(&lk_cmap, LK_RETRY);				}				(*pmemfree)(&Usrptmap[ad], p->p_datapt);				if (takelock) {					smp_unlock(&lk_cmap);					(void) splx(s);				}				rmfree(kernelmap, (long)p->p_datapt, ad);			}			rmfree(kernelmap, (long)p->p_stakpt, as);			return (0);		}	}	p->p_databr = kmxtob(ad);	p->p_stakbr = kmxtob(as);	p->p_textbr = 0;	/*	 * Now validate the system page table entries for the	 * user page table pages, flushing old translations	 * for these kernel virtual addresses.  Clear the new	 * page table pages for clean post-mortems.	 */	if (p->p_datapt) {		vmaccess(&Usrptmap[ad], (caddr_t)p->p_databr, p->p_datapt, DO_CACHE);		for (i = 0; i < p->p_datapt; i++) {#ifdef USE_IDLE			/* don't bother if it's already done */			if (cmap[pgtocm(Usrptmap[ad + i].pg_pfnum)].c_zero) {				extern int v_zero_pt_hits;				v_zero_pt_hits++;				cmap[pgtocm(Usrptmap[ad+i].pg_pfnum)].c_zero=0;			}			else {				extern int v_zero_pt_misses;				v_zero_pt_misses++;				clearseg(Usrptmap[ad + i].pg_pfnum);			}#else			clearseg(Usrptmap[ad + i].pg_pfnum);#endif#ifdef CACHETRICKS			if (Usrptmap[ad + i].pg_n == 0) {				pf = Usrptmap[ad + i].pg_pfnum;				c = &cmap[pgtocm(pf)];				c->c_icachecnt = icachecnt[pf & icachemask];				c->c_dcachecnt = dcachecnt[pf & dcachemask];			}#endif CACHETRICKS		}	}	if (p->p_stakpt) {		vmaccess(&Usrptmap[as], (caddr_t)p->p_stakbr, p->p_stakpt, DO_CACHE);		for (i = 0; i < p->p_stakpt; i++) {#ifdef USE_IDLE			/* don't bother if it's already done */			if (cmap[pgtocm(Usrptmap[as + i].pg_pfnum)].c_zero) {				extern int v_zero_pt_hits;				v_zero_pt_hits++;				cmap[pgtocm(Usrptmap[as+i].pg_pfnum)].c_zero=0;			}			else {				extern int v_zero_pt_misses;				v_zero_pt_misses++;				clearseg(Usrptmap[as + i].pg_pfnum);			}#else			clearseg(Usrptmap[as + i].pg_pfnum);#endif#ifdef CACHETRICKS			if (Usrptmap[as + i].pg_n == 0) {				pf = Usrptmap[as + i].pg_pfnum;				c = &cmap[pgtocm(pf)];				c->c_icachecnt = icachecnt[pf & icachemask];				c->c_dcachecnt = dcachecnt[pf & dcachemask];			}#endif CACHETRICKS		}	}	return (1);}/* * Initialize text portion of page table. */vinitpt(p,s)	struct proc *p;	int s;{	register struct text *xp;	register struct proc *q;	register struct pte *pte;	register int i;	struct pte proto;	unsigned unlock_flag = NULL;        register long at = 0;	XPRINTF(XPR_VM,"enter vinitpt",0,0,0,0);	xp = p->p_textp;	if (xp == 0)                return (1);	pte = tptopte(p, 0);	if (q = xp->x_caddr) {	/*	 * If there is another instance of same text in core	 * then just copy page tables from other process.	 *	 * This operation can be thought of as a large "distpte", so	 * we lock it under the same protocol as we lock "distpte".	 * We don't give up the lock until the process is linked to	 * the text chain (see xlink(p) in sys/vm_text.c), so that	 * real "distpte"s will see this process.	 */                p->p_textbr = q->p_textbr;                p->p_textpt = q->p_textpt;		goto done;	}	/*	 * OK to give up the spin lock, as we are the one and only	 * process using this text and have excluded others by	 * maintaining ((xp->x_flag & X_LOCK) == 1).	 */	unlock_flag = !NULL;	smp_unlock(&lk_text);	splx(s);	/*	 * allocate text page table if it cannot be shared	 */	p->p_textpt = clrnd(ctopt(xp->x_size));	at = rmalloc(kernelmap, (long)p->p_textpt);	if (at == 0){		(void)splimp();		smp_lock(&lk_text, LK_RETRY);		return (0);	}	if (vmemall(&Usrptmap[at], p->p_textpt, p, CSYS, NULL, V_NOOP) == 0) {		rmfree(kernelmap, (long)p->p_textpt, at);		(void)splimp();		smp_lock(&lk_text, LK_RETRY);		return (0);	}	p->p_textbr = kmxtob(at);	vmaccess(&Usrptmap[at], (caddr_t)p->p_textbr, p->p_textpt, DO_CACHE);	for (i=0; i < p->p_textpt; i++) {#ifdef USE_IDLE		/* don't bother if it's already done */		if (cmap[pgtocm(Usrptmap[at+i].pg_pfnum)].c_zero) {			extern int v_zero_pt_hits;			v_zero_pt_hits++;			cmap[pgtocm(Usrptmap[at+i].pg_pfnum)].c_zero=0;		}		else {			extern int v_zero_pt_misses;			v_zero_pt_misses++;			clearseg(Usrptmap[at+i].pg_pfnum);		}#else		clearseg(Usrptmap[at+i].pg_pfnum);#endif USE_IDLE	}	pte = tptopte(p, 0);	/*	 * Initialize text page tables, zfod if we are loading	 * the text now; unless the process is demand loaded,	 * this will suffice as the text will henceforth either be	 * read from a file or demand paged in.	 */	*(int *)&proto = PG_URKR;	if (xp->x_flag & XLOAD || xp->x_flag & XNOSPCE) {		proto.pg_fod = 1;		((struct fpte *)&proto)->pg_fileno = PG_FZERO;	}	for (i = 0; i < xp->x_size; i++)		*pte++ = proto;	if ((xp->x_flag & XPAGI) == 0)		goto done;	/*	 * Text is demand loaded.  If process is not loaded (i.e. being	 * swapped in) then retrieve page tables from swap area.  Otherwise	 * this is the first time and we must initialize the page tables	 * from the blocks in the file system.	 */	if (xp->x_flag & XLOAD || xp->x_flag & XNOSPCE){		vinifod((struct fpte *)tptopte(p, 0), PG_FTEXT, xp->x_gptr,		    (daddr_t)0, xp->x_size);		xp->x_flag &= ~XNOSPCE; /* clear the XNOSPCE flag setin xccdec*/	} else {		register int *dp, poff, ptsize,nfrag;		dp = xp->x_dmap->dm_ptdaddr;		nfrag = dtob(swapfrag);		poff = 0;

⌨️ 快捷键说明

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