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