]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/i386/i386/pmap.c
Tidy up some loose ends.
[FreeBSD/FreeBSD.git] / sys / i386 / i386 / pmap.c
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  * $FreeBSD$
43  */
44
45 /*
46  *      Manages physical address maps.
47  *
48  *      In addition to hardware address maps, this
49  *      module is called upon to provide software-use-only
50  *      maps which may or may not be stored in the same
51  *      form as hardware maps.  These pseudo-maps are
52  *      used to store intermediate results from copy
53  *      operations to and from address spaces.
54  *
55  *      Since the information managed by this module is
56  *      also stored by the logical address mapping module,
57  *      this module may throw away valid virtual-to-physical
58  *      mappings at almost any time.  However, invalidations
59  *      of virtual-to-physical mappings must be done as
60  *      requested.
61  *
62  *      In order to cope with hardware architectures which
63  *      make virtual-to-physical map invalidates expensive,
64  *      this module may delay invalidate or reduced protection
65  *      operations until such time as they are actually
66  *      necessary.  This module is given full information as
67  *      to which processors are currently using which maps,
68  *      and to when physical maps must be made correct.
69  */
70
71 #include "opt_disable_pse.h"
72 #include "opt_pmap.h"
73 #include "opt_msgbuf.h"
74 #include "opt_kstack_pages.h"
75
76 #include <sys/param.h>
77 #include <sys/systm.h>
78 #include <sys/kernel.h>
79 #include <sys/lock.h>
80 #include <sys/mman.h>
81 #include <sys/msgbuf.h>
82 #include <sys/mutex.h>
83 #include <sys/proc.h>
84 #include <sys/sx.h>
85 #include <sys/user.h>
86 #include <sys/vmmeter.h>
87 #include <sys/sysctl.h>
88
89 #include <vm/vm.h>
90 #include <vm/vm_param.h>
91 #include <vm/vm_kern.h>
92 #include <vm/vm_page.h>
93 #include <vm/vm_map.h>
94 #include <vm/vm_object.h>
95 #include <vm/vm_extern.h>
96 #include <vm/vm_pageout.h>
97 #include <vm/vm_pager.h>
98 #include <vm/uma.h>
99
100 #include <machine/cputypes.h>
101 #include <machine/md_var.h>
102 #include <machine/specialreg.h>
103 #if defined(SMP) || defined(APIC_IO)
104 #include <machine/smp.h>
105 #include <machine/apic.h>
106 #include <machine/segments.h>
107 #include <machine/tss.h>
108 #endif /* SMP || APIC_IO */
109
110 #define PMAP_KEEP_PDIRS
111 #ifndef PMAP_SHPGPERPROC
112 #define PMAP_SHPGPERPROC 200
113 #endif
114
115 #if defined(DIAGNOSTIC)
116 #define PMAP_DIAGNOSTIC
117 #endif
118
119 #define MINPV 2048
120
121 #if !defined(PMAP_DIAGNOSTIC)
122 #define PMAP_INLINE __inline
123 #else
124 #define PMAP_INLINE
125 #endif
126
127 /*
128  * Get PDEs and PTEs for user/kernel address space
129  */
130 #define pmap_pde(m, v)  (&((m)->pm_pdir[(vm_offset_t)(v) >> PDRSHIFT]))
131 #define pdir_pde(m, v) (m[(vm_offset_t)(v) >> PDRSHIFT])
132
133 #define pmap_pde_v(pte)         ((*(int *)pte & PG_V) != 0)
134 #define pmap_pte_w(pte)         ((*(int *)pte & PG_W) != 0)
135 #define pmap_pte_m(pte)         ((*(int *)pte & PG_M) != 0)
136 #define pmap_pte_u(pte)         ((*(int *)pte & PG_A) != 0)
137 #define pmap_pte_v(pte)         ((*(int *)pte & PG_V) != 0)
138
139 #define pmap_pte_set_w(pte, v) ((v)?(*(int *)pte |= PG_W):(*(int *)pte &= ~PG_W))
140 #define pmap_pte_set_prot(pte, v) ((*(int *)pte &= ~PG_PROT), (*(int *)pte |= (v)))
141
142 /*
143  * Given a map and a machine independent protection code,
144  * convert to a vax protection code.
145  */
146 #define pte_prot(m, p)  (protection_codes[p])
147 static int protection_codes[8];
148
149 struct pmap kernel_pmap_store;
150 LIST_HEAD(pmaplist, pmap);
151 struct pmaplist allpmaps;
152
153 vm_offset_t avail_start;        /* PA of first available physical page */
154 vm_offset_t avail_end;          /* PA of last available physical page */
155 vm_offset_t virtual_avail;      /* VA of first avail page (after kernel bss) */
156 vm_offset_t virtual_end;        /* VA of last avail page (end of kernel AS) */
157 static boolean_t pmap_initialized = FALSE;      /* Has pmap_init completed? */
158 static int pgeflag;             /* PG_G or-in */
159 static int pseflag;             /* PG_PS or-in */
160
161 static vm_object_t kptobj;
162
163 static int nkpt;
164 vm_offset_t kernel_vm_end;
165
166 /*
167  * Data for the pv entry allocation mechanism
168  */
169 static uma_zone_t pvzone;
170 static struct vm_object pvzone_obj;
171 static int pv_entry_count = 0, pv_entry_max = 0, pv_entry_high_water = 0;
172 static int pmap_pagedaemon_waken = 0;
173
174 /*
175  * All those kernel PT submaps that BSD is so fond of
176  */
177 pt_entry_t *CMAP1 = 0;
178 static pt_entry_t *CMAP2, *ptmmap;
179 caddr_t CADDR1 = 0, ptvmmap = 0;
180 static caddr_t CADDR2;
181 static pt_entry_t *msgbufmap;
182 struct msgbuf *msgbufp = 0;
183
184 /*
185  * Crashdump maps.
186  */
187 static pt_entry_t *pt_crashdumpmap;
188 static caddr_t crashdumpmap;
189
190 #ifdef SMP
191 extern pt_entry_t *SMPpt;
192 #endif
193 static pt_entry_t *PMAP1 = 0;
194 static pt_entry_t *PADDR1 = 0;
195
196 static PMAP_INLINE void free_pv_entry(pv_entry_t pv);
197 static pt_entry_t *get_ptbase(pmap_t pmap);
198 static pv_entry_t get_pv_entry(void);
199 static void     i386_protection_init(void);
200 static __inline void    pmap_changebit(vm_page_t m, int bit, boolean_t setem);
201
202 static void     pmap_remove_all(vm_page_t m);
203 static vm_page_t pmap_enter_quick(pmap_t pmap, vm_offset_t va,
204                                       vm_page_t m, vm_page_t mpte);
205 static int pmap_remove_pte(pmap_t pmap, pt_entry_t *ptq, vm_offset_t sva);
206 static void pmap_remove_page(struct pmap *pmap, vm_offset_t va);
207 static int pmap_remove_entry(struct pmap *pmap, vm_page_t m,
208                                         vm_offset_t va);
209 static boolean_t pmap_testbit(vm_page_t m, int bit);
210 static void pmap_insert_entry(pmap_t pmap, vm_offset_t va,
211                 vm_page_t mpte, vm_page_t m);
212
213 static vm_page_t pmap_allocpte(pmap_t pmap, vm_offset_t va);
214
215 static int pmap_release_free_page(pmap_t pmap, vm_page_t p);
216 static vm_page_t _pmap_allocpte(pmap_t pmap, unsigned ptepindex);
217 static pt_entry_t *pmap_pte_quick(pmap_t pmap, vm_offset_t va);
218 static vm_page_t pmap_page_lookup(vm_object_t object, vm_pindex_t pindex);
219 static int pmap_unuse_pt(pmap_t, vm_offset_t, vm_page_t);
220 static vm_offset_t pmap_kmem_choose(vm_offset_t addr);
221 static void *pmap_allocf(uma_zone_t zone, int bytes, u_int8_t *flags, int wait);
222
223 static pd_entry_t pdir4mb;
224
225 /*
226  *      Routine:        pmap_pte
227  *      Function:
228  *              Extract the page table entry associated
229  *              with the given map/virtual_address pair.
230  */
231
232 PMAP_INLINE pt_entry_t *
233 pmap_pte(pmap, va)
234         register pmap_t pmap;
235         vm_offset_t va;
236 {
237         pd_entry_t *pdeaddr;
238
239         if (pmap) {
240                 pdeaddr = pmap_pde(pmap, va);
241                 if (*pdeaddr & PG_PS)
242                         return pdeaddr;
243                 if (*pdeaddr) {
244                         return get_ptbase(pmap) + i386_btop(va);
245                 }
246         }
247         return (0);
248 }
249
250 /*
251  * Move the kernel virtual free pointer to the next
252  * 4MB.  This is used to help improve performance
253  * by using a large (4MB) page for much of the kernel
254  * (.text, .data, .bss)
255  */
256 static vm_offset_t
257 pmap_kmem_choose(vm_offset_t addr)
258 {
259         vm_offset_t newaddr = addr;
260 #ifndef DISABLE_PSE
261         if (cpu_feature & CPUID_PSE) {
262                 newaddr = (addr + (NBPDR - 1)) & ~(NBPDR - 1);
263         }
264 #endif
265         return newaddr;
266 }
267
268 /*
269  *      Bootstrap the system enough to run with virtual memory.
270  *
271  *      On the i386 this is called after mapping has already been enabled
272  *      and just syncs the pmap module with what has already been done.
273  *      [We can't call it easily with mapping off since the kernel is not
274  *      mapped with PA == VA, hence we would have to relocate every address
275  *      from the linked base (virtual) address "KERNBASE" to the actual
276  *      (physical) address starting relative to 0]
277  */
278 void
279 pmap_bootstrap(firstaddr, loadaddr)
280         vm_offset_t firstaddr;
281         vm_offset_t loadaddr;
282 {
283         vm_offset_t va;
284         pt_entry_t *pte;
285         int i;
286
287         avail_start = firstaddr;
288
289         /*
290          * XXX The calculation of virtual_avail is wrong. It's NKPT*PAGE_SIZE too
291          * large. It should instead be correctly calculated in locore.s and
292          * not based on 'first' (which is a physical address, not a virtual
293          * address, for the start of unused physical memory). The kernel
294          * page tables are NOT double mapped and thus should not be included
295          * in this calculation.
296          */
297         virtual_avail = (vm_offset_t) KERNBASE + firstaddr;
298         virtual_avail = pmap_kmem_choose(virtual_avail);
299
300         virtual_end = VM_MAX_KERNEL_ADDRESS;
301
302         /*
303          * Initialize protection array.
304          */
305         i386_protection_init();
306
307         /*
308          * Initialize the kernel pmap (which is statically allocated).
309          */
310         kernel_pmap->pm_pdir = (pd_entry_t *) (KERNBASE + (u_int)IdlePTD);
311         kernel_pmap->pm_active = -1;    /* don't allow deactivation */
312         TAILQ_INIT(&kernel_pmap->pm_pvlist);
313         LIST_INIT(&allpmaps);
314         LIST_INSERT_HEAD(&allpmaps, kernel_pmap, pm_list);
315         nkpt = NKPT;
316
317         /*
318          * Reserve some special page table entries/VA space for temporary
319          * mapping of pages.
320          */
321 #define SYSMAP(c, p, v, n)      \
322         v = (c)va; va += ((n)*PAGE_SIZE); p = pte; pte += (n);
323
324         va = virtual_avail;
325         pte = (pt_entry_t *) pmap_pte(kernel_pmap, va);
326
327         /*
328          * CMAP1/CMAP2 are used for zeroing and copying pages.
329          */
330         SYSMAP(caddr_t, CMAP1, CADDR1, 1)
331         SYSMAP(caddr_t, CMAP2, CADDR2, 1)
332
333         /*
334          * Crashdump maps.
335          */
336         SYSMAP(caddr_t, pt_crashdumpmap, crashdumpmap, MAXDUMPPGS);
337
338         /*
339          * ptvmmap is used for reading arbitrary physical pages via /dev/mem.
340          * XXX ptmmap is not used.
341          */
342         SYSMAP(caddr_t, ptmmap, ptvmmap, 1)
343
344         /*
345          * msgbufp is used to map the system message buffer.
346          * XXX msgbufmap is not used.
347          */
348         SYSMAP(struct msgbuf *, msgbufmap, msgbufp,
349                atop(round_page(MSGBUF_SIZE)))
350
351         /*
352          * ptemap is used for pmap_pte_quick
353          */
354         SYSMAP(pt_entry_t *, PMAP1, PADDR1, 1);
355
356         virtual_avail = va;
357
358         *CMAP1 = *CMAP2 = 0;
359         for (i = 0; i < NKPT; i++)
360                 PTD[i] = 0;
361
362         pgeflag = 0;
363 #if !defined(SMP)                       /* XXX - see also mp_machdep.c */
364         if (cpu_feature & CPUID_PGE) {
365                 pgeflag = PG_G;
366         }
367 #endif
368         
369 /*
370  * Initialize the 4MB page size flag
371  */
372         pseflag = 0;
373 /*
374  * The 4MB page version of the initial
375  * kernel page mapping.
376  */
377         pdir4mb = 0;
378
379 #if !defined(DISABLE_PSE)
380         if (cpu_feature & CPUID_PSE) {
381                 pd_entry_t ptditmp;
382                 /*
383                  * Note that we have enabled PSE mode
384                  */
385                 pseflag = PG_PS;
386                 ptditmp = *(PTmap + i386_btop(KERNBASE));
387                 ptditmp &= ~(NBPDR - 1);
388                 ptditmp |= PG_V | PG_RW | PG_PS | PG_U | pgeflag;
389                 pdir4mb = ptditmp;
390
391 #if !defined(SMP)
392                 /*
393                  * Enable the PSE mode.
394                  */
395                 load_cr4(rcr4() | CR4_PSE);
396
397                 /*
398                  * We can do the mapping here for the single processor
399                  * case.  We simply ignore the old page table page from
400                  * now on.
401                  */
402                 /*
403                  * For SMP, we still need 4K pages to bootstrap APs,
404                  * PSE will be enabled as soon as all APs are up.
405                  */
406                 PTD[KPTDI] = (pd_entry_t) ptditmp;
407                 kernel_pmap->pm_pdir[KPTDI] = (pd_entry_t) ptditmp;
408                 invltlb();
409 #endif
410         }
411 #endif
412
413 #ifdef SMP
414         if (cpu_apic_address == 0)
415                 panic("pmap_bootstrap: no local apic! (non-SMP hardware?)");
416
417         /* local apic is mapped on last page */
418         SMPpt[NPTEPG - 1] = (pt_entry_t)(PG_V | PG_RW | PG_N | pgeflag |
419             (cpu_apic_address & PG_FRAME));
420 #endif
421
422         invltlb();
423 }
424
425 #ifdef SMP
426 /*
427  * Set 4mb pdir for mp startup
428  */
429 void
430 pmap_set_opt(void)
431 {
432         if (pseflag && (cpu_feature & CPUID_PSE)) {
433                 load_cr4(rcr4() | CR4_PSE);
434                 if (pdir4mb && PCPU_GET(cpuid) == 0) {  /* only on BSP */
435                         kernel_pmap->pm_pdir[KPTDI] = PTD[KPTDI] = pdir4mb;
436                         cpu_invltlb();
437                 }
438         }
439 }
440 #endif
441
442 void *
443 pmap_allocf(uma_zone_t zone, int bytes, u_int8_t *flags, int wait)
444 {
445         *flags = UMA_SLAB_PRIV;
446         return (void *)kmem_alloc(kernel_map, bytes);
447 }
448
449 /*
450  *      Initialize the pmap module.
451  *      Called by vm_init, to initialize any structures that the pmap
452  *      system needs to map virtual memory.
453  *      pmap_init has been enhanced to support in a fairly consistant
454  *      way, discontiguous physical memory.
455  */
456 void
457 pmap_init(phys_start, phys_end)
458         vm_offset_t phys_start, phys_end;
459 {
460         int i;
461         int initial_pvs;
462
463         /*
464          * object for kernel page table pages
465          */
466         kptobj = vm_object_allocate(OBJT_DEFAULT, NKPDE);
467
468         /*
469          * Allocate memory for random pmap data structures.  Includes the
470          * pv_head_table.
471          */
472
473         for(i = 0; i < vm_page_array_size; i++) {
474                 vm_page_t m;
475
476                 m = &vm_page_array[i];
477                 TAILQ_INIT(&m->md.pv_list);
478                 m->md.pv_list_count = 0;
479         }
480
481         /*
482          * init the pv free list
483          */
484         initial_pvs = vm_page_array_size;
485         if (initial_pvs < MINPV)
486                 initial_pvs = MINPV;
487         pvzone = uma_zcreate("PV ENTRY", sizeof (struct pv_entry), NULL, NULL, 
488             NULL, NULL, UMA_ALIGN_PTR, 0);
489         uma_zone_set_allocf(pvzone, pmap_allocf);
490         uma_prealloc(pvzone, initial_pvs);
491
492         /*
493          * Now it is safe to enable pv_table recording.
494          */
495         pmap_initialized = TRUE;
496 }
497
498 /*
499  * Initialize the address space (zone) for the pv_entries.  Set a
500  * high water mark so that the system can recover from excessive
501  * numbers of pv entries.
502  */
503 void
504 pmap_init2()
505 {
506         int shpgperproc = PMAP_SHPGPERPROC;
507
508         TUNABLE_INT_FETCH("vm.pmap.shpgperproc", &shpgperproc);
509         pv_entry_max = shpgperproc * maxproc + vm_page_array_size;
510         TUNABLE_INT_FETCH("vm.pmap.pv_entries", &pv_entry_max);
511         pv_entry_high_water = 9 * (pv_entry_max / 10);
512         uma_zone_set_obj(pvzone, &pvzone_obj, pv_entry_max);
513 }
514
515
516 /***************************************************
517  * Low level helper routines.....
518  ***************************************************/
519
520 #if defined(PMAP_DIAGNOSTIC)
521
522 /*
523  * This code checks for non-writeable/modified pages.
524  * This should be an invalid condition.
525  */
526 static int
527 pmap_nw_modified(pt_entry_t ptea)
528 {
529         int pte;
530
531         pte = (int) ptea;
532
533         if ((pte & (PG_M|PG_RW)) == PG_M)
534                 return 1;
535         else
536                 return 0;
537 }
538 #endif
539
540
541 /*
542  * this routine defines the region(s) of memory that should
543  * not be tested for the modified bit.
544  */
545 static PMAP_INLINE int
546 pmap_track_modified(vm_offset_t va)
547 {
548         if ((va < kmi.clean_sva) || (va >= kmi.clean_eva)) 
549                 return 1;
550         else
551                 return 0;
552 }
553
554 static PMAP_INLINE void
555 invltlb_1pg(vm_offset_t va)
556 {
557 #ifdef I386_CPU
558         invltlb();
559 #else
560         invlpg(va);
561 #endif
562 }
563
564 static __inline void
565 pmap_invalidate_page(pmap_t pmap, vm_offset_t va)
566 {
567 #if defined(SMP)
568         if (pmap->pm_active & PCPU_GET(cpumask))
569                 cpu_invlpg((void *)va);
570         if (pmap->pm_active & PCPU_GET(other_cpus))
571                 smp_invltlb();
572 #else
573         if (pmap->pm_active)
574                 invltlb_1pg(va);
575 #endif
576 }
577
578 static __inline void
579 pmap_invalidate_all(pmap_t pmap)
580 {
581 #if defined(SMP)
582         if (pmap->pm_active & PCPU_GET(cpumask))
583                 cpu_invltlb();
584         if (pmap->pm_active & PCPU_GET(other_cpus))
585                 smp_invltlb();
586 #else
587         if (pmap->pm_active)
588                 invltlb();
589 #endif
590 }
591
592 /*
593  * Return an address which is the base of the Virtual mapping of
594  * all the PTEs for the given pmap. Note this doesn't say that
595  * all the PTEs will be present or that the pages there are valid.
596  * The PTEs are made available by the recursive mapping trick.
597  * It will map in the alternate PTE space if needed.
598  */
599 static pt_entry_t *
600 get_ptbase(pmap)
601         pmap_t pmap;
602 {
603         pd_entry_t frame = pmap->pm_pdir[PTDPTDI] & PG_FRAME;
604
605         /* are we current address space or kernel? */
606         if (pmap == kernel_pmap || frame == (PTDpde & PG_FRAME))
607                 return PTmap;
608         /* otherwise, we are alternate address space */
609         if (frame != (APTDpde & PG_FRAME)) {
610                 APTDpde = (pd_entry_t) (frame | PG_RW | PG_V);
611 #if defined(SMP)
612                 /* The page directory is not shared between CPUs */
613                 cpu_invltlb();
614 #else
615                 invltlb();
616 #endif
617         }
618         return APTmap;
619 }
620
621 /*
622  * Super fast pmap_pte routine best used when scanning
623  * the pv lists.  This eliminates many coarse-grained
624  * invltlb calls.  Note that many of the pv list
625  * scans are across different pmaps.  It is very wasteful
626  * to do an entire invltlb for checking a single mapping.
627  */
628
629 static pt_entry_t * 
630 pmap_pte_quick(pmap, va)
631         register pmap_t pmap;
632         vm_offset_t va;
633 {
634         pd_entry_t pde, newpf;
635         pde = pmap->pm_pdir[va >> PDRSHIFT];
636         if (pde != 0) {
637                 pd_entry_t frame = pmap->pm_pdir[PTDPTDI] & PG_FRAME;
638                 unsigned index = i386_btop(va);
639                 /* are we current address space or kernel? */
640                 if (pmap == kernel_pmap || frame == (PTDpde & PG_FRAME))
641                         return PTmap + index;
642                 newpf = pde & PG_FRAME;
643                 if (((*PMAP1) & PG_FRAME) != newpf) {
644                         *PMAP1 = newpf | PG_RW | PG_V;
645                         invltlb_1pg((vm_offset_t) PADDR1);
646                 }
647                 return PADDR1 + (index & (NPTEPG - 1));
648         }
649         return (0);
650 }
651
652 /*
653  *      Routine:        pmap_extract
654  *      Function:
655  *              Extract the physical page address associated
656  *              with the given map/virtual_address pair.
657  */
658 vm_offset_t 
659 pmap_extract(pmap, va)
660         register pmap_t pmap;
661         vm_offset_t va;
662 {
663         vm_offset_t rtval;      /* XXX FIXME */
664         vm_offset_t pdirindex;
665
666         if (pmap == 0)
667                 return 0;
668         pdirindex = va >> PDRSHIFT;
669         rtval = pmap->pm_pdir[pdirindex];
670         if (rtval != 0) {
671                 pt_entry_t *pte;
672                 if ((rtval & PG_PS) != 0) {
673                         rtval &= ~(NBPDR - 1);
674                         rtval |= va & (NBPDR - 1);
675                         return rtval;
676                 }
677                 pte = get_ptbase(pmap) + i386_btop(va);
678                 rtval = ((*pte & PG_FRAME) | (va & PAGE_MASK));
679                 return rtval;
680         }
681         return 0;
682
683 }
684
685 /***************************************************
686  * Low level mapping routines.....
687  ***************************************************/
688
689 /*
690  * add a wired page to the kva
691  * note that in order for the mapping to take effect -- you
692  * should do a invltlb after doing the pmap_kenter...
693  */
694 PMAP_INLINE void 
695 pmap_kenter(vm_offset_t va, vm_offset_t pa)
696 {
697         pt_entry_t *pte;
698         pt_entry_t npte, opte;
699
700         npte = pa | PG_RW | PG_V | pgeflag;
701         pte = vtopte(va);
702         opte = *pte;
703         *pte = npte;
704         invltlb_1pg(va);
705 }
706
707 /*
708  * remove a page from the kernel pagetables
709  */
710 PMAP_INLINE void
711 pmap_kremove(vm_offset_t va)
712 {
713         register pt_entry_t *pte;
714
715         pte = vtopte(va);
716         *pte = 0;
717         invltlb_1pg(va);
718 }
719
720 /*
721  *      Used to map a range of physical addresses into kernel
722  *      virtual address space.
723  *
724  *      The value passed in '*virt' is a suggested virtual address for
725  *      the mapping. Architectures which can support a direct-mapped
726  *      physical to virtual region can return the appropriate address
727  *      within that region, leaving '*virt' unchanged. Other
728  *      architectures should map the pages starting at '*virt' and
729  *      update '*virt' with the first usable address after the mapped
730  *      region.
731  */
732 vm_offset_t
733 pmap_map(vm_offset_t *virt, vm_offset_t start, vm_offset_t end, int prot)
734 {
735         vm_offset_t sva = *virt;
736         vm_offset_t va = sva;
737         while (start < end) {
738                 pmap_kenter(va, start);
739                 va += PAGE_SIZE;
740                 start += PAGE_SIZE;
741         }
742         *virt = va;
743         return (sva);
744 }
745
746
747 /*
748  * Add a list of wired pages to the kva
749  * this routine is only used for temporary
750  * kernel mappings that do not need to have
751  * page modification or references recorded.
752  * Note that old mappings are simply written
753  * over.  The page *must* be wired.
754  */
755 void
756 pmap_qenter(vm_offset_t va, vm_page_t *m, int count)
757 {
758         vm_offset_t end_va;
759
760         end_va = va + count * PAGE_SIZE;
761                 
762         while (va < end_va) {
763                 pt_entry_t *pte;
764
765                 pte = vtopte(va);
766                 *pte = VM_PAGE_TO_PHYS(*m) | PG_RW | PG_V | pgeflag;
767 #ifdef SMP
768                 cpu_invlpg((void *)va);
769 #else
770                 invltlb_1pg(va);
771 #endif
772                 va += PAGE_SIZE;
773                 m++;
774         }
775 #ifdef SMP
776         smp_invltlb();
777 #endif
778 }
779
780 /*
781  * this routine jerks page mappings from the
782  * kernel -- it is meant only for temporary mappings.
783  */
784 void
785 pmap_qremove(vm_offset_t va, int count)
786 {
787         vm_offset_t end_va;
788
789         end_va = va + count*PAGE_SIZE;
790
791         while (va < end_va) {
792                 pt_entry_t *pte;
793
794                 pte = vtopte(va);
795                 *pte = 0;
796 #ifdef SMP
797                 cpu_invlpg((void *)va);
798 #else
799                 invltlb_1pg(va);
800 #endif
801                 va += PAGE_SIZE;
802         }
803 #ifdef SMP
804         smp_invltlb();
805 #endif
806 }
807
808 static vm_page_t
809 pmap_page_lookup(vm_object_t object, vm_pindex_t pindex)
810 {
811         vm_page_t m;
812 retry:
813         m = vm_page_lookup(object, pindex);
814         if (m && vm_page_sleep_busy(m, FALSE, "pplookp"))
815                 goto retry;
816         return m;
817 }
818
819 /*
820  * Create the Uarea stack for a new process.
821  * This routine directly affects the fork perf for a process.
822  */
823 void
824 pmap_new_proc(struct proc *p)
825 {
826 #ifdef I386_CPU
827         int updateneeded = 0;
828 #endif
829         int i;
830         vm_object_t upobj;
831         vm_offset_t up;
832         vm_page_t m;
833         pt_entry_t *ptek, oldpte;
834
835         /*
836          * allocate object for the upages
837          */
838         upobj = p->p_upages_obj;
839         if (upobj == NULL) {
840                 upobj = vm_object_allocate(OBJT_DEFAULT, UAREA_PAGES);
841                 p->p_upages_obj = upobj;
842         }
843
844         /* get a kernel virtual address for the U area for this thread */
845         up = (vm_offset_t)p->p_uarea;
846         if (up == 0) {
847                 up = kmem_alloc_nofault(kernel_map, UAREA_PAGES * PAGE_SIZE);
848                 if (up == 0)
849                         panic("pmap_new_proc: upage allocation failed");
850                 p->p_uarea = (struct user *)up;
851         }
852
853         ptek = vtopte(up);
854
855         for (i = 0; i < UAREA_PAGES; i++) {
856                 /*
857                  * Get a kernel stack page
858                  */
859                 m = vm_page_grab(upobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
860
861                 /*
862                  * Wire the page
863                  */
864                 m->wire_count++;
865                 cnt.v_wire_count++;
866
867                 oldpte = *(ptek + i);
868                 /*
869                  * Enter the page into the kernel address space.
870                  */
871                 *(ptek + i) = VM_PAGE_TO_PHYS(m) | PG_RW | PG_V | pgeflag;
872                 if (oldpte) {
873 #ifdef I386_CPU
874                         updateneeded = 1;
875 #else
876                         invlpg(up + i * PAGE_SIZE);
877 #endif
878                 }
879
880                 vm_page_wakeup(m);
881                 vm_page_flag_clear(m, PG_ZERO);
882                 vm_page_flag_set(m, PG_MAPPED | PG_WRITEABLE);
883                 m->valid = VM_PAGE_BITS_ALL;
884         }
885 #ifdef I386_CPU
886         if (updateneeded)
887                 invltlb();
888 #endif
889 }
890
891 /*
892  * Dispose the U-Area for a process that has exited.
893  * This routine directly impacts the exit perf of a process.
894  */
895 void
896 pmap_dispose_proc(p)
897         struct proc *p;
898 {
899         int i;
900         vm_object_t upobj;
901         vm_offset_t up;
902         vm_page_t m;
903         pt_entry_t *ptek, oldpte;
904
905         upobj = p->p_upages_obj;
906         up = (vm_offset_t)p->p_uarea;
907         ptek = vtopte(up);
908         for (i = 0; i < UAREA_PAGES; i++) {
909                 m = vm_page_lookup(upobj, i);
910                 if (m == NULL)
911                         panic("pmap_dispose_proc: upage already missing?");
912                 vm_page_busy(m);
913                 oldpte = *(ptek + i);
914                 *(ptek + i) = 0;
915 #ifndef I386_CPU
916                 invlpg(up + i * PAGE_SIZE);
917 #endif
918                 vm_page_unwire(m, 0);
919                 vm_page_free(m);
920         }
921 #ifdef I386_CPU
922         invltlb();
923 #endif
924
925         /*
926          * If the process got swapped out some of its UPAGES might have gotten
927          * swapped.  Just get rid of the object to clean up the swap use
928          * proactively.  NOTE! might block waiting for paging I/O to complete.
929          */
930         if (upobj->type == OBJT_SWAP) {
931                 p->p_upages_obj = NULL;
932                 vm_object_deallocate(upobj);
933         }
934 }
935
936 /*
937  * Allow the U_AREA for a process to be prejudicially paged out.
938  */
939 void
940 pmap_swapout_proc(p)
941         struct proc *p;
942 {
943         int i;
944         vm_object_t upobj;
945         vm_offset_t up;
946         vm_page_t m;
947
948         upobj = p->p_upages_obj;
949         up = (vm_offset_t)p->p_uarea;
950         for (i = 0; i < UAREA_PAGES; i++) {
951                 m = vm_page_lookup(upobj, i);
952                 if (m == NULL)
953                         panic("pmap_swapout_proc: upage already missing?");
954                 vm_page_dirty(m);
955                 vm_page_unwire(m, 0);
956                 pmap_kremove(up + i * PAGE_SIZE);
957         }
958 }
959
960 /*
961  * Bring the U-Area for a specified process back in.
962  */
963 void
964 pmap_swapin_proc(p)
965         struct proc *p;
966 {
967         int i, rv;
968         vm_object_t upobj;
969         vm_offset_t up;
970         vm_page_t m;
971
972         upobj = p->p_upages_obj;
973         up = (vm_offset_t)p->p_uarea;
974         for (i = 0; i < UAREA_PAGES; i++) {
975                 m = vm_page_grab(upobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
976                 pmap_kenter(up + i * PAGE_SIZE, VM_PAGE_TO_PHYS(m));
977                 if (m->valid != VM_PAGE_BITS_ALL) {
978                         rv = vm_pager_get_pages(upobj, &m, 1, 0);
979                         if (rv != VM_PAGER_OK)
980                                 panic("pmap_swapin_proc: cannot get upage for proc: %d\n", p->p_pid);
981                         m = vm_page_lookup(upobj, i);
982                         m->valid = VM_PAGE_BITS_ALL;
983                 }
984                 vm_page_wire(m);
985                 vm_page_wakeup(m);
986                 vm_page_flag_set(m, PG_MAPPED | PG_WRITEABLE);
987         }
988 }
989
990 /*
991  * Create the kernel stack (including pcb for i386) for a new thread.
992  * This routine directly affects the fork perf for a process and
993  * create performance for a thread.
994  */
995 void
996 pmap_new_thread(struct thread *td)
997 {
998 #ifdef I386_CPU
999         int updateneeded = 0;
1000 #endif
1001         int i;
1002         vm_object_t ksobj;
1003         vm_page_t m;
1004         vm_offset_t ks;
1005         pt_entry_t *ptek, oldpte;
1006
1007         /*
1008          * allocate object for the kstack
1009          */
1010         ksobj = td->td_kstack_obj;
1011         if (ksobj == NULL) {
1012                 ksobj = vm_object_allocate(OBJT_DEFAULT, KSTACK_PAGES);
1013                 td->td_kstack_obj = ksobj;
1014         }
1015
1016 #ifdef KSTACK_GUARD
1017         /* get a kernel virtual address for the kstack for this thread */
1018         ks = td->td_kstack;
1019         if (ks == 0) {
1020                 ks = kmem_alloc_nofault(kernel_map,
1021                     (KSTACK_PAGES + 1) * PAGE_SIZE);
1022                 if (ks == 0)
1023                         panic("pmap_new_thread: kstack allocation failed");
1024                 ks += PAGE_SIZE;
1025                 td->td_kstack = ks;
1026         }
1027
1028         ptek = vtopte(ks - PAGE_SIZE);
1029         oldpte = *ptek;
1030         *ptek = 0;
1031         if (oldpte) {
1032 #ifdef I386_CPU
1033                 updateneeded = 1;
1034 #else
1035                 invlpg(ks - PAGE_SIZE);
1036 #endif
1037         }
1038         ptek++;
1039 #else
1040         /* get a kernel virtual address for the kstack for this thread */
1041         ks = td->td_kstack;
1042         if (ks == 0) {
1043                 ks = kmem_alloc_nofault(kernel_map, KSTACK_PAGES * PAGE_SIZE);
1044                 if (ks == 0)
1045                         panic("pmap_new_thread: kstack allocation failed");
1046                 td->td_kstack = ks;
1047         }
1048         ptek = vtopte(ks);
1049 #endif
1050         for (i = 0; i < KSTACK_PAGES; i++) {
1051                 /*
1052                  * Get a kernel stack page
1053                  */
1054                 m = vm_page_grab(ksobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
1055
1056                 /*
1057                  * Wire the page
1058                  */
1059                 m->wire_count++;
1060                 cnt.v_wire_count++;
1061
1062                 oldpte = *(ptek + i);
1063                 /*
1064                  * Enter the page into the kernel address space.
1065                  */
1066                 *(ptek + i) = VM_PAGE_TO_PHYS(m) | PG_RW | PG_V | pgeflag;
1067                 if (oldpte) {
1068 #ifdef I386_CPU
1069                         updateneeded = 1;
1070 #else
1071                         invlpg(ks + i * PAGE_SIZE);
1072 #endif
1073                 }
1074
1075                 vm_page_wakeup(m);
1076                 vm_page_flag_clear(m, PG_ZERO);
1077                 vm_page_flag_set(m, PG_MAPPED | PG_WRITEABLE);
1078                 m->valid = VM_PAGE_BITS_ALL;
1079         }
1080 #ifdef I386_CPU
1081         if (updateneeded)
1082                 invltlb();
1083 #endif
1084 }
1085
1086 /*
1087  * Dispose the kernel stack for a thread that has exited.
1088  * This routine directly impacts the exit perf of a process and thread.
1089  */
1090 void
1091 pmap_dispose_thread(td)
1092         struct thread *td;
1093 {
1094         int i;
1095         vm_object_t ksobj;
1096         vm_offset_t ks;
1097         vm_page_t m;
1098         pt_entry_t *ptek, oldpte;
1099
1100         ksobj = td->td_kstack_obj;
1101         ks = td->td_kstack;
1102         ptek = vtopte(ks);
1103         for (i = 0; i < KSTACK_PAGES; i++) {
1104                 m = vm_page_lookup(ksobj, i);
1105                 if (m == NULL)
1106                         panic("pmap_dispose_thread: kstack already missing?");
1107                 vm_page_busy(m);
1108                 oldpte = *(ptek + i);
1109                 *(ptek + i) = 0;
1110 #ifndef I386_CPU
1111                 invlpg(ks + i * PAGE_SIZE);
1112 #endif
1113                 vm_page_unwire(m, 0);
1114                 vm_page_free(m);
1115         }
1116 #ifdef I386_CPU
1117         invltlb();
1118 #endif
1119
1120         /*
1121          * If the thread got swapped out some of its KSTACK might have gotten
1122          * swapped.  Just get rid of the object to clean up the swap use
1123          * proactively.  NOTE! might block waiting for paging I/O to complete.
1124          */
1125         if (ksobj->type == OBJT_SWAP) {
1126                 td->td_kstack_obj = NULL;
1127                 vm_object_deallocate(ksobj);
1128         }
1129 }
1130
1131 /*
1132  * Allow the Kernel stack for a thread to be prejudicially paged out.
1133  */
1134 void
1135 pmap_swapout_thread(td)
1136         struct thread *td;
1137 {
1138         int i;
1139         vm_object_t ksobj;
1140         vm_offset_t ks;
1141         vm_page_t m;
1142
1143         ksobj = td->td_kstack_obj;
1144         ks = td->td_kstack;
1145         for (i = 0; i < KSTACK_PAGES; i++) {
1146                 m = vm_page_lookup(ksobj, i);
1147                 if (m == NULL)
1148                         panic("pmap_swapout_thread: kstack already missing?");
1149                 vm_page_dirty(m);
1150                 vm_page_unwire(m, 0);
1151                 pmap_kremove(ks + i * PAGE_SIZE);
1152         }
1153 }
1154
1155 /*
1156  * Bring the kernel stack for a specified thread back in.
1157  */
1158 void
1159 pmap_swapin_thread(td)
1160         struct thread *td;
1161 {
1162         int i, rv;
1163         vm_object_t ksobj;
1164         vm_offset_t ks;
1165         vm_page_t m;
1166
1167         ksobj = td->td_kstack_obj;
1168         ks = td->td_kstack;
1169         for (i = 0; i < KSTACK_PAGES; i++) {
1170                 m = vm_page_grab(ksobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
1171                 pmap_kenter(ks + i * PAGE_SIZE, VM_PAGE_TO_PHYS(m));
1172                 if (m->valid != VM_PAGE_BITS_ALL) {
1173                         rv = vm_pager_get_pages(ksobj, &m, 1, 0);
1174                         if (rv != VM_PAGER_OK)
1175                                 panic("pmap_swapin_thread: cannot get kstack for proc: %d\n", td->td_proc->p_pid);
1176                         m = vm_page_lookup(ksobj, i);
1177                         m->valid = VM_PAGE_BITS_ALL;
1178                 }
1179                 vm_page_wire(m);
1180                 vm_page_wakeup(m);
1181                 vm_page_flag_set(m, PG_MAPPED | PG_WRITEABLE);
1182         }
1183 }
1184
1185 /***************************************************
1186  * Page table page management routines.....
1187  ***************************************************/
1188
1189 /*
1190  * This routine unholds page table pages, and if the hold count
1191  * drops to zero, then it decrements the wire count.
1192  */
1193 static int 
1194 _pmap_unwire_pte_hold(pmap_t pmap, vm_page_t m)
1195 {
1196
1197         while (vm_page_sleep_busy(m, FALSE, "pmuwpt"))
1198                 ;
1199
1200         if (m->hold_count == 0) {
1201                 vm_offset_t pteva;
1202                 /*
1203                  * unmap the page table page
1204                  */
1205                 pmap->pm_pdir[m->pindex] = 0;
1206                 --pmap->pm_stats.resident_count;
1207                 if ((pmap->pm_pdir[PTDPTDI] & PG_FRAME) ==
1208                     (PTDpde & PG_FRAME)) {
1209                         /*
1210                          * Do a invltlb to make the invalidated mapping
1211                          * take effect immediately.
1212                          */
1213                         pteva = VM_MAXUSER_ADDRESS + i386_ptob(m->pindex);
1214                         pmap_invalidate_page(pmap, pteva);
1215                 }
1216
1217                 if (pmap->pm_ptphint == m)
1218                         pmap->pm_ptphint = NULL;
1219
1220                 /*
1221                  * If the page is finally unwired, simply free it.
1222                  */
1223                 --m->wire_count;
1224                 if (m->wire_count == 0) {
1225
1226                         vm_page_flash(m);
1227                         vm_page_busy(m);
1228                         vm_page_free_zero(m);
1229                         --cnt.v_wire_count;
1230                 }
1231                 return 1;
1232         }
1233         return 0;
1234 }
1235
1236 static PMAP_INLINE int
1237 pmap_unwire_pte_hold(pmap_t pmap, vm_page_t m)
1238 {
1239         vm_page_unhold(m);
1240         if (m->hold_count == 0)
1241                 return _pmap_unwire_pte_hold(pmap, m);
1242         else
1243                 return 0;
1244 }
1245
1246 /*
1247  * After removing a page table entry, this routine is used to
1248  * conditionally free the page, and manage the hold/wire counts.
1249  */
1250 static int
1251 pmap_unuse_pt(pmap_t pmap, vm_offset_t va, vm_page_t mpte)
1252 {
1253         unsigned ptepindex;
1254         if (va >= VM_MAXUSER_ADDRESS)
1255                 return 0;
1256
1257         if (mpte == NULL) {
1258                 ptepindex = (va >> PDRSHIFT);
1259                 if (pmap->pm_ptphint &&
1260                         (pmap->pm_ptphint->pindex == ptepindex)) {
1261                         mpte = pmap->pm_ptphint;
1262                 } else {
1263                         mpte = pmap_page_lookup(pmap->pm_pteobj, ptepindex);
1264                         pmap->pm_ptphint = mpte;
1265                 }
1266         }
1267
1268         return pmap_unwire_pte_hold(pmap, mpte);
1269 }
1270
1271 void
1272 pmap_pinit0(pmap)
1273         struct pmap *pmap;
1274 {
1275         pmap->pm_pdir =
1276                 (pd_entry_t *)kmem_alloc_pageable(kernel_map, PAGE_SIZE);
1277         pmap_kenter((vm_offset_t) pmap->pm_pdir, (vm_offset_t) IdlePTD);
1278         pmap->pm_ptphint = NULL;
1279         pmap->pm_active = 0;
1280         TAILQ_INIT(&pmap->pm_pvlist);
1281         bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
1282         LIST_INSERT_HEAD(&allpmaps, pmap, pm_list);
1283 }
1284
1285 /*
1286  * Initialize a preallocated and zeroed pmap structure,
1287  * such as one in a vmspace structure.
1288  */
1289 void
1290 pmap_pinit(pmap)
1291         register struct pmap *pmap;
1292 {
1293         vm_page_t ptdpg;
1294
1295         /*
1296          * No need to allocate page table space yet but we do need a valid
1297          * page directory table.
1298          */
1299         if (pmap->pm_pdir == NULL)
1300                 pmap->pm_pdir =
1301                         (pd_entry_t *)kmem_alloc_pageable(kernel_map, PAGE_SIZE);
1302
1303         /*
1304          * allocate object for the ptes
1305          */
1306         if (pmap->pm_pteobj == NULL)
1307                 pmap->pm_pteobj = vm_object_allocate(OBJT_DEFAULT, PTDPTDI + 1);
1308
1309         /*
1310          * allocate the page directory page
1311          */
1312         ptdpg = vm_page_grab(pmap->pm_pteobj, PTDPTDI,
1313                         VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
1314
1315         ptdpg->wire_count = 1;
1316         ++cnt.v_wire_count;
1317
1318
1319         vm_page_flag_clear(ptdpg, PG_MAPPED | PG_BUSY); /* not usually mapped*/
1320         ptdpg->valid = VM_PAGE_BITS_ALL;
1321
1322         pmap_kenter((vm_offset_t) pmap->pm_pdir, VM_PAGE_TO_PHYS(ptdpg));
1323         if ((ptdpg->flags & PG_ZERO) == 0)
1324                 bzero(pmap->pm_pdir, PAGE_SIZE);
1325
1326         LIST_INSERT_HEAD(&allpmaps, pmap, pm_list);
1327         /* Wire in kernel global address entries. */
1328         /* XXX copies current process, does not fill in MPPTDI */
1329         bcopy(PTD + KPTDI, pmap->pm_pdir + KPTDI, nkpt * PTESIZE);
1330 #ifdef SMP
1331         pmap->pm_pdir[MPPTDI] = PTD[MPPTDI];
1332 #endif
1333
1334         /* install self-referential address mapping entry */
1335         pmap->pm_pdir[PTDPTDI] =
1336                 VM_PAGE_TO_PHYS(ptdpg) | PG_V | PG_RW | PG_A | PG_M;
1337
1338         pmap->pm_active = 0;
1339         pmap->pm_ptphint = NULL;
1340         TAILQ_INIT(&pmap->pm_pvlist);
1341         bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
1342 }
1343
1344 /*
1345  * Wire in kernel global address entries.  To avoid a race condition
1346  * between pmap initialization and pmap_growkernel, this procedure
1347  * should be called after the vmspace is attached to the process
1348  * but before this pmap is activated.
1349  */
1350 void
1351 pmap_pinit2(pmap)
1352         struct pmap *pmap;
1353 {
1354         /* XXX: Remove this stub when no longer called */
1355 }
1356
1357 static int
1358 pmap_release_free_page(pmap_t pmap, vm_page_t p)
1359 {
1360         pd_entry_t *pde = pmap->pm_pdir;
1361         /*
1362          * This code optimizes the case of freeing non-busy
1363          * page-table pages.  Those pages are zero now, and
1364          * might as well be placed directly into the zero queue.
1365          */
1366         if (vm_page_sleep_busy(p, FALSE, "pmaprl"))
1367                 return 0;
1368
1369         vm_page_busy(p);
1370
1371         /*
1372          * Remove the page table page from the processes address space.
1373          */
1374         pde[p->pindex] = 0;
1375         pmap->pm_stats.resident_count--;
1376
1377         if (p->hold_count)  {
1378                 panic("pmap_release: freeing held page table page");
1379         }
1380         /*
1381          * Page directory pages need to have the kernel
1382          * stuff cleared, so they can go into the zero queue also.
1383          */
1384         if (p->pindex == PTDPTDI) {
1385                 bzero(pde + KPTDI, nkpt * PTESIZE);
1386 #ifdef SMP
1387                 pde[MPPTDI] = 0;
1388 #endif
1389                 pde[APTDPTDI] = 0;
1390                 pmap_kremove((vm_offset_t) pmap->pm_pdir);
1391         }
1392
1393         if (pmap->pm_ptphint && (pmap->pm_ptphint->pindex == p->pindex))
1394                 pmap->pm_ptphint = NULL;
1395
1396         p->wire_count--;
1397         cnt.v_wire_count--;
1398         vm_page_free_zero(p);
1399         return 1;
1400 }
1401
1402 /*
1403  * this routine is called if the page table page is not
1404  * mapped correctly.
1405  */
1406 static vm_page_t
1407 _pmap_allocpte(pmap, ptepindex)
1408         pmap_t  pmap;
1409         unsigned ptepindex;
1410 {
1411         vm_offset_t pteva, ptepa;       /* XXXPA */
1412         vm_page_t m;
1413
1414         /*
1415          * Find or fabricate a new pagetable page
1416          */
1417         m = vm_page_grab(pmap->pm_pteobj, ptepindex,
1418                         VM_ALLOC_ZERO | VM_ALLOC_RETRY);
1419
1420         KASSERT(m->queue == PQ_NONE,
1421                 ("_pmap_allocpte: %p->queue != PQ_NONE", m));
1422
1423         if (m->wire_count == 0)
1424                 cnt.v_wire_count++;
1425         m->wire_count++;
1426
1427         /*
1428          * Increment the hold count for the page table page
1429          * (denoting a new mapping.)
1430          */
1431         m->hold_count++;
1432
1433         /*
1434          * Map the pagetable page into the process address space, if
1435          * it isn't already there.
1436          */
1437
1438         pmap->pm_stats.resident_count++;
1439
1440         ptepa = VM_PAGE_TO_PHYS(m);
1441         pmap->pm_pdir[ptepindex] =
1442                 (pd_entry_t) (ptepa | PG_U | PG_RW | PG_V | PG_A | PG_M);
1443
1444         /*
1445          * Set the page table hint
1446          */
1447         pmap->pm_ptphint = m;
1448
1449         /*
1450          * Try to use the new mapping, but if we cannot, then
1451          * do it with the routine that maps the page explicitly.
1452          */
1453         if ((m->flags & PG_ZERO) == 0) {
1454                 if ((pmap->pm_pdir[PTDPTDI] & PG_FRAME) ==
1455                     (PTDpde & PG_FRAME)) {
1456                         pteva = VM_MAXUSER_ADDRESS + i386_ptob(ptepindex);
1457                         bzero((caddr_t) pteva, PAGE_SIZE);
1458                 } else {
1459                         pmap_zero_page(m);
1460                 }
1461         }
1462
1463         m->valid = VM_PAGE_BITS_ALL;
1464         vm_page_flag_clear(m, PG_ZERO);
1465         vm_page_flag_set(m, PG_MAPPED);
1466         vm_page_wakeup(m);
1467
1468         return m;
1469 }
1470
1471 static vm_page_t
1472 pmap_allocpte(pmap_t pmap, vm_offset_t va)
1473 {
1474         unsigned ptepindex;
1475         pd_entry_t ptepa;
1476         vm_page_t m;
1477
1478         /*
1479          * Calculate pagetable page index
1480          */
1481         ptepindex = va >> PDRSHIFT;
1482
1483         /*
1484          * Get the page directory entry
1485          */
1486         ptepa = (vm_offset_t) pmap->pm_pdir[ptepindex];
1487
1488         /*
1489          * This supports switching from a 4MB page to a
1490          * normal 4K page.
1491          */
1492         if (ptepa & PG_PS) {
1493                 pmap->pm_pdir[ptepindex] = 0;
1494                 ptepa = 0;
1495                 invltlb();
1496         }
1497
1498         /*
1499          * If the page table page is mapped, we just increment the
1500          * hold count, and activate it.
1501          */
1502         if (ptepa) {
1503                 /*
1504                  * In order to get the page table page, try the
1505                  * hint first.
1506                  */
1507                 if (pmap->pm_ptphint &&
1508                         (pmap->pm_ptphint->pindex == ptepindex)) {
1509                         m = pmap->pm_ptphint;
1510                 } else {
1511                         m = pmap_page_lookup(pmap->pm_pteobj, ptepindex);
1512                         pmap->pm_ptphint = m;
1513                 }
1514                 m->hold_count++;
1515                 return m;
1516         }
1517         /*
1518          * Here if the pte page isn't mapped, or if it has been deallocated.
1519          */
1520         return _pmap_allocpte(pmap, ptepindex);
1521 }
1522
1523
1524 /***************************************************
1525 * Pmap allocation/deallocation routines.
1526  ***************************************************/
1527
1528 /*
1529  * Release any resources held by the given physical map.
1530  * Called when a pmap initialized by pmap_pinit is being released.
1531  * Should only be called if the map contains no valid mappings.
1532  */
1533 void
1534 pmap_release(pmap_t pmap)
1535 {
1536         vm_page_t p,n,ptdpg;
1537         vm_object_t object = pmap->pm_pteobj;
1538         int curgeneration;
1539
1540 #if defined(DIAGNOSTIC)
1541         if (object->ref_count != 1)
1542                 panic("pmap_release: pteobj reference count != 1");
1543 #endif
1544         
1545         ptdpg = NULL;
1546         LIST_REMOVE(pmap, pm_list);
1547 retry:
1548         curgeneration = object->generation;
1549         for (p = TAILQ_FIRST(&object->memq); p != NULL; p = n) {
1550                 n = TAILQ_NEXT(p, listq);
1551                 if (p->pindex == PTDPTDI) {
1552                         ptdpg = p;
1553                         continue;
1554                 }
1555                 while (1) {
1556                         if (!pmap_release_free_page(pmap, p) &&
1557                                 (object->generation != curgeneration))
1558                                 goto retry;
1559                 }
1560         }
1561
1562         if (ptdpg && !pmap_release_free_page(pmap, ptdpg))
1563                 goto retry;
1564 }
1565 \f
1566 static int
1567 kvm_size(SYSCTL_HANDLER_ARGS)
1568 {
1569         unsigned long ksize = VM_MAX_KERNEL_ADDRESS - KERNBASE;
1570
1571         return sysctl_handle_long(oidp, &ksize, 0, req);
1572 }
1573 SYSCTL_PROC(_vm, OID_AUTO, kvm_size, CTLTYPE_LONG|CTLFLAG_RD, 
1574     0, 0, kvm_size, "IU", "Size of KVM");
1575
1576 static int
1577 kvm_free(SYSCTL_HANDLER_ARGS)
1578 {
1579         unsigned long kfree = VM_MAX_KERNEL_ADDRESS - kernel_vm_end;
1580
1581         return sysctl_handle_long(oidp, &kfree, 0, req);
1582 }
1583 SYSCTL_PROC(_vm, OID_AUTO, kvm_free, CTLTYPE_LONG|CTLFLAG_RD, 
1584     0, 0, kvm_free, "IU", "Amount of KVM free");
1585
1586 /*
1587  * grow the number of kernel page table entries, if needed
1588  */
1589 void
1590 pmap_growkernel(vm_offset_t addr)
1591 {
1592         struct pmap *pmap;
1593         int s;
1594         vm_offset_t ptppaddr;
1595         vm_page_t nkpg;
1596         pd_entry_t newpdir;
1597
1598         s = splhigh();
1599         if (kernel_vm_end == 0) {
1600                 kernel_vm_end = KERNBASE;
1601                 nkpt = 0;
1602                 while (pdir_pde(PTD, kernel_vm_end)) {
1603                         kernel_vm_end = (kernel_vm_end + PAGE_SIZE * NPTEPG) & ~(PAGE_SIZE * NPTEPG - 1);
1604                         nkpt++;
1605                 }
1606         }
1607         addr = (addr + PAGE_SIZE * NPTEPG) & ~(PAGE_SIZE * NPTEPG - 1);
1608         while (kernel_vm_end < addr) {
1609                 if (pdir_pde(PTD, kernel_vm_end)) {
1610                         kernel_vm_end = (kernel_vm_end + PAGE_SIZE * NPTEPG) & ~(PAGE_SIZE * NPTEPG - 1);
1611                         continue;
1612                 }
1613
1614                 /*
1615                  * This index is bogus, but out of the way
1616                  */
1617                 nkpg = vm_page_alloc(kptobj, nkpt, VM_ALLOC_SYSTEM);
1618                 if (!nkpg)
1619                         panic("pmap_growkernel: no memory to grow kernel");
1620
1621                 nkpt++;
1622
1623                 vm_page_wire(nkpg);
1624                 pmap_zero_page(nkpg);
1625                 ptppaddr = VM_PAGE_TO_PHYS(nkpg);
1626                 newpdir = (pd_entry_t) (ptppaddr | PG_V | PG_RW | PG_A | PG_M);
1627                 pdir_pde(PTD, kernel_vm_end) = newpdir;
1628
1629                 LIST_FOREACH(pmap, &allpmaps, pm_list) {
1630                         *pmap_pde(pmap, kernel_vm_end) = newpdir;
1631                 }
1632                 kernel_vm_end = (kernel_vm_end + PAGE_SIZE * NPTEPG) & ~(PAGE_SIZE * NPTEPG - 1);
1633         }
1634         splx(s);
1635 }
1636
1637
1638 /***************************************************
1639  * page management routines.
1640  ***************************************************/
1641
1642 /*
1643  * free the pv_entry back to the free list
1644  */
1645 static PMAP_INLINE void
1646 free_pv_entry(pv_entry_t pv)
1647 {
1648         pv_entry_count--;
1649         uma_zfree(pvzone, pv);
1650 }
1651
1652 /*
1653  * get a new pv_entry, allocating a block from the system
1654  * when needed.
1655  * the memory allocation is performed bypassing the malloc code
1656  * because of the possibility of allocations at interrupt time.
1657  */
1658 static pv_entry_t
1659 get_pv_entry(void)
1660 {
1661         pv_entry_count++;
1662         if (pv_entry_high_water &&
1663                 (pv_entry_count > pv_entry_high_water) &&
1664                 (pmap_pagedaemon_waken == 0)) {
1665                 pmap_pagedaemon_waken = 1;
1666                 wakeup (&vm_pages_needed);
1667         }
1668         return uma_zalloc(pvzone, M_NOWAIT);
1669 }
1670
1671 /*
1672  * This routine is very drastic, but can save the system
1673  * in a pinch.
1674  */
1675 void
1676 pmap_collect()
1677 {
1678         int i;
1679         vm_page_t m;
1680         static int warningdone = 0;
1681
1682         if (pmap_pagedaemon_waken == 0)
1683                 return;
1684
1685         if (warningdone < 5) {
1686                 printf("pmap_collect: collecting pv entries -- suggest increasing PMAP_SHPGPERPROC\n");
1687                 warningdone++;
1688         }
1689
1690         for(i = 0; i < vm_page_array_size; i++) {
1691                 m = &vm_page_array[i];
1692                 if (m->wire_count || m->hold_count || m->busy ||
1693                     (m->flags & (PG_BUSY | PG_UNMANAGED)))
1694                         continue;
1695                 pmap_remove_all(m);
1696         }
1697         pmap_pagedaemon_waken = 0;
1698 }
1699         
1700
1701 /*
1702  * If it is the first entry on the list, it is actually
1703  * in the header and we must copy the following entry up
1704  * to the header.  Otherwise we must search the list for
1705  * the entry.  In either case we free the now unused entry.
1706  */
1707
1708 static int
1709 pmap_remove_entry(pmap_t pmap, vm_page_t m, vm_offset_t va)
1710 {
1711         pv_entry_t pv;
1712         int rtval;
1713         int s;
1714
1715         s = splvm();
1716         if (m->md.pv_list_count < pmap->pm_stats.resident_count) {
1717                 TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
1718                         if (pmap == pv->pv_pmap && va == pv->pv_va) 
1719                                 break;
1720                 }
1721         } else {
1722                 TAILQ_FOREACH(pv, &pmap->pm_pvlist, pv_plist) {
1723                         if (va == pv->pv_va) 
1724                                 break;
1725                 }
1726         }
1727
1728         rtval = 0;
1729         if (pv) {
1730                 rtval = pmap_unuse_pt(pmap, va, pv->pv_ptem);
1731                 TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
1732                 m->md.pv_list_count--;
1733                 if (TAILQ_FIRST(&m->md.pv_list) == NULL)
1734                         vm_page_flag_clear(m, PG_MAPPED | PG_WRITEABLE);
1735
1736                 TAILQ_REMOVE(&pmap->pm_pvlist, pv, pv_plist);
1737                 free_pv_entry(pv);
1738         }
1739                         
1740         splx(s);
1741         return rtval;
1742 }
1743
1744 /*
1745  * Create a pv entry for page at pa for
1746  * (pmap, va).
1747  */
1748 static void
1749 pmap_insert_entry(pmap_t pmap, vm_offset_t va, vm_page_t mpte, vm_page_t m)
1750 {
1751
1752         int s;
1753         pv_entry_t pv;
1754
1755         s = splvm();
1756         pv = get_pv_entry();
1757         pv->pv_va = va;
1758         pv->pv_pmap = pmap;
1759         pv->pv_ptem = mpte;
1760
1761         TAILQ_INSERT_TAIL(&pmap->pm_pvlist, pv, pv_plist);
1762         TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list);
1763         m->md.pv_list_count++;
1764
1765         splx(s);
1766 }
1767
1768 /*
1769  * pmap_remove_pte: do the things to unmap a page in a process
1770  */
1771 static int
1772 pmap_remove_pte(pmap_t pmap, pt_entry_t *ptq, vm_offset_t va)
1773 {
1774         pt_entry_t oldpte;
1775         vm_page_t m;
1776
1777         oldpte = atomic_readandclear_int(ptq);
1778         if (oldpte & PG_W)
1779                 pmap->pm_stats.wired_count -= 1;
1780         /*
1781          * Machines that don't support invlpg, also don't support
1782          * PG_G.
1783          */
1784         if (oldpte & PG_G)
1785                 invlpg(va);
1786         pmap->pm_stats.resident_count -= 1;
1787         if (oldpte & PG_MANAGED) {
1788                 m = PHYS_TO_VM_PAGE(oldpte);
1789                 if (oldpte & PG_M) {
1790 #if defined(PMAP_DIAGNOSTIC)
1791                         if (pmap_nw_modified((pt_entry_t) oldpte)) {
1792                                 printf(
1793         "pmap_remove: modified page not writable: va: 0x%x, pte: 0x%x\n",
1794                                     va, oldpte);
1795                         }
1796 #endif
1797                         if (pmap_track_modified(va))
1798                                 vm_page_dirty(m);
1799                 }
1800                 if (oldpte & PG_A)
1801                         vm_page_flag_set(m, PG_REFERENCED);
1802                 return pmap_remove_entry(pmap, m, va);
1803         } else {
1804                 return pmap_unuse_pt(pmap, va, NULL);
1805         }
1806
1807         return 0;
1808 }
1809
1810 /*
1811  * Remove a single page from a process address space
1812  */
1813 static void
1814 pmap_remove_page(pmap_t pmap, vm_offset_t va)
1815 {
1816         register pt_entry_t *ptq;
1817
1818         /*
1819          * if there is no pte for this address, just skip it!!!
1820          */
1821         if (*pmap_pde(pmap, va) == 0) {
1822                 return;
1823         }
1824
1825         /*
1826          * get a local va for mappings for this pmap.
1827          */
1828         ptq = get_ptbase(pmap) + i386_btop(va);
1829         if (*ptq) {
1830                 (void) pmap_remove_pte(pmap, ptq, va);
1831                 pmap_invalidate_page(pmap, va);
1832         }
1833         return;
1834 }
1835
1836 /*
1837  *      Remove the given range of addresses from the specified map.
1838  *
1839  *      It is assumed that the start and end are properly
1840  *      rounded to the page size.
1841  */
1842 void
1843 pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
1844 {
1845         register pt_entry_t *ptbase;
1846         vm_offset_t pdnxt;
1847         pd_entry_t ptpaddr;
1848         vm_offset_t sindex, eindex;
1849         int anyvalid;
1850
1851         if (pmap == NULL)
1852                 return;
1853
1854         if (pmap->pm_stats.resident_count == 0)
1855                 return;
1856
1857         /*
1858          * special handling of removing one page.  a very
1859          * common operation and easy to short circuit some
1860          * code.
1861          */
1862         if ((sva + PAGE_SIZE == eva) && 
1863             ((pmap->pm_pdir[(sva >> PDRSHIFT)] & PG_PS) == 0)) {
1864                 pmap_remove_page(pmap, sva);
1865                 return;
1866         }
1867
1868         anyvalid = 0;
1869
1870         /*
1871          * Get a local virtual address for the mappings that are being
1872          * worked with.
1873          */
1874         ptbase = get_ptbase(pmap);
1875
1876         sindex = i386_btop(sva);
1877         eindex = i386_btop(eva);
1878
1879         for (; sindex < eindex; sindex = pdnxt) {
1880                 unsigned pdirindex;
1881
1882                 /*
1883                  * Calculate index for next page table.
1884                  */
1885                 pdnxt = ((sindex + NPTEPG) & ~(NPTEPG - 1));
1886                 if (pmap->pm_stats.resident_count == 0)
1887                         break;
1888
1889                 pdirindex = sindex / NPDEPG;
1890                 ptpaddr = pmap->pm_pdir[pdirindex];
1891                 if ((ptpaddr & PG_PS) != 0) {
1892                         pmap->pm_pdir[pdirindex] = 0;
1893                         pmap->pm_stats.resident_count -= NBPDR / PAGE_SIZE;
1894                         anyvalid++;
1895                         continue;
1896                 }
1897
1898                 /*
1899                  * Weed out invalid mappings. Note: we assume that the page
1900                  * directory table is always allocated, and in kernel virtual.
1901                  */
1902                 if (ptpaddr == 0)
1903                         continue;
1904
1905                 /*
1906                  * Limit our scan to either the end of the va represented
1907                  * by the current page table page, or to the end of the
1908                  * range being removed.
1909                  */
1910                 if (pdnxt > eindex) {
1911                         pdnxt = eindex;
1912                 }
1913
1914                 for (; sindex != pdnxt; sindex++) {
1915                         vm_offset_t va;
1916                         if (ptbase[sindex] == 0) {
1917                                 continue;
1918                         }
1919                         va = i386_ptob(sindex);
1920                         
1921                         anyvalid++;
1922                         if (pmap_remove_pte(pmap,
1923                                 ptbase + sindex, va))
1924                                 break;
1925                 }
1926         }
1927
1928         if (anyvalid)
1929                 pmap_invalidate_all(pmap);
1930 }
1931
1932 /*
1933  *      Routine:        pmap_remove_all
1934  *      Function:
1935  *              Removes this physical page from
1936  *              all physical maps in which it resides.
1937  *              Reflects back modify bits to the pager.
1938  *
1939  *      Notes:
1940  *              Original versions of this routine were very
1941  *              inefficient because they iteratively called
1942  *              pmap_remove (slow...)
1943  */
1944
1945 static void
1946 pmap_remove_all(vm_page_t m)
1947 {
1948         register pv_entry_t pv;
1949         pt_entry_t *pte, tpte;
1950         int s;
1951
1952 #if defined(PMAP_DIAGNOSTIC)
1953         /*
1954          * XXX this makes pmap_page_protect(NONE) illegal for non-managed
1955          * pages!
1956          */
1957         if (!pmap_initialized || (m->flags & PG_FICTITIOUS)) {
1958                 panic("pmap_page_protect: illegal for unmanaged page, va: 0x%x", VM_PAGE_TO_PHYS(m));
1959         }
1960 #endif
1961
1962         s = splvm();
1963         while ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) {
1964                 pv->pv_pmap->pm_stats.resident_count--;
1965
1966                 pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
1967
1968                 tpte = atomic_readandclear_int(pte);
1969                 if (tpte & PG_W)
1970                         pv->pv_pmap->pm_stats.wired_count--;
1971
1972                 if (tpte & PG_A)
1973                         vm_page_flag_set(m, PG_REFERENCED);
1974
1975                 /*
1976                  * Update the vm_page_t clean and reference bits.
1977                  */
1978                 if (tpte & PG_M) {
1979 #if defined(PMAP_DIAGNOSTIC)
1980                         if (pmap_nw_modified((pt_entry_t) tpte)) {
1981                                 printf(
1982         "pmap_remove_all: modified page not writable: va: 0x%x, pte: 0x%x\n",
1983                                     pv->pv_va, tpte);
1984                         }
1985 #endif
1986                         if (pmap_track_modified(pv->pv_va))
1987                                 vm_page_dirty(m);
1988                 }
1989                 pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
1990
1991                 TAILQ_REMOVE(&pv->pv_pmap->pm_pvlist, pv, pv_plist);
1992                 TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
1993                 m->md.pv_list_count--;
1994                 pmap_unuse_pt(pv->pv_pmap, pv->pv_va, pv->pv_ptem);
1995                 free_pv_entry(pv);
1996         }
1997
1998         vm_page_flag_clear(m, PG_MAPPED | PG_WRITEABLE);
1999
2000         splx(s);
2001 }
2002
2003 /*
2004  *      Set the physical protection on the
2005  *      specified range of this map as requested.
2006  */
2007 void
2008 pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
2009 {
2010         register pt_entry_t *ptbase;
2011         vm_offset_t pdnxt;
2012         pd_entry_t ptpaddr;
2013         vm_pindex_t sindex, eindex;
2014         int anychanged;
2015
2016         if (pmap == NULL)
2017                 return;
2018
2019         if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
2020                 pmap_remove(pmap, sva, eva);
2021                 return;
2022         }
2023
2024         if (prot & VM_PROT_WRITE)
2025                 return;
2026
2027         anychanged = 0;
2028
2029         ptbase = get_ptbase(pmap);
2030
2031         sindex = i386_btop(sva);
2032         eindex = i386_btop(eva);
2033
2034         for (; sindex < eindex; sindex = pdnxt) {
2035
2036                 unsigned pdirindex;
2037
2038                 pdnxt = ((sindex + NPTEPG) & ~(NPTEPG - 1));
2039
2040                 pdirindex = sindex / NPDEPG;
2041                 ptpaddr = pmap->pm_pdir[pdirindex];
2042                 if ((ptpaddr & PG_PS) != 0) {
2043                         pmap->pm_pdir[pdirindex] &= ~(PG_M|PG_RW);
2044                         pmap->pm_stats.resident_count -= NBPDR / PAGE_SIZE;
2045                         anychanged++;
2046                         continue;
2047                 }
2048
2049                 /*
2050                  * Weed out invalid mappings. Note: we assume that the page
2051                  * directory table is always allocated, and in kernel virtual.
2052                  */
2053                 if (ptpaddr == 0)
2054                         continue;
2055
2056                 if (pdnxt > eindex) {
2057                         pdnxt = eindex;
2058                 }
2059
2060                 for (; sindex != pdnxt; sindex++) {
2061
2062                         pt_entry_t pbits;
2063                         vm_page_t m;
2064
2065                         pbits = ptbase[sindex];
2066
2067                         if (pbits & PG_MANAGED) {
2068                                 m = NULL;
2069                                 if (pbits & PG_A) {
2070                                         m = PHYS_TO_VM_PAGE(pbits);
2071                                         vm_page_flag_set(m, PG_REFERENCED);
2072                                         pbits &= ~PG_A;
2073                                 }
2074                                 if (pbits & PG_M) {
2075                                         if (pmap_track_modified(i386_ptob(sindex))) {
2076                                                 if (m == NULL)
2077                                                         m = PHYS_TO_VM_PAGE(pbits);
2078                                                 vm_page_dirty(m);
2079                                                 pbits &= ~PG_M;
2080                                         }
2081                                 }
2082                         }
2083
2084                         pbits &= ~PG_RW;
2085
2086                         if (pbits != ptbase[sindex]) {
2087                                 ptbase[sindex] = pbits;
2088                                 anychanged = 1;
2089                         }
2090                 }
2091         }
2092         if (anychanged)
2093                 pmap_invalidate_all(pmap);
2094 }
2095
2096 /*
2097  *      Insert the given physical page (p) at
2098  *      the specified virtual address (v) in the
2099  *      target physical map with the protection requested.
2100  *
2101  *      If specified, the page will be wired down, meaning
2102  *      that the related pte can not be reclaimed.
2103  *
2104  *      NB:  This is the only routine which MAY NOT lazy-evaluate
2105  *      or lose information.  That is, this routine must actually
2106  *      insert this page into the given map NOW.
2107  */
2108 void
2109 pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
2110            boolean_t wired)
2111 {
2112         vm_offset_t pa;
2113         register pt_entry_t *pte;
2114         vm_offset_t opa;
2115         pt_entry_t origpte, newpte;
2116         vm_page_t mpte;
2117
2118         if (pmap == NULL)
2119                 return;
2120
2121         va &= PG_FRAME;
2122 #ifdef PMAP_DIAGNOSTIC
2123         if (va > VM_MAX_KERNEL_ADDRESS)
2124                 panic("pmap_enter: toobig");
2125         if ((va >= UPT_MIN_ADDRESS) && (va < UPT_MAX_ADDRESS))
2126                 panic("pmap_enter: invalid to pmap_enter page table pages (va: 0x%x)", va);
2127 #endif
2128
2129         mpte = NULL;
2130         /*
2131          * In the case that a page table page is not
2132          * resident, we are creating it here.
2133          */
2134         if (va < VM_MAXUSER_ADDRESS) {
2135                 mpte = pmap_allocpte(pmap, va);
2136         }
2137 #if 0 && defined(PMAP_DIAGNOSTIC)
2138         else {
2139                 pd_entry_t *pdeaddr = pmap_pde(pmap, va);
2140                 origpte = *pdeaddr;
2141                 if ((origpte & PG_V) == 0) { 
2142                         panic("pmap_enter: invalid kernel page table page, pdir=%p, pde=%p, va=%p\n",
2143                                 pmap->pm_pdir[PTDPTDI], origpte, va);
2144                 }
2145         }
2146 #endif
2147
2148         pte = pmap_pte(pmap, va);
2149
2150         /*
2151          * Page Directory table entry not valid, we need a new PT page
2152          */
2153         if (pte == NULL) {
2154                 panic("pmap_enter: invalid page directory, pdir=%p, va=0x%x\n",
2155                         (void *)pmap->pm_pdir[PTDPTDI], va);
2156         }
2157
2158         pa = VM_PAGE_TO_PHYS(m) & PG_FRAME;
2159         origpte = *(vm_offset_t *)pte;
2160         opa = origpte & PG_FRAME;
2161
2162         if (origpte & PG_PS)
2163                 panic("pmap_enter: attempted pmap_enter on 4MB page");
2164
2165         /*
2166          * Mapping has not changed, must be protection or wiring change.
2167          */
2168         if (origpte && (opa == pa)) {
2169                 /*
2170                  * Wiring change, just update stats. We don't worry about
2171                  * wiring PT pages as they remain resident as long as there
2172                  * are valid mappings in them. Hence, if a user page is wired,
2173                  * the PT page will be also.
2174                  */
2175                 if (wired && ((origpte & PG_W) == 0))
2176                         pmap->pm_stats.wired_count++;
2177                 else if (!wired && (origpte & PG_W))
2178                         pmap->pm_stats.wired_count--;
2179
2180 #if defined(PMAP_DIAGNOSTIC)
2181                 if (pmap_nw_modified((pt_entry_t) origpte)) {
2182                         printf(
2183         "pmap_enter: modified page not writable: va: 0x%x, pte: 0x%x\n",
2184                             va, origpte);
2185                 }
2186 #endif
2187
2188                 /*
2189                  * Remove extra pte reference
2190                  */
2191                 if (mpte)
2192                         mpte->hold_count--;
2193
2194                 if ((prot & VM_PROT_WRITE) && (origpte & PG_V)) {
2195                         if ((origpte & PG_RW) == 0) {
2196                                 *pte |= PG_RW;
2197 #ifdef SMP
2198                                 cpu_invlpg((void *)va);
2199                                 if (pmap->pm_active & PCPU_GET(other_cpus))
2200                                         smp_invltlb();
2201 #else
2202                                 invltlb_1pg(va);
2203 #endif
2204                         }
2205                         return;
2206                 }
2207
2208                 /*
2209                  * We might be turning off write access to the page,
2210                  * so we go ahead and sense modify status.
2211                  */
2212                 if (origpte & PG_MANAGED) {
2213                         if ((origpte & PG_M) && pmap_track_modified(va)) {
2214                                 vm_page_t om;
2215                                 om = PHYS_TO_VM_PAGE(opa);
2216                                 vm_page_dirty(om);
2217                         }
2218                         pa |= PG_MANAGED;
2219                 }
2220                 goto validate;
2221         } 
2222         /*
2223          * Mapping has changed, invalidate old range and fall through to
2224          * handle validating new mapping.
2225          */
2226         if (opa) {
2227                 int err;
2228                 err = pmap_remove_pte(pmap, pte, va);
2229                 if (err)
2230                         panic("pmap_enter: pte vanished, va: 0x%x", va);
2231         }
2232
2233         /*
2234          * Enter on the PV list if part of our managed memory. Note that we
2235          * raise IPL while manipulating pv_table since pmap_enter can be
2236          * called at interrupt time.
2237          */
2238         if (pmap_initialized && 
2239             (m->flags & (PG_FICTITIOUS|PG_UNMANAGED)) == 0) {
2240                 pmap_insert_entry(pmap, va, mpte, m);
2241                 pa |= PG_MANAGED;
2242         }
2243
2244         /*
2245          * Increment counters
2246          */
2247         pmap->pm_stats.resident_count++;
2248         if (wired)
2249                 pmap->pm_stats.wired_count++;
2250
2251 validate:
2252         /*
2253          * Now validate mapping with desired protection/wiring.
2254          */
2255         newpte = (vm_offset_t) (pa | pte_prot(pmap, prot) | PG_V);
2256
2257         if (wired)
2258                 newpte |= PG_W;
2259         if (va < VM_MAXUSER_ADDRESS)
2260                 newpte |= PG_U;
2261         if (pmap == kernel_pmap)
2262                 newpte |= pgeflag;
2263
2264         /*
2265          * if the mapping or permission bits are different, we need
2266          * to update the pte.
2267          */
2268         if ((origpte & ~(PG_M|PG_A)) != newpte) {
2269                 *pte = newpte | PG_A;
2270                 /*if (origpte)*/ {
2271 #ifdef SMP
2272                         cpu_invlpg((void *)va);
2273                         if (pmap->pm_active & PCPU_GET(other_cpus))
2274                                 smp_invltlb();
2275 #else
2276                         invltlb_1pg(va);
2277 #endif
2278                 }
2279         }
2280 }
2281
2282 /*
2283  * this code makes some *MAJOR* assumptions:
2284  * 1. Current pmap & pmap exists.
2285  * 2. Not wired.
2286  * 3. Read access.
2287  * 4. No page table pages.
2288  * 5. Tlbflush is deferred to calling procedure.
2289  * 6. Page IS managed.
2290  * but is *MUCH* faster than pmap_enter...
2291  */
2292
2293 static vm_page_t
2294 pmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_page_t mpte)
2295 {
2296         pt_entry_t *pte;
2297         vm_offset_t pa;
2298
2299         /*
2300          * In the case that a page table page is not
2301          * resident, we are creating it here.
2302          */
2303         if (va < VM_MAXUSER_ADDRESS) {
2304                 unsigned ptepindex;
2305                 pd_entry_t ptepa;
2306
2307                 /*
2308                  * Calculate pagetable page index
2309                  */
2310                 ptepindex = va >> PDRSHIFT;
2311                 if (mpte && (mpte->pindex == ptepindex)) {
2312                         mpte->hold_count++;
2313                 } else {
2314 retry:
2315                         /*
2316                          * Get the page directory entry
2317                          */
2318                         ptepa = pmap->pm_pdir[ptepindex];
2319
2320                         /*
2321                          * If the page table page is mapped, we just increment
2322                          * the hold count, and activate it.
2323                          */
2324                         if (ptepa) {
2325                                 if (ptepa & PG_PS)
2326                                         panic("pmap_enter_quick: unexpected mapping into 4MB page");
2327                                 if (pmap->pm_ptphint &&
2328                                         (pmap->pm_ptphint->pindex == ptepindex)) {
2329                                         mpte = pmap->pm_ptphint;
2330                                 } else {
2331                                         mpte = pmap_page_lookup(pmap->pm_pteobj, ptepindex);
2332                                         pmap->pm_ptphint = mpte;
2333                                 }
2334                                 if (mpte == NULL)
2335                                         goto retry;
2336                                 mpte->hold_count++;
2337                         } else {
2338                                 mpte = _pmap_allocpte(pmap, ptepindex);
2339                         }
2340                 }
2341         } else {
2342                 mpte = NULL;
2343         }
2344
2345         /*
2346          * This call to vtopte makes the assumption that we are
2347          * entering the page into the current pmap.  In order to support
2348          * quick entry into any pmap, one would likely use pmap_pte_quick.
2349          * But that isn't as quick as vtopte.
2350          */
2351         pte = vtopte(va);
2352         if (*pte) {
2353                 if (mpte)
2354                         pmap_unwire_pte_hold(pmap, mpte);
2355                 return 0;
2356         }
2357
2358         /*
2359          * Enter on the PV list if part of our managed memory. Note that we
2360          * raise IPL while manipulating pv_table since pmap_enter can be
2361          * called at interrupt time.
2362          */
2363         if ((m->flags & (PG_FICTITIOUS|PG_UNMANAGED)) == 0)
2364                 pmap_insert_entry(pmap, va, mpte, m);
2365
2366         /*
2367          * Increment counters
2368          */
2369         pmap->pm_stats.resident_count++;
2370
2371         pa = VM_PAGE_TO_PHYS(m);
2372
2373         /*
2374          * Now validate mapping with RO protection
2375          */
2376         if (m->flags & (PG_FICTITIOUS|PG_UNMANAGED))
2377                 *pte = pa | PG_V | PG_U;
2378         else
2379                 *pte = pa | PG_V | PG_U | PG_MANAGED;
2380
2381         return mpte;
2382 }
2383
2384 /*
2385  * Make a temporary mapping for a physical address.  This is only intended
2386  * to be used for panic dumps.
2387  */
2388 void *
2389 pmap_kenter_temporary(vm_offset_t pa, int i)
2390 {
2391         pmap_kenter((vm_offset_t)crashdumpmap + (i * PAGE_SIZE), pa);
2392         return ((void *)crashdumpmap);
2393 }
2394
2395 #define MAX_INIT_PT (96)
2396 /*
2397  * pmap_object_init_pt preloads the ptes for a given object
2398  * into the specified pmap.  This eliminates the blast of soft
2399  * faults on process startup and immediately after an mmap.
2400  */
2401 void
2402 pmap_object_init_pt(pmap_t pmap, vm_offset_t addr,
2403                     vm_object_t object, vm_pindex_t pindex,
2404                     vm_size_t size, int limit)
2405 {
2406         vm_offset_t tmpidx;
2407         int psize;
2408         vm_page_t p, mpte;
2409         int objpgs;
2410
2411         if (pmap == NULL || object == NULL)
2412                 return;
2413
2414         /*
2415          * This code maps large physical mmap regions into the
2416          * processor address space.  Note that some shortcuts
2417          * are taken, but the code works.
2418          */
2419         if (pseflag && (object->type == OBJT_DEVICE) &&
2420             ((addr & (NBPDR - 1)) == 0) && ((size & (NBPDR - 1)) == 0)) {
2421                 int i;
2422                 vm_page_t m[1];
2423                 unsigned int ptepindex;
2424                 int npdes;
2425                 pd_entry_t ptepa;
2426
2427                 if (pmap->pm_pdir[ptepindex = (addr >> PDRSHIFT)])
2428                         return;
2429
2430 retry:
2431                 p = vm_page_lookup(object, pindex);
2432                 if (p && vm_page_sleep_busy(p, FALSE, "init4p"))
2433                         goto retry;
2434
2435                 if (p == NULL) {
2436                         p = vm_page_alloc(object, pindex, VM_ALLOC_NORMAL);
2437                         if (p == NULL)
2438                                 return;
2439                         m[0] = p;
2440
2441                         if (vm_pager_get_pages(object, m, 1, 0) != VM_PAGER_OK) {
2442                                 vm_page_free(p);
2443                                 return;
2444                         }
2445
2446                         p = vm_page_lookup(object, pindex);
2447                         vm_page_wakeup(p);
2448                 }
2449
2450                 ptepa = VM_PAGE_TO_PHYS(p);
2451                 if (ptepa & (NBPDR - 1)) {
2452                         return;
2453                 }
2454
2455                 p->valid = VM_PAGE_BITS_ALL;
2456
2457                 pmap->pm_stats.resident_count += size >> PAGE_SHIFT;
2458                 npdes = size >> PDRSHIFT;
2459                 for(i = 0; i < npdes; i++) {
2460                         pmap->pm_pdir[ptepindex] =
2461                             ptepa | PG_U | PG_RW | PG_V | PG_PS;
2462                         ptepa += NBPDR;
2463                         ptepindex += 1;
2464                 }
2465                 vm_page_flag_set(p, PG_MAPPED);
2466                 invltlb();
2467                 return;
2468         }
2469
2470         psize = i386_btop(size);
2471
2472         if ((object->type != OBJT_VNODE) ||
2473             ((limit & MAP_PREFAULT_PARTIAL) && (psize > MAX_INIT_PT) &&
2474              (object->resident_page_count > MAX_INIT_PT))) {
2475                 return;
2476         }
2477
2478         if (psize + pindex > object->size) {
2479                 if (object->size < pindex)
2480                         return;
2481                 psize = object->size - pindex;
2482         }
2483
2484         mpte = NULL;
2485         /*
2486          * if we are processing a major portion of the object, then scan the
2487          * entire thing.
2488          */
2489         if (psize > (object->resident_page_count >> 2)) {
2490                 objpgs = psize;
2491
2492                 for (p = TAILQ_FIRST(&object->memq);
2493                     ((objpgs > 0) && (p != NULL));
2494                     p = TAILQ_NEXT(p, listq)) {
2495
2496                         tmpidx = p->pindex;
2497                         if (tmpidx < pindex) {
2498                                 continue;
2499                         }
2500                         tmpidx -= pindex;
2501                         if (tmpidx >= psize) {
2502                                 continue;
2503                         }
2504                         /*
2505                          * don't allow an madvise to blow away our really
2506                          * free pages allocating pv entries.
2507                          */
2508                         if ((limit & MAP_PREFAULT_MADVISE) &&
2509                             cnt.v_free_count < cnt.v_free_reserved) {
2510                                 break;
2511                         }
2512                         if (((p->valid & VM_PAGE_BITS_ALL) == VM_PAGE_BITS_ALL) &&
2513                                 (p->busy == 0) &&
2514                             (p->flags & (PG_BUSY | PG_FICTITIOUS)) == 0) {
2515                                 if ((p->queue - p->pc) == PQ_CACHE)
2516                                         vm_page_deactivate(p);
2517                                 vm_page_busy(p);
2518                                 mpte = pmap_enter_quick(pmap, 
2519                                         addr + i386_ptob(tmpidx), p, mpte);
2520                                 vm_page_flag_set(p, PG_MAPPED);
2521                                 vm_page_wakeup(p);
2522                         }
2523                         objpgs -= 1;
2524                 }
2525         } else {
2526                 /*
2527                  * else lookup the pages one-by-one.
2528                  */
2529                 for (tmpidx = 0; tmpidx < psize; tmpidx += 1) {
2530                         /*
2531                          * don't allow an madvise to blow away our really
2532                          * free pages allocating pv entries.
2533                          */
2534                         if ((limit & MAP_PREFAULT_MADVISE) &&
2535                             cnt.v_free_count < cnt.v_free_reserved) {
2536                                 break;
2537                         }
2538                         p = vm_page_lookup(object, tmpidx + pindex);
2539                         if (p &&
2540                             ((p->valid & VM_PAGE_BITS_ALL) == VM_PAGE_BITS_ALL) &&
2541                                 (p->busy == 0) &&
2542                             (p->flags & (PG_BUSY | PG_FICTITIOUS)) == 0) {
2543                                 if ((p->queue - p->pc) == PQ_CACHE)
2544                                         vm_page_deactivate(p);
2545                                 vm_page_busy(p);
2546                                 mpte = pmap_enter_quick(pmap, 
2547                                         addr + i386_ptob(tmpidx), p, mpte);
2548                                 vm_page_flag_set(p, PG_MAPPED);
2549                                 vm_page_wakeup(p);
2550                         }
2551                 }
2552         }
2553         return;
2554 }
2555
2556 /*
2557  * pmap_prefault provides a quick way of clustering
2558  * pagefaults into a processes address space.  It is a "cousin"
2559  * of pmap_object_init_pt, except it runs at page fault time instead
2560  * of mmap time.
2561  */
2562 #define PFBAK 4
2563 #define PFFOR 4
2564 #define PAGEORDER_SIZE (PFBAK+PFFOR)
2565
2566 static int pmap_prefault_pageorder[] = {
2567         -PAGE_SIZE, PAGE_SIZE,
2568         -2 * PAGE_SIZE, 2 * PAGE_SIZE,
2569         -3 * PAGE_SIZE, 3 * PAGE_SIZE
2570         -4 * PAGE_SIZE, 4 * PAGE_SIZE
2571 };
2572
2573 void
2574 pmap_prefault(pmap, addra, entry)
2575         pmap_t pmap;
2576         vm_offset_t addra;
2577         vm_map_entry_t entry;
2578 {
2579         int i;
2580         vm_offset_t starta;
2581         vm_offset_t addr;
2582         vm_pindex_t pindex;
2583         vm_page_t m, mpte;
2584         vm_object_t object;
2585
2586         if (!curthread || (pmap != vmspace_pmap(curthread->td_proc->p_vmspace)))
2587                 return;
2588
2589         object = entry->object.vm_object;
2590
2591         starta = addra - PFBAK * PAGE_SIZE;
2592         if (starta < entry->start) {
2593                 starta = entry->start;
2594         } else if (starta > addra) {
2595                 starta = 0;
2596         }
2597
2598         mpte = NULL;
2599         for (i = 0; i < PAGEORDER_SIZE; i++) {
2600                 vm_object_t lobject;
2601                 pt_entry_t *pte;
2602
2603                 addr = addra + pmap_prefault_pageorder[i];
2604                 if (addr > addra + (PFFOR * PAGE_SIZE))
2605                         addr = 0;
2606
2607                 if (addr < starta || addr >= entry->end)
2608                         continue;
2609
2610                 if ((*pmap_pde(pmap, addr)) == NULL) 
2611                         continue;
2612
2613                 pte = vtopte(addr);
2614                 if (*pte)
2615                         continue;
2616
2617                 pindex = ((addr - entry->start) + entry->offset) >> PAGE_SHIFT;
2618                 lobject = object;
2619                 for (m = vm_page_lookup(lobject, pindex);
2620                     (!m && (lobject->type == OBJT_DEFAULT) && (lobject->backing_object));
2621                     lobject = lobject->backing_object) {
2622                         if (lobject->backing_object_offset & PAGE_MASK)
2623                                 break;
2624                         pindex += (lobject->backing_object_offset >> PAGE_SHIFT);
2625                         m = vm_page_lookup(lobject->backing_object, pindex);
2626                 }
2627
2628                 /*
2629                  * give-up when a page is not in memory
2630                  */
2631                 if (m == NULL)
2632                         break;
2633
2634                 if (((m->valid & VM_PAGE_BITS_ALL) == VM_PAGE_BITS_ALL) &&
2635                         (m->busy == 0) &&
2636                     (m->flags & (PG_BUSY | PG_FICTITIOUS)) == 0) {
2637
2638                         if ((m->queue - m->pc) == PQ_CACHE) {
2639                                 vm_page_deactivate(m);
2640                         }
2641                         vm_page_busy(m);
2642                         mpte = pmap_enter_quick(pmap, addr, m, mpte);
2643                         vm_page_flag_set(m, PG_MAPPED);
2644                         vm_page_wakeup(m);
2645                 }
2646         }
2647 }
2648
2649 /*
2650  *      Routine:        pmap_change_wiring
2651  *      Function:       Change the wiring attribute for a map/virtual-address
2652  *                      pair.
2653  *      In/out conditions:
2654  *                      The mapping must already exist in the pmap.
2655  */
2656 void
2657 pmap_change_wiring(pmap, va, wired)
2658         register pmap_t pmap;
2659         vm_offset_t va;
2660         boolean_t wired;
2661 {
2662         register pt_entry_t *pte;
2663
2664         if (pmap == NULL)
2665                 return;
2666
2667         pte = pmap_pte(pmap, va);
2668
2669         if (wired && !pmap_pte_w(pte))
2670                 pmap->pm_stats.wired_count++;
2671         else if (!wired && pmap_pte_w(pte))
2672                 pmap->pm_stats.wired_count--;
2673
2674         /*
2675          * Wiring is not a hardware characteristic so there is no need to
2676          * invalidate TLB.
2677          */
2678         pmap_pte_set_w(pte, wired);
2679 }
2680
2681
2682
2683 /*
2684  *      Copy the range specified by src_addr/len
2685  *      from the source map to the range dst_addr/len
2686  *      in the destination map.
2687  *
2688  *      This routine is only advisory and need not do anything.
2689  */
2690
2691 void
2692 pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len,
2693           vm_offset_t src_addr)
2694 {
2695         vm_offset_t addr;
2696         vm_offset_t end_addr = src_addr + len;
2697         vm_offset_t pdnxt;
2698         pd_entry_t src_frame, dst_frame;
2699         vm_page_t m;
2700         pd_entry_t saved_pde;
2701
2702         if (dst_addr != src_addr)
2703                 return;
2704
2705         src_frame = src_pmap->pm_pdir[PTDPTDI] & PG_FRAME;
2706         if (src_frame != (PTDpde & PG_FRAME))
2707                 return;
2708
2709         dst_frame = dst_pmap->pm_pdir[PTDPTDI] & PG_FRAME;
2710         if (dst_frame != (APTDpde & PG_FRAME)) {
2711                 APTDpde = dst_frame | PG_RW | PG_V;
2712 #if defined(SMP)
2713                 /* The page directory is not shared between CPUs */
2714                 cpu_invltlb();
2715 #else
2716                 invltlb();
2717 #endif
2718         }
2719         saved_pde = APTDpde & (PG_FRAME | PG_RW | PG_V);
2720         for(addr = src_addr; addr < end_addr; addr = pdnxt) {
2721                 pt_entry_t *src_pte, *dst_pte;
2722                 vm_page_t dstmpte, srcmpte;
2723                 pd_entry_t srcptepaddr;
2724                 unsigned ptepindex;
2725
2726                 if (addr >= UPT_MIN_ADDRESS)
2727                         panic("pmap_copy: invalid to pmap_copy page tables\n");
2728
2729                 /*
2730                  * Don't let optional prefaulting of pages make us go
2731                  * way below the low water mark of free pages or way
2732                  * above high water mark of used pv entries.
2733                  */
2734                 if (cnt.v_free_count < cnt.v_free_reserved ||
2735                     pv_entry_count > pv_entry_high_water)
2736                         break;
2737                 
2738                 pdnxt = ((addr + PAGE_SIZE*NPTEPG) & ~(PAGE_SIZE*NPTEPG - 1));
2739                 ptepindex = addr >> PDRSHIFT;
2740
2741                 srcptepaddr = src_pmap->pm_pdir[ptepindex];
2742                 if (srcptepaddr == 0)
2743                         continue;
2744                         
2745                 if (srcptepaddr & PG_PS) {
2746                         if (dst_pmap->pm_pdir[ptepindex] == 0) {
2747                                 dst_pmap->pm_pdir[ptepindex] = srcptepaddr;
2748                                 dst_pmap->pm_stats.resident_count += NBPDR / PAGE_SIZE;
2749                         }
2750                         continue;
2751                 }
2752
2753                 srcmpte = vm_page_lookup(src_pmap->pm_pteobj, ptepindex);
2754                 if ((srcmpte == NULL) ||
2755                     (srcmpte->hold_count == 0) || (srcmpte->flags & PG_BUSY))
2756                         continue;
2757
2758                 if (pdnxt > end_addr)
2759                         pdnxt = end_addr;
2760
2761                 src_pte = vtopte(addr);
2762                 dst_pte = avtopte(addr);
2763                 while (addr < pdnxt) {
2764                         pt_entry_t ptetemp;
2765                         ptetemp = *src_pte;
2766                         /*
2767                          * we only virtual copy managed pages
2768                          */
2769                         if ((ptetemp & PG_MANAGED) != 0) {
2770                                 /*
2771                                  * We have to check after allocpte for the
2772                                  * pte still being around...  allocpte can
2773                                  * block.
2774                                  */
2775                                 dstmpte = pmap_allocpte(dst_pmap, addr);
2776                                 if ((APTDpde & PG_FRAME) !=
2777                                     (saved_pde & PG_FRAME)) {
2778                                         APTDpde = saved_pde;
2779 printf ("IT HAPPENNED!");
2780 #if defined(SMP)
2781                                         cpu_invltlb();
2782 #else
2783                                         invltlb();
2784 #endif
2785                                 }
2786                                 if ((*dst_pte == 0) && (ptetemp = *src_pte)) {
2787                                         /*
2788                                          * Clear the modified and
2789                                          * accessed (referenced) bits
2790                                          * during the copy.
2791                                          */
2792                                         m = PHYS_TO_VM_PAGE(ptetemp);
2793                                         *dst_pte = ptetemp & ~(PG_M | PG_A);
2794                                         dst_pmap->pm_stats.resident_count++;
2795                                         pmap_insert_entry(dst_pmap, addr,
2796                                                 dstmpte, m);
2797                                 } else {
2798                                         pmap_unwire_pte_hold(dst_pmap, dstmpte);
2799                                 }
2800                                 if (dstmpte->hold_count >= srcmpte->hold_count)
2801                                         break;
2802                         }
2803                         addr += PAGE_SIZE;
2804                         src_pte++;
2805                         dst_pte++;
2806                 }
2807         }
2808 }       
2809
2810 /*
2811  *      pmap_zero_page zeros the specified hardware page by mapping 
2812  *      the page into KVM and using bzero to clear its contents.
2813  */
2814 void
2815 pmap_zero_page(vm_page_t m)
2816 {
2817         vm_offset_t phys = VM_PAGE_TO_PHYS(m);
2818
2819         if (*CMAP2)
2820                 panic("pmap_zero_page: CMAP2 busy");
2821
2822         *CMAP2 = PG_V | PG_RW | phys | PG_A | PG_M;
2823         invltlb_1pg((vm_offset_t)CADDR2);
2824
2825 #if defined(I686_CPU)
2826         if (cpu_class == CPUCLASS_686)
2827                 i686_pagezero(CADDR2);
2828         else
2829 #endif
2830                 bzero(CADDR2, PAGE_SIZE);
2831         *CMAP2 = 0;
2832 }
2833
2834 /*
2835  *      pmap_zero_page_area zeros the specified hardware page by mapping 
2836  *      the page into KVM and using bzero to clear its contents.
2837  *
2838  *      off and size may not cover an area beyond a single hardware page.
2839  */
2840 void
2841 pmap_zero_page_area(vm_page_t m, int off, int size)
2842 {
2843         vm_offset_t phys = VM_PAGE_TO_PHYS(m);
2844
2845         if (*CMAP2)
2846                 panic("pmap_zero_page: CMAP2 busy");
2847
2848         *CMAP2 = PG_V | PG_RW | phys | PG_A | PG_M;
2849         invltlb_1pg((vm_offset_t)CADDR2);
2850
2851 #if defined(I686_CPU)
2852         if (cpu_class == CPUCLASS_686 && off == 0 && size == PAGE_SIZE)
2853                 i686_pagezero(CADDR2);
2854         else
2855 #endif
2856                 bzero((char *)CADDR2 + off, size);
2857         *CMAP2 = 0;
2858 }
2859
2860 /*
2861  *      pmap_copy_page copies the specified (machine independent)
2862  *      page by mapping the page into virtual memory and using
2863  *      bcopy to copy the page, one machine dependent page at a
2864  *      time.
2865  */
2866 void
2867 pmap_copy_page(vm_page_t src, vm_page_t dst)
2868 {
2869
2870         if (*CMAP1)
2871                 panic("pmap_copy_page: CMAP1 busy");
2872         if (*CMAP2)
2873                 panic("pmap_copy_page: CMAP2 busy");
2874
2875         *CMAP1 = PG_V | VM_PAGE_TO_PHYS(src) | PG_A;
2876         *CMAP2 = PG_V | PG_RW | VM_PAGE_TO_PHYS(dst) | PG_A | PG_M;
2877 #ifdef I386_CPU
2878         invltlb();
2879 #else
2880         invlpg((u_int)CADDR1);
2881         invlpg((u_int)CADDR2);
2882 #endif
2883
2884         bcopy(CADDR1, CADDR2, PAGE_SIZE);
2885
2886         *CMAP1 = 0;
2887         *CMAP2 = 0;
2888 }
2889
2890
2891 /*
2892  *      Routine:        pmap_pageable
2893  *      Function:
2894  *              Make the specified pages (by pmap, offset)
2895  *              pageable (or not) as requested.
2896  *
2897  *              A page which is not pageable may not take
2898  *              a fault; therefore, its page table entry
2899  *              must remain valid for the duration.
2900  *
2901  *              This routine is merely advisory; pmap_enter
2902  *              will specify that these pages are to be wired
2903  *              down (or not) as appropriate.
2904  */
2905 void
2906 pmap_pageable(pmap, sva, eva, pageable)
2907         pmap_t pmap;
2908         vm_offset_t sva, eva;
2909         boolean_t pageable;
2910 {
2911 }
2912
2913 /*
2914  * Returns true if the pmap's pv is one of the first
2915  * 16 pvs linked to from this page.  This count may
2916  * be changed upwards or downwards in the future; it
2917  * is only necessary that true be returned for a small
2918  * subset of pmaps for proper page aging.
2919  */
2920 boolean_t
2921 pmap_page_exists_quick(pmap, m)
2922         pmap_t pmap;
2923         vm_page_t m;
2924 {
2925         pv_entry_t pv;
2926         int loops = 0;
2927         int s;
2928
2929         if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
2930                 return FALSE;
2931
2932         s = splvm();
2933
2934         TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
2935                 if (pv->pv_pmap == pmap) {
2936                         splx(s);
2937                         return TRUE;
2938                 }
2939                 loops++;
2940                 if (loops >= 16)
2941                         break;
2942         }
2943         splx(s);
2944         return (FALSE);
2945 }
2946
2947 #define PMAP_REMOVE_PAGES_CURPROC_ONLY
2948 /*
2949  * Remove all pages from specified address space
2950  * this aids process exit speeds.  Also, this code
2951  * is special cased for current process only, but
2952  * can have the more generic (and slightly slower)
2953  * mode enabled.  This is much faster than pmap_remove
2954  * in the case of running down an entire address space.
2955  */
2956 void
2957 pmap_remove_pages(pmap, sva, eva)
2958         pmap_t pmap;
2959         vm_offset_t sva, eva;
2960 {
2961         pt_entry_t *pte, tpte;
2962         vm_page_t m;
2963         pv_entry_t pv, npv;
2964         int s;
2965
2966 #ifdef PMAP_REMOVE_PAGES_CURPROC_ONLY
2967         if (!curthread || (pmap != vmspace_pmap(curthread->td_proc->p_vmspace))) {
2968                 printf("warning: pmap_remove_pages called with non-current pmap\n");
2969                 return;
2970         }
2971 #endif
2972
2973         s = splvm();
2974         for (pv = TAILQ_FIRST(&pmap->pm_pvlist); pv; pv = npv) {
2975
2976                 if (pv->pv_va >= eva || pv->pv_va < sva) {
2977                         npv = TAILQ_NEXT(pv, pv_plist);
2978                         continue;
2979                 }
2980
2981 #ifdef PMAP_REMOVE_PAGES_CURPROC_ONLY
2982                 pte = vtopte(pv->pv_va);
2983 #else
2984                 pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
2985 #endif
2986                 tpte = *pte;
2987
2988                 if (tpte == 0) {
2989                         printf("TPTE at %p  IS ZERO @ VA %08x\n",
2990                                                         pte, pv->pv_va);
2991                         panic("bad pte");
2992                 }
2993
2994 /*
2995  * We cannot remove wired pages from a process' mapping at this time
2996  */
2997                 if (tpte & PG_W) {
2998                         npv = TAILQ_NEXT(pv, pv_plist);
2999                         continue;
3000                 }
3001
3002                 m = PHYS_TO_VM_PAGE(tpte);
3003                 KASSERT(m->phys_addr == (tpte & PG_FRAME),
3004                     ("vm_page_t %p phys_addr mismatch %08x %08x",
3005                     m, m->phys_addr, tpte));
3006
3007                 KASSERT(m < &vm_page_array[vm_page_array_size],
3008                         ("pmap_remove_pages: bad tpte %x", tpte));
3009
3010                 pv->pv_pmap->pm_stats.resident_count--;
3011
3012                 *pte = 0;
3013
3014                 /*
3015                  * Update the vm_page_t clean and reference bits.
3016                  */
3017                 if (tpte & PG_M) {
3018                         vm_page_dirty(m);
3019                 }
3020
3021                 npv = TAILQ_NEXT(pv, pv_plist);
3022                 TAILQ_REMOVE(&pv->pv_pmap->pm_pvlist, pv, pv_plist);
3023
3024                 m->md.pv_list_count--;
3025                 TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
3026                 if (TAILQ_FIRST(&m->md.pv_list) == NULL) {
3027                         vm_page_flag_clear(m, PG_MAPPED | PG_WRITEABLE);
3028                 }
3029
3030                 pmap_unuse_pt(pv->pv_pmap, pv->pv_va, pv->pv_ptem);
3031                 free_pv_entry(pv);
3032         }
3033         splx(s);
3034         pmap_invalidate_all(pmap);
3035 }
3036
3037 /*
3038  * pmap_testbit tests bits in pte's
3039  * note that the testbit/changebit routines are inline,
3040  * and a lot of things compile-time evaluate.
3041  */
3042 static boolean_t
3043 pmap_testbit(m, bit)
3044         vm_page_t m;
3045         int bit;
3046 {
3047         pv_entry_t pv;
3048         pt_entry_t *pte;
3049         int s;
3050
3051         if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
3052                 return FALSE;
3053
3054         if (TAILQ_FIRST(&m->md.pv_list) == NULL)
3055                 return FALSE;
3056
3057         s = splvm();
3058
3059         TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
3060                 /*
3061                  * if the bit being tested is the modified bit, then
3062                  * mark clean_map and ptes as never
3063                  * modified.
3064                  */
3065                 if (bit & (PG_A|PG_M)) {
3066                         if (!pmap_track_modified(pv->pv_va))
3067                                 continue;
3068                 }
3069
3070 #if defined(PMAP_DIAGNOSTIC)
3071                 if (!pv->pv_pmap) {
3072                         printf("Null pmap (tb) at va: 0x%x\n", pv->pv_va);
3073                         continue;
3074                 }
3075 #endif
3076                 pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
3077                 if (*pte & bit) {
3078                         splx(s);
3079                         return TRUE;
3080                 }
3081         }
3082         splx(s);
3083         return (FALSE);
3084 }
3085
3086 /*
3087  * this routine is used to modify bits in ptes
3088  */
3089 static __inline void
3090 pmap_changebit(vm_page_t m, int bit, boolean_t setem)
3091 {
3092         register pv_entry_t pv;
3093         register pt_entry_t *pte;
3094         int s;
3095
3096         if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
3097                 return;
3098
3099         s = splvm();
3100
3101         /*
3102          * Loop over all current mappings setting/clearing as appropos If
3103          * setting RO do we need to clear the VAC?
3104          */
3105         TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
3106                 /*
3107                  * don't write protect pager mappings
3108                  */
3109                 if (!setem && (bit == PG_RW)) {
3110                         if (!pmap_track_modified(pv->pv_va))
3111                                 continue;
3112                 }
3113
3114 #if defined(PMAP_DIAGNOSTIC)
3115                 if (!pv->pv_pmap) {
3116                         printf("Null pmap (cb) at va: 0x%x\n", pv->pv_va);
3117                         continue;
3118                 }
3119 #endif
3120
3121                 pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
3122
3123                 if (setem) {
3124                         *pte |= bit;
3125                         pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
3126                 } else {
3127                         pt_entry_t pbits = *pte;
3128                         if (pbits & bit) {
3129                                 if (bit == PG_RW) {
3130                                         if (pbits & PG_M) {
3131                                                 vm_page_dirty(m);
3132                                         }
3133                                         *pte = pbits & ~(PG_M|PG_RW);
3134                                 } else {
3135                                         *pte = pbits & ~bit;
3136                                 }
3137                                 pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
3138                         }
3139                 }
3140         }
3141         splx(s);
3142 }
3143
3144 /*
3145  *      pmap_page_protect:
3146  *
3147  *      Lower the permission for all mappings to a given page.
3148  */
3149 void
3150 pmap_page_protect(vm_page_t m, vm_prot_t prot)
3151 {
3152         if ((prot & VM_PROT_WRITE) == 0) {
3153                 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
3154                         pmap_changebit(m, PG_RW, FALSE);
3155                 } else {
3156                         pmap_remove_all(m);
3157                 }
3158         }
3159 }
3160
3161 vm_offset_t
3162 pmap_phys_address(ppn)
3163         int ppn;
3164 {
3165         return (i386_ptob(ppn));
3166 }
3167
3168 /*
3169  *      pmap_ts_referenced:
3170  *
3171  *      Return a count of reference bits for a page, clearing those bits.
3172  *      It is not necessary for every reference bit to be cleared, but it
3173  *      is necessary that 0 only be returned when there are truly no
3174  *      reference bits set.
3175  *
3176  *      XXX: The exact number of bits to check and clear is a matter that
3177  *      should be tested and standardized at some point in the future for
3178  *      optimal aging of shared pages.
3179  */
3180 int
3181 pmap_ts_referenced(vm_page_t m)
3182 {
3183         register pv_entry_t pv, pvf, pvn;
3184         pt_entry_t *pte;
3185         int s;
3186         int rtval = 0;
3187
3188         if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
3189                 return (rtval);
3190
3191         s = splvm();
3192
3193         if ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) {
3194
3195                 pvf = pv;
3196
3197                 do {
3198                         pvn = TAILQ_NEXT(pv, pv_list);
3199
3200                         TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
3201
3202                         TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list);
3203
3204                         if (!pmap_track_modified(pv->pv_va))
3205                                 continue;
3206
3207                         pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
3208
3209                         if (pte && (*pte & PG_A)) {
3210                                 *pte &= ~PG_A;
3211
3212                                 pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
3213
3214                                 rtval++;
3215                                 if (rtval > 4) {
3216                                         break;
3217                                 }
3218                         }
3219                 } while ((pv = pvn) != NULL && pv != pvf);
3220         }
3221         splx(s);
3222
3223         return (rtval);
3224 }
3225
3226 /*
3227  *      pmap_is_modified:
3228  *
3229  *      Return whether or not the specified physical page was modified
3230  *      in any physical maps.
3231  */
3232 boolean_t
3233 pmap_is_modified(vm_page_t m)
3234 {
3235         return pmap_testbit(m, PG_M);
3236 }
3237
3238 /*
3239  *      Clear the modify bits on the specified physical page.
3240  */
3241 void
3242 pmap_clear_modify(vm_page_t m)
3243 {
3244         pmap_changebit(m, PG_M, FALSE);
3245 }
3246
3247 /*
3248  *      pmap_clear_reference:
3249  *
3250  *      Clear the reference bit on the specified physical page.
3251  */
3252 void
3253 pmap_clear_reference(vm_page_t m)
3254 {
3255         pmap_changebit(m, PG_A, FALSE);
3256 }
3257
3258 /*
3259  * Miscellaneous support routines follow
3260  */
3261
3262 static void
3263 i386_protection_init()
3264 {
3265         register int *kp, prot;
3266
3267         kp = protection_codes;
3268         for (prot = 0; prot < 8; prot++) {
3269                 switch (prot) {
3270                 case VM_PROT_NONE | VM_PROT_NONE | VM_PROT_NONE:
3271                         /*
3272                          * Read access is also 0. There isn't any execute bit,
3273                          * so just make it readable.
3274                          */
3275                 case VM_PROT_READ | VM_PROT_NONE | VM_PROT_NONE:
3276                 case VM_PROT_READ | VM_PROT_NONE | VM_PROT_EXECUTE:
3277                 case VM_PROT_NONE | VM_PROT_NONE | VM_PROT_EXECUTE:
3278                         *kp++ = 0;
3279                         break;
3280                 case VM_PROT_NONE | VM_PROT_WRITE | VM_PROT_NONE:
3281                 case VM_PROT_NONE | VM_PROT_WRITE | VM_PROT_EXECUTE:
3282                 case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_NONE:
3283                 case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE:
3284                         *kp++ = PG_RW;
3285                         break;
3286                 }
3287         }
3288 }
3289
3290 /*
3291  * Map a set of physical memory pages into the kernel virtual
3292  * address space. Return a pointer to where it is mapped. This
3293  * routine is intended to be used for mapping device memory,
3294  * NOT real memory.
3295  */
3296 void *
3297 pmap_mapdev(pa, size)
3298         vm_offset_t pa;
3299         vm_size_t size;
3300 {
3301         vm_offset_t va, tmpva, offset;
3302         pt_entry_t *pte;
3303
3304         offset = pa & PAGE_MASK;
3305         size = roundup(offset + size, PAGE_SIZE);
3306
3307         GIANT_REQUIRED;
3308
3309         va = kmem_alloc_pageable(kernel_map, size);
3310         if (!va)
3311                 panic("pmap_mapdev: Couldn't alloc kernel virtual memory");
3312
3313         pa = pa & PG_FRAME;
3314         for (tmpva = va; size > 0;) {
3315                 pte = vtopte(tmpva);
3316                 *pte = pa | PG_RW | PG_V | pgeflag;
3317                 size -= PAGE_SIZE;
3318                 tmpva += PAGE_SIZE;
3319                 pa += PAGE_SIZE;
3320         }
3321         invltlb();
3322
3323         return ((void *)(va + offset));
3324 }
3325
3326 void
3327 pmap_unmapdev(va, size)
3328         vm_offset_t va;
3329         vm_size_t size;
3330 {
3331         vm_offset_t base, offset;
3332
3333         base = va & PG_FRAME;
3334         offset = va & PAGE_MASK;
3335         size = roundup(offset + size, PAGE_SIZE);
3336         kmem_free(kernel_map, base, size);
3337 }
3338
3339 /*
3340  * perform the pmap work for mincore
3341  */
3342 int
3343 pmap_mincore(pmap, addr)
3344         pmap_t pmap;
3345         vm_offset_t addr;
3346 {
3347         pt_entry_t *ptep, pte;
3348         vm_page_t m;
3349         int val = 0;
3350         
3351         ptep = pmap_pte(pmap, addr);
3352         if (ptep == 0) {
3353                 return 0;
3354         }
3355
3356         if ((pte = *ptep) != 0) {
3357                 vm_offset_t pa;
3358
3359                 val = MINCORE_INCORE;
3360                 if ((pte & PG_MANAGED) == 0)
3361                         return val;
3362
3363                 pa = pte & PG_FRAME;
3364
3365                 m = PHYS_TO_VM_PAGE(pa);
3366
3367                 /*
3368                  * Modified by us
3369                  */
3370                 if (pte & PG_M)
3371                         val |= MINCORE_MODIFIED|MINCORE_MODIFIED_OTHER;
3372                 /*
3373                  * Modified by someone
3374                  */
3375                 else if (m->dirty || pmap_is_modified(m))
3376                         val |= MINCORE_MODIFIED_OTHER;
3377                 /*
3378                  * Referenced by us
3379                  */
3380                 if (pte & PG_A)
3381                         val |= MINCORE_REFERENCED|MINCORE_REFERENCED_OTHER;
3382
3383                 /*
3384                  * Referenced by someone
3385                  */
3386                 else if ((m->flags & PG_REFERENCED) || pmap_ts_referenced(m)) {
3387                         val |= MINCORE_REFERENCED_OTHER;
3388                         vm_page_flag_set(m, PG_REFERENCED);
3389                 }
3390         } 
3391         return val;
3392 }
3393
3394 void
3395 pmap_activate(struct thread *td)
3396 {
3397         struct proc *p = td->td_proc;
3398         pmap_t  pmap;
3399         u_int32_t  cr3;
3400
3401         pmap = vmspace_pmap(td->td_proc->p_vmspace);
3402 #if defined(SMP)
3403         pmap->pm_active |= PCPU_GET(cpumask);
3404 #else
3405         pmap->pm_active |= 1;
3406 #endif
3407 #if defined(SWTCH_OPTIM_STATS)
3408         tlb_flush_count++;
3409 #endif
3410         cr3 = vtophys(pmap->pm_pdir);
3411         /* XXXKSE this is wrong.
3412          * pmap_activate is for the current thread on the current cpu
3413          */
3414         if (p->p_flag & P_KSES) {
3415                 /* Make sure all other cr3 entries are updated. */
3416                 /* what if they are running?  XXXKSE (maybe abort them) */
3417                 FOREACH_THREAD_IN_PROC(p, td) {
3418                         td->td_pcb->pcb_cr3 = cr3;
3419                 }
3420         } else {
3421                 td->td_pcb->pcb_cr3 = cr3;
3422         }
3423         load_cr3(cr3);
3424 }
3425
3426 vm_offset_t
3427 pmap_addr_hint(vm_object_t obj, vm_offset_t addr, vm_size_t size)
3428 {
3429
3430         if ((obj == NULL) || (size < NBPDR) || (obj->type != OBJT_DEVICE)) {
3431                 return addr;
3432         }
3433
3434         addr = (addr + (NBPDR - 1)) & ~(NBPDR - 1);
3435         return addr;
3436 }
3437
3438
3439 #if defined(PMAP_DEBUG)
3440 pmap_pid_dump(int pid)
3441 {
3442         pmap_t pmap;
3443         struct proc *p;
3444         int npte = 0;
3445         int index;
3446
3447         sx_slock(&allproc_lock);
3448         LIST_FOREACH(p, &allproc, p_list) {
3449                 if (p->p_pid != pid)
3450                         continue;
3451
3452                 if (p->p_vmspace) {
3453                         int i,j;
3454                         index = 0;
3455                         pmap = vmspace_pmap(p->p_vmspace);
3456                         for (i = 0; i < NPDEPG; i++) {
3457                                 pd_entry_t *pde;
3458                                 pt_entry_t *pte;
3459                                 vm_offset_t base = i << PDRSHIFT;
3460                                 
3461                                 pde = &pmap->pm_pdir[i];
3462                                 if (pde && pmap_pde_v(pde)) {
3463                                         for (j = 0; j < NPTEPG; j++) {
3464                                                 vm_offset_t va = base + (j << PAGE_SHIFT);
3465                                                 if (va >= (vm_offset_t) VM_MIN_KERNEL_ADDRESS) {
3466                                                         if (index) {
3467                                                                 index = 0;
3468                                                                 printf("\n");
3469                                                         }
3470                                                         sx_sunlock(&allproc_lock);
3471                                                         return npte;
3472                                                 }
3473                                                 pte = pmap_pte_quick(pmap, va);
3474                                                 if (pte && pmap_pte_v(pte)) {
3475                                                         pt_entry_t pa;
3476                                                         vm_page_t m;
3477                                                         pa = *pte;
3478                                                         m = PHYS_TO_VM_PAGE(pa);
3479                                                         printf("va: 0x%x, pt: 0x%x, h: %d, w: %d, f: 0x%x",
3480                                                                 va, pa, m->hold_count, m->wire_count, m->flags);
3481                                                         npte++;
3482                                                         index++;
3483                                                         if (index >= 2) {
3484                                                                 index = 0;
3485                                                                 printf("\n");
3486                                                         } else {
3487                                                                 printf(" ");
3488                                                         }
3489                                                 }
3490                                         }
3491                                 }
3492                         }
3493                 }
3494         }
3495         sx_sunlock(&allproc_lock);
3496         return npte;
3497 }
3498 #endif
3499
3500 #if defined(DEBUG)
3501
3502 static void     pads(pmap_t pm);
3503 void            pmap_pvdump(vm_offset_t pa);
3504
3505 /* print address space of pmap*/
3506 static void
3507 pads(pm)
3508         pmap_t pm;
3509 {
3510         int i, j;
3511         vm_offset_t va;
3512         pt_entry_t *ptep;
3513
3514         if (pm == kernel_pmap)
3515                 return;
3516         for (i = 0; i < NPDEPG; i++)
3517                 if (pm->pm_pdir[i])
3518                         for (j = 0; j < NPTEPG; j++) {
3519                                 va = (i << PDRSHIFT) + (j << PAGE_SHIFT);
3520                                 if (pm == kernel_pmap && va < KERNBASE)
3521                                         continue;
3522                                 if (pm != kernel_pmap && va > UPT_MAX_ADDRESS)
3523                                         continue;
3524                                 ptep = pmap_pte_quick(pm, va);
3525                                 if (pmap_pte_v(ptep))
3526                                         printf("%x:%x ", va, *ptep);
3527                         };
3528
3529 }
3530
3531 void
3532 pmap_pvdump(pa)
3533         vm_offset_t pa;
3534 {
3535         pv_entry_t pv;
3536         vm_page_t m;
3537
3538         printf("pa %x", pa);
3539         m = PHYS_TO_VM_PAGE(pa);
3540         TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
3541                 printf(" -> pmap %p, va %x", (void *)pv->pv_pmap, pv->pv_va);
3542                 pads(pv->pv_pmap);
3543         }
3544         printf(" ");
3545 }
3546 #endif