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