Home | History | Annotate | Line # | Download | only in vax
      1 /*	$NetBSD: pmap.c,v 1.201 2023/12/22 19:14:57 thorpej Exp $	   */
      2 /*
      3  * Copyright (c) 1994, 1998, 1999, 2003 Ludd, University of Lule}, Sweden.
      4  * All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25  */
     26 
     27 #include <sys/cdefs.h>
     28 __KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.201 2023/12/22 19:14:57 thorpej Exp $");
     29 
     30 #include "opt_cputype.h"
     31 #include "opt_ddb.h"
     32 #include "opt_lockdebug.h"
     33 #include "opt_modular.h"
     34 #include "opt_multiprocessor.h"
     35 #include "opt_pipe.h"
     36 
     37 #include <sys/param.h>
     38 
     39 #include <sys/atomic.h>
     40 #include <sys/buf.h>
     41 #include <sys/cpu.h>
     42 #include <sys/device.h>
     43 #include <sys/extent.h>
     44 #include <sys/kmem.h>
     45 #include <sys/mutex.h>
     46 #include <sys/proc.h>
     47 #include <sys/syncobj.h>
     48 #include <sys/systm.h>
     49 
     50 #include <uvm/uvm.h>
     51 #include <uvm/uvm_physseg.h>
     52 
     53 #ifdef PMAPDEBUG
     54 #include <dev/cons.h>
     55 #endif
     56 
     57 #include <machine/macros.h>
     58 #include <machine/rpb.h>
     59 #include <machine/scb.h>
     60 #include <machine/sid.h>
     61 
     62 /* QDSS console mapping hack */
     63 #include "qd.h"
     64 void	qdearly(void);
     65 
     66 /*
     67  * This code uses bitfield operators for most page table entries.
     68  */
     69 #define PROTSHIFT	27
     70 #define PROT_KW		(PG_KW >> PROTSHIFT)
     71 #define PROT_KR		(PG_KR >> PROTSHIFT)
     72 #define PROT_RW		(PG_RW >> PROTSHIFT)
     73 #define PROT_RO		(PG_RO >> PROTSHIFT)
     74 #define PROT_URKW	(PG_URKW >> PROTSHIFT)
     75 
     76 /*
     77  * Scratch pages usage:
     78  * Page 1: initial frame pointer during autoconfig. Stack and pcb for
     79  *	   processes during exit on boot CPU only.
     80  * Page 2: cpu_info struct for any CPU.
     81  * Page 3: unused
     82  * Page 4: unused
     83  */
     84 uintptr_t scratch;
     85 #define SCRATCHPAGES	4
     86 
     87 
     88 static struct pmap kernel_pmap_store;
     89 struct pmap *const kernel_pmap_ptr = &kernel_pmap_store;
     90 
     91 struct	pte *Sysmap;		/* System page table */
     92 struct	pv_entry *pv_table;	/* array of entries, one per LOGICAL page */
     93 u_int	pventries;
     94 u_int	pvinuse;
     95 vaddr_t iospace;
     96 
     97 vaddr_t ptemapstart, ptemapend;
     98 struct	extent *ptemap;
     99 #define PTMAPSZ EXTENT_FIXED_STORAGE_SIZE(100)
    100 char	ptmapstorage[PTMAPSZ];
    101 
    102 extern	void *msgbufaddr;
    103 
    104 #define IOSPACE_P(p)	(((u_long)(p) & 0xe0000000) != 0)
    105 #define NPTEPROCSPC	0x1000	/* # of virtual PTEs per process space */
    106 #define NPTEPG		0x80	/* # of PTEs per page (logical or physical) */
    107 #define PPTESZ		sizeof(struct pte)
    108 #define NOVADDR		0xffffffff /* Illegal virtual address */
    109 #define NPTEPERREG	0x200000
    110 
    111 #define	SEGTYPE(x)	(((unsigned int)(x)) >> 30)
    112 #define	P0SEG		0
    113 #define P1SEG		1
    114 #define	SYSSEG		2
    115 
    116 static inline void
    117 pmap_decrement_stats(struct pmap *pm, bool wired)
    118 {
    119 	pm->pm_stats.resident_count--;
    120 	if (wired)
    121 		pm->pm_stats.wired_count--;
    122 }
    123 
    124 /*
    125  * Map in a virtual page.
    126  */
    127 static inline void
    128 mapin8(int *ptep, long pte)
    129 {
    130 	ptep[0] = pte;
    131 	ptep[1] = pte+1;
    132 	ptep[2] = pte+2;
    133 	ptep[3] = pte+3;
    134 	ptep[4] = pte+4;
    135 	ptep[5] = pte+5;
    136 	ptep[6] = pte+6;
    137 	ptep[7] = pte+7;
    138 }
    139 
    140 /*
    141  * Check if page table page is in use.
    142  */
    143 static inline int
    144 ptpinuse(void *pte)
    145 {
    146 	int *pve = (int *)vax_trunc_page(pte);
    147 	int i;
    148 
    149 	for (i = 0; i < NPTEPG; i += 8)
    150 		if (pve[i] != 0)
    151 			return 1;
    152 	return 0;
    153 }
    154 
    155 #ifdef PMAPDEBUG
    156 #define PMDEBUG(x) if (startpmapdebug)printf x
    157 #else
    158 #define PMDEBUG(x)
    159 #endif
    160 
    161 #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
    162 static kmutex_t pmap_lock;
    163 #define PMAP_LOCK	mutex_spin_enter(&pmap_lock);
    164 #define PMAP_UNLOCK	mutex_spin_exit(&pmap_lock);
    165 #else
    166 #define PMAP_LOCK
    167 #define PMAP_UNLOCK
    168 #endif
    169 
    170 #ifdef PMAPDEBUG
    171 int	startpmapdebug = 0;
    172 #endif
    173 
    174 paddr_t	  avail_start, avail_end;
    175 vaddr_t	  virtual_avail, virtual_end; /* Available virtual memory	*/
    176 
    177 struct pv_entry *get_pventry(void);
    178 void free_pventry(struct pv_entry *);
    179 void more_pventries(void);
    180 vaddr_t get_ptp(void);
    181 void free_ptp(paddr_t);
    182 
    183 /*
    184  * Calculation of the System Page Table is somewhat a pain, because it
    185  * must be in contiguous physical memory and all size calculations must
    186  * be done before memory management is turned on.
    187  * Arg is usrptsize in ptes.
    188  */
    189 static vsize_t
    190 calc_kvmsize(vsize_t usrptsize)
    191 {
    192 	vsize_t kvmsize, bufsz;
    193 
    194 	/*
    195 	 * Compute the number of pages kmem_arena will have.
    196 	 */
    197 	kmeminit_nkmempages();
    198 
    199 	/* All physical memory */
    200 	kvmsize = avail_end;
    201 	/* User Page table area. This may be large */
    202 	kvmsize += (usrptsize * sizeof(struct pte));
    203 	/* Kernel stacks per process */
    204 	kvmsize += (USPACE * maxproc);
    205 	/* kernel malloc arena */
    206 	kvmsize += nkmempages * PAGE_SIZE;
    207 	/* IO device register space */
    208 	kvmsize += (IOSPSZ * VAX_NBPG);
    209 	/* Pager allocations */
    210 	kvmsize += (pager_map_size + MAXBSIZE);
    211 	/* Anon pool structures */
    212 	kvmsize += (physmem * sizeof(struct vm_anon));
    213 	/* kernel malloc arena */
    214 	kvmsize += avail_end;
    215 
    216 	/* Buffer space - get size of buffer cache and set an upper limit */
    217 	bufsz = buf_memcalc();
    218 	buf_setvalimit(bufsz);
    219 	kvmsize += bufsz;
    220 
    221 	/* UBC submap space */
    222 	kvmsize += (UBC_NWINS << UBC_WINSHIFT);
    223 
    224 	/* Exec arg space */
    225 	kvmsize += NCARGS;
    226 #if VAX46 || VAX48 || VAX49 || VAX53 || VAXANY
    227 	/* Physmap */
    228 	kvmsize += VM_PHYS_SIZE;
    229 #endif
    230 #if VAX46 || VAX49
    231 	kvmsize += 0x800000; /* 8 MB framebuffer */
    232 #endif
    233 #ifdef MODULAR
    234 	/* Modules are allocated out of kernel_map */
    235 #define MAXLKMSIZ	0x100000	/* XXX */
    236 	kvmsize += MAXLKMSIZ;
    237 #endif
    238 
    239 	/* The swapper uses many anon's, set an arbitrary size */
    240 #ifndef SWAPSIZE
    241 #define	SWAPSIZE (200*1024*1024)	/* Assume 200MB swap */
    242 #endif
    243 	kvmsize += ((SWAPSIZE/PAGE_SIZE)*sizeof(struct vm_anon));
    244 
    245 	/* New pipes may steal some amount of memory. Calculate 10 pipes */
    246 #ifndef PIPE_SOCKETPAIR
    247 	kvmsize += PIPE_DIRECT_CHUNK*10;
    248 #endif
    249 	kvmsize = round_page(kvmsize);
    250 	return kvmsize;
    251 }
    252 
    253 /*
    254  * pmap_bootstrap().
    255  * Called as part of vm bootstrap, allocates internal pmap structures.
    256  * Assumes that nothing is mapped, and that kernel stack is located
    257  * immediately after end.
    258  */
    259 void
    260 pmap_bootstrap(void)
    261 {
    262 	struct pcb * const pcb = lwp_getpcb(&lwp0);
    263 	struct pmap * const pmap = pmap_kernel();
    264 	struct cpu_info *ci;
    265 	extern unsigned int etext;
    266 	unsigned int sysptsize, i;
    267 	vsize_t kvmsize, usrptsize;
    268 	vaddr_t istack;
    269 
    270 	/* Set logical page size */
    271 	uvmexp.pagesize = NBPG;
    272 	uvm_md_init();
    273 
    274 	physmem = btoc(avail_end);
    275 
    276 	usrptsize = (1024*1024*1024)/VAX_NBPG;	/* 1GB total VM */
    277 	if (vax_btop(usrptsize)* PPTESZ > avail_end/20)
    278 		usrptsize = (avail_end/(20 * PPTESZ)) * VAX_NBPG;
    279 
    280 	kvmsize = calc_kvmsize(usrptsize);
    281 	/*
    282 	 * Ensure that not more than 1G is allocated, since that is
    283 	 * max size of S0 space.
    284 	 * Also note that for full S0 space the SLR should be 0x200000,
    285 	 * since the comparison in the vax microcode is >= SLR.
    286 	 */
    287 #define	S0SPACE	(1*1024*1024*1024)
    288 	if (kvmsize > S0SPACE)
    289 		kvmsize = S0SPACE;
    290 	sysptsize = kvmsize >> VAX_PGSHIFT;
    291 	/*
    292 	 * Virtual_* and avail_* is used for mapping of system page table.
    293 	 * The need for kernel virtual memory is linear dependent of the
    294 	 * amount of physical memory also, therefore sysptsize is
    295 	 * a variable here that is changed dependent of the physical
    296 	 * memory size.
    297 	 */
    298 	virtual_avail = avail_end + KERNBASE;
    299 	virtual_end = KERNBASE + sysptsize * VAX_NBPG;
    300 	memset(Sysmap, 0, sysptsize * 4); /* clear SPT before using it */
    301 
    302 	/*
    303 	 * The first part of Kernel Virtual memory is the physical
    304 	 * memory mapped in. This makes some mm routines both simpler
    305 	 * and faster, but takes ~0.75% more memory.
    306 	 */
    307 	pmap_map(KERNBASE, 0, avail_end, VM_PROT_READ|VM_PROT_WRITE);
    308 	/*
    309 	 * Kernel code is always readable for user, it must be because
    310 	 * of the emulation code that is somewhere in there.
    311 	 * And it doesn't hurt, /netbsd is also public readable.
    312 	 * There are also a couple of other things that must be in
    313 	 * physical memory and that isn't managed by the vm system.
    314 	 */
    315 	for (i = 0; i < ((unsigned)&etext ^ KERNBASE) >> VAX_PGSHIFT; i++)
    316 		Sysmap[i].pg_prot = PROT_URKW;
    317 
    318 	/* Map System Page Table and zero it,  Sysmap already set. */
    319 	mtpr((unsigned)Sysmap - KERNBASE, PR_SBR);
    320 
    321 	/* Map Interrupt stack and set red zone */
    322 	istack = (uintptr_t)Sysmap + round_page(sysptsize * 4);
    323 	mtpr(istack + USPACE, PR_ISP);
    324 	kvtopte(istack)->pg_v = 0;
    325 
    326 	/* Some scratch pages */
    327 	scratch = istack + USPACE;
    328 
    329 	/* Physical-to-virtual translation table */
    330 	pv_table = (struct pv_entry *)(scratch + SCRATCHPAGES * VAX_NBPG);
    331 
    332 	avail_start = (vaddr_t)pv_table + (round_page(avail_end >> PGSHIFT)) *
    333 	    sizeof(struct pv_entry) - KERNBASE;
    334 
    335 	/* Kernel message buffer */
    336 	avail_end -= MSGBUFSIZE;
    337 	msgbufaddr = (void *)(avail_end + KERNBASE);
    338 
    339 	/* zero all mapped physical memory from Sysmap to here */
    340 	memset((void *)istack, 0, (avail_start + KERNBASE) - istack);
    341 
    342 	/* QDSS console mapping hack */
    343 #if NQD > 0
    344 	qdearly();
    345 #endif
    346 
    347 	/* User page table map. This is big. */
    348 	MAPVIRT(ptemapstart, vax_btoc(usrptsize * sizeof(struct pte)));
    349 	ptemapend = virtual_avail;
    350 
    351 	MAPVIRT(iospace, IOSPSZ); /* Device iospace mapping area */
    352 
    353 	/* Init SCB and set up stray vectors. */
    354 	avail_start = scb_init(avail_start);
    355 	*(struct rpb *)0 = *(struct rpb *)(uvm_lwp_getuarea(&lwp0) + REDZONEADDR);
    356 
    357 	if (dep_call->cpu_steal_pages)
    358 		(*dep_call->cpu_steal_pages)();
    359 
    360 	avail_start = round_page(avail_start);
    361 	virtual_avail = round_page(virtual_avail);
    362 	virtual_end = trunc_page(virtual_end);
    363 
    364 
    365 #if 0 /* Breaks cninit() on some machines */
    366 	cninit();
    367 	printf("Sysmap %p, istack %lx, scratch %lx\n",Sysmap,ci->ci_istack,scratch);
    368 	printf("etext %p, kvmsize %lx\n", &etext, kvmsize);
    369 	printf("SYSPTSIZE %x usrptsize %lx\n",
    370 	    sysptsize, usrptsize * sizeof(struct pte));
    371 	printf("pv_table %p, ptemapstart %lx ptemapend %lx\n",
    372 	    pv_table, ptemapstart, ptemapend);
    373 	printf("avail_start %lx, avail_end %lx\n",avail_start,avail_end);
    374 	printf("virtual_avail %lx,virtual_end %lx\n",
    375 	    virtual_avail, virtual_end);
    376 	printf("startpmapdebug %p\n",&startpmapdebug);
    377 #endif
    378 
    379 
    380 	/* Init kernel pmap */
    381 	pmap->pm_p1br = (struct pte *)KERNBASE;
    382 	pmap->pm_p0br = (struct pte *)KERNBASE;
    383 	pmap->pm_p1lr = NPTEPERREG;
    384 	pmap->pm_p0lr = 0;
    385 	pmap->pm_stats.wired_count = pmap->pm_stats.resident_count = 0;
    386 	    /* btop(virtual_avail - KERNBASE); */
    387 
    388 	pmap->pm_count = 1;
    389 
    390 	/* Activate the kernel pmap. */
    391 	pcb->P1BR = pmap->pm_p1br;
    392 	pcb->P0BR = pmap->pm_p0br;
    393 	pcb->P1LR = pmap->pm_p1lr;
    394 	pcb->P0LR = pmap->pm_p0lr|AST_PCB;
    395 	pcb->pcb_pm = pmap;
    396 	pcb->pcb_pmnext = pmap->pm_pcbs;
    397 	pmap->pm_pcbs = pcb;
    398 	mtpr((uintptr_t)pcb->P1BR, PR_P1BR);
    399 	mtpr((uintptr_t)pcb->P0BR, PR_P0BR);
    400 	mtpr(pcb->P1LR, PR_P1LR);
    401 	mtpr(pcb->P0LR, PR_P0LR);
    402 
    403 	/* initialize SSP to point curlwp (lwp0) */
    404 	pcb->SSP = (uintptr_t)&lwp0;
    405 	mtpr(pcb->SSP, PR_SSP);
    406 
    407 	/* cpu_info struct */
    408 	ci = (struct cpu_info *) scratch;
    409 	lwp0.l_cpu = ci;
    410 	ci->ci_istack = istack;
    411 	memset(ci, 0, sizeof(*ci));
    412 #if defined(MULTIPROCESSOR)
    413 	ci->ci_curlwp = &lwp0;
    414 	ci->ci_flags = CI_MASTERCPU|CI_RUNNING;
    415 	SIMPLEQ_FIRST(&cpus) = ci;
    416 #endif
    417 #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
    418 	mutex_init(&pmap_lock, MUTEX_DEFAULT, IPL_VM);
    419 #endif
    420 
    421 	/*
    422 	 * Now everything should be complete, start virtual memory.
    423 	 */
    424 	uvm_page_physload(avail_start >> PGSHIFT, avail_end >> PGSHIFT,
    425 	    avail_start >> PGSHIFT, avail_end >> PGSHIFT,
    426 	    VM_FREELIST_DEFAULT);
    427 	mtpr(sysptsize, PR_SLR);
    428 	rpb.sbr = mfpr(PR_SBR);
    429 	rpb.slr = mfpr(PR_SLR);
    430 	rpb.wait = 0;	/* DDB signal */
    431 	mtpr(1, PR_MAPEN);
    432 }
    433 
    434 /*
    435  * Define the initial bounds of the kernel virtual address space.
    436  */
    437 void
    438 pmap_virtual_space(vaddr_t *vstartp, vaddr_t *vendp)
    439 {
    440 	*vstartp = virtual_avail;
    441 	*vendp = virtual_end;
    442 }
    443 
    444 /*
    445  * Let the VM system do early memory allocation from the direct-mapped
    446  * physical memory instead.
    447  */
    448 vaddr_t
    449 pmap_steal_memory(vsize_t size, vaddr_t *vstartp, vaddr_t *vendp)
    450 {
    451 	vaddr_t v;
    452 	int npgs;
    453 	uvm_physseg_t bank;
    454 
    455 	PMDEBUG(("pmap_steal_memory: size 0x%lx start %p end %p\n",
    456 		    size, vstartp, vendp));
    457 
    458 	size = round_page(size);
    459 	npgs = btoc(size);
    460 
    461 #ifdef DIAGNOSTIC
    462 	if (uvm.page_init_done == true)
    463 		panic("pmap_steal_memory: called _after_ bootstrap");
    464 #endif
    465 
    466 	/*
    467 	 * A vax only have one segment of memory.
    468 	 */
    469 	bank = uvm_physseg_get_first();
    470 
    471 	v = (uvm_physseg_get_start(bank) << PGSHIFT) | KERNBASE;
    472 	uvm_physseg_unplug(uvm_physseg_get_start(bank), npgs);
    473 	memset((void *)v, 0, size);
    474 	return v;
    475 }
    476 
    477 /*
    478  * pmap_init() is called as part of vm init after memory management
    479  * is enabled. It is meant to do machine-specific allocations.
    480  * Here is the resource map for the user page tables inited.
    481  */
    482 void
    483 pmap_init(void)
    484 {
    485 	/*
    486 	 * Create the extent map used to manage the page table space.
    487 	 */
    488 	ptemap = extent_create("ptemap", ptemapstart, ptemapend,
    489 	    ptmapstorage, PTMAPSZ, EX_NOCOALESCE);
    490 	if (ptemap == NULL)
    491 		panic("pmap_init");
    492 }
    493 
    494 static u_long
    495 pmap_extwrap(vsize_t nsize)
    496 {
    497 	int res;
    498 	u_long rv;
    499 
    500 	for (;;) {
    501 		res = extent_alloc(ptemap, nsize, PAGE_SIZE, 0,
    502 		    EX_WAITOK|EX_MALLOCOK, &rv);
    503 		if (res == EAGAIN)
    504 			return 0;
    505 		if (res == 0)
    506 			return rv;
    507 	}
    508 }
    509 
    510 /*
    511  * Do a page removal from the pv table. A page is identified by its
    512  * virtual address combined with its struct pmap in the pv table.
    513  */
    514 static void
    515 rmpage(pmap_t pm, int *br)
    516 {
    517 	struct pv_entry *pv, *pl, *pf;
    518 	vaddr_t vaddr;
    519 	int found = 0;
    520 
    521 	if (pm == pmap_kernel())
    522 		vaddr = (br - (int *)Sysmap) * VAX_NBPG + 0x80000000;
    523 	else if ((br >= (int *)pm->pm_p0br) &&
    524 	    (br < ((int *)pm->pm_p0br + pm->pm_p0lr)))
    525 		vaddr = (br - (int *)pm->pm_p0br) * VAX_NBPG;
    526 	else
    527 		vaddr = (br - (int *)pm->pm_p1br) * VAX_NBPG + 0x40000000;
    528 
    529 	if (IOSPACE_P((br[0] & PG_FRAME) << VAX_PGSHIFT))
    530 		return; /* Forget mappings of IO space */
    531 
    532 	pv = pv_table + ((br[0] & PG_FRAME) >> LTOHPS);
    533 	if (((br[0] & PG_PROT) == PG_RW) &&
    534 	    ((pv->pv_attr & PG_M) != PG_M))
    535 		pv->pv_attr |= br[0]|br[1]|br[2]|br[3]|br[4]|br[5]|br[6]|br[7];
    536 	pmap_decrement_stats(pm, (br[0] & PG_W) != 0);
    537 	if (pv->pv_pmap == pm && pv->pv_vaddr == vaddr) {
    538 		pv->pv_vaddr = NOVADDR;
    539 		pv->pv_pmap = 0;
    540 		found++;
    541 	} else
    542 		for (pl = pv; pl->pv_next; pl = pl->pv_next) {
    543 			if (pl->pv_next->pv_pmap != pm ||
    544 			    pl->pv_next->pv_vaddr != vaddr)
    545 				continue;
    546 			pf = pl->pv_next;
    547 			pl->pv_next = pl->pv_next->pv_next;
    548 			free_pventry(pf);
    549 			found++;
    550 			break;
    551 		}
    552 	if (found == 0)
    553 		panic("rmpage: pm %p br %p", pm, br);
    554 }
    555 /*
    556  * Update the PCBs using this pmap after a change.
    557  */
    558 static void
    559 update_pcbs(struct pmap *pm)
    560 {
    561 	struct pcb *pcb;
    562 
    563 	for (pcb = pm->pm_pcbs; pcb != NULL; pcb = pcb->pcb_pmnext) {
    564 		KASSERT(pcb->pcb_pm == pm);
    565 		pcb->P0BR = pm->pm_p0br;
    566 		pcb->P0LR = pm->pm_p0lr | (pcb->P0LR & AST_MASK);
    567 		pcb->P1BR = pm->pm_p1br;
    568 		pcb->P1LR = pm->pm_p1lr;
    569 
    570 	}
    571 
    572 	/* If curlwp uses this pmap update the regs too */
    573 	if (pm == curproc->p_vmspace->vm_map.pmap) {
    574 		mtpr((uintptr_t)pm->pm_p0br, PR_P0BR);
    575 		mtpr(pm->pm_p0lr, PR_P0LR);
    576 		mtpr((uintptr_t)pm->pm_p1br, PR_P1BR);
    577 		mtpr(pm->pm_p1lr, PR_P1LR);
    578 	}
    579 
    580 #if defined(MULTIPROCESSOR) && defined(notyet)
    581 	/* If someone else is using this pmap, be sure to reread */
    582 	cpu_send_ipi(IPI_DEST_ALL, IPI_NEWPTE);
    583 #endif
    584 }
    585 
    586 /*
    587  * Allocate a page through direct-mapped segment.
    588  */
    589 static vaddr_t
    590 getpage(void)
    591 {
    592 	struct vm_page *pg;
    593 
    594 	pg = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_ZERO);
    595 	if (pg == NULL)
    596 		return 0;
    597 	return (VM_PAGE_TO_PHYS(pg)|KERNBASE);
    598 }
    599 
    600 #if 0
    601 /*
    602  * Free the page allocated above.
    603  */
    604 static void
    605 freepage(vaddr_t v)
    606 {
    607 	paddr_t paddr = (kvtopte(v)->pg_pfn << VAX_PGSHIFT);
    608 	uvm_pagefree(PHYS_TO_VM_PAGE(paddr));
    609 }
    610 #endif
    611 
    612 /*
    613  * Remove a full process space. Update all processes pcbs.
    614  */
    615 static void
    616 rmspace(struct pmap *pm)
    617 {
    618 	int lr, i, j, *br, *ptpp;
    619 
    620 	if (pm->pm_p0lr == 0 && pm->pm_p1lr == NPTEPERREG)
    621 		return; /* Already free */
    622 
    623 	lr = pm->pm_p0lr/NPTEPG;
    624 	for (i = 0; i < lr; i++) {
    625 		ptpp = (int *)kvtopte(&pm->pm_p0br[i*NPTEPG]);
    626 		if (*ptpp == 0)
    627 			continue;
    628 		br = (int *)&pm->pm_p0br[i*NPTEPG];
    629 		for (j = 0; j < NPTEPG; j+=LTOHPN) {
    630 			if (br[j] == 0)
    631 				continue;
    632 			rmpage(pm, &br[j]);
    633 		}
    634 		free_ptp((((struct pte *)ptpp)->pg_pfn << VAX_PGSHIFT));
    635 		*ptpp = 0;
    636 		mtpr((vaddr_t)br, PR_TBIS);
    637 	}
    638 	lr = pm->pm_p1lr/NPTEPG;
    639 	for (i = lr; i < NPTEPERREG/NPTEPG; i++) {
    640 		ptpp = (int *)kvtopte(&pm->pm_p1br[i*NPTEPG]);
    641 		if (*ptpp == 0)
    642 			continue;
    643 		br = (int *)&pm->pm_p1br[i*NPTEPG];
    644 		for (j = 0; j < NPTEPG; j+=LTOHPN) {
    645 			if (br[j] == 0)
    646 				continue;
    647 			rmpage(pm, &br[j]);
    648 		}
    649 		free_ptp((((struct pte *)ptpp)->pg_pfn << VAX_PGSHIFT));
    650 		*ptpp = 0;
    651 		mtpr((vaddr_t)br, PR_TBIS);
    652 	}
    653 
    654 	if (pm->pm_p0lr != 0)
    655 		extent_free(ptemap, (u_long)pm->pm_p0br,
    656 		    pm->pm_p0lr * PPTESZ, EX_WAITOK);
    657 	if (pm->pm_p1lr != NPTEPERREG)
    658 		extent_free(ptemap, (u_long)pm->pm_p1ap,
    659 		    (NPTEPERREG - pm->pm_p1lr) * PPTESZ, EX_WAITOK);
    660 	pm->pm_p0br = pm->pm_p1br = (struct pte *)KERNBASE;
    661 	pm->pm_p0lr = 0;
    662 	pm->pm_p1lr = NPTEPERREG;
    663 	pm->pm_p1ap = NULL;
    664 	update_pcbs(pm);
    665 }
    666 
    667 /*
    668  * Find a process to remove the process space for. *sigh*
    669  * Avoid to remove ourselves.
    670  */
    671 
    672 static inline bool
    673 pmap_vax_swappable(struct lwp *l, struct pmap *pm)
    674 {
    675 
    676 	if (l->l_flag & (LW_SYSTEM | LW_WEXIT))
    677 		return false;
    678 	if (l->l_proc->p_vmspace->vm_map.pmap == pm)
    679 		return false;
    680 	if ((l->l_pflag & LP_RUNNING) != 0)
    681 		return false;
    682 	if (l->l_class != SCHED_OTHER)
    683 		return false;
    684 	if (l->l_syncobj == &rw_syncobj || l->l_syncobj == &mutex_syncobj)
    685 		return false;
    686 	if (l->l_proc->p_stat != SACTIVE && l->l_proc->p_stat != SSTOP)
    687 		return false;
    688 	return true;
    689 }
    690 
    691 static int
    692 pmap_rmproc(struct pmap *pm)
    693 {
    694 	struct pmap *ppm;
    695 	struct lwp *l;
    696 	struct lwp *outl, *outl2;
    697 	int outpri, outpri2;
    698 	int didswap = 0;
    699 	extern int maxslp;
    700 
    701 	outl = outl2 = NULL;
    702 	outpri = outpri2 = 0;
    703 	mutex_enter(&proc_lock);
    704 	LIST_FOREACH(l, &alllwp, l_list) {
    705 		if (!pmap_vax_swappable(l, pm))
    706 			continue;
    707 		ppm = l->l_proc->p_vmspace->vm_map.pmap;
    708 		if (ppm->pm_p0lr == 0 && ppm->pm_p1lr == NPTEPERREG)
    709 			continue; /* Already swapped */
    710 		switch (l->l_stat) {
    711 		case LSRUN:
    712 		case LSONPROC:
    713 			if (l->l_swtime > outpri2) {
    714 				outl2 = l;
    715 				outpri2 = l->l_swtime;
    716 			}
    717 			continue;
    718 		case LSSLEEP:
    719 		case LSSTOP:
    720 			if (l->l_slptime >= maxslp) {
    721 				rmspace(l->l_proc->p_vmspace->vm_map.pmap);
    722 				didswap++;
    723 			} else if (l->l_slptime > outpri) {
    724 				outl = l;
    725 				outpri = l->l_slptime;
    726 			}
    727 			continue;
    728 		}
    729 	}
    730 	mutex_exit(&proc_lock);
    731 	if (didswap == 0) {
    732 		if ((l = outl) == NULL)
    733 			l = outl2;
    734 		if (l) {
    735 			rmspace(l->l_proc->p_vmspace->vm_map.pmap);
    736 			didswap++;
    737 		}
    738 	}
    739 	return didswap;
    740 }
    741 
    742 /*
    743  * Allocate space for user page tables, from ptemap.
    744  * Argument is needed space, in bytes.
    745  * Returns a pointer to the newly allocated space, or 0 if failed.
    746  */
    747 static vaddr_t
    748 pmap_getusrptes(pmap_t pm, vsize_t nsize)
    749 {
    750 	u_long rv;
    751 
    752 #ifdef DEBUG
    753 	if (nsize & PAGE_MASK)
    754 		panic("pmap_getusrptes: bad size %lx", nsize);
    755 #endif
    756 	while (((rv = pmap_extwrap(nsize)) == 0) && (pmap_rmproc(pm) != 0))
    757 		;
    758 	return rv;
    759 }
    760 
    761 /*
    762  * Remove a pte page when all references are gone.
    763  */
    764 static void
    765 rmptep(struct pte *pte)
    766 {
    767 	int *ptpp = (int *)kvtopte(pte);
    768 #ifdef DEBUG
    769 	{	int i, *ptr = (int *)vax_trunc_page(pte);
    770 		for (i = 0; i < NPTEPG; i++)
    771 			if (ptr[i] != 0)
    772 				panic("rmptep: ptr[%d] != 0", i);
    773 	}
    774 #endif
    775 	free_ptp((((struct pte *)ptpp)->pg_pfn << VAX_PGSHIFT));
    776 	*ptpp = 0;
    777 	/* N.B. callers all do a TBIA, so TBIS not needed here. */
    778 }
    779 
    780 static int
    781 grow_p0(struct pmap *pm, int reqlen)
    782 {
    783 	vaddr_t nptespc;
    784 	char *from, *to;
    785 	int srclen, dstlen;
    786 	int inuse, len, p0lr;
    787 	u_long p0br;
    788 
    789 	PMDEBUG(("grow_p0: pmap %p reqlen %d\n", pm, reqlen));
    790 
    791 	/* Get new pte space */
    792 	p0lr = pm->pm_p0lr;
    793 	inuse = p0lr != 0;
    794 	len = round_page((reqlen+1) * PPTESZ);
    795 	PMAP_UNLOCK;
    796 	nptespc = pmap_getusrptes(pm, len);
    797 	PMAP_LOCK;
    798 
    799 	if (nptespc == 0)
    800 		return 0;
    801 	/*
    802 	 * Copy the old ptes to the new space.
    803 	 * Done by moving on system page table.
    804 	 */
    805 	srclen = vax_btop(p0lr * PPTESZ) * PPTESZ;
    806 	dstlen = vax_btoc(len)*PPTESZ;
    807 	from = (char *)kvtopte(pm->pm_p0br);
    808 	to = (char *)kvtopte(nptespc);
    809 
    810 	PMDEBUG(("grow_p0: from %p to %p src %d dst %d\n",
    811 	    from, to, srclen, dstlen));
    812 
    813 	if (inuse)
    814 		memcpy(to, from, srclen);
    815 	memset(to+srclen, 0, dstlen-srclen);
    816 	p0br = (u_long)pm->pm_p0br;
    817 	pm->pm_p0br = (struct pte *)nptespc;
    818 	pm->pm_p0lr = (len/PPTESZ);
    819 	update_pcbs(pm);
    820 
    821 	/* Remove the old after update_pcbs() (for multi-CPU propagation) */
    822 	if (inuse)
    823 		extent_free(ptemap, p0br, p0lr*PPTESZ, EX_WAITOK);
    824 	return 1;
    825 }
    826 
    827 
    828 static int
    829 grow_p1(struct pmap *pm, int len)
    830 {
    831 	vaddr_t nptespc, optespc;
    832 	int nlen, olen;
    833 
    834 	PMDEBUG(("grow_p1: pm %p len %x\n", pm, len));
    835 
    836 	/* Get new pte space */
    837 	nlen = (NPTEPERREG*PPTESZ) - trunc_page(len * PPTESZ);
    838 	PMAP_UNLOCK;
    839 	nptespc = pmap_getusrptes(pm, nlen);
    840 	PMAP_LOCK;
    841 	if (nptespc == 0)
    842 		return 0;
    843 
    844 	olen = (NPTEPERREG*PPTESZ) - (pm->pm_p1lr * PPTESZ);
    845 	optespc = (vaddr_t)pm->pm_p1ap;
    846 
    847 	/*
    848 	 * Copy the old ptes to the new space.
    849 	 * Done by moving on system page table.
    850 	 */
    851 	memset(kvtopte(nptespc), 0, vax_btop(nlen-olen) * PPTESZ);
    852 	if (optespc)
    853 		memcpy(kvtopte(nptespc+nlen-olen), kvtopte(optespc),
    854 		    vax_btop(olen) * PPTESZ);
    855 
    856 	pm->pm_p1ap = (struct pte *)nptespc;
    857 	pm->pm_p1br = (struct pte *)(nptespc+nlen-(NPTEPERREG*PPTESZ));
    858 	pm->pm_p1lr = NPTEPERREG - nlen/PPTESZ;
    859 	update_pcbs(pm);
    860 
    861 	if (optespc)
    862 		extent_free(ptemap, optespc, olen, EX_WAITOK);
    863 	return 1;
    864 }
    865 
    866 /*
    867  * Initialize a preallocated and zeroed pmap structure,
    868  */
    869 static void
    870 pmap_pinit(pmap_t pmap)
    871 {
    872 
    873 	/*
    874 	 * Do not allocate any pte's here, we don't know the size and
    875 	 * we'll get a page fault anyway when some page is referenced,
    876 	 * so do it then.
    877 	 */
    878 	pmap->pm_p0br = (struct pte *)KERNBASE;
    879 	pmap->pm_p1br = (struct pte *)KERNBASE;
    880 	pmap->pm_p0lr = 0;
    881 	pmap->pm_p1lr = NPTEPERREG;
    882 	pmap->pm_p1ap = NULL;
    883 
    884 	PMDEBUG(("pmap_pinit(%p): p0br=%p p0lr=0x%lx p1br=%p p1lr=0x%lx\n",
    885 	    pmap, pmap->pm_p0br, pmap->pm_p0lr, pmap->pm_p1br, pmap->pm_p1lr));
    886 
    887 	pmap->pm_count = 1;
    888 	pmap->pm_stats.resident_count = pmap->pm_stats.wired_count = 0;
    889 }
    890 
    891 /*
    892  * pmap_create() creates a pmap for a new task.
    893  * If not already allocated, allocate space for one.
    894  */
    895 struct pmap *
    896 pmap_create(void)
    897 {
    898 	struct pmap *pmap;
    899 
    900 	pmap = kmem_zalloc(sizeof(*pmap), KM_SLEEP);
    901 	pmap_pinit(pmap);
    902 	return pmap;
    903 }
    904 
    905 /*
    906  * Release any resources held by the given physical map.
    907  * Called when a pmap initialized by pmap_pinit is being released.
    908  * Should only be called if the map contains no valid mappings.
    909  */
    910 static void
    911 pmap_release(struct pmap *pmap)
    912 {
    913 #ifdef DEBUG
    914 	vaddr_t saddr, eaddr;
    915 #endif
    916 
    917 	PMDEBUG(("pmap_release: pmap %p\n",pmap));
    918 
    919 	if (pmap->pm_p0br == 0)
    920 		return;
    921 
    922 #ifdef DEBUG
    923 #if 0
    924 	for (i = 0; i < NPTEPROCSPC; i++)
    925 		if (pmap->pm_pref[i])
    926 			panic("pmap_release: refcnt %d index %d",
    927 			    pmap->pm_pref[i], i);
    928 #endif
    929 
    930 	saddr = (vaddr_t)pmap->pm_p0br;
    931 	eaddr = saddr + pmap->pm_p0lr * PPTESZ;
    932 	for (; saddr < eaddr; saddr += PAGE_SIZE)
    933 		if (kvtopte(saddr)->pg_pfn)
    934 			panic("pmap_release: P0 page mapped");
    935 	saddr = (vaddr_t)pmap->pm_p1br + pmap->pm_p1lr * PPTESZ;
    936 	eaddr = KERNBASE;
    937 	for (; saddr < eaddr; saddr += PAGE_SIZE)
    938 		if (kvtopte(saddr)->pg_pfn)
    939 			panic("pmap_release: P1 page mapped");
    940 #endif
    941 	if (pmap->pm_p0lr != 0)
    942 		extent_free(ptemap, (u_long)pmap->pm_p0br,
    943 		    pmap->pm_p0lr * PPTESZ, EX_WAITOK);
    944 	if (pmap->pm_p1lr != NPTEPERREG)
    945 		extent_free(ptemap, (u_long)pmap->pm_p1ap,
    946 		    (NPTEPERREG - pmap->pm_p1lr) * PPTESZ, EX_WAITOK);
    947 }
    948 
    949 /*
    950  * pmap_destroy(pmap): Remove a reference from the pmap.
    951  * If the pmap is NULL then just return else decrease pm_count.
    952  * If this was the last reference we call's pmap_release to release this pmap.
    953  */
    954 
    955 void
    956 pmap_destroy(pmap_t pmap)
    957 {
    958 	PMDEBUG(("pmap_destroy: pmap %p\n",pmap));
    959 
    960 	if (atomic_dec_uint_nv(&pmap->pm_count) == 0) {
    961 #ifdef DIAGNOSTIC
    962 		if (pmap->pm_pcbs)
    963 			panic("pmap_destroy used pmap");
    964 #endif
    965 		pmap_release(pmap);
    966 		kmem_free(pmap, sizeof(*pmap));
    967 	}
    968 }
    969 
    970 static struct pte *
    971 vaddrtopte(const struct pv_entry *pv)
    972 {
    973 	struct pmap *pm;
    974 	if (pv->pv_pmap == NULL || pv->pv_vaddr == NOVADDR)
    975 		return NULL;
    976 	if (pv->pv_vaddr & KERNBASE)
    977 		return &Sysmap[(pv->pv_vaddr & ~KERNBASE) >> VAX_PGSHIFT];
    978 	pm = pv->pv_pmap;
    979 	if (pv->pv_vaddr & 0x40000000)
    980 		return &pm->pm_p1br[vax_btop(pv->pv_vaddr & ~0x40000000)];
    981 	else
    982 		return &pm->pm_p0br[vax_btop(pv->pv_vaddr)];
    983 }
    984 
    985 /*
    986  * New (real nice!) function that allocates memory in kernel space
    987  * without tracking it in the MD code.
    988  */
    989 void
    990 pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags)
    991 {
    992 	int *ptp, opte;
    993 
    994 	ptp = (int *)kvtopte(va);
    995 	PMDEBUG(("pmap_kenter_pa: va: %lx, pa %lx, prot %x ptp %p\n",
    996 	    va, pa, prot, ptp));
    997 	opte = ptp[0];
    998 	ptp[0] = PG_V | ((prot & VM_PROT_WRITE)? PG_KW : PG_KR) |
    999 	    PG_PFNUM(pa) | PG_SREF;
   1000 	ptp[1] = ptp[0] + 1;
   1001 	ptp[2] = ptp[0] + 2;
   1002 	ptp[3] = ptp[0] + 3;
   1003 	ptp[4] = ptp[0] + 4;
   1004 	ptp[5] = ptp[0] + 5;
   1005 	ptp[6] = ptp[0] + 6;
   1006 	ptp[7] = ptp[0] + 7;
   1007 	if (opte & PG_V) {
   1008 #if defined(MULTIPROCESSOR)
   1009 		cpu_send_ipi(IPI_DEST_ALL, IPI_TBIA);
   1010 #endif
   1011 		mtpr(0, PR_TBIA);
   1012 	}
   1013 }
   1014 
   1015 void
   1016 pmap_kremove(vaddr_t va, vsize_t len)
   1017 {
   1018 	struct pte *pte;
   1019 #ifdef PMAPDEBUG
   1020 	int i;
   1021 #endif
   1022 
   1023 	PMDEBUG(("pmap_kremove: va: %lx, len %lx, ptp %p\n",
   1024 		    va, len, kvtopte(va)));
   1025 
   1026 	pte = kvtopte(va);
   1027 
   1028 #ifdef PMAPDEBUG
   1029 	/*
   1030 	 * Check if any pages are on the pv list.
   1031 	 * This shouldn't happen anymore.
   1032 	 */
   1033 	len >>= PGSHIFT;
   1034 	for (i = 0; i < len; i++) {
   1035 		if (pte->pg_pfn == 0)
   1036 			continue;
   1037 		if (pte->pg_sref == 0)
   1038 			panic("pmap_kremove");
   1039 		memset(pte, 0, LTOHPN * sizeof(struct pte));
   1040 		pte += LTOHPN;
   1041 	}
   1042 #else
   1043 	len >>= VAX_PGSHIFT;
   1044 	memset(pte, 0, len * sizeof(struct pte));
   1045 #endif
   1046 #if defined(MULTIPROCESSOR)
   1047 	cpu_send_ipi(IPI_DEST_ALL, IPI_TBIA);
   1048 #endif
   1049 	mtpr(0, PR_TBIA);
   1050 }
   1051 
   1052 /*
   1053  * pmap_enter() is the main routine that puts in mappings for pages, or
   1054  * upgrades mappings to more "rights".
   1055  */
   1056 int
   1057 pmap_enter(pmap_t pmap, vaddr_t v, paddr_t p, vm_prot_t prot, u_int flags)
   1058 {
   1059 	struct pv_entry *pv, *tmp;
   1060 	int newpte, oldpte;
   1061 	int *pteptr;	/* current pte to write mapping info to */
   1062 	int *ptpptr;	/* ptr to page table page */
   1063 
   1064 
   1065 	PMDEBUG(("pmap_enter: pmap %p v %lx p %lx prot %x wired %d access %x\n",
   1066 	    pmap, v, p, prot, (flags & PMAP_WIRED) != 0, flags & VM_PROT_ALL));
   1067 
   1068 	PMAP_LOCK;
   1069 
   1070 	/* Find address of correct pte */
   1071 	switch (SEGTYPE(v)) {
   1072 	case SYSSEG:
   1073 		pteptr = ((int *)Sysmap) + vax_btop(v - KERNBASE);
   1074 		newpte = (prot & VM_PROT_WRITE ? PG_KW : PG_KR);
   1075 		break;
   1076 
   1077 	case P0SEG:
   1078 		if (vax_btop(v) >= pmap->pm_p0lr)
   1079 			if (grow_p0(pmap, vax_btop(v)) == 0)
   1080 				goto growfail;
   1081 		pteptr = (int *)pmap->pm_p0br + vax_btop(v);
   1082 		newpte = (prot & VM_PROT_WRITE ? PG_RW : PG_RO);
   1083 		break;
   1084 
   1085 	case P1SEG:
   1086 		if (vax_btop(v - 0x40000000) < pmap->pm_p1lr)
   1087 			if (grow_p1(pmap, vax_btop(v - 0x40000000)) == 0)
   1088 				goto growfail;
   1089 		pteptr = (int *)pmap->pm_p1br + vax_btop(v - 0x40000000);
   1090 		newpte = (prot & VM_PROT_WRITE ? PG_RW : PG_RO);
   1091 		break;
   1092 	default:
   1093 		panic("bad seg");
   1094 	}
   1095 	newpte |= vax_btop(p);
   1096 
   1097 	if (SEGTYPE(v) != SYSSEG) {
   1098 		/*
   1099 		 * Check if a pte page must be mapped in.
   1100 		 */
   1101 		ptpptr = (int *)kvtopte(pteptr);
   1102 
   1103 		if (*ptpptr == 0) {
   1104 			paddr_t phys;
   1105 
   1106 			phys = get_ptp();
   1107 			if (phys == 0) {
   1108 				PMAP_UNLOCK;
   1109 				if ((flags & PMAP_CANFAIL) != 0)
   1110 					return ENOMEM;
   1111 				panic("pmap_enter: out of memory");
   1112 			}
   1113 			*ptpptr = PG_V | PG_KW | PG_PFNUM(phys);
   1114 		}
   1115 	}
   1116 
   1117 	/*
   1118 	 * Do not keep track of anything if mapping IO space.
   1119 	 */
   1120 	if (IOSPACE_P(p)) {
   1121 		mapin8(pteptr, newpte);
   1122 		PMAP_UNLOCK;
   1123 		return 0;
   1124 	}
   1125 
   1126 	if (flags & PMAP_WIRED)
   1127 		newpte |= PG_W;
   1128 
   1129 	oldpte = *pteptr & ~(PG_V|PG_M);
   1130 	pv = pv_table + (p >> PGSHIFT);
   1131 
   1132 	/* just a wiring change? */
   1133 	if (newpte == (oldpte | PG_W)) {
   1134 		*pteptr |= PG_W;
   1135 		pmap->pm_stats.wired_count++;
   1136 		PMAP_UNLOCK;
   1137 		return 0;
   1138 	}
   1139 
   1140 	/* mapping unchanged? just return. */
   1141 	if (newpte == oldpte) {
   1142 		PMAP_UNLOCK;
   1143 		return 0;
   1144 	}
   1145 
   1146 	/* Changing mapping? */
   1147 
   1148 	if ((newpte & PG_FRAME) == (oldpte & PG_FRAME)) {
   1149 		/* prot change. resident_count will be increased later */
   1150 		pmap_decrement_stats(pmap, (oldpte & PG_W) != 0);
   1151 	} else {
   1152 
   1153 		/*
   1154 		 * Mapped before? Remove it then.
   1155 		 */
   1156 
   1157 		if (oldpte & PG_FRAME) {
   1158 			if ((oldpte & PG_SREF) == 0)
   1159 				rmpage(pmap, pteptr);
   1160 			else {
   1161 				PMAP_UNLOCK;
   1162 				panic("pmap_enter on PG_SREF page");
   1163 			}
   1164 		}
   1165 
   1166 		if (pv->pv_pmap == NULL) {
   1167 			pv->pv_vaddr = v;
   1168 			pv->pv_pmap = pmap;
   1169 		} else {
   1170 			tmp = get_pventry();
   1171 			tmp->pv_vaddr = v;
   1172 			tmp->pv_pmap = pmap;
   1173 			tmp->pv_next = pv->pv_next;
   1174 			pv->pv_next = tmp;
   1175 		}
   1176 	}
   1177 	pmap->pm_stats.resident_count++;
   1178 	if ((flags & PMAP_WIRED) != 0)
   1179 		pmap->pm_stats.wired_count++;
   1180 
   1181 	if (flags & (VM_PROT_READ|VM_PROT_WRITE)) {
   1182 		pv->pv_attr |= PG_V;
   1183 		newpte |= PG_V;
   1184 	}
   1185 	if (flags & VM_PROT_WRITE)
   1186 		pv->pv_attr |= PG_M;
   1187 
   1188 	if (flags & PMAP_WIRED)
   1189 		newpte |= PG_V; /* Not allowed to be invalid */
   1190 
   1191 	mapin8(pteptr, newpte);
   1192 
   1193 	if (pventries < 10)
   1194 		more_pventries();
   1195 
   1196 	PMAP_UNLOCK;
   1197 
   1198 	mtpr(0, PR_TBIA); /* Always; safety belt */
   1199 	return 0;
   1200 
   1201 growfail:
   1202 	PMAP_UNLOCK;
   1203 	if (flags & PMAP_CANFAIL)
   1204 		return ENOMEM;
   1205 	panic("usrptmap space leakage");
   1206 }
   1207 
   1208 vaddr_t
   1209 pmap_map(vaddr_t virtual, paddr_t pstart, paddr_t pend, int prot)
   1210 {
   1211 	vaddr_t count;
   1212 	int *pentry;
   1213 
   1214 	PMDEBUG(("pmap_map: virt %lx, pstart %lx, pend %lx, Sysmap %p\n",
   1215 	    virtual, pstart, pend, Sysmap));
   1216 
   1217 	pstart &= 0x7fffffffUL;
   1218 	pend &= 0x7fffffffUL;
   1219 	virtual &= 0x7fffffffUL;
   1220 	pentry = &((int *)Sysmap)[virtual >> VAX_PGSHIFT];
   1221 	for (count = pstart; count < pend; count += VAX_NBPG) {
   1222 		*pentry++ = (count >> VAX_PGSHIFT)|PG_V|
   1223 		    (prot & VM_PROT_WRITE ? PG_KW : PG_KR);
   1224 	}
   1225 	return virtual + (count - pstart) + KERNBASE;
   1226 }
   1227 
   1228 #if 0
   1229 bool
   1230 pmap_extract(pmap_t pmap, vaddr_t va, paddr_t *pap)
   1231 {
   1232 	paddr_t pa = 0;
   1233 	int	*pte, sva;
   1234 
   1235 	PMDEBUG(("pmap_extract: pmap %p, va %lx\n",pmap, va));
   1236 
   1237 	if (va & KERNBASE) {
   1238 		pa = kvtophys(va); /* Is 0 if not mapped */
   1239 		if (pap)
   1240 			*pap = pa;
   1241 		if (pa)
   1242 			return (true);
   1243 		return (false);
   1244 	}
   1245 
   1246 	sva = PG_PFNUM(va);
   1247 	if (va < 0x40000000) {
   1248 		if (sva > pmap->pm_p0lr)
   1249 			return false;
   1250 		pte = (int *)pmap->pm_p0br;
   1251 	} else {
   1252 		if (sva < pmap->pm_p1lr)
   1253 			return false;
   1254 		pte = (int *)pmap->pm_p1br;
   1255 	}
   1256 	if (kvtopte(&pte[sva])->pg_pfn) {
   1257 		if (pap)
   1258 			*pap = (pte[sva] & PG_FRAME) << VAX_PGSHIFT;
   1259 		return (true);
   1260 	}
   1261 	return (false);
   1262 }
   1263 #endif
   1264 /*
   1265  * Sets protection for a given region to prot. If prot == none then
   1266  * unmap region. pmap_remove is implemented as pmap_protect with
   1267  * protection none.
   1268  */
   1269 void
   1270 pmap_protect_long(pmap_t pmap, vaddr_t start, vaddr_t end, vm_prot_t prot)
   1271 {
   1272 	struct	pte *pt, *pts, *ptd;
   1273 	int	pr, lr;
   1274 
   1275 	PMDEBUG(("pmap_protect: pmap %p, start %lx, end %lx, prot %x\n",
   1276 	    pmap, start, end,prot));
   1277 
   1278 	PMAP_LOCK;
   1279 
   1280 	switch (SEGTYPE(start)) {
   1281 	case SYSSEG:
   1282 		pt = Sysmap;
   1283 #ifdef DIAGNOSTIC
   1284 		if (((end & 0x3fffffff) >> VAX_PGSHIFT) > mfpr(PR_SLR))
   1285 			panic("pmap_protect: outside SLR: %lx", end);
   1286 #endif
   1287 		start &= ~KERNBASE;
   1288 		end &= ~KERNBASE;
   1289 		pr = (prot & VM_PROT_WRITE ? PROT_KW : PROT_KR);
   1290 		break;
   1291 
   1292 	case P1SEG:
   1293 		if (vax_btop(end - 0x40000000) <= pmap->pm_p1lr) {
   1294 			PMAP_UNLOCK;
   1295 			return;
   1296 		}
   1297 		if (vax_btop(start - 0x40000000) < pmap->pm_p1lr)
   1298 			start = pmap->pm_p1lr * VAX_NBPG;
   1299 		pt = pmap->pm_p1br;
   1300 		start &= 0x3fffffff;
   1301 		end = (end == KERNBASE ? end >> 1 : end & 0x3fffffff);
   1302 		pr = (prot & VM_PROT_WRITE ? PROT_RW : PROT_RO);
   1303 		break;
   1304 
   1305 	case P0SEG:
   1306 		lr = pmap->pm_p0lr;
   1307 
   1308 		/* Anything to care about at all? */
   1309 		if (vax_btop(start) > lr) {
   1310 			PMAP_UNLOCK;
   1311 			return;
   1312 		}
   1313 		if (vax_btop(end) > lr)
   1314 			end = lr * VAX_NBPG;
   1315 		pt = pmap->pm_p0br;
   1316 		pr = (prot & VM_PROT_WRITE ? PROT_RW : PROT_RO);
   1317 		break;
   1318 	default:
   1319 		panic("unsupported segtype: %d", SEGTYPE(start));
   1320 	}
   1321 
   1322 	pts = &pt[start >> VAX_PGSHIFT];
   1323 	ptd = &pt[end >> VAX_PGSHIFT];
   1324 #ifdef DEBUG
   1325 	if (((int)pts - (int)pt) & 7)
   1326 		panic("pmap_remove: pts not even");
   1327 	if (((int)ptd - (int)pt) & 7)
   1328 		panic("pmap_remove: ptd not even");
   1329 #endif
   1330 
   1331 	while (pts < ptd) {
   1332 		if (kvtopte(pts)->pg_pfn && *(int *)pts) {
   1333 			if (prot == VM_PROT_NONE) {
   1334 				if ((*(int *)pts & PG_SREF) == 0)
   1335 					rmpage(pmap, (u_int *)pts);
   1336 #ifdef DEBUG
   1337 				else {
   1338 					PMAP_UNLOCK;
   1339 					panic("pmap_remove PG_SREF page");
   1340 				}
   1341 #endif
   1342 				memset(pts, 0, sizeof(struct pte) * LTOHPN);
   1343 				if (pt != Sysmap) {
   1344 					if (ptpinuse(pts) == 0)
   1345 						rmptep(pts);
   1346 				}
   1347 			} else {
   1348 				pts[0].pg_prot = pr;
   1349 				pts[1].pg_prot = pr;
   1350 				pts[2].pg_prot = pr;
   1351 				pts[3].pg_prot = pr;
   1352 				pts[4].pg_prot = pr;
   1353 				pts[5].pg_prot = pr;
   1354 				pts[6].pg_prot = pr;
   1355 				pts[7].pg_prot = pr;
   1356 			}
   1357 		}
   1358 		pts += LTOHPN;
   1359 	}
   1360 	PMAP_UNLOCK;
   1361 #ifdef MULTIPROCESSOR
   1362 	cpu_send_ipi(IPI_DEST_ALL, IPI_TBIA);
   1363 #endif
   1364 	mtpr(0, PR_TBIA);
   1365 }
   1366 
   1367 int pmap_simulref(int bits, int addr);
   1368 
   1369 /*
   1370  * Called from interrupt vector routines if we get a page invalid fault.
   1371  * Note: the save mask must be or'ed with 0x3f for this function.
   1372  * Returns 0 if normal call, 1 if CVAX bug detected.
   1373  */
   1374 int
   1375 pmap_simulref(int bits, int addr)
   1376 {
   1377 	u_int	*pte;
   1378 	struct	pv_entry *pv;
   1379 	paddr_t pa;
   1380 
   1381 	PMDEBUG(("pmap_simulref: bits %x addr %x\n", bits, addr));
   1382 
   1383 #ifdef DEBUG
   1384 	if (bits & 1)
   1385 		panic("pte trans len");
   1386 #endif
   1387 	/* Set address on logical page boundary */
   1388 	addr &= ~PGOFSET;
   1389 	/* First decode userspace addr */
   1390 	if (addr >= 0) {
   1391 		if ((addr << 1) < 0)
   1392 			pte = (u_int *)mfpr(PR_P1BR);
   1393 		else
   1394 			pte = (u_int *)mfpr(PR_P0BR);
   1395 		pte += PG_PFNUM(addr);
   1396 		if (bits & 2) { /* PTE reference */
   1397 			pte = (u_int *)kvtopte(vax_trunc_page(pte));
   1398 			if (pte[0] == 0) /* Check for CVAX bug */
   1399 				return 1;
   1400 			panic("pmap_simulref");
   1401 			pa = (u_int)pte & ~KERNBASE;
   1402 		} else
   1403 			pa = Sysmap[PG_PFNUM(pte)].pg_pfn << VAX_PGSHIFT;
   1404 	} else {
   1405 		pte = (u_int *)kvtopte(addr);
   1406 		pa = (u_int)pte & ~KERNBASE;
   1407 	}
   1408 	pte[0] |= PG_V;
   1409 	pte[1] |= PG_V;
   1410 	pte[2] |= PG_V;
   1411 	pte[3] |= PG_V;
   1412 	pte[4] |= PG_V;
   1413 	pte[5] |= PG_V;
   1414 	pte[6] |= PG_V;
   1415 	pte[7] |= PG_V;
   1416 	if (!IOSPACE_P(pa)) { /* No pv_table fiddling in iospace */
   1417 		PMAP_LOCK;
   1418 		pv = pv_table + (pa >> PGSHIFT);
   1419 		pv->pv_attr |= PG_V; /* Referenced */
   1420 		if (bits & 4) /* (will be) modified. XXX page tables  */
   1421 			pv->pv_attr |= PG_M;
   1422 		PMAP_UNLOCK;
   1423 	}
   1424 	return 0;
   1425 }
   1426 
   1427 /*
   1428  * Clears valid bit in all ptes referenced to this physical page.
   1429  */
   1430 bool
   1431 pmap_clear_reference(struct vm_page *pg)
   1432 {
   1433 	struct pv_entry *pv = pmap_pg_to_pv(pg);
   1434 	struct pte *pte;
   1435 	bool ref;
   1436 
   1437 	PMDEBUG(("pmap_clear_reference: pv_entry %p\n", pv));
   1438 
   1439 	PMAP_LOCK;
   1440 	ref = ISSET(pv->pv_attr, PG_V);
   1441 	CLR(pv->pv_attr, PG_V);
   1442 	if (pv->pv_pmap != NULL) do {
   1443 		pte = vaddrtopte(pv);
   1444 		if (pte[0].pg_w == 0) {
   1445 			pte[0].pg_v = 0; pte[1].pg_v = 0;
   1446 			pte[2].pg_v = 0; pte[3].pg_v = 0;
   1447 			pte[4].pg_v = 0; pte[5].pg_v = 0;
   1448 			pte[6].pg_v = 0; pte[7].pg_v = 0;
   1449 		}
   1450 	} while ((pv = pv->pv_next) != NULL);
   1451 	PMAP_UNLOCK;
   1452 #ifdef MULTIPROCESSOR
   1453 	cpu_send_ipi(IPI_DEST_ALL, IPI_TBIA);
   1454 #endif
   1455 	mtpr(0, PR_TBIA);
   1456 	return ref;
   1457 }
   1458 
   1459 /*
   1460  * Checks if page is modified; returns true or false depending on result.
   1461  */
   1462 bool
   1463 pmap_is_modified(struct vm_page *pg)
   1464 {
   1465 	struct pv_entry *pv = pmap_pg_to_pv(pg);
   1466 	bool rv;
   1467 
   1468 	PMDEBUG(("pmap_is_modified: pv_entry %p ", pv));
   1469 
   1470 	PMAP_LOCK;
   1471 	rv = ISSET(pv->pv_attr, PG_M);
   1472 	if (rv == false && pv->pv_pmap != NULL) do {
   1473 		const struct pte * const pte = vaddrtopte(pv);
   1474 		if (pte[0].pg_m | pte[1].pg_m | pte[2].pg_m | pte[3].pg_m
   1475 		    | pte[4].pg_m | pte[5].pg_m | pte[6].pg_m | pte[7].pg_m) {
   1476 			rv = true;
   1477 			SET(pv->pv_attr, PG_M);
   1478 			break;
   1479 		}
   1480 	} while ((pv = pv->pv_next) != NULL);
   1481 	PMAP_UNLOCK;
   1482 	return rv;
   1483 }
   1484 
   1485 /*
   1486  * Clears modify bit in all ptes referenced to this physical page.
   1487  */
   1488 bool
   1489 pmap_clear_modify(struct vm_page *pg)
   1490 {
   1491 	struct pv_entry *pv = pmap_pg_to_pv(pg);
   1492 	bool rv = false;
   1493 
   1494 	PMDEBUG(("pmap_clear_modify: pv_entry %p\n", pv));
   1495 
   1496 	PMAP_LOCK;
   1497 	rv = ISSET(pv->pv_attr, PG_M);
   1498 	CLR(pv->pv_attr, PG_M);
   1499 	if (pv->pv_pmap != NULL) do {
   1500 		struct pte * const pte = vaddrtopte(pv);
   1501 		if (pte[0].pg_m | pte[1].pg_m | pte[2].pg_m | pte[3].pg_m |
   1502 		    pte[4].pg_m | pte[5].pg_m | pte[6].pg_m | pte[7].pg_m) {
   1503 			rv = true;
   1504 		}
   1505 		pte[0].pg_m = pte[1].pg_m = pte[2].pg_m = pte[3].pg_m = 0;
   1506 		pte[4].pg_m = pte[5].pg_m = pte[6].pg_m = pte[7].pg_m = 0;
   1507 	} while ((pv = pv->pv_next) != NULL);
   1508 	PMAP_UNLOCK;
   1509 	return rv;
   1510 }
   1511 
   1512 /*
   1513  * Lower the permission for all mappings to a given page.
   1514  * Lower permission can only mean setting protection to either read-only
   1515  * or none; where none is unmapping of the page.
   1516  */
   1517 void
   1518 pmap_page_protect_long(struct pv_entry *pv, vm_prot_t prot)
   1519 {
   1520 	struct	pte *pt;
   1521 	struct	pv_entry *opv, *pl;
   1522 	int	*g;
   1523 
   1524 	PMDEBUG(("pmap_page_protect: pv %p, prot %x\n", pv, prot));
   1525 
   1526 	if (prot == VM_PROT_ALL) /* 'cannot happen' */
   1527 		return;
   1528 
   1529 	PMAP_LOCK;
   1530 	if (prot == VM_PROT_NONE) {
   1531 		g = (int *)vaddrtopte(pv);
   1532 		if (g) {
   1533 			pmap_decrement_stats(pv->pv_pmap, (g[0] & PG_W) != 0);
   1534 			if ((pv->pv_attr & (PG_V|PG_M)) != (PG_V|PG_M))
   1535 				pv->pv_attr |=
   1536 				    g[0]|g[1]|g[2]|g[3]|g[4]|g[5]|g[6]|g[7];
   1537 			memset(g, 0, sizeof(struct pte) * LTOHPN);
   1538 			if (pv->pv_pmap != pmap_kernel()) {
   1539 				if (ptpinuse(g) == 0)
   1540 					rmptep((void *)g);
   1541 			}
   1542 			pv->pv_vaddr = NOVADDR;
   1543 			pv->pv_pmap = NULL;
   1544 		}
   1545 		pl = pv->pv_next;
   1546 		pv->pv_pmap = 0;
   1547 		pv->pv_next = 0;
   1548 		while (pl) {
   1549 			g = (int *)vaddrtopte(pl);
   1550 			pmap_decrement_stats(pl->pv_pmap, (g[0] & PG_W) != 0);
   1551 			if ((pv->pv_attr & (PG_V|PG_M)) != (PG_V|PG_M))
   1552 				pv->pv_attr |=
   1553 				    g[0]|g[1]|g[2]|g[3]|g[4]|g[5]|g[6]|g[7];
   1554 			memset(g, 0, sizeof(struct pte) * LTOHPN);
   1555 			if (pl->pv_pmap != pmap_kernel()) {
   1556 				if (ptpinuse(g) == 0)
   1557 					rmptep((void *)g);
   1558 			}
   1559 			opv = pl;
   1560 			pl = pl->pv_next;
   1561 			free_pventry(opv);
   1562 		}
   1563 	} else { /* read-only */
   1564 		do {
   1565 			int pr;
   1566 			pt = vaddrtopte(pv);
   1567 			if (pt == 0)
   1568 				continue;
   1569 			pr = ((vaddr_t)pt < ptemapstart ? PROT_KR : PROT_RO);
   1570 			pt[0].pg_prot = pr; pt[1].pg_prot = pr;
   1571 			pt[2].pg_prot = pr; pt[3].pg_prot = pr;
   1572 			pt[4].pg_prot = pr; pt[5].pg_prot = pr;
   1573 			pt[6].pg_prot = pr; pt[7].pg_prot = pr;
   1574 		} while ((pv = pv->pv_next));
   1575 	}
   1576 	PMAP_UNLOCK;
   1577 #ifdef MULTIPROCESSOR
   1578 	cpu_send_ipi(IPI_DEST_ALL, IPI_TBIA);
   1579 #endif
   1580 	mtpr(0, PR_TBIA);
   1581 }
   1582 
   1583 static void
   1584 pmap_remove_pcb(struct pmap *pm, struct pcb *thispcb)
   1585 {
   1586 	struct pcb *pcb, **pcbp;
   1587 
   1588 	for (pcbp = &pm->pm_pcbs;
   1589 	     (pcb = *pcbp) != NULL;
   1590 	     pcbp = &pcb->pcb_pmnext) {
   1591 #ifdef DIAGNOSTIC
   1592 		if (pcb->pcb_pm != pm)
   1593 			panic("pmap_remove_pcb: pcb %p (pm %p) not owned by pmap %p",
   1594 			    pcb, pcb->pcb_pm, pm);
   1595 #endif
   1596 		if (pcb == thispcb) {
   1597 			*pcbp = pcb->pcb_pmnext;
   1598 			thispcb->pcb_pm = NULL;
   1599 			return;
   1600 		}
   1601 	}
   1602 #ifdef DIAGNOSTIC
   1603 	panic("pmap_remove_pcb: pmap %p: pcb %p not in list", pm, thispcb);
   1604 #endif
   1605 }
   1606 
   1607 /*
   1608  * Activate the address space for the specified process.
   1609  * Note that if the process to activate is the current process, then
   1610  * the processor internal registers must also be loaded; otherwise
   1611  * the current process will have wrong pagetables.
   1612  */
   1613 void
   1614 pmap_activate(struct lwp *l)
   1615 {
   1616 	struct pcb * const pcb = lwp_getpcb(l);
   1617 	struct pmap * const pmap = l->l_proc->p_vmspace->vm_map.pmap;
   1618 
   1619 	PMDEBUG(("pmap_activate: l %p\n", l));
   1620 
   1621 	pcb->P0BR = pmap->pm_p0br;
   1622 	pcb->P0LR = pmap->pm_p0lr|AST_PCB;
   1623 	pcb->P1BR = pmap->pm_p1br;
   1624 	pcb->P1LR = pmap->pm_p1lr;
   1625 
   1626 	if (pcb->pcb_pm != pmap) {
   1627 		if (pcb->pcb_pm != NULL)
   1628 			pmap_remove_pcb(pcb->pcb_pm, pcb);
   1629 		pcb->pcb_pmnext = pmap->pm_pcbs;
   1630 		pmap->pm_pcbs = pcb;
   1631 		pcb->pcb_pm = pmap;
   1632 	}
   1633 
   1634 	if (l == curlwp) {
   1635 		mtpr((uintptr_t)pmap->pm_p0br, PR_P0BR);
   1636 		mtpr(pmap->pm_p0lr|AST_PCB, PR_P0LR);
   1637 		mtpr((uintptr_t)pmap->pm_p1br, PR_P1BR);
   1638 		mtpr(pmap->pm_p1lr, PR_P1LR);
   1639 		mtpr(0, PR_TBIA);
   1640 	}
   1641 }
   1642 
   1643 void
   1644 pmap_deactivate(struct lwp *l)
   1645 {
   1646 	struct pcb * const pcb = lwp_getpcb(l);
   1647 	struct pmap * const pmap = l->l_proc->p_vmspace->vm_map.pmap;
   1648 
   1649 	PMDEBUG(("pmap_deactivate: l %p\n", l));
   1650 
   1651 	if (pcb->pcb_pm == NULL)
   1652 		return;
   1653 #ifdef DIAGNOSTIC
   1654 	if (pcb->pcb_pm != pmap)
   1655 		panic("pmap_deactivate: lwp %p pcb %p not owned by pmap %p",
   1656 		    l, pcb, pmap);
   1657 #endif
   1658 	pmap_remove_pcb(pmap, pcb);
   1659 }
   1660 
   1661 /*
   1662  * removes the wired bit from a bunch of PTE's.
   1663  */
   1664 void
   1665 pmap_unwire(pmap_t pmap, vaddr_t v)
   1666 {
   1667 	int *pte;
   1668 
   1669 	PMDEBUG(("pmap_unwire: pmap %p v %lx\n", pmap, v));
   1670 
   1671 	PMAP_LOCK;
   1672 	if (v & KERNBASE) {
   1673 		pte = (int *)kvtopte(v);
   1674 	} else {
   1675 		if (v < 0x40000000)
   1676 			pte = (int *)&pmap->pm_p0br[PG_PFNUM(v)];
   1677 		else
   1678 			pte = (int *)&pmap->pm_p1br[PG_PFNUM(v)];
   1679 	}
   1680 	pte[0] &= ~PG_W;
   1681 	pmap->pm_stats.wired_count--;
   1682 	PMAP_UNLOCK;
   1683 }
   1684 
   1685 /*
   1686  * pv_entry functions.
   1687  */
   1688 struct pv_entry *pv_list;
   1689 
   1690 /*
   1691  * get_pventry().
   1692  * The pv_table lock must be held before calling this.
   1693  */
   1694 struct pv_entry *
   1695 get_pventry(void)
   1696 {
   1697 	struct pv_entry *tmp;
   1698 
   1699 	if (pventries == 0)
   1700 		panic("get_pventry");
   1701 
   1702 	tmp = pv_list;
   1703 	pv_list = tmp->pv_next;
   1704 	pventries--;
   1705 	pvinuse++;
   1706 	return tmp;
   1707 }
   1708 
   1709 /*
   1710  * free_pventry().
   1711  * The pv_table lock must be held before calling this.
   1712  */
   1713 void
   1714 free_pventry(struct pv_entry *pv)
   1715 {
   1716 	pv->pv_next = pv_list;
   1717 	pv_list = pv;
   1718 	pventries++;
   1719 	pvinuse--;
   1720 }
   1721 
   1722 /*
   1723  * more_pventries().
   1724  * The pmap_lock must be held before calling this.
   1725  */
   1726 void
   1727 more_pventries(void)
   1728 {
   1729 	struct pv_entry *pv;
   1730 	int i, count;
   1731 
   1732 	pv = (struct pv_entry *)getpage();
   1733 	if (pv == NULL)
   1734 		return;
   1735 	count = PAGE_SIZE/sizeof(struct pv_entry);
   1736 
   1737 	for (i = 0; i < count - 1; i++)
   1738 		pv[i].pv_next = &pv[i + 1];
   1739 
   1740 	pv[count - 1].pv_next = pv_list;
   1741 	pv_list = pv;
   1742 	pventries += count;
   1743 }
   1744 
   1745 static int *ptpp;
   1746 
   1747 /*
   1748  * Get a (vax-size) page, to use for page tables.
   1749  */
   1750 vaddr_t
   1751 get_ptp(void)
   1752 {
   1753 	int *a;
   1754 
   1755 	if ((a = ptpp)) {
   1756 		ptpp = (int *)*ptpp;
   1757 		memset(a, 0, VAX_NBPG);
   1758 		return (vaddr_t)a;
   1759 	}
   1760 	a = (int *)getpage();
   1761 	if (a != NULL) {
   1762 		a[128] = (int)&a[256];
   1763 		a[256] = (int)&a[384];
   1764 		a[384] = (int)&a[512];
   1765 		a[512] = (int)&a[640];
   1766 		a[640] = (int)&a[768];
   1767 		a[768] = (int)&a[896];
   1768 		a[896] = (int)ptpp;
   1769 		ptpp = &a[128];
   1770 	}
   1771 	return (vaddr_t)a;
   1772 }
   1773 
   1774 /*
   1775  * Put a page table page on the free list.
   1776  * The address v is in the direct-mapped area.
   1777  */
   1778 void
   1779 free_ptp(paddr_t v)
   1780 {
   1781 	v |= KERNBASE;
   1782 	*(int *)v = (int)ptpp;
   1783 	ptpp = (int *)v;
   1784 }
   1785