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