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