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

📄 pt_machdep.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic	char	*sccsid = "@(#)pt_machdep.c	4.3	(ULTRIX)	9/6/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 * * 4-Sep-90	dlh *	added vector processor support code * * 03-Aug-90	rafiey (Ali Rafieymehr) *	Set the pages (u.pages) to modify. * * 19-Jun-90 -- jmartin *	Fixes for "panic: vrelvm rssize" * * 05 Mar 90 jaw *	IPL level lowered when text lock is released 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/mtpr.h"#include "../machine/cpu.h"#include "../h/ipc.h"#include "../h/shm.h"#include "../h/cpudata.h"#ifdef vax#include "../machine/cpu.h"#include "../../machine/common/cpuconf.h"#include "../machine/vectors.h"#endif vaxextern struct sminfo sminfo;extern int swapfrag;/* * Get 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)();       /* here for consistency with mips */{	register long a;	register int i;	if (p->p_szpt == 0)		panic("vgetpt");	/*	 * Allocate space in the kernel map for this process.	 * Then allocate page table pages, and initialize the	 * process' p0br and addr pointer 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 ((a = rmalloc(kernelmap, (long)p->p_szpt)) == 0)		return (0);	if ((*pmemall)(&Usrptmap[a], p->p_szpt, p, CSYS, NULL, V_NOOP) == 0) {		rmfree(kernelmap, (long)p->p_szpt, a);		return (0);	}	p->p_p0br = kmxtob(a);	p->p_addr = uaddr(p);	/*	 * 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.	 */	vmaccess(&Usrptmap[a], (caddr_t)p->p_p0br, p->p_szpt, 0);	blkclr((caddr_t)p->p_p0br, p->p_szpt*NBPG);	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;	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.	 */		struct pte *qpte = tptopte(q, 0);		int s1;		/* synchronize with ptexpand() */		s1 = splclock();		smp_lock(&lk_rq,LK_RETRY);		if (CURRENT_CPUDATA->cpu_tbi_flag) {			mtpr(TBIA,0);			CURRENT_CPUDATA->cpu_tbi_flag = 0;		}		smp_unlock(&lk_rq);		splx(s1);		blkcpy((caddr_t)qpte, (caddr_t)pte,		    (unsigned) (sizeof(struct pte) * xp->x_size));		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);	/*	 * 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)1, 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;		ptsize = xp->x_size * sizeof (struct pte);		while(ptsize > nfrag){			if(*dp == 0)				panic("vinitpt: text pt swap addr 0");			swap(p, *dp++, (caddr_t)tptopte(p, poff),			nfrag, B_READ, B_PAGET, swapdev,0);			ptsize -= nfrag;			poff += nfrag/sizeof(struct pte);		}		if(*dp == 0)			panic("vinitpt: text pt swap addr 0");		swap(p, *dp, (caddr_t)tptopte(p, poff),		    ptsize, B_READ, B_PAGET, swapdev, 0);	}done:	/*	 * In the case where we are overlaying ourself with new page	 * table entries, old user-space translations should be flushed.	 */	if (p == u.u_procp)		newptes(p, tptov(p, 0), xp->x_size);	else		SET_P_VM(p, SPTECHG);	if (unlock_flag) {		(void)splimp();		smp_lock(&lk_text, LK_RETRY);	}	return(1);}/* VINITSMPT - Initialize shared memory portion of page table	*//*	for the given shared memory segment.			*//*	As a short cut, to get this done in a hurry, I have	*//*	made shared memory segment page tables wired-down.	*//* LeRoy Fundingsland    1/18/85    DEC		SHMEM		*/vinitsmpt(p, sp)	register struct proc *p;	register struct smem *sp;{	register struct pte *pte, *pte1;	register int i, smindex;	register int smsize;		/* SMS size in clicks	*/	int s;	XPRINTF(XPR_VM,"enter vinitsmpt",0,0,0,0);	if(sp == NULL)		return;	if(p->p_sm == (struct p_sm *) NULL) {		panic("vinitsmpt: p_sm");	}	for(smindex=0; smindex < sminfo.smseg; smindex++)		if(p->p_sm[smindex].sm_p == sp)			break;	if(smindex >= sminfo.smseg)		panic("vinitsmpt");	pte = p->p_p0br + p->p_sm[smindex].sm_saddr;	smsize = clrnd(btoc(sp->sm_size));	/* set up process' ptes */	pte1 = sp->sm_ptaddr;	for(i=0; i < smsize; i++)			*(int *)pte++ = *(int *)pte1++ |				(int)p->p_sm[smindex].sm_pflag;	/*	 * In the case where we are overlaying ourself with new page	 * table entries, old user-space translations must be flushed.	 */	if (p == u.u_procp)		newptes(p, tptov(p,p->p_sm[smindex].sm_saddr),							smsize);	else		SET_P_VM(p, SPTECHG);}#ifndef distpte/* * Update the page tables of all processes linked * to a particular text segment, by distributing * dpte to the the text page at virtual frame v. * * Note that invalidation in the translation buffer for * the current process is the responsibility of the caller. */distpte(xp, tp, dpte)	struct text *xp;	register size_t tp;	register struct pte *dpte;{	register struct proc *p;	register struct pte *pte;	register int i;	int s;#ifdef SMP_DEBUG	if (smp_debug)		lsert(&lk_text);#endif SMP_DEBUG	s = splclock();	smp_lock(&lk_rq,LK_RETRY);	if (CURRENT_CPUDATA->cpu_tbi_flag) {		mtpr(TBIA,0);		CURRENT_CPUDATA->cpu_tbi_flag = 0;	}	smp_unlock(&lk_rq);	splx(s);	for (p = xp->x_caddr; p; p = p->p_xlink) {		pte = tptopte(p, tp);		SET_P_VM(p, SPTECHG);      		if (pte != dpte) {			for (i = 0; i < CLSIZE; i++)				pte[i] = dpte[i];		}	}}#endif distpte#ifndef distsmpte/* DISTSMPTE - Update the page tables of all processes linked	*//*	to a particular shared memory segment, by distributing	*//*	dpte to the the shared memory page at virtual frame smp.*//*								*//*	Note that invalidation in the translation buffer for	*//*	the current process is the responsibility of the caller.*//* 			 SHMEM					*/distsmpte(sp, smp, dpte, cm)	register struct smem *sp;	size_t smp;	register struct pte *dpte;	/* Global PTE */	int cm;				/* clear pg_m flag */{	register struct pte *pte;	register int i, j;	register struct proc *p;	int s;	/* if the SMS is currently not attached	*/	/* to any process then return.		*/	if(sp->sm_ccount == 0 || sp->sm_caddr == NULL)		return;	p = sp->sm_caddr;	if(p->p_sm == (struct p_sm *) NULL) {		panic("distmpte: p_sm1");	}	for(i=0; i < sminfo.smseg; i++)		if(p->p_sm[i].sm_p == sp)			break;	if(i >= sminfo.smseg)		panic("distsmpte");	/* if requested, clear pg_m bit in global PTE */	if (cm == PG_CLEARM) {		dpte->pg_m = 0;		distcl(dpte);	}	while(p){		int unlock_text;		unlock_text = 0;		if (smp_owner(&lk_text) == LK_FALSE) {			smp_lock(&lk_text, LK_RETRY);			++unlock_text;		}		pte = p->p_p0br + p->p_sm[i].sm_saddr+smp;		/* synchronize with ptexpand() */		s = splclock();		smp_lock(&lk_rq,LK_RETRY);		if (CURRENT_CPUDATA->cpu_tbi_flag) {			mtpr(TBIA,0);			CURRENT_CPUDATA->cpu_tbi_flag = 0;		}		smp_unlock(&lk_rq);		splx(s);		/* this panic should eventually go away */		if (pte->pg_v && dpte->pg_fod) {			panic("distsmpte: PG_V && PG_FOD");		}		SET_P_VM(p, SPTECHG);		/* CAREFUL: I'm incrementing 'pte' */		for (j=0; j < CLSIZE; j++, pte++) {			*(int *) pte &= PG_PROT|PG_M;			*(int *) pte |= (*(int *)(dpte+j)) & ~(PG_PROT|PG_M);			if (cm == PG_CLEARM)				pte->pg_m = 0;		}

⌨️ 快捷键说明

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