pmap.c revision 2112
1/*
2 * Copyright (c) 1991 Regents of the University of California.
3 * All rights reserved.
4 * Copyright (c) 1994 John S. Dyson
5 * All rights reserved.
6 * Copyright (c) 1994 David Greenman
7 * All rights reserved.
8 *
9 * This code is derived from software contributed to Berkeley by
10 * the Systems Programming Group of the University of Utah Computer
11 * Science Department and William Jolitz of UUNET Technologies Inc.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 *    notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 *    notice, this list of conditions and the following disclaimer in the
20 *    documentation and/or other materials provided with the distribution.
21 * 3. All advertising materials mentioning features or use of this software
22 *    must display the following acknowledgement:
23 *	This product includes software developed by the University of
24 *	California, Berkeley and its contributors.
25 * 4. Neither the name of the University nor the names of its contributors
26 *    may be used to endorse or promote products derived from this software
27 *    without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 * SUCH DAMAGE.
40 *
41 *	from:	@(#)pmap.c	7.7 (Berkeley)	5/12/91
42 *	$Id: pmap.c,v 1.32 1994/08/13 03:49:44 wollman Exp $
43 */
44
45/*
46 * Derived from hp300 version by Mike Hibler, this version by William
47 * Jolitz uses a recursive map [a pde points to the page directory] to
48 * map the page tables using the pagetables themselves. This is done to
49 * reduce the impact on kernel virtual memory for lots of sparse address
50 * space, and to reduce the cost of memory to each process.
51 *
52 *	Derived from: hp300/@(#)pmap.c	7.1 (Berkeley) 12/5/90
53 */
54/*
55 * Major modifications by John S. Dyson primarily to support
56 * pageable page tables, eliminating pmap_attributes,
57 * discontiguous memory pages, and using more efficient string
58 * instructions. Jan 13, 1994.  Further modifications on Mar 2, 1994,
59 * general clean-up and efficiency mods.
60 */
61
62/*
63 *	Manages physical address maps.
64 *
65 *	In addition to hardware address maps, this
66 *	module is called upon to provide software-use-only
67 *	maps which may or may not be stored in the same
68 *	form as hardware maps.  These pseudo-maps are
69 *	used to store intermediate results from copy
70 *	operations to and from address spaces.
71 *
72 *	Since the information managed by this module is
73 *	also stored by the logical address mapping module,
74 *	this module may throw away valid virtual-to-physical
75 *	mappings at almost any time.  However, invalidations
76 *	of virtual-to-physical mappings must be done as
77 *	requested.
78 *
79 *	In order to cope with hardware architectures which
80 *	make virtual-to-physical map invalidates expensive,
81 *	this module may delay invalidate or reduced protection
82 *	operations until such time as they are actually
83 *	necessary.  This module is given full information as
84 *	to which processors are currently using which maps,
85 *	and to when physical maps must be made correct.
86 */
87
88#include <sys/param.h>
89#include <sys/proc.h>
90#include <sys/malloc.h>
91#include <sys/user.h>
92
93#include <vm/vm.h>
94#include <vm/vm_kern.h>
95#include <vm/vm_page.h>
96
97#include <i386/include/cpufunc.h>
98#include <i386/include/cputypes.h>
99
100#include <i386/isa/isa.h>
101
102/*
103 * Allocate various and sundry SYSMAPs used in the days of old VM
104 * and not yet converted.  XXX.
105 */
106#define BSDVM_COMPAT	1
107
108/*
109 * Get PDEs and PTEs for user/kernel address space
110 */
111#define	pmap_pde(m, v)	(&((m)->pm_pdir[((vm_offset_t)(v) >> PD_SHIFT)&1023]))
112#define pdir_pde(m, v) (m[((vm_offset_t)(v) >> PD_SHIFT)&1023])
113
114#define pmap_pte_pa(pte)	(*(int *)(pte) & PG_FRAME)
115
116#define pmap_pde_v(pte)		((*(int *)pte & PG_V) != 0)
117#define pmap_pte_w(pte)		((*(int *)pte & PG_W) != 0)
118#define pmap_pte_m(pte)		((*(int *)pte & PG_M) != 0)
119#define pmap_pte_u(pte)		((*(int *)pte & PG_U) != 0)
120#define pmap_pte_v(pte)		((*(int *)pte & PG_V) != 0)
121
122#define pmap_pte_set_w(pte, v)		((v)?(*(int *)pte |= PG_W):(*(int *)pte &= ~PG_W))
123#define pmap_pte_set_prot(pte, v)	((*(int *)pte &= ~PG_PROT), (*(int *)pte |= (v)))
124
125/*
126 * Given a map and a machine independent protection code,
127 * convert to a vax protection code.
128 */
129#define pte_prot(m, p)	(protection_codes[p])
130int	protection_codes[8];
131
132struct pmap	kernel_pmap_store;
133pmap_t		kernel_pmap;
134
135vm_offset_t	phys_avail[6];		/* 2 entries + 1 null */
136vm_offset_t    	avail_start;		/* PA of first available physical page */
137vm_offset_t	avail_end;		/* PA of last available physical page */
138vm_size_t	mem_size;		/* memory size in bytes */
139vm_offset_t	virtual_avail; 		/* VA of first avail page (after kernel bss)*/
140vm_offset_t	virtual_end;		/* VA of last avail page (end of kernel AS) */
141int		i386pagesperpage;	/* PAGE_SIZE / I386_PAGE_SIZE */
142boolean_t	pmap_initialized = FALSE; /* Has pmap_init completed? */
143vm_offset_t	vm_first_phys, vm_last_phys;
144
145static inline boolean_t		pmap_testbit();
146static inline void		pmap_changebit();
147static inline int		pmap_is_managed();
148static inline void *		vm_get_pmap();
149static inline void		vm_put_pmap();
150static void			i386_protection_init();
151static void			pmap_alloc_pv_entry();
152static inline pv_entry_t	get_pv_entry();
153static inline void		pmap_use_pt();
154static inline void		pmap_unuse_pt();
155
156
157extern vm_offset_t clean_sva, clean_eva;
158extern int cpu_class;
159
160#if BSDVM_COMPAT
161#include <sys/msgbuf.h>
162
163/*
164 * All those kernel PT submaps that BSD is so fond of
165 */
166pt_entry_t *CMAP1, *CMAP2, *ptmmap;
167caddr_t		CADDR1, CADDR2, ptvmmap;
168pt_entry_t *msgbufmap;
169struct msgbuf	*msgbufp;
170#endif
171
172void init_pv_entries(int) ;
173
174/*
175 *	Routine:	pmap_pte
176 *	Function:
177 *		Extract the page table entry associated
178 *		with the given map/virtual_address pair.
179 * [ what about induced faults -wfj]
180 */
181
182inline pt_entry_t *
183const pmap_pte(pmap, va)
184	register pmap_t	pmap;
185	vm_offset_t va;
186{
187
188	if (pmap && *pmap_pde(pmap, va)) {
189		vm_offset_t frame = (int) pmap->pm_pdir[PTDPTDI] & PG_FRAME;
190		/* are we current address space or kernel? */
191		if ( (pmap == kernel_pmap) || (frame == ((int) PTDpde & PG_FRAME)))
192			return ((pt_entry_t *) vtopte(va));
193		/* otherwise, we are alternate address space */
194		else {
195			if ( frame != ((int) APTDpde & PG_FRAME) ) {
196				APTDpde = pmap->pm_pdir[PTDPTDI];
197				tlbflush();
198			}
199			return((pt_entry_t *) avtopte(va));
200		}
201	}
202	return(0);
203}
204
205/*
206 *	Routine:	pmap_extract
207 *	Function:
208 *		Extract the physical page address associated
209 *		with the given map/virtual_address pair.
210 */
211
212vm_offset_t
213pmap_extract(pmap, va)
214	register pmap_t	pmap;
215	vm_offset_t va;
216{
217	pd_entry_t save;
218	vm_offset_t pa;
219	int s;
220
221	if (pmap && *pmap_pde(pmap, va)) {
222		vm_offset_t frame = (int) pmap->pm_pdir[PTDPTDI] & PG_FRAME;
223		/* are we current address space or kernel? */
224		if ( (pmap == kernel_pmap)
225			|| (frame == ((int) PTDpde & PG_FRAME)) ) {
226			pa = *(int *) vtopte(va);
227		/* otherwise, we are alternate address space */
228		} else {
229			if ( frame != ((int) APTDpde & PG_FRAME)) {
230				APTDpde = pmap->pm_pdir[PTDPTDI];
231				tlbflush();
232			}
233			pa = *(int *) avtopte(va);
234		}
235		pa = (pa & PG_FRAME) | (va & ~PG_FRAME);
236		return pa;
237	}
238	return 0;
239
240}
241
242/*
243 * determine if a page is managed (memory vs. device)
244 */
245static inline int
246pmap_is_managed(pa)
247	vm_offset_t pa;
248{
249	int i;
250
251	if (!pmap_initialized)
252		return 0;
253
254	for (i = 0; phys_avail[i + 1]; i += 2) {
255		if (pa >= phys_avail[i] && pa < phys_avail[i + 1])
256			return 1;
257	}
258	return 0;
259}
260
261/*
262 * find the vm_page_t of a pte (only) given va of pte and pmap
263 */
264inline vm_page_t
265pmap_pte_vm_page(pmap, pt)
266	pmap_t pmap;
267	vm_offset_t pt;
268{
269	pt = i386_trunc_page( pt);
270	pt = (pt - UPT_MIN_ADDRESS) / NBPG;
271	pt = ((vm_offset_t) pmap->pm_pdir[pt]) & PG_FRAME;
272	return PHYS_TO_VM_PAGE(pt);
273}
274
275/*
276 * Wire a page table page
277 */
278inline void
279pmap_use_pt(pmap, va)
280	pmap_t pmap;
281	vm_offset_t va;
282{
283	vm_offset_t pt;
284
285	if (va >= VM_MAX_ADDRESS || !pmap_initialized)
286		return;
287
288	pt = (vm_offset_t) vtopte(va);
289	vm_page_hold( pmap_pte_vm_page(pmap, pt));
290}
291
292/*
293 * Unwire a page table page
294 */
295inline void
296pmap_unuse_pt(pmap, va)
297	pmap_t pmap;
298	vm_offset_t va;
299{
300	vm_offset_t pt;
301
302	if (va >= VM_MAX_ADDRESS || !pmap_initialized)
303		return;
304
305	pt = (vm_offset_t) vtopte(va);
306	vm_page_unhold( pmap_pte_vm_page(pmap, pt));
307}
308
309/* [ macro again?, should I force kstack into user map here? -wfj ] */
310void
311pmap_activate(pmap, pcbp)
312	register pmap_t pmap;
313	struct pcb *pcbp;
314{
315	PMAP_ACTIVATE(pmap, pcbp);
316}
317
318/*
319 *	Bootstrap the system enough to run with virtual memory.
320 *	Map the kernel's code and data, and allocate the system page table.
321 *
322 *	On the I386 this is called after mapping has already been enabled
323 *	and just syncs the pmap module with what has already been done.
324 *	[We can't call it easily with mapping off since the kernel is not
325 *	mapped with PA == VA, hence we would have to relocate every address
326 *	from the linked base (virtual) address "KERNBASE" to the actual
327 *	(physical) address starting relative to 0]
328 */
329
330#define DMAPAGES 8
331void
332pmap_bootstrap(firstaddr, loadaddr)
333	vm_offset_t firstaddr;
334	vm_offset_t loadaddr;
335{
336#if BSDVM_COMPAT
337	vm_offset_t va;
338	pt_entry_t *pte;
339#endif
340
341	avail_start = firstaddr + DMAPAGES*NBPG;
342
343	virtual_avail = (vm_offset_t) KERNBASE + avail_start;
344	virtual_end = VM_MAX_KERNEL_ADDRESS;
345	i386pagesperpage = PAGE_SIZE / NBPG;
346
347	/*
348	 * Initialize protection array.
349	 */
350	i386_protection_init();
351
352	/*
353	 * The kernel's pmap is statically allocated so we don't
354	 * have to use pmap_create, which is unlikely to work
355	 * correctly at this part of the boot sequence.
356	 */
357	kernel_pmap = &kernel_pmap_store;
358
359	kernel_pmap->pm_pdir = (pd_entry_t *)(KERNBASE + IdlePTD);
360
361	simple_lock_init(&kernel_pmap->pm_lock);
362	kernel_pmap->pm_count = 1;
363
364#if BSDVM_COMPAT
365	/*
366	 * Allocate all the submaps we need
367	 */
368#define	SYSMAP(c, p, v, n)	\
369	v = (c)va; va += ((n)*NBPG); p = pte; pte += (n);
370
371	va = virtual_avail;
372	pte = pmap_pte(kernel_pmap, va);
373
374	SYSMAP(caddr_t		,CMAP1		,CADDR1	   ,1		)
375	SYSMAP(caddr_t		,CMAP2		,CADDR2	   ,1		)
376	SYSMAP(caddr_t		,ptmmap		,ptvmmap	   ,1		)
377	SYSMAP(struct msgbuf *	,msgbufmap	,msgbufp   ,1		)
378	virtual_avail = va;
379#endif
380	/*
381	 * reserve special hunk of memory for use by bus dma as a bounce
382	 * buffer (contiguous virtual *and* physical memory). for now,
383	 * assume vm does not use memory beneath hole, and we know that
384	 * the bootstrap uses top 32k of base memory. -wfj
385	 */
386	{
387		extern vm_offset_t isaphysmem;
388		isaphysmem = va;
389
390		virtual_avail = pmap_map(va, firstaddr,
391				firstaddr + DMAPAGES*NBPG, VM_PROT_ALL);
392	}
393
394	*(int *)CMAP1 = *(int *)CMAP2 = *(int *)PTD = 0;
395	tlbflush();
396
397}
398
399/*
400 *	Initialize the pmap module.
401 *	Called by vm_init, to initialize any structures that the pmap
402 *	system needs to map virtual memory.
403 *	pmap_init has been enhanced to support in a fairly consistant
404 *	way, discontiguous physical memory.
405 */
406void
407pmap_init(phys_start, phys_end)
408	vm_offset_t	phys_start, phys_end;
409{
410	vm_offset_t	addr, addr2;
411	vm_size_t	npg, s;
412	int		rv;
413	int i;
414	extern int KPTphys;
415
416	/*
417	 * Now that kernel map has been allocated, we can mark as
418	 * unavailable regions which we have mapped in locore.
419	 */
420	addr = atdevbase;
421	(void) vm_map_find(kernel_map, NULL, (vm_offset_t) 0,
422			   &addr, (0x100000-0xa0000), FALSE);
423
424	addr = (vm_offset_t) KERNBASE + IdlePTD;
425	vm_object_reference(kernel_object);
426	(void) vm_map_find(kernel_map, kernel_object, addr,
427			   &addr, (4 + NKPT) * NBPG, FALSE);
428
429
430	/*
431	 * calculate the number of pv_entries needed
432	 */
433	vm_first_phys = phys_avail[0];
434	for (i = 0; phys_avail[i + 1]; i += 2) ;
435	npg = (phys_avail[(i - 2) + 1] - vm_first_phys) / NBPG;
436
437	/*
438	 * Allocate memory for random pmap data structures.  Includes the
439	 * pv_head_table.
440	 */
441	s = (vm_size_t) (sizeof(struct pv_entry) * npg);
442	s = i386_round_page(s);
443	addr = (vm_offset_t) kmem_alloc(kernel_map, s);
444	pv_table = (pv_entry_t) addr;
445
446	/*
447	 * init the pv free list
448	 */
449	init_pv_entries(npg);
450	/*
451	 * Now it is safe to enable pv_table recording.
452	 */
453	pmap_initialized = TRUE;
454}
455
456/*
457 *	Used to map a range of physical addresses into kernel
458 *	virtual address space.
459 *
460 *	For now, VM is already on, we only need to map the
461 *	specified memory.
462 */
463vm_offset_t
464pmap_map(virt, start, end, prot)
465	vm_offset_t	virt;
466	vm_offset_t	start;
467	vm_offset_t	end;
468	int		prot;
469{
470	while (start < end) {
471		pmap_enter(kernel_pmap, virt, start, prot, FALSE);
472		virt += PAGE_SIZE;
473		start += PAGE_SIZE;
474	}
475	return(virt);
476}
477
478/*
479 *	Create and return a physical map.
480 *
481 *	If the size specified for the map
482 *	is zero, the map is an actual physical
483 *	map, and may be referenced by the
484 *	hardware.
485 *
486 *	If the size specified is non-zero,
487 *	the map will be used in software only, and
488 *	is bounded by that size.
489 *
490 * [ just allocate a ptd and mark it uninitialize -- should we track
491 *   with a table which process has which ptd? -wfj ]
492 */
493
494pmap_t
495pmap_create(size)
496	vm_size_t	size;
497{
498	register pmap_t pmap;
499
500	/*
501	 * Software use map does not need a pmap
502	 */
503	if (size)
504		return(NULL);
505
506	pmap = (pmap_t) malloc(sizeof *pmap, M_VMPMAP, M_WAITOK);
507	bzero(pmap, sizeof(*pmap));
508	pmap_pinit(pmap);
509	return (pmap);
510}
511
512
513struct pmaplist {
514	struct pmaplist *next;
515};
516
517static inline void *
518vm_get_pmap()
519{
520	struct pmaplist *rtval;
521
522	rtval = (struct pmaplist *)kmem_alloc(kernel_map, ctob(1));
523	bzero(rtval, ctob(1));
524	return rtval;
525}
526
527static inline void
528vm_put_pmap(up)
529	struct pmaplist *up;
530{
531	kmem_free(kernel_map, (vm_offset_t)up, ctob(1));
532}
533
534/*
535 * Initialize a preallocated and zeroed pmap structure,
536 * such as one in a vmspace structure.
537 */
538void
539pmap_pinit(pmap)
540	register struct pmap *pmap;
541{
542	/*
543	 * No need to allocate page table space yet but we do need a
544	 * valid page directory table.
545	 */
546	pmap->pm_pdir = (pd_entry_t *) vm_get_pmap();
547
548	/* wire in kernel global address entries */
549	bcopy(PTD+KPTDI, pmap->pm_pdir+KPTDI, NKPT*PTESIZE);
550
551	/* install self-referential address mapping entry */
552	*(int *)(pmap->pm_pdir+PTDPTDI) =
553		((int)pmap_kextract((vm_offset_t)pmap->pm_pdir)) | PG_V | PG_KW;
554
555	pmap->pm_count = 1;
556	simple_lock_init(&pmap->pm_lock);
557}
558
559/*
560 *	Retire the given physical map from service.
561 *	Should only be called if the map contains
562 *	no valid mappings.
563 */
564void
565pmap_destroy(pmap)
566	register pmap_t pmap;
567{
568	int count;
569
570	if (pmap == NULL)
571		return;
572
573	simple_lock(&pmap->pm_lock);
574	count = --pmap->pm_count;
575	simple_unlock(&pmap->pm_lock);
576	if (count == 0) {
577		pmap_release(pmap);
578		free((caddr_t)pmap, M_VMPMAP);
579	}
580}
581
582/*
583 * Release any resources held by the given physical map.
584 * Called when a pmap initialized by pmap_pinit is being released.
585 * Should only be called if the map contains no valid mappings.
586 */
587void
588pmap_release(pmap)
589	register struct pmap *pmap;
590{
591	vm_put_pmap((struct pmaplist *) pmap->pm_pdir);
592}
593
594/*
595 *	Add a reference to the specified pmap.
596 */
597void
598pmap_reference(pmap)
599	pmap_t	pmap;
600{
601	if (pmap != NULL) {
602		simple_lock(&pmap->pm_lock);
603		pmap->pm_count++;
604		simple_unlock(&pmap->pm_lock);
605	}
606}
607
608#define PV_FREELIST_MIN ((NBPG / sizeof (struct pv_entry)) / 2)
609
610/*
611 * Data for the pv entry allocation mechanism
612 */
613int pv_freelistcnt;
614pv_entry_t pv_freelist;
615vm_offset_t pvva;
616int npvvapg;
617
618/*
619 * free the pv_entry back to the free list
620 */
621inline static void
622free_pv_entry(pv)
623	pv_entry_t pv;
624{
625	if (!pv) return;
626	++pv_freelistcnt;
627	pv->pv_next = pv_freelist;
628	pv_freelist = pv;
629}
630
631/*
632 * get a new pv_entry, allocating a block from the system
633 * when needed.
634 * the memory allocation is performed bypassing the malloc code
635 * because of the possibility of allocations at interrupt time.
636 */
637static inline pv_entry_t
638get_pv_entry()
639{
640	pv_entry_t tmp;
641
642	/*
643	 * get more pv_entry pages if needed
644	 */
645	while (pv_freelistcnt < PV_FREELIST_MIN || pv_freelist == 0) {
646		pmap_alloc_pv_entry();
647	}
648
649	/*
650	 * get a pv_entry off of the free list
651	 */
652	--pv_freelistcnt;
653	tmp = pv_freelist;
654	pv_freelist = tmp->pv_next;
655	tmp->pv_pmap = 0;
656	tmp->pv_va = 0;
657	tmp->pv_next = 0;
658	return tmp;
659}
660
661/*
662 * this *strange* allocation routine *statistically* eliminates the
663 * *possibility* of a malloc failure (*FATAL*) for a pv_entry_t data structure.
664 * also -- this code is MUCH MUCH faster than the malloc equiv...
665 */
666static void
667pmap_alloc_pv_entry()
668{
669	/*
670	 * do we have any pre-allocated map-pages left?
671	 */
672	if (npvvapg) {
673		vm_page_t m;
674		/*
675		 * we do this to keep recursion away
676		 */
677		pv_freelistcnt += PV_FREELIST_MIN;
678		/*
679		 * allocate a physical page out of the vm system
680		 */
681		if (m = vm_page_alloc(kernel_object, pvva-vm_map_min(kernel_map))) {
682			int newentries;
683			int i;
684			pv_entry_t entry;
685			newentries = (NBPG/sizeof (struct pv_entry));
686			/*
687			 * wire the page
688			 */
689			vm_page_wire(m);
690			m->flags &= ~PG_BUSY;
691			/*
692			 * let the kernel see it
693			 */
694			pmap_kenter(pvva, VM_PAGE_TO_PHYS(m));
695
696			entry = (pv_entry_t) pvva;
697			/*
698			 * update the allocation pointers
699			 */
700			pvva += NBPG;
701			--npvvapg;
702
703			/*
704			 * free the entries into the free list
705			 */
706			for (i = 0; i < newentries; i++) {
707				free_pv_entry(entry);
708				entry++;
709			}
710		}
711		pv_freelistcnt -= PV_FREELIST_MIN;
712	}
713	if (!pv_freelist)
714		panic("get_pv_entry: cannot get a pv_entry_t");
715}
716
717
718
719/*
720 * init the pv_entry allocation system
721 */
722#define PVSPERPAGE 64
723void
724init_pv_entries(npg)
725	int npg;
726{
727	/*
728	 * allocate enough kvm space for PVSPERPAGE entries per page (lots)
729	 * kvm space is fairly cheap, be generous!!!  (the system can panic
730	 * if this is too small.)
731	 */
732	npvvapg = ((npg*PVSPERPAGE) * sizeof(struct pv_entry) + NBPG - 1)/NBPG;
733	pvva = kmem_alloc_pageable(kernel_map, npvvapg * NBPG);
734	/*
735	 * get the first batch of entries
736	 */
737	free_pv_entry(get_pv_entry());
738}
739
740static pt_entry_t *
741get_pt_entry(pmap)
742	pmap_t pmap;
743{
744	pt_entry_t *ptp;
745	vm_offset_t frame = (int) pmap->pm_pdir[PTDPTDI] & PG_FRAME;
746	/* are we current address space or kernel? */
747	if (pmap == kernel_pmap || frame == ((int) PTDpde & PG_FRAME)) {
748		ptp=PTmap;
749	/* otherwise, we are alternate address space */
750	} else {
751		if ( frame != ((int) APTDpde & PG_FRAME)) {
752			APTDpde = pmap->pm_pdir[PTDPTDI];
753			tlbflush();
754		}
755		ptp=APTmap;
756	     }
757	return ptp;
758}
759
760/*
761 * If it is the first entry on the list, it is actually
762 * in the header and we must copy the following entry up
763 * to the header.  Otherwise we must search the list for
764 * the entry.  In either case we free the now unused entry.
765 */
766void
767pmap_remove_entry(pmap, pv, va)
768	struct pmap *pmap;
769	pv_entry_t pv;
770	vm_offset_t va;
771{
772	pv_entry_t npv;
773	int wired;
774	int s;
775	s = splhigh();
776	if (pmap == pv->pv_pmap && va == pv->pv_va) {
777		npv = pv->pv_next;
778		if (npv) {
779			*pv = *npv;
780			free_pv_entry(npv);
781		} else {
782			pv->pv_pmap = NULL;
783		}
784	} else {
785		for (npv = pv->pv_next; npv; npv = npv->pv_next) {
786			if (pmap == npv->pv_pmap && va == npv->pv_va) {
787				break;
788			}
789			pv = npv;
790		}
791		if (npv) {
792			pv->pv_next = npv->pv_next;
793			free_pv_entry(npv);
794		}
795	}
796	splx(s);
797}
798
799/*
800 *	Remove the given range of addresses from the specified map.
801 *
802 *	It is assumed that the start and end are properly
803 *	rounded to the page size.
804 */
805void
806pmap_remove(pmap, sva, eva)
807	struct pmap *pmap;
808	register vm_offset_t sva;
809	register vm_offset_t eva;
810{
811	register pt_entry_t *ptp,*ptq;
812	vm_offset_t pa;
813	register pv_entry_t pv;
814	vm_offset_t va;
815	vm_page_t m;
816	pt_entry_t oldpte;
817
818	if (pmap == NULL)
819		return;
820
821	ptp = get_pt_entry(pmap);
822
823/*
824 * special handling of removing one page.  a very
825 * common operation and easy to short circuit some
826 * code.
827 */
828	if( (sva + NBPG) == eva) {
829
830		if( *pmap_pde( pmap, sva) == 0)
831			return;
832
833		ptq = ptp + i386_btop(sva);
834
835		if( !*ptq)
836			return;
837		/*
838		 * Update statistics
839		 */
840		if (pmap_pte_w(ptq))
841			pmap->pm_stats.wired_count--;
842		pmap->pm_stats.resident_count--;
843
844		pa = pmap_pte_pa(ptq);
845		oldpte = *ptq;
846		*ptq = 0;
847
848		if (pmap_is_managed(pa)) {
849			if ((int) oldpte & (PG_M | PG_U)) {
850				if ((sva < USRSTACK || sva > UPT_MAX_ADDRESS) ||
851				    (sva >= USRSTACK && sva < USRSTACK+(UPAGES*NBPG))) {
852					if (sva < clean_sva || sva >= clean_eva) {
853						m = PHYS_TO_VM_PAGE(pa);
854						if ((int) oldpte & PG_M) {
855							m->flags &= ~PG_CLEAN;
856						}
857						if ((int) oldpte & PG_U) {
858							m->flags |= PG_REFERENCED;
859						}
860					}
861				}
862			}
863
864			pv = pa_to_pvh(pa);
865			pmap_remove_entry(pmap, pv, sva);
866			pmap_unuse_pt(pmap, sva);
867		}
868		tlbflush();
869		return;
870	}
871
872	sva = i386_btop(sva);
873	eva = i386_btop(eva);
874
875	while (sva < eva) {
876		/*
877		 * Weed out invalid mappings.
878		 * Note: we assume that the page directory table is
879	 	 * always allocated, and in kernel virtual.
880		 */
881
882		if ( *pmap_pde(pmap, i386_ptob(sva)) == 0 ) {
883			/* We can race ahead here, straight to next pde.. */
884	nextpde:
885			sva = ((sva + NPTEPG) & ~(NPTEPG - 1));
886			continue;
887		}
888
889		ptq = ptp + sva;
890
891		/*
892		 * search for page table entries, use string operations
893		 * that are much faster than
894		 * explicitly scanning when page tables are not fully
895		 * populated.
896		 */
897		if ( *ptq == 0) {
898			vm_offset_t pdnxt = ((sva + NPTEPG) & ~(NPTEPG - 1));
899			vm_offset_t nscan = pdnxt - sva;
900			int found = 0;
901
902			if ((nscan + sva) > eva)
903				nscan = eva - sva;
904
905			asm("xorl %%eax,%%eax;cld;repe;scasl;jz 1f;incl %%eax;1:;"
906				:"=D"(ptq),"=a"(found)
907				:"c"(nscan),"0"(ptq)
908				:"cx");
909
910			if( !found) {
911				sva = pdnxt;
912				continue;
913			}
914			ptq -= 1;
915
916			sva = ptq - ptp;
917		}
918
919		/*
920		 * Update statistics
921		 */
922		oldpte = *ptq;
923		if (((int)oldpte) & PG_W)
924			pmap->pm_stats.wired_count--;
925		pmap->pm_stats.resident_count--;
926
927		/*
928		 * Invalidate the PTEs.
929		 * XXX: should cluster them up and invalidate as many
930		 * as possible at once.
931		 */
932		*ptq = 0;
933
934		va = i386_ptob(sva);
935
936		/*
937		 * Remove from the PV table (raise IPL since we
938		 * may be called at interrupt time).
939		 */
940		pa = ((int)oldpte) & PG_FRAME;
941		if (!pmap_is_managed(pa)) {
942			++sva;
943			continue;
944		}
945
946		if ((((int) oldpte & PG_M) && (va < USRSTACK || va > UPT_MAX_ADDRESS))
947			|| (va >= USRSTACK && va < USRSTACK+(UPAGES*NBPG))) {
948			if (va < clean_sva || va >= clean_eva ) {
949				m = PHYS_TO_VM_PAGE(pa);
950				m->flags &= ~PG_CLEAN;
951			}
952		}
953
954		pv = pa_to_pvh(pa);
955		pmap_remove_entry(pmap, pv, va);
956		pmap_unuse_pt(pmap, va);
957		++sva;
958	}
959	tlbflush();
960}
961
962/*
963 *	Routine:	pmap_remove_all
964 *	Function:
965 *		Removes this physical page from
966 *		all physical maps in which it resides.
967 *		Reflects back modify bits to the pager.
968 *
969 *	Notes:
970 *		Original versions of this routine were very
971 *		inefficient because they iteratively called
972 *		pmap_remove (slow...)
973 */
974void
975pmap_remove_all(pa)
976	vm_offset_t pa;
977{
978	register pv_entry_t pv, npv;
979	register pt_entry_t *pte, *ptp;
980	vm_offset_t va;
981	struct pmap *pmap;
982	struct map *map;
983	vm_page_t m;
984	int s;
985	int anyvalid = 0;
986
987	/*
988	 * Not one of ours
989	 */
990	if (!pmap_is_managed(pa))
991		return;
992
993	pa = i386_trunc_page(pa);
994	pv = pa_to_pvh(pa);
995	m = PHYS_TO_VM_PAGE(pa);
996
997	s = splhigh();
998	while (pv->pv_pmap != NULL) {
999		pmap = pv->pv_pmap;
1000		ptp = get_pt_entry(pmap);
1001		va = i386_btop(pv->pv_va);
1002		pte = ptp + va;
1003		if (pmap_pte_w(pte))
1004			pmap->pm_stats.wired_count--;
1005		if ( *pte) {
1006			pmap->pm_stats.resident_count--;
1007			anyvalid++;
1008
1009			/*
1010			 * update the vm_page_t clean bit
1011			 */
1012			if ( (m->flags & PG_CLEAN) &&
1013				((((int) *pte) & PG_M) && (pv->pv_va < USRSTACK || pv->pv_va > UPT_MAX_ADDRESS))
1014				|| (pv->pv_va >= USRSTACK && pv->pv_va < USRSTACK+(UPAGES*NBPG))) {
1015				if (pv->pv_va < clean_sva || pv->pv_va >= clean_eva) {
1016					m->flags &= ~PG_CLEAN;
1017				}
1018			}
1019
1020			*pte = 0;
1021		}
1022		pmap_unuse_pt(pmap, pv->pv_va);
1023
1024		npv = pv->pv_next;
1025		if (npv) {
1026			*pv = *npv;
1027			free_pv_entry(npv);
1028		} else {
1029			pv->pv_pmap = NULL;
1030		}
1031	}
1032	splx(s);
1033	if (anyvalid)
1034		tlbflush();
1035}
1036
1037
1038/*
1039 *	Set the physical protection on the
1040 *	specified range of this map as requested.
1041 */
1042void
1043pmap_protect(pmap, sva, eva, prot)
1044	register pmap_t	pmap;
1045	vm_offset_t	sva, eva;
1046	vm_prot_t	prot;
1047{
1048	register pt_entry_t *pte;
1049	register vm_offset_t va;
1050	int i386prot;
1051	register pt_entry_t *ptp;
1052	int evap = i386_btop(eva);
1053	int s;
1054	int anyvalid = 0;;
1055
1056	if (pmap == NULL)
1057		return;
1058
1059	if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
1060		pmap_remove(pmap, sva, eva);
1061		return;
1062	}
1063	if (prot & VM_PROT_WRITE)
1064		return;
1065
1066	ptp = get_pt_entry(pmap);
1067
1068	va = sva;
1069	while (va < eva) {
1070		int found=0;
1071		int svap;
1072		vm_offset_t nscan;
1073		/*
1074		 * Page table page is not allocated.
1075		 * Skip it, we don't want to force allocation
1076		 * of unnecessary PTE pages just to set the protection.
1077		 */
1078		if (! *pmap_pde(pmap, va)) {
1079			/* XXX: avoid address wrap around */
1080nextpde:
1081			if (va >= i386_trunc_pdr((vm_offset_t)-1))
1082				break;
1083			va = i386_round_pdr(va + PAGE_SIZE);
1084			continue;
1085		}
1086
1087		pte = ptp + i386_btop(va);
1088
1089		if( *pte == 0) {
1090		/*
1091		 * scan for a non-empty pte
1092		 */
1093			svap = pte - ptp;
1094			nscan = ((svap + NPTEPG) & ~(NPTEPG - 1)) - svap;
1095
1096			if (nscan + svap > evap)
1097				nscan = evap - svap;
1098
1099			found = 0;
1100			if (nscan)
1101				asm("xorl %%eax,%%eax;cld;repe;scasl;jz 1f;incl %%eax;1:;"
1102					:"=D"(pte),"=a"(found)
1103					:"c"(nscan),"0"(pte):"cx");
1104
1105			if( !found)
1106				goto nextpde;
1107
1108			pte -= 1;
1109			svap = pte - ptp;
1110
1111			va = i386_ptob(svap);
1112		}
1113
1114		anyvalid++;
1115
1116		i386prot = pte_prot(pmap, prot);
1117		if (va < UPT_MAX_ADDRESS) {
1118			i386prot |= PG_u;
1119			if( va >= UPT_MIN_ADDRESS)
1120				i386prot |= PG_RW;
1121		}
1122		pmap_pte_set_prot(pte, i386prot);
1123		va += PAGE_SIZE;
1124	}
1125	if (anyvalid)
1126		tlbflush();
1127}
1128
1129/*
1130 *	Insert the given physical page (p) at
1131 *	the specified virtual address (v) in the
1132 *	target physical map with the protection requested.
1133 *
1134 *	If specified, the page will be wired down, meaning
1135 *	that the related pte can not be reclaimed.
1136 *
1137 *	NB:  This is the only routine which MAY NOT lazy-evaluate
1138 *	or lose information.  That is, this routine must actually
1139 *	insert this page into the given map NOW.
1140 */
1141void
1142pmap_enter(pmap, va, pa, prot, wired)
1143	register pmap_t pmap;
1144	vm_offset_t va;
1145	register vm_offset_t pa;
1146	vm_prot_t prot;
1147	boolean_t wired;
1148{
1149	register pt_entry_t *pte;
1150	register pt_entry_t npte;
1151	vm_offset_t opa;
1152	int cacheable=1;
1153	int ptevalid = 0;
1154
1155	if (pmap == NULL)
1156		return;
1157
1158	va = i386_trunc_page(va);
1159	pa = i386_trunc_page(pa);
1160	if (va > VM_MAX_KERNEL_ADDRESS)panic("pmap_enter: toobig");
1161
1162	/*
1163	 * Page Directory table entry not valid, we need a new PT page
1164	 */
1165	if ( *pmap_pde(pmap, va) == 0) {
1166		pg("ptdi %x, va %x", pmap->pm_pdir[PTDPTDI], va);
1167	}
1168
1169	pte = pmap_pte(pmap, va);
1170	opa = pmap_pte_pa(pte);
1171
1172	/*
1173	 * Mapping has not changed, must be protection or wiring change.
1174	 */
1175	if (opa == pa) {
1176		/*
1177		 * Wiring change, just update stats.
1178		 * We don't worry about wiring PT pages as they remain
1179		 * resident as long as there are valid mappings in them.
1180		 * Hence, if a user page is wired, the PT page will be also.
1181		 */
1182		if (wired && !pmap_pte_w(pte) || !wired && pmap_pte_w(pte)) {
1183			if (wired)
1184				pmap->pm_stats.wired_count++;
1185			else
1186				pmap->pm_stats.wired_count--;
1187		}
1188		goto validate;
1189	}
1190
1191	/*
1192	 * Mapping has changed, invalidate old range and fall through to
1193	 * handle validating new mapping.
1194	 */
1195	if (opa) {
1196		pmap_remove(pmap, va, va + PAGE_SIZE);
1197	}
1198
1199	/*
1200	 * Enter on the PV list if part of our managed memory
1201	 * Note that we raise IPL while manipulating pv_table
1202	 * since pmap_enter can be called at interrupt time.
1203	 */
1204	if (pmap_is_managed(pa)) {
1205		register pv_entry_t pv, npv;
1206		int s;
1207
1208		pv = pa_to_pvh(pa);
1209		s = splhigh();
1210		/*
1211		 * No entries yet, use header as the first entry
1212		 */
1213		if (pv->pv_pmap == NULL) {
1214			pv->pv_va = va;
1215			pv->pv_pmap = pmap;
1216			pv->pv_next = NULL;
1217		}
1218		/*
1219		 * There is at least one other VA mapping this page.
1220		 * Place this entry after the header.
1221		 */
1222		else {
1223			npv = get_pv_entry();
1224			npv->pv_va = va;
1225			npv->pv_pmap = pmap;
1226			npv->pv_next = pv->pv_next;
1227			pv->pv_next = npv;
1228		}
1229		splx(s);
1230		cacheable = 1;
1231	} else {
1232		cacheable = 0;
1233	}
1234
1235	pmap_use_pt(pmap, va);
1236
1237	/*
1238	 * Increment counters
1239	 */
1240	pmap->pm_stats.resident_count++;
1241	if (wired)
1242		pmap->pm_stats.wired_count++;
1243
1244validate:
1245	/*
1246	 * Now validate mapping with desired protection/wiring.
1247	 */
1248	npte = (pt_entry_t) ( (int) (pa | pte_prot(pmap, prot) | PG_V));
1249	/*
1250	 * for correctness:
1251	 */
1252	if( !cacheable)
1253		(int) npte |= PG_N;
1254
1255	/*
1256	 * When forking (copy-on-write, etc):
1257	 * A process will turn off write permissions for any of its writable
1258	 * pages.  If the data (object) is only referred to by one process, the
1259	 * processes map is modified directly as opposed to using the
1260	 * object manipulation routine.  When using pmap_protect, the
1261	 * modified bits are not kept in the vm_page_t data structure.
1262	 * Therefore, when using pmap_enter in vm_fault to bring back
1263	 * writability of a page, there has been no memory of the
1264	 * modified or referenced bits except at the pte level.
1265	 * this clause supports the carryover of the modified and
1266	 * used (referenced) bits.
1267	 */
1268	if (pa == opa)
1269		(int) npte |= (int) *pte & (PG_M|PG_U);
1270
1271
1272	if (wired)
1273		(int) npte |= PG_W;
1274	if (va < UPT_MIN_ADDRESS)
1275		(int) npte |= PG_u;
1276	else if (va < UPT_MAX_ADDRESS)
1277		(int) npte |= PG_u | PG_RW;
1278
1279	if(*pte != npte) {
1280		if (*pte)
1281			ptevalid++;
1282		*pte = npte;
1283	}
1284	if (ptevalid)
1285		tlbflush();
1286}
1287
1288/*
1289 * Add a list of wired pages to the kva
1290 * this routine is only used for temporary
1291 * kernel mappings that do not need to have
1292 * page modification or references recorded.
1293 * Note that old mappings are simply written
1294 * over.  The page *must* be wired.
1295 */
1296void
1297pmap_qenter(va, m, count)
1298	vm_offset_t va;
1299	vm_page_t *m;
1300	int count;
1301{
1302	int i;
1303	int anyvalid = 0;
1304	register pt_entry_t *pte;
1305
1306	for(i=0;i<count;i++) {
1307		pte = vtopte(va + i * NBPG);
1308		if (*pte)
1309			anyvalid++;
1310		*pte = (pt_entry_t) ( (int) (VM_PAGE_TO_PHYS(m[i]) | PG_RW | PG_V | PG_W));
1311	}
1312	if (anyvalid)
1313		tlbflush();
1314}
1315/*
1316 * this routine jerks page mappings from the
1317 * kernel -- it is meant only for temporary mappings.
1318 */
1319void
1320pmap_qremove(va, count)
1321	vm_offset_t va;
1322	int count;
1323{
1324	int i;
1325	register pt_entry_t *pte;
1326	for(i=0;i<count;i++) {
1327		pte = vtopte(va + i * NBPG);
1328		*pte = 0;
1329	}
1330	tlbflush();
1331}
1332
1333/*
1334 * add a wired page to the kva
1335 * note that in order for the mapping to take effect -- you
1336 * should do a tlbflush after doing the pmap_kenter...
1337 */
1338void
1339pmap_kenter(va, pa)
1340	vm_offset_t va;
1341	register vm_offset_t pa;
1342{
1343	register pt_entry_t *pte;
1344	int wasvalid = 0;
1345
1346	pte = vtopte(va);
1347
1348	if (*pte)
1349		wasvalid++;
1350
1351	*pte = (pt_entry_t) ( (int) (pa | PG_RW | PG_V | PG_W));
1352
1353	if (wasvalid)
1354		tlbflush();
1355}
1356
1357/*
1358 * remove a page from the kernel pagetables
1359 */
1360void
1361pmap_kremove( va)
1362	vm_offset_t va;
1363{
1364	register pt_entry_t *pte;
1365	pte = vtopte(va);
1366
1367	*pte = (pt_entry_t) 0;
1368	tlbflush();
1369}
1370
1371/*
1372 * this code makes some *MAJOR* assumptions:
1373 * 1. Current pmap & pmap exists.
1374 * 2. Not wired.
1375 * 3. Read access.
1376 * 4. No page table pages.
1377 * 5. Tlbflush is deferred to calling procedure.
1378 * 6. Page IS managed.
1379 * but is *MUCH* faster than pmap_enter...
1380 */
1381
1382static inline int
1383pmap_enter_quick(pmap, va, pa)
1384	register pmap_t pmap;
1385	vm_offset_t va;
1386	register vm_offset_t pa;
1387{
1388	register pt_entry_t *pte;
1389	register pv_entry_t pv, npv;
1390	int s;
1391	int anyvalid = 0;
1392
1393	/*
1394	 * Enter on the PV list if part of our managed memory
1395	 * Note that we raise IPL while manipulating pv_table
1396	 * since pmap_enter can be called at interrupt time.
1397	 */
1398
1399	pte = vtopte(va);
1400	if (pmap_pte_pa(pte)) {
1401		pmap_remove(pmap, va, va + PAGE_SIZE);
1402	}
1403
1404	pv = pa_to_pvh(pa);
1405	s = splhigh();
1406	/*
1407	 * No entries yet, use header as the first entry
1408	 */
1409	if (pv->pv_pmap == NULL) {
1410		pv->pv_va = va;
1411		pv->pv_pmap = pmap;
1412		pv->pv_next = NULL;
1413	}
1414	/*
1415	 * There is at least one other VA mapping this page.
1416	 * Place this entry after the header.
1417	 */
1418	else {
1419		npv = get_pv_entry();
1420		npv->pv_va = va;
1421		npv->pv_pmap = pmap;
1422		npv->pv_next = pv->pv_next;
1423		pv->pv_next = npv;
1424	}
1425	splx(s);
1426
1427	pmap_use_pt(pmap, va);
1428
1429	/*
1430	 * Increment counters
1431	 */
1432	pmap->pm_stats.resident_count++;
1433
1434validate:
1435
1436	if (*pte)
1437		anyvalid++;
1438	/*
1439	 * Now validate mapping with desired protection/wiring.
1440	 */
1441	*pte = (pt_entry_t) ( (int) (pa | PG_V | PG_u));
1442
1443	return (anyvalid);
1444}
1445
1446/*
1447 * pmap_object_init_pt preloads the ptes for a given object
1448 * into the specified pmap.  This eliminates the blast of soft
1449 * faults on process startup and immediately after an mmap.
1450 */
1451void
1452pmap_object_init_pt(pmap, addr, object, offset, size)
1453	pmap_t pmap;
1454	vm_offset_t addr;
1455	vm_object_t object;
1456	vm_offset_t offset;
1457	vm_offset_t size;
1458{
1459
1460	vm_offset_t tmpoff;
1461	vm_page_t p;
1462	int s;
1463	vm_offset_t v, lastv=0;
1464	pt_entry_t pte;
1465	vm_offset_t objbytes;
1466	int anyvalid = 0;
1467
1468	if (!pmap)
1469		return;
1470
1471	/*
1472	 * if we are processing a major portion of the object, then
1473	 * scan the entire thing.
1474	 */
1475	if( size > object->size / 2) {
1476		objbytes = size;
1477		p = object->memq.tqh_first;
1478		while ((p != NULL) && (objbytes != 0)) {
1479			tmpoff = p->offset;
1480			if( tmpoff < offset) {
1481				p = p->listq.tqe_next;
1482				continue;
1483			}
1484			tmpoff -= offset;
1485			if( tmpoff >= size) {
1486				p = p->listq.tqe_next;
1487				continue;
1488			}
1489
1490			if ((p->flags & (PG_BUSY|PG_FICTITIOUS)) == 0 ) {
1491				vm_page_hold(p);
1492				v = i386_trunc_page(((vm_offset_t)vtopte( addr+tmpoff)));
1493				/* a fault might occur here */
1494				*(volatile char *)v += 0;
1495				vm_page_unhold(p);
1496				anyvalid += pmap_enter_quick(pmap, addr+tmpoff, VM_PAGE_TO_PHYS(p));
1497			}
1498			p = p->listq.tqe_next;
1499			objbytes -= NBPG;
1500		}
1501	} else {
1502	/*
1503	 * else lookup the pages one-by-one.
1504	 */
1505		for(tmpoff = 0; tmpoff < size; tmpoff += NBPG) {
1506			if( p = vm_page_lookup(object, tmpoff + offset)) {
1507				if( (p->flags & (PG_BUSY|PG_FICTITIOUS)) == 0) {
1508					vm_page_hold(p);
1509					v = i386_trunc_page(((vm_offset_t)vtopte( addr+tmpoff)));
1510					/* a fault might occur here */
1511					*(volatile char *)v += 0;
1512					vm_page_unhold(p);
1513					anyvalid += pmap_enter_quick(pmap, addr+tmpoff, VM_PAGE_TO_PHYS(p));
1514				}
1515			}
1516		}
1517	}
1518
1519	if (anyvalid)
1520		tlbflush();
1521}
1522
1523/*
1524 *	Routine:	pmap_change_wiring
1525 *	Function:	Change the wiring attribute for a map/virtual-address
1526 *			pair.
1527 *	In/out conditions:
1528 *			The mapping must already exist in the pmap.
1529 */
1530void
1531pmap_change_wiring(pmap, va, wired)
1532	register pmap_t	pmap;
1533	vm_offset_t	va;
1534	boolean_t	wired;
1535{
1536	register pt_entry_t *pte;
1537
1538	if (pmap == NULL)
1539		return;
1540
1541	pte = pmap_pte(pmap, va);
1542	if (wired && !pmap_pte_w(pte) || !wired && pmap_pte_w(pte)) {
1543		if (wired)
1544			pmap->pm_stats.wired_count++;
1545		else
1546			pmap->pm_stats.wired_count--;
1547	}
1548	/*
1549	 * Wiring is not a hardware characteristic so there is no need
1550	 * to invalidate TLB.
1551	 */
1552	pmap_pte_set_w(pte, wired);
1553	/*
1554 	 * When unwiring, set the modified bit in the pte -- could have
1555	 * been changed by the kernel
1556 	 */
1557	if (!wired)
1558		(int) *pte |= PG_M;
1559}
1560
1561
1562
1563/*
1564 *	Copy the range specified by src_addr/len
1565 *	from the source map to the range dst_addr/len
1566 *	in the destination map.
1567 *
1568 *	This routine is only advisory and need not do anything.
1569 */
1570void
1571pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr)
1572	pmap_t dst_pmap, src_pmap;
1573	vm_offset_t	dst_addr;
1574	vm_size_t	len;
1575	vm_offset_t	src_addr;
1576{
1577}
1578/*
1579 *	Require that all active physical maps contain no
1580 *	incorrect entries NOW.  [This update includes
1581 *	forcing updates of any address map caching.]
1582 *
1583 *	Generally used to insure that a thread about
1584 *	to run will see a semantically correct world.
1585 */
1586void
1587pmap_update()
1588{
1589	tlbflush();
1590}
1591
1592/*
1593 *	Routine:	pmap_kernel
1594 *	Function:
1595 *		Returns the physical map handle for the kernel.
1596 */
1597pmap_t
1598pmap_kernel()
1599{
1600    	return (kernel_pmap);
1601}
1602
1603/*
1604 *	pmap_zero_page zeros the specified (machine independent)
1605 *	page by mapping the page into virtual memory and using
1606 *	bzero to clear its contents, one machine dependent page
1607 *	at a time.
1608 */
1609void
1610pmap_zero_page(phys)
1611	vm_offset_t phys;
1612{
1613	if (*(int *)CMAP2)
1614		panic("pmap_zero_page: CMAP busy");
1615
1616	*(int *)CMAP2 = PG_V | PG_KW | i386_trunc_page(phys);
1617	bzero(CADDR2,NBPG);
1618
1619	*(int *)CMAP2 = 0;
1620	tlbflush();
1621}
1622
1623/*
1624 *	pmap_copy_page copies the specified (machine independent)
1625 *	page by mapping the page into virtual memory and using
1626 *	bcopy to copy the page, one machine dependent page at a
1627 *	time.
1628 */
1629void
1630pmap_copy_page(src, dst)
1631	vm_offset_t src;
1632	vm_offset_t dst;
1633{
1634	if (*(int *)CMAP1 || *(int *)CMAP2)
1635		panic("pmap_copy_page: CMAP busy");
1636
1637	*(int *)CMAP1 = PG_V | PG_KW | i386_trunc_page(src);
1638	*(int *)CMAP2 = PG_V | PG_KW | i386_trunc_page(dst);
1639
1640#if __GNUC__ > 1
1641	memcpy(CADDR2, CADDR1, NBPG);
1642#else
1643	bcopy(CADDR1, CADDR2, NBPG);
1644#endif
1645	*(int *)CMAP1 = 0;
1646	*(int *)CMAP2 = 0;
1647	tlbflush();
1648}
1649
1650
1651/*
1652 *	Routine:	pmap_pageable
1653 *	Function:
1654 *		Make the specified pages (by pmap, offset)
1655 *		pageable (or not) as requested.
1656 *
1657 *		A page which is not pageable may not take
1658 *		a fault; therefore, its page table entry
1659 *		must remain valid for the duration.
1660 *
1661 *		This routine is merely advisory; pmap_enter
1662 *		will specify that these pages are to be wired
1663 *		down (or not) as appropriate.
1664 */
1665void
1666pmap_pageable(pmap, sva, eva, pageable)
1667	pmap_t		pmap;
1668	vm_offset_t	sva, eva;
1669	boolean_t	pageable;
1670{
1671}
1672
1673/*
1674 * this routine returns true if a physical page resides
1675 * in the given pmap.
1676 */
1677boolean_t
1678pmap_page_exists(pmap, pa)
1679	pmap_t pmap;
1680	vm_offset_t pa;
1681{
1682	register pv_entry_t pv;
1683	int s;
1684
1685	if (!pmap_is_managed(pa))
1686		return FALSE;
1687
1688	pv = pa_to_pvh(pa);
1689	s = splhigh();
1690
1691	/*
1692	 * Not found, check current mappings returning
1693	 * immediately if found.
1694	 */
1695	if (pv->pv_pmap != NULL) {
1696		for (; pv; pv = pv->pv_next) {
1697			if (pv->pv_pmap == pmap) {
1698				splx(s);
1699				return TRUE;
1700			}
1701		}
1702	}
1703	splx(s);
1704	return(FALSE);
1705}
1706
1707/*
1708 * pmap_testbit tests bits in pte's
1709 * note that the testbit/changebit routines are inline,
1710 * and a lot of things compile-time evaluate.
1711 */
1712static inline boolean_t
1713pmap_testbit(pa, bit)
1714	register vm_offset_t pa;
1715	int bit;
1716{
1717	register pv_entry_t pv;
1718	pt_entry_t *pte;
1719	int s;
1720
1721	if (!pmap_is_managed(pa))
1722		return FALSE;
1723
1724	pv = pa_to_pvh(pa);
1725	s = splhigh();
1726
1727	/*
1728	 * Not found, check current mappings returning
1729	 * immediately if found.
1730	 */
1731	if (pv->pv_pmap != NULL) {
1732		for (; pv; pv = pv->pv_next) {
1733			/*
1734			 * if the bit being tested is the modified bit,
1735			 * then mark UPAGES as always modified, and
1736			 * ptes as never modified.
1737			 */
1738			if (bit & PG_U ) {
1739				if ((pv->pv_va >= clean_sva) && (pv->pv_va < clean_eva)) {
1740					continue;
1741				}
1742			}
1743			if (bit & PG_M ) {
1744				if (pv->pv_va >= USRSTACK) {
1745					if (pv->pv_va >= clean_sva && pv->pv_va < clean_eva) {
1746						continue;
1747					}
1748					if (pv->pv_va < USRSTACK+(UPAGES*NBPG)) {
1749						splx(s);
1750						return TRUE;
1751					}
1752					else if (pv->pv_va < UPT_MAX_ADDRESS) {
1753						splx(s);
1754						return FALSE;
1755					}
1756				}
1757			}
1758			if( !pv->pv_pmap) {
1759				printf("Null pmap (tb) at va: 0x%lx\n", pv->pv_va);
1760				continue;
1761			}
1762			pte = pmap_pte(pv->pv_pmap, pv->pv_va);
1763			if ((int) *pte & bit) {
1764				splx(s);
1765				return TRUE;
1766			}
1767		}
1768	}
1769	splx(s);
1770	return(FALSE);
1771}
1772
1773/*
1774 * this routine is used to modify bits in ptes
1775 */
1776static inline void
1777pmap_changebit(pa, bit, setem)
1778	vm_offset_t pa;
1779	int bit;
1780	boolean_t setem;
1781{
1782	register pv_entry_t pv;
1783	register pt_entry_t *pte, npte;
1784	vm_offset_t va;
1785	int s;
1786
1787	if (!pmap_is_managed(pa))
1788		return;
1789
1790	pv = pa_to_pvh(pa);
1791	s = splhigh();
1792
1793	/*
1794	 * Loop over all current mappings setting/clearing as appropos
1795	 * If setting RO do we need to clear the VAC?
1796	 */
1797	if (pv->pv_pmap != NULL) {
1798		for (; pv; pv = pv->pv_next) {
1799			va = pv->pv_va;
1800
1801			/*
1802			 * don't write protect pager mappings
1803			 */
1804			if (!setem && (bit == PG_RW)) {
1805				if (va >= clean_sva && va < clean_eva)
1806					continue;
1807			}
1808
1809			if( !pv->pv_pmap) {
1810				printf("Null pmap (cb) at va: 0x%lx\n", va);
1811				continue;
1812			}
1813			pte = pmap_pte(pv->pv_pmap, va);
1814			if (setem)
1815				(int) npte = (int) *pte | bit;
1816			else
1817				(int) npte = (int) *pte & ~bit;
1818			*pte = npte;
1819		}
1820	}
1821	splx(s);
1822	tlbflush();
1823}
1824
1825/*
1826 *      pmap_page_protect:
1827 *
1828 *      Lower the permission for all mappings to a given page.
1829 */
1830void
1831pmap_page_protect(phys, prot)
1832        vm_offset_t     phys;
1833        vm_prot_t       prot;
1834{
1835	if ((prot & VM_PROT_WRITE) == 0) {
1836		if (prot & (VM_PROT_READ | VM_PROT_EXECUTE))
1837			pmap_changebit(phys, PG_RW, FALSE);
1838		else
1839			pmap_remove_all(phys);
1840	}
1841}
1842
1843/*
1844 *	Clear the modify bits on the specified physical page.
1845 */
1846void
1847pmap_clear_modify(pa)
1848	vm_offset_t	pa;
1849{
1850	pmap_changebit(pa, PG_M, FALSE);
1851}
1852
1853/*
1854 *	pmap_clear_reference:
1855 *
1856 *	Clear the reference bit on the specified physical page.
1857 */
1858void
1859pmap_clear_reference(pa)
1860	vm_offset_t	pa;
1861{
1862	pmap_changebit(pa, PG_U, FALSE);
1863}
1864
1865/*
1866 *	pmap_is_referenced:
1867 *
1868 *	Return whether or not the specified physical page is referenced
1869 *	by any physical maps.
1870 */
1871
1872boolean_t
1873pmap_is_referenced(pa)
1874	vm_offset_t	pa;
1875{
1876	return(pmap_testbit(pa, PG_U));
1877}
1878
1879/*
1880 *	pmap_is_modified:
1881 *
1882 *	Return whether or not the specified physical page is modified
1883 *	by any physical maps.
1884 */
1885
1886boolean_t
1887pmap_is_modified(pa)
1888	vm_offset_t	pa;
1889{
1890	return(pmap_testbit(pa, PG_M));
1891}
1892
1893/*
1894 *	Routine:	pmap_copy_on_write
1895 *	Function:
1896 *		Remove write privileges from all
1897 *		physical maps for this physical page.
1898 */
1899void
1900pmap_copy_on_write(pa)
1901	vm_offset_t pa;
1902{
1903	pmap_changebit(pa, PG_RW, FALSE);
1904}
1905
1906
1907vm_offset_t
1908pmap_phys_address(ppn)
1909	int ppn;
1910{
1911	return(i386_ptob(ppn));
1912}
1913
1914/*
1915 * Miscellaneous support routines follow
1916 */
1917
1918void
1919i386_protection_init()
1920{
1921	register int *kp, prot;
1922
1923	kp = protection_codes;
1924	for (prot = 0; prot < 8; prot++) {
1925		switch (prot) {
1926		case VM_PROT_NONE | VM_PROT_NONE | VM_PROT_NONE:
1927		/*
1928		 * Read access is also 0. There isn't any execute
1929		 * bit, so just make it readable.
1930		 */
1931		case VM_PROT_READ | VM_PROT_NONE | VM_PROT_NONE:
1932		case VM_PROT_READ | VM_PROT_NONE | VM_PROT_EXECUTE:
1933		case VM_PROT_NONE | VM_PROT_NONE | VM_PROT_EXECUTE:
1934			*kp++ = 0;
1935			break;
1936		case VM_PROT_NONE | VM_PROT_WRITE | VM_PROT_NONE:
1937		case VM_PROT_NONE | VM_PROT_WRITE | VM_PROT_EXECUTE:
1938		case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_NONE:
1939		case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE:
1940			*kp++ = PG_RW;
1941			break;
1942		}
1943	}
1944}
1945
1946#ifdef DEBUG
1947/* print address space of pmap*/
1948void
1949pads(pm)
1950	pmap_t pm;
1951{
1952	unsigned va, i, j;
1953	pt_entry_t *ptep;
1954
1955	if (pm == kernel_pmap) return;
1956	for (i = 0; i < 1024; i++)
1957		if (pm->pm_pdir[i])
1958			for (j = 0; j < 1024 ; j++) {
1959				va = (i<<PD_SHIFT)+(j<<PG_SHIFT);
1960				if (pm == kernel_pmap && va < KERNBASE)
1961						continue;
1962				if (pm != kernel_pmap && va > UPT_MAX_ADDRESS)
1963						continue;
1964				ptep = pmap_pte(pm, va);
1965				if (pmap_pte_v(ptep))
1966					printf("%x:%x ", va, *(int *)ptep);
1967			} ;
1968
1969}
1970
1971void
1972pmap_pvdump(pa)
1973	vm_offset_t pa;
1974{
1975	register pv_entry_t pv;
1976
1977	printf("pa %x", pa);
1978	for (pv = pa_to_pvh(pa); pv; pv = pv->pv_next) {
1979#ifdef used_to_be
1980		printf(" -> pmap %x, va %x, flags %x",
1981		       pv->pv_pmap, pv->pv_va, pv->pv_flags);
1982#endif
1983		printf(" -> pmap %x, va %x",
1984		       pv->pv_pmap, pv->pv_va);
1985		pads(pv->pv_pmap);
1986	}
1987	printf(" ");
1988}
1989#endif
1990
1991