Continue fleshing out the VKERNEL.
[dragonfly.git] / sys / platform / vkernel / platform / pmap.c
1 /*
2  * Copyright (c) 2006 The DragonFly Project.  All rights reserved.
3  * Copyright (c) 1991 Regents of the University of California.
4  * All rights reserved.
5  * Copyright (c) 1994 John S. Dyson
6  * All rights reserved.
7  * Copyright (c) 1994 David Greenman
8  * All rights reserved.
9  * Copyright (c) 2004-2006 Matthew Dillon
10  * All rights reserved.
11  * 
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 
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
20  *    the documentation and/or other materials provided with the
21  *    distribution.
22  * 3. Neither the name of The DragonFly Project nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific, prior written permission.
25  * 
26  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
29  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
30  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
31  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
32  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
33  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
34  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
35  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
36  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37  * SUCH DAMAGE.
38  * 
39  * from:   @(#)pmap.c      7.7 (Berkeley)  5/12/91
40  * $FreeBSD: src/sys/i386/i386/pmap.c,v 1.250.2.18 2002/03/06 22:48:53 silby Exp $
41  * $DragonFly: src/sys/platform/vkernel/platform/pmap.c,v 1.2 2007/01/05 22:18:20 dillon Exp $
42  */
43
44 #include <sys/types.h>
45 #include <sys/systm.h>
46 #include <sys/kernel.h>
47 #include <sys/stat.h>
48 #include <sys/mman.h>
49 #include <sys/vkernel.h>
50 #include <sys/proc.h>
51 #include <sys/thread.h>
52 #include <sys/user.h>
53
54 #include <vm/pmap.h>
55 #include <vm/vm_page.h>
56 #include <vm/vm_extern.h>
57 #include <vm/vm_kern.h>
58 #include <vm/vm_object.h>
59 #include <vm/vm_zone.h>
60 #include <vm/vm_pageout.h>
61
62 #include <machine/md_var.h>
63 #include <machine/pcb.h>
64 #include <machine/pmap_inval.h>
65 #include <machine/globaldata.h>
66
67 #include <assert.h>
68
69 struct pmap kernel_pmap;
70
71 static struct vm_zone pvzone;
72 static struct vm_object pvzone_obj;
73 static TAILQ_HEAD(,pmap) pmap_list = TAILQ_HEAD_INITIALIZER(pmap_list);
74 static int pv_entry_count;
75 static int pv_entry_max;
76 static int pv_entry_high_water;
77 static int pmap_pagedaemon_waken;
78 static boolean_t pmap_initialized = FALSE;
79 static int protection_codes[8];
80
81 static void i386_protection_init(void);
82 static void pmap_remove_all(vm_page_t m);
83 static int pmap_release_free_page(struct pmap *pmap, vm_page_t p);
84
85 #define MINPV   2048
86 #ifndef PMAP_SHPGPERPROC
87 #define PMAP_SHPGPERPROC 200
88 #endif
89
90 #define pmap_pde(m, v)  (&((m)->pm_pdir[(vm_offset_t)(v) >> PDRSHIFT]))
91
92 #define pte_prot(m, p) \
93         (protection_codes[p & (VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE)])
94
95 void
96 pmap_init(void)
97 {
98         int i;
99         struct pv_entry *pvinit;
100
101         for (i = 0; i < vm_page_array_size; i++) {
102                 vm_page_t m;
103
104                 m = &vm_page_array[i];
105                 TAILQ_INIT(&m->md.pv_list);
106                 m->md.pv_list_count = 0;
107         }
108
109         i = vm_page_array_size;
110         if (i < MINPV)
111                 i = MINPV;
112         pvinit = (struct pv_entry *)kmem_alloc(&kernel_map, i*sizeof(*pvinit));
113         zbootinit(&pvzone, "PV ENTRY", sizeof(*pvinit), pvinit, i);
114         pmap_initialized = TRUE;
115 }
116
117 void
118 pmap_init2(void)
119 {
120         int shpgperproc = PMAP_SHPGPERPROC;
121
122         TUNABLE_INT_FETCH("vm.pmap.shpgperproc", &shpgperproc);
123         pv_entry_max = shpgperproc * maxproc + vm_page_array_size;
124         TUNABLE_INT_FETCH("vm.pmap.pv_entries", &pv_entry_max);
125         pv_entry_high_water = 9 * (pv_entry_max / 10);
126         zinitna(&pvzone, &pvzone_obj, NULL, 0, pv_entry_max, ZONE_INTERRUPT, 1);
127 }
128
129 /*
130  * Bootstrap the kernel_pmap so it can be used with pmap_enter().  
131  *
132  * Page table pages are not managed like they are in normal pmaps, so
133  * no pteobj is needed.
134  */
135 void
136 pmap_bootstrap(void)
137 {
138         vm_pindex_t i = (((vm_offset_t)KernelPTD - KvaStart) >> PAGE_SHIFT);
139
140         kernel_pmap.pm_pdir = KernelPTD;
141         kernel_pmap.pm_pdirpte = KernelPTA[i];
142         kernel_pmap.pm_count = 1;
143         kernel_pmap.pm_active = (cpumask_t)-1;
144         TAILQ_INIT(&kernel_pmap.pm_pvlist);
145         i386_protection_init();
146 }
147
148 /*
149  * Initialize pmap0/vmspace0 .  Since process 0 never enters user mode we
150  * just dummy it up so it works well enough for fork().
151  *
152  * In DragonFly, process pmaps may only be used to manipulate user address
153  * space, never kernel address space.
154  */
155 void
156 pmap_pinit0(struct pmap *pmap)
157 {
158         pmap_pinit(pmap);
159 }
160
161 /************************************************************************
162  *              Procedures to manage whole physical maps                *
163  ************************************************************************
164  *
165  * Initialize a preallocated and zeroed pmap structure,
166  * such as one in a vmspace structure.
167  */
168 void
169 pmap_pinit(struct pmap *pmap)
170 {
171         vm_page_t ptdpg;
172         int npages;
173
174         /*
175          * No need to allocate page table space yet but we do need a valid
176          * page directory table.
177          */
178         if (pmap->pm_pdir == NULL) {
179                 pmap->pm_pdir =
180                     (pd_entry_t *)kmem_alloc_pageable(&kernel_map, PAGE_SIZE);
181         }
182
183         /*
184          * allocate object for the pte array and page directory
185          */
186         npages = VPTE_PAGETABLE_SIZE +
187                  (VM_MAX_USER_ADDRESS / PAGE_SIZE) * sizeof(vpte_t);
188         npages = (npages + PAGE_MASK) / PAGE_SIZE;
189
190         if (pmap->pm_pteobj == NULL)
191                 pmap->pm_pteobj = vm_object_allocate(OBJT_DEFAULT, npages);
192         pmap->pm_pdindex = npages - 1;
193
194         /*
195          * allocate the page directory page
196          */
197         ptdpg = vm_page_grab(pmap->pm_pteobj, pmap->pm_pdindex,
198                              VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
199
200         ptdpg->wire_count = 1;
201         ++vmstats.v_wire_count;
202
203         /* not usually mapped */
204         vm_page_flag_clear(ptdpg, PG_MAPPED | PG_BUSY);
205         ptdpg->valid = VM_PAGE_BITS_ALL;
206
207         pmap_kenter((vm_offset_t)pmap->pm_pdir, VM_PAGE_TO_PHYS(ptdpg));
208         if ((ptdpg->flags & PG_ZERO) == 0)
209                 bzero(pmap->pm_pdir, PAGE_SIZE);
210
211         pmap->pm_count = 1;
212         pmap->pm_active = 0;
213         pmap->pm_ptphint = NULL;
214         TAILQ_INIT(&pmap->pm_pvlist);
215         bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
216 }
217
218 /*
219  * Wire in kernel global address entries.  To avoid a race condition
220  * between pmap initialization and pmap_growkernel, this procedure
221  * adds the pmap to the master list (which growkernel scans to update),
222  * then copies the template.
223  *
224  * In a virtual kernel there are no kernel global address entries.
225  */
226 void
227 pmap_pinit2(struct pmap *pmap)
228 {
229         crit_enter();
230         TAILQ_INSERT_TAIL(&pmap_list, pmap, pm_pmnode);
231         crit_exit();
232 }
233
234 /*
235  * Release all resources held by the given physical map.
236  *
237  * Should only be called if the map contains no valid mappings.
238  */
239 static int pmap_release_callback(struct vm_page *p, void *data);
240
241 void
242 pmap_release(struct pmap *pmap)
243 {
244         vm_object_t object = pmap->pm_pteobj;
245         struct rb_vm_page_scan_info info;
246
247         KKASSERT(pmap != &kernel_pmap);
248
249 #if defined(DIAGNOSTIC)
250         if (object->ref_count != 1)
251                 panic("pmap_release: pteobj reference count != 1");
252 #endif
253         
254         info.pmap = pmap;
255         info.object = object;
256         crit_enter();
257         TAILQ_REMOVE(&pmap_list, pmap, pm_pmnode);
258         crit_exit();
259
260         do {
261                 crit_enter();
262                 info.error = 0;
263                 info.mpte = NULL;
264                 info.limit = object->generation;
265
266                 vm_page_rb_tree_RB_SCAN(&object->rb_memq, NULL, 
267                                         pmap_release_callback, &info);
268                 if (info.error == 0 && info.mpte) {
269                         if (!pmap_release_free_page(pmap, info.mpte))
270                                 info.error = 1;
271                 }
272                 crit_exit();
273         } while (info.error);
274 }
275
276 static int
277 pmap_release_callback(struct vm_page *p, void *data)
278 {
279         struct rb_vm_page_scan_info *info = data;
280
281         if (p->pindex == info->pmap->pm_pdindex) {
282                 info->mpte = p;
283                 return(0);
284         }
285         if (!pmap_release_free_page(info->pmap, p)) {
286                 info->error = 1;
287                 return(-1);
288         }
289         if (info->object->generation != info->limit) {
290                 info->error = 1;
291                 return(-1);
292         }
293         return(0);
294 }
295
296 /*
297  * Retire the given physical map from service.  Should only be called if
298  * the map contains no valid mappings.
299  */
300 void
301 pmap_destroy(pmap_t pmap)
302 {
303         int count;
304
305         if (pmap == NULL)
306                 return;
307
308         count = --pmap->pm_count;
309         if (count == 0) {
310                 pmap_release(pmap);
311                 panic("destroying a pmap is not yet implemented");
312         }
313 }
314
315 /*
316  * Add a reference to the specified pmap.
317  */
318 void
319 pmap_reference(pmap_t pmap)
320 {
321         if (pmap != NULL) {
322                 pmap->pm_count++;
323         }
324 }
325
326 /************************************************************************
327  *          Procedures which operate directly on the kernel PMAP        *
328  ************************************************************************/
329
330 /*
331  * This maps the requested page table and gives us access to it.
332  */
333 static vpte_t *
334 get_ptbase(struct pmap *pmap)
335 {
336         struct mdglobaldata *gd = mdcpu;
337
338         if (pmap == &kernel_pmap) {
339                 return(KernelPTA);
340         } else if (pmap->pm_pdir == gd->gd_PT1pdir) {
341                 return(gd->gd_PT1map);
342         } else if (pmap->pm_pdir == gd->gd_PT2pdir) {
343                 return(gd->gd_PT2map);
344         }
345
346         /*
347          * Otherwise choose one or the other and map the page table
348          * in the KVA space reserved for it.
349          */
350         KKASSERT(gd->mi.gd_intr_nesting_level == 0 &&
351                  (gd->mi.gd_curthread->td_flags & TDF_INTTHREAD) == 0);
352
353         if ((gd->gd_PTflip = 1 - gd->gd_PTflip) == 0) {
354                 gd->gd_PT1pdir = pmap->pm_pdir;
355                 *gd->gd_PT1pde = pmap->pm_pdirpte;
356                 madvise(gd->gd_PT1map, SEG_SIZE, MADV_INVAL);
357                 return(gd->gd_PT1map);
358         } else {
359                 gd->gd_PT2pdir = pmap->pm_pdir;
360                 *gd->gd_PT2pde = pmap->pm_pdirpte;
361                 madvise(gd->gd_PT2map, SEG_SIZE, MADV_INVAL);
362                 return(gd->gd_PT2map);
363         }
364 }
365
366 static vpte_t *
367 get_ptbase1(struct pmap *pmap)
368 {
369         struct mdglobaldata *gd = mdcpu;
370
371         if (pmap == &kernel_pmap) {
372                 return(KernelPTA);
373         } else if (pmap->pm_pdir == gd->gd_PT1pdir) {
374                 return(gd->gd_PT1map);
375         }
376         KKASSERT(gd->mi.gd_intr_nesting_level == 0 &&
377                  (gd->mi.gd_curthread->td_flags & TDF_INTTHREAD) == 0);
378         gd->gd_PT1pdir = pmap->pm_pdir;
379         *gd->gd_PT1pde = pmap->pm_pdirpte;
380         madvise(gd->gd_PT1map, SEG_SIZE, MADV_INVAL);
381         return(gd->gd_PT1map);
382 }
383
384 static vpte_t *
385 get_ptbase2(struct pmap *pmap)
386 {
387         struct mdglobaldata *gd = mdcpu;
388
389         if (pmap == &kernel_pmap) {
390                 return(KernelPTA);
391         } else if (pmap->pm_pdir == gd->gd_PT2pdir) {
392                 return(gd->gd_PT2map);
393         }
394         KKASSERT(gd->mi.gd_intr_nesting_level == 0 &&
395                  (gd->mi.gd_curthread->td_flags & TDF_INTTHREAD) == 0);
396         gd->gd_PT2pdir = pmap->pm_pdir;
397         *gd->gd_PT2pde = pmap->pm_pdirpte;
398         madvise(gd->gd_PT2map, SEG_SIZE, MADV_INVAL);
399         return(gd->gd_PT2map);
400 }
401
402 /*
403  * Return a pointer to the page table entry for the specified va in the
404  * specified pmap.  NULL is returned if there is no valid page table page
405  * for the VA.
406  */
407 static __inline vpte_t *
408 pmap_pte(struct pmap *pmap, vm_offset_t va)
409 {
410         vpte_t *ptep;
411
412         ptep = &pmap->pm_pdir[va >> PAGE_SHIFT];
413         if (*ptep & VPTE_PS)
414                 return(ptep);
415         if (*ptep)
416                 return (get_ptbase(pmap) + (va >> PAGE_SHIFT));
417         return(NULL);
418 }
419
420
421 /*
422  * Enter a mapping into kernel_pmap.  Mappings created in this fashion
423  * are not managed.
424  */
425 void
426 pmap_kenter(vm_offset_t va, vm_paddr_t pa)
427 {
428         vpte_t *ptep;
429         vpte_t npte;
430 #ifdef SMP
431         pmap_inval_info info;
432 #endif
433
434         KKASSERT(va >= KvaStart && va < KvaEnd);
435         npte = (vpte_t)pa | VPTE_R | VPTE_W | VPTE_V;
436         ptep = KernelPTA + ((va - KvaStart) >> PAGE_SHIFT);
437         if (*ptep & VPTE_V) {
438 #ifdef SMP
439                 pmap_inval_init(&info);
440                 pmap_inval_add(&info, &kernel_pmap, va);
441 #endif
442                 *ptep = npte;
443 #ifdef SMP
444                 pmap_inval_flush(&info);
445 #else
446                 madvise((void *)va, PAGE_SIZE, MADV_INVAL);
447 #endif
448         } else {
449                 *ptep = npte;
450         }
451 }
452
453 void
454 pmap_kenter_sync(vm_offset_t va)
455 {
456         pmap_inval_info info;
457
458         pmap_inval_init(&info);
459         pmap_inval_add(&info, &kernel_pmap, va);
460         pmap_inval_flush(&info);
461 }
462
463 void
464 pmap_kenter_sync_quick(vm_offset_t va)
465 {
466         madvise((void *)va, PAGE_SIZE, MADV_INVAL);
467 }
468
469 /*
470  * Map a contiguous range of physical memory to a KVM
471  */
472 vm_offset_t
473 pmap_map(vm_offset_t virt, vm_paddr_t start, vm_paddr_t end, int prot)
474 {
475         while (start < end) {
476                 pmap_kenter(virt, start);
477                 virt += PAGE_SIZE;
478                 start += PAGE_SIZE;
479         }
480         return (virt);
481 }
482
483 vpte_t *
484 pmap_kpte(vm_offset_t va)
485 {
486         vpte_t *ptep;
487
488         KKASSERT(va >= KvaStart && va < KvaEnd);
489         ptep = KernelPTA + ((va - KvaStart) >> PAGE_SHIFT);
490         return(ptep);
491 }
492
493 /*
494  * Enter a mapping into kernel_pmap without any SMP interactions.
495  * 
496  * Mappings created in this fashion are not managed.
497  */
498 void
499 pmap_kenter_quick(vm_offset_t va, vm_paddr_t pa)
500 {
501         vpte_t *ptep;
502         vpte_t npte;
503
504         KKASSERT(va >= KvaStart && va < KvaEnd);
505
506         npte = (vpte_t)pa | VPTE_R | VPTE_W | VPTE_V;
507         ptep = KernelPTA + ((va - KvaStart) >> PAGE_SHIFT);
508         if (*ptep & VPTE_V) {
509                 *ptep = npte;
510                 madvise((void *)va, PAGE_SIZE, MADV_INVAL);
511         } else {
512                 *ptep = npte;
513         }
514 }
515
516 /*
517  * Make a temporary mapping for a physical address.  This is only intended
518  * to be used for panic dumps.
519  */
520 void *
521 pmap_kenter_temporary(vm_paddr_t pa, int i)
522 {
523         pmap_kenter(crashdumpmap + (i * PAGE_SIZE), pa);
524         return ((void *)crashdumpmap);
525 }
526
527 /*
528  * Remove an unmanaged mapping created with pmap_kenter*().
529  */
530 void
531 pmap_kremove(vm_offset_t va)
532 {
533         vpte_t *ptep;
534 #ifdef SMP
535         pmap_inval_info info;
536 #endif
537
538         KKASSERT(va >= KvaStart && va < KvaEnd);
539
540         ptep = KernelPTA + ((va - KvaStart) >> PAGE_SHIFT);
541         if (*ptep & VPTE_V) {
542 #ifdef SMP
543                 pmap_inval_init(&info);
544                 pmap_inval_add(&info, &kernel_pmap, va);
545 #endif
546                 *ptep = 0;
547 #ifdef SMP
548                 pmap_inval_flush(&info);
549 #else
550                 madvise((void *)va, PAGE_SIZE, MADV_INVAL);
551 #endif
552         } else {
553                 *ptep = 0;
554         }
555
556 }
557
558 /*
559  * Remove an unmanaged mapping created with pmap_kenter*() without
560  * going through any SMP interactions.
561  */
562 void
563 pmap_kremove_quick(vm_offset_t va)
564 {
565         vpte_t *ptep;
566
567         KKASSERT(va >= KvaStart && va < KvaEnd);
568
569         ptep = KernelPTA + ((va - KvaStart) >> PAGE_SHIFT);
570         if (*ptep & VPTE_V) {
571                 *ptep = 0;
572                 madvise((void *)va, PAGE_SIZE, MADV_INVAL);
573         } else {
574                 *ptep = 0;
575         }
576 }
577
578 /*
579  * Extract the physical address from the kernel_pmap that is associated
580  * with the specified virtual address.
581  */
582 vm_paddr_t
583 pmap_kextract(vm_offset_t va)
584 {
585         vpte_t *ptep;
586         vm_paddr_t pa;
587
588         KKASSERT(va >= KvaStart && va < KvaEnd);
589
590         ptep = KernelPTA + ((va - KvaStart) >> PAGE_SHIFT);
591         pa = (vm_paddr_t)(*ptep & VPTE_FRAME) | (va & PAGE_MASK);
592         return(pa);
593 }
594
595 /*
596  * Map a set of unmanaged VM pages into KVM.
597  */
598 void
599 pmap_qenter(vm_offset_t va, struct vm_page **m, int count)
600 {
601         KKASSERT(va >= KvaStart && va + count * PAGE_SIZE < KvaEnd);
602         while (count) {
603                 vpte_t *ptep;
604
605                 ptep = KernelPTA + ((va - KvaStart) >> PAGE_SHIFT);
606                 if (*ptep & VPTE_V)
607                         madvise((void *)va, PAGE_SIZE, MADV_INVAL);
608                 *ptep = (vpte_t)(*m)->phys_addr | VPTE_R | VPTE_W | VPTE_V;
609                 --count;
610                 ++m;
611                 va += PAGE_SIZE;
612         }
613 #ifdef SMP
614         XXX
615         smp_invltlb();
616 #endif
617 }
618
619 /*
620  * Map a set of VM pages to kernel virtual memory.  If a mapping changes
621  * clear the supplied mask.  The caller handles any SMP interactions.
622  * The mask is used to provide the caller with hints on what SMP interactions
623  * might be needed.
624  */
625 void
626 pmap_qenter2(vm_offset_t va, struct vm_page **m, int count, cpumask_t *mask)
627 {
628         cpumask_t cmask = mycpu->gd_cpumask;
629
630         KKASSERT(va >= KvaStart && va + count * PAGE_SIZE < KvaEnd);
631         while (count) {
632                 vpte_t *ptep;
633                 vpte_t npte;
634
635                 ptep = KernelPTA + ((va - KvaStart) >> PAGE_SHIFT);
636                 npte = (vpte_t)(*m)->phys_addr | VPTE_R | VPTE_W | VPTE_V;
637                 if (*ptep != npte) {
638                         *mask = 0;
639                         *ptep = npte;
640                         madvise((void *)va, PAGE_SIZE, MADV_INVAL);
641                 } else if ((*mask & cmask) == 0) {
642                         madvise((void *)va, PAGE_SIZE, MADV_INVAL);
643                 }
644                 --count;
645                 ++m;
646                 va += PAGE_SIZE;
647         }
648         *mask |= cmask;
649 }
650
651 /*
652  * Undo the effects of pmap_qenter*().
653  */
654 void
655 pmap_qremove(vm_offset_t va, int count)
656 {
657         KKASSERT(va >= KvaStart && va + count * PAGE_SIZE < KvaEnd);
658         while (count) {
659                 vpte_t *ptep;
660
661                 ptep = KernelPTA + ((va - KvaStart) >> PAGE_SHIFT);
662                 if (*ptep & VPTE_V)
663                         madvise((void *)va, PAGE_SIZE, MADV_INVAL);
664                 *ptep = 0;
665                 --count;
666                 va += PAGE_SIZE;
667         }
668 #ifdef SMP
669         XXX
670         smp_invltlb();
671 #endif
672 }
673
674 /************************************************************************
675  *        Misc support glue called by machine independant code          *
676  ************************************************************************
677  *
678  * These routines are called by machine independant code to operate on
679  * certain machine-dependant aspects of processes, threads, and pmaps.
680  */
681
682 /*
683  * Initialize MD portions of the thread structure.
684  */
685 void
686 pmap_init_thread(thread_t td)
687 {
688         /* enforce pcb placement */
689         td->td_pcb = (struct pcb *)(td->td_kstack + td->td_kstack_size) - 1;
690         td->td_savefpu = &td->td_pcb->pcb_save;
691         td->td_sp = (char *)td->td_pcb - 16;
692 }
693
694 /*
695  * Initialize MD portions of a process structure. XXX this aint MD
696  */
697 void
698 pmap_init_proc(struct proc *p, struct thread *td)
699 {
700         p->p_addr = (void *)td->td_kstack;
701         p->p_thread = td;
702         td->td_proc = p;
703         td->td_lwp = &p->p_lwp;
704         td->td_switch = cpu_heavy_switch;
705 #ifdef SMP
706         KKASSERT(td->td_mpcount == 1);
707 #endif
708         bzero(p->p_addr, sizeof(*p->p_addr));
709 }
710
711 /*
712  * Destroy the UPAGES for a process that has exited and disassociate
713  * the process from its thread.
714  */
715 struct thread *
716 pmap_dispose_proc(struct proc *p)
717 {
718         struct thread *td;
719
720         KASSERT(p->p_lock == 0, ("attempt to dispose referenced proc! %p", p));
721
722         if ((td = p->p_thread) != NULL) {
723                 p->p_thread = NULL;
724                 td->td_proc = NULL;
725         }
726         p->p_addr = NULL;
727         return(td);
728 }
729
730 /*
731  * We pre-allocate all page table pages for kernel virtual memory so
732  * this routine will only be called if KVM has been exhausted.
733  */
734 void
735 pmap_growkernel(vm_offset_t size)
736 {
737         panic("KVM exhausted");
738 }
739
740 /*
741  * The modification bit is not tracked for any pages in this range. XXX
742  * such pages in this maps should always use pmap_k*() functions and not
743  * be managed anyhow.
744  */
745 static int
746 pmap_track_modified(vm_offset_t va)
747 {
748         if ((va < clean_sva) || (va >= clean_eva))
749                 return 1;
750         else
751                 return 0;
752 }
753
754 /************************************************************************
755  *          Procedures supporting managed page table pages              *
756  ************************************************************************
757  *
758  * These procedures are used to track managed page table pages.  These pages
759  * use the page table page's vm_page_t to track PTEs in the page.  The
760  * page table pages themselves are arranged in a VM object, pmap->pm_pteobj.
761  *
762  * This allows the system to throw away page table pages for user processes
763  * at will and reinstantiate them on demand.
764  */
765
766 /*
767  * This routine works like vm_page_lookup() but also blocks as long as the
768  * page is busy.  This routine does not busy the page it returns.
769  *
770  * Unless the caller is managing objects whos pages are in a known state,
771  * the call should be made with a critical section held so the page's object
772  * association remains valid on return.
773  */
774 static vm_page_t
775 pmap_page_lookup(vm_object_t object, vm_pindex_t pindex)
776 {
777         vm_page_t m;
778                          
779 retry:
780         m = vm_page_lookup(object, pindex);
781         if (m && vm_page_sleep_busy(m, FALSE, "pplookp"))
782                 goto retry;
783         return(m);
784 }
785
786 /*
787  * This routine unholds page table pages, and if the hold count
788  * drops to zero, then it decrements the wire count.
789  */
790 static int 
791 _pmap_unwire_pte_hold(pmap_t pmap, vm_page_t m, pmap_inval_info_t info) 
792 {
793         pmap_inval_flush(info);
794         while (vm_page_sleep_busy(m, FALSE, "pmuwpt"))
795                 ;
796
797         if (m->hold_count == 0) {
798                 /*
799                  * unmap the page table page
800                  */
801                 pmap_inval_add(info, pmap, -1);
802                 pmap->pm_pdir[m->pindex] = 0;
803                 --pmap->pm_stats.resident_count;
804
805                 if (pmap->pm_ptphint == m)
806                         pmap->pm_ptphint = NULL;
807
808                 /*
809                  * If the page is finally unwired, simply free it.
810                  */
811                 --m->wire_count;
812                 if (m->wire_count == 0) {
813                         vm_page_flash(m);
814                         vm_page_busy(m);
815                         vm_page_free_zero(m);
816                         --vmstats.v_wire_count;
817                 }
818                 return 1;
819         }
820         return 0;
821 }
822
823 static __inline int
824 pmap_unwire_pte_hold(pmap_t pmap, vm_page_t m, pmap_inval_info_t info)
825 {
826         vm_page_unhold(m);
827         if (m->hold_count == 0)
828                 return _pmap_unwire_pte_hold(pmap, m, info);
829         else
830                 return 0;
831 }
832
833 /*
834  * After removing a page table entry, this routine is used to
835  * conditionally free the page, and manage the hold/wire counts.
836  */
837 static int
838 pmap_unuse_pt(pmap_t pmap, vm_offset_t va, vm_page_t mpte,
839                 pmap_inval_info_t info)
840 {
841         unsigned ptepindex;
842
843         if (mpte == NULL) {
844                 /*
845                  * page table pages in the kernel_pmap are not managed.
846                  */
847                 if (pmap == &kernel_pmap)
848                         return(0);
849                 ptepindex = (va >> PDRSHIFT);
850                 if (pmap->pm_ptphint &&
851                         (pmap->pm_ptphint->pindex == ptepindex)) {
852                         mpte = pmap->pm_ptphint;
853                 } else {
854                         pmap_inval_flush(info);
855                         mpte = pmap_page_lookup( pmap->pm_pteobj, ptepindex);
856                         pmap->pm_ptphint = mpte;
857                 }
858         }
859         return pmap_unwire_pte_hold(pmap, mpte, info);
860 }
861
862 /*
863  * Attempt to release and free an vm_page in a pmap.  Returns 1 on success,
864  * 0 on failure (if the procedure had to sleep).
865  */
866 static int
867 pmap_release_free_page(struct pmap *pmap, vm_page_t p)
868 {
869         vpte_t *pde = pmap->pm_pdir;
870         /*
871          * This code optimizes the case of freeing non-busy
872          * page-table pages.  Those pages are zero now, and
873          * might as well be placed directly into the zero queue.
874          */
875         if (vm_page_sleep_busy(p, FALSE, "pmaprl"))
876                 return 0;
877
878         vm_page_busy(p);
879
880         /*
881          * Remove the page table page from the processes address space.
882          */
883         pde[p->pindex] = 0;
884         pmap->pm_stats.resident_count--;
885
886         if (p->hold_count)  {
887                 panic("pmap_release: freeing held page table page");
888         }
889         /*
890          * Page directory pages need to have the kernel stuff cleared, so
891          * they can go into the zero queue also.
892          *
893          * In virtual kernels there is no 'kernel stuff'.  For the moment
894          * I just make sure the whole thing has been zero'd even though
895          * it should already be completely zero'd.
896          */
897         if (p->pindex == pmap->pm_pdindex) {
898                 bzero(pde, VPTE_PAGETABLE_SIZE);
899                 pmap_kremove((vm_offset_t)pmap->pm_pdir);
900         }
901
902         /*
903          * Clear the matching hint
904          */
905         if (pmap->pm_ptphint && (pmap->pm_ptphint->pindex == p->pindex))
906                 pmap->pm_ptphint = NULL;
907
908         /*
909          * And throw the page away.  The page is completely zero'd out so
910          * optimize the free call.
911          */
912         p->wire_count--;
913         vmstats.v_wire_count--;
914         vm_page_free_zero(p);
915         return 1;
916 }
917
918 /*
919  * This routine is called if the page table page is not mapped in the page
920  * table directory.
921  *
922  * The routine is broken up into two parts for readability.
923  */
924 static vm_page_t
925 _pmap_allocpte(pmap_t pmap, unsigned ptepindex)
926 {
927         vm_paddr_t ptepa;
928         vm_page_t m;
929
930         /*
931          * Find or fabricate a new pagetable page
932          */
933         m = vm_page_grab(pmap->pm_pteobj, ptepindex,
934                          VM_ALLOC_NORMAL | VM_ALLOC_ZERO | VM_ALLOC_RETRY);
935
936         KASSERT(m->queue == PQ_NONE,
937                 ("_pmap_allocpte: %p->queue != PQ_NONE", m));
938
939         if (m->wire_count == 0)
940                 vmstats.v_wire_count++;
941         m->wire_count++;
942
943         /*
944          * Increment the hold count for the page table page
945          * (denoting a new mapping.)
946          */
947         m->hold_count++;
948
949         /*
950          * Map the pagetable page into the process address space, if
951          * it isn't already there.
952          */
953         pmap->pm_stats.resident_count++;
954
955         ptepa = VM_PAGE_TO_PHYS(m);
956         pmap->pm_pdir[ptepindex] = (vpte_t)ptepa | VPTE_R | VPTE_W | VPTE_V |
957                                    VPTE_A | VPTE_M;
958
959         /*
960          * We are likely about to access this page table page, so set the
961          * page table hint to reduce overhead.
962          */
963         pmap->pm_ptphint = m;
964
965         /*
966          * Try to use the new mapping, but if we cannot, then
967          * do it with the routine that maps the page explicitly.
968          */
969         if ((m->flags & PG_ZERO) == 0)
970                 pmap_zero_page(ptepa);
971
972         m->valid = VM_PAGE_BITS_ALL;
973         vm_page_flag_clear(m, PG_ZERO);
974         vm_page_flag_set(m, PG_MAPPED);
975         vm_page_wakeup(m);
976
977         return (m);
978 }
979
980 /*
981  * Determine the page table page required to access the VA in the pmap
982  * and allocate it if necessary.  Return a held vm_page_t for the page.
983  *
984  * Only used with user pmaps.
985  */
986 static vm_page_t
987 pmap_allocpte(pmap_t pmap, vm_offset_t va)
988 {
989         unsigned ptepindex;
990         vm_offset_t ptepa;
991         vm_page_t m;
992
993         /*
994          * Calculate pagetable page index
995          */
996         ptepindex = va >> PDRSHIFT;
997
998         /*
999          * Get the page directory entry
1000          */
1001         ptepa = (vm_offset_t) pmap->pm_pdir[ptepindex];
1002
1003         /*
1004          * This supports switching from a 4MB page to a
1005          * normal 4K page.
1006          */
1007         if (ptepa & VPTE_PS) {
1008                 pmap->pm_pdir[ptepindex] = 0;
1009                 ptepa = 0;
1010                 cpu_invltlb();
1011                 smp_invltlb();
1012         }
1013
1014         /*
1015          * If the page table page is mapped, we just increment the
1016          * hold count, and activate it.
1017          */
1018         if (ptepa) {
1019                 /*
1020                  * In order to get the page table page, try the
1021                  * hint first.
1022                  */
1023                 if (pmap->pm_ptphint &&
1024                         (pmap->pm_ptphint->pindex == ptepindex)) {
1025                         m = pmap->pm_ptphint;
1026                 } else {
1027                         m = pmap_page_lookup( pmap->pm_pteobj, ptepindex);
1028                         pmap->pm_ptphint = m;
1029                 }
1030                 m->hold_count++;
1031                 return m;
1032         }
1033         /*
1034          * Here if the pte page isn't mapped, or if it has been deallocated.
1035          */
1036         return _pmap_allocpte(pmap, ptepindex);
1037 }
1038
1039 /************************************************************************
1040  *                      Managed pages in pmaps                          *
1041  ************************************************************************
1042  *
1043  * All pages entered into user pmaps and some pages entered into the kernel
1044  * pmap are managed, meaning that pmap_protect() and other related management
1045  * functions work on these pages.
1046  */
1047
1048 /*
1049  * free the pv_entry back to the free list.  This function may be
1050  * called from an interrupt.
1051  */
1052 static __inline void
1053 free_pv_entry(pv_entry_t pv)
1054 {
1055         pv_entry_count--;
1056         zfree(&pvzone, pv);
1057 }
1058
1059 /*
1060  * get a new pv_entry, allocating a block from the system
1061  * when needed.  This function may be called from an interrupt.
1062  */
1063 static pv_entry_t
1064 get_pv_entry(void)
1065 {
1066         pv_entry_count++;
1067         if (pv_entry_high_water &&
1068                 (pv_entry_count > pv_entry_high_water) &&
1069                 (pmap_pagedaemon_waken == 0)) {
1070                 pmap_pagedaemon_waken = 1;
1071                 wakeup (&vm_pages_needed);
1072         }
1073         return zalloc(&pvzone);
1074 }
1075
1076 /*
1077  * This routine is very drastic, but can save the system
1078  * in a pinch.
1079  */
1080 void
1081 pmap_collect(void)
1082 {
1083         int i;
1084         vm_page_t m;
1085         static int warningdone=0;
1086
1087         if (pmap_pagedaemon_waken == 0)
1088                 return;
1089
1090         if (warningdone < 5) {
1091                 kprintf("pmap_collect: collecting pv entries -- suggest increasing PMAP_SHPGPERPROC\n");
1092                 warningdone++;
1093         }
1094
1095         for(i = 0; i < vm_page_array_size; i++) {
1096                 m = &vm_page_array[i];
1097                 if (m->wire_count || m->hold_count || m->busy ||
1098                     (m->flags & PG_BUSY))
1099                         continue;
1100                 pmap_remove_all(m);
1101         }
1102         pmap_pagedaemon_waken = 0;
1103 }
1104         
1105 /*
1106  * If it is the first entry on the list, it is actually
1107  * in the header and we must copy the following entry up
1108  * to the header.  Otherwise we must search the list for
1109  * the entry.  In either case we free the now unused entry.
1110  */
1111 static int
1112 pmap_remove_entry(struct pmap *pmap, vm_page_t m, 
1113                   vm_offset_t va, pmap_inval_info_t info)
1114 {
1115         pv_entry_t pv;
1116         int rtval;
1117
1118         crit_enter();
1119         if (m->md.pv_list_count < pmap->pm_stats.resident_count) {
1120                 TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
1121                         if (pmap == pv->pv_pmap && va == pv->pv_va) 
1122                                 break;
1123                 }
1124         } else {
1125                 TAILQ_FOREACH(pv, &pmap->pm_pvlist, pv_plist) {
1126                         if (va == pv->pv_va) 
1127                                 break;
1128                 }
1129         }
1130
1131         /*
1132          * Note that pv_ptem is NULL if the page table page itself is not
1133          * managed, even if the page being removed IS managed.
1134          */
1135         rtval = 0;
1136         if (pv) {
1137                 rtval = pmap_unuse_pt(pmap, va, pv->pv_ptem, info);
1138                 TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
1139                 m->md.pv_list_count--;
1140                 if (TAILQ_FIRST(&m->md.pv_list) == NULL)
1141                         vm_page_flag_clear(m, PG_MAPPED | PG_WRITEABLE);
1142                 TAILQ_REMOVE(&pmap->pm_pvlist, pv, pv_plist);
1143                 free_pv_entry(pv);
1144         }
1145         crit_exit();
1146         return rtval;
1147 }
1148
1149 /*
1150  * Create a pv entry for page at pa for (pmap, va).  If the page table page
1151  * holding the VA is managed, mpte will be non-NULL.
1152  */
1153 static void
1154 pmap_insert_entry(pmap_t pmap, vm_offset_t va, vm_page_t mpte, vm_page_t m)
1155 {
1156         pv_entry_t pv;
1157
1158         crit_enter();
1159         pv = get_pv_entry();
1160         pv->pv_va = va;
1161         pv->pv_pmap = pmap;
1162         pv->pv_ptem = mpte;
1163
1164         TAILQ_INSERT_TAIL(&pmap->pm_pvlist, pv, pv_plist);
1165         TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list);
1166         m->md.pv_list_count++;
1167
1168         crit_exit();
1169 }
1170
1171 /*
1172  * pmap_remove_pte: do the things to unmap a page in a process
1173  */
1174 static int
1175 pmap_remove_pte(struct pmap *pmap, vpte_t *ptq, vm_offset_t va,
1176         pmap_inval_info_t info)
1177 {
1178         vpte_t oldpte;
1179         vm_page_t m;
1180
1181         pmap_inval_add(info, pmap, va);
1182         oldpte = loadandclear(ptq);
1183         if (oldpte & VPTE_W)
1184                 pmap->pm_stats.wired_count -= 1;
1185         /*
1186          * Machines that don't support invlpg, also don't support
1187          * VPTE_G.  XXX VPTE_G is disabled for SMP so don't worry about
1188          * the SMP case.
1189          */
1190         if (oldpte & VPTE_G)
1191                 madvise((void *)va, PAGE_SIZE, MADV_INVAL);
1192         pmap->pm_stats.resident_count -= 1;
1193         if (oldpte & PG_MANAGED) {
1194                 m = PHYS_TO_VM_PAGE(oldpte);
1195                 if (oldpte & VPTE_M) {
1196 #if defined(PMAP_DIAGNOSTIC)
1197                         if (pmap_nw_modified((pt_entry_t) oldpte)) {
1198                                 kprintf(
1199         "pmap_remove: modified page not writable: va: 0x%x, pte: 0x%x\n",
1200                                     va, oldpte);
1201                         }
1202 #endif
1203                         if (pmap_track_modified(va))
1204                                 vm_page_dirty(m);
1205                 }
1206                 if (oldpte & VPTE_A)
1207                         vm_page_flag_set(m, PG_REFERENCED);
1208                 return pmap_remove_entry(pmap, m, va, info);
1209         } else {
1210                 return pmap_unuse_pt(pmap, va, NULL, info);
1211         }
1212
1213         return 0;
1214 }
1215
1216 /*
1217  * pmap_remove_page:
1218  *
1219  *      Remove a single page from a process address space.
1220  *
1221  *      This function may not be called from an interrupt if the pmap is
1222  *      not kernel_pmap.
1223  */
1224 static void
1225 pmap_remove_page(struct pmap *pmap, vm_offset_t va, pmap_inval_info_t info)
1226 {
1227         vpte_t *ptq;
1228
1229         /*
1230          * if there is no pte for this address, just skip it!!!  Otherwise
1231          * get a local va for mappings for this pmap and remove the entry.
1232          */
1233         if (*pmap_pde(pmap, va) != 0) {
1234                 ptq = get_ptbase(pmap) + (va >> PAGE_SHIFT);
1235                 if (*ptq) {
1236                         pmap_remove_pte(pmap, ptq, va, info);
1237                 }
1238         }
1239 }
1240
1241 /*
1242  * pmap_remove:
1243  *
1244  *      Remove the given range of addresses from the specified map.
1245  *
1246  *      It is assumed that the start and end are properly
1247  *      rounded to the page size.
1248  *
1249  *      This function may not be called from an interrupt if the pmap is
1250  *      not kernel_pmap.
1251  */
1252 void
1253 pmap_remove(struct pmap *pmap, vm_offset_t sva, vm_offset_t eva)
1254 {
1255         vpte_t *ptbase;
1256         vm_offset_t pdnxt;
1257         vm_offset_t ptpaddr;
1258         vm_offset_t sindex, eindex;
1259         struct pmap_inval_info info;
1260
1261         if (pmap == NULL)
1262                 return;
1263
1264         if (pmap->pm_stats.resident_count == 0)
1265                 return;
1266
1267         pmap_inval_init(&info);
1268
1269         /*
1270          * special handling of removing one page.  a very
1271          * common operation and easy to short circuit some
1272          * code.
1273          */
1274         if (((sva + PAGE_SIZE) == eva) && 
1275                 ((pmap->pm_pdir[(sva >> PDRSHIFT)] & VPTE_PS) == 0)) {
1276                 pmap_remove_page(pmap, sva, &info);
1277                 pmap_inval_flush(&info);
1278                 return;
1279         }
1280
1281         /*
1282          * Get a local virtual address for the mappings that are being
1283          * worked with.
1284          */
1285         ptbase = get_ptbase(pmap);
1286
1287         sindex = (sva >> PAGE_SHIFT);
1288         eindex = (eva >> PAGE_SHIFT);
1289
1290         for (; sindex < eindex; sindex = pdnxt) {
1291                 vpte_t pdirindex;
1292
1293                 /*
1294                  * Calculate index for next page table.
1295                  */
1296                 pdnxt = ((sindex + NPTEPG) & ~(NPTEPG - 1));
1297                 if (pmap->pm_stats.resident_count == 0)
1298                         break;
1299
1300                 pdirindex = sindex / NPDEPG;
1301                 if (((ptpaddr = pmap->pm_pdir[pdirindex]) & VPTE_PS) != 0) {
1302                         pmap_inval_add(&info, pmap, -1);
1303                         pmap->pm_pdir[pdirindex] = 0;
1304                         pmap->pm_stats.resident_count -= NBPDR / PAGE_SIZE;
1305                         continue;
1306                 }
1307
1308                 /*
1309                  * Weed out invalid mappings. Note: we assume that the page
1310                  * directory table is always allocated, and in kernel virtual.
1311                  */
1312                 if (ptpaddr == 0)
1313                         continue;
1314
1315                 /*
1316                  * Limit our scan to either the end of the va represented
1317                  * by the current page table page, or to the end of the
1318                  * range being removed.
1319                  */
1320                 if (pdnxt > eindex) {
1321                         pdnxt = eindex;
1322                 }
1323
1324                 for (; sindex != pdnxt; sindex++) {
1325                         vm_offset_t va;
1326                         if (ptbase[sindex] == 0)
1327                                 continue;
1328                         va = i386_ptob(sindex);
1329                         if (pmap_remove_pte(pmap, ptbase + sindex, va, &info))
1330                                 break;
1331                 }
1332         }
1333         pmap_inval_flush(&info);
1334 }
1335
1336 /*
1337  * pmap_remove_all:
1338  *
1339  * Removes this physical page from all physical maps in which it resides.
1340  * Reflects back modify bits to the pager.
1341  *
1342  * This routine may not be called from an interrupt.
1343  */
1344 static void
1345 pmap_remove_all(vm_page_t m)
1346 {
1347         struct pmap_inval_info info;
1348         vpte_t *pte, tpte;
1349         pv_entry_t pv;
1350
1351 #if defined(PMAP_DIAGNOSTIC)
1352         /*
1353          * XXX this makes pmap_page_protect(NONE) illegal for non-managed
1354          * pages!
1355          */
1356         if (!pmap_initialized || (m->flags & PG_FICTITIOUS)) {
1357                 panic("pmap_page_protect: illegal for unmanaged page, va: 0x%08llx", (long long)VM_PAGE_TO_PHYS(m));
1358         }
1359 #endif
1360
1361         pmap_inval_init(&info);
1362         crit_enter();
1363         while ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) {
1364                 pv->pv_pmap->pm_stats.resident_count--;
1365
1366                 pte = pmap_pte(pv->pv_pmap, pv->pv_va);
1367                 pmap_inval_add(&info, pv->pv_pmap, pv->pv_va);
1368
1369                 tpte = loadandclear(pte);
1370                 if (tpte & VPTE_W)
1371                         pv->pv_pmap->pm_stats.wired_count--;
1372
1373                 if (tpte & VPTE_A)
1374                         vm_page_flag_set(m, PG_REFERENCED);
1375
1376                 /*
1377                  * Update the vm_page_t clean and reference bits.
1378                  */
1379                 if (tpte & VPTE_M) {
1380 #if defined(PMAP_DIAGNOSTIC)
1381                         if (pmap_nw_modified((pt_entry_t) tpte)) {
1382                                 kprintf(
1383         "pmap_remove_all: modified page not writable: va: 0x%x, pte: 0x%x\n",
1384                                     pv->pv_va, tpte);
1385                         }
1386 #endif
1387                         if (pmap_track_modified(pv->pv_va))
1388                                 vm_page_dirty(m);
1389                 }
1390                 TAILQ_REMOVE(&pv->pv_pmap->pm_pvlist, pv, pv_plist);
1391                 TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
1392                 m->md.pv_list_count--;
1393                 pmap_unuse_pt(pv->pv_pmap, pv->pv_va, pv->pv_ptem, &info);
1394                 free_pv_entry(pv);
1395         }
1396
1397         vm_page_flag_clear(m, PG_MAPPED | PG_WRITEABLE);
1398         crit_exit();
1399         pmap_inval_flush(&info);
1400 }
1401
1402 /*
1403  * pmap_protect:
1404  *
1405  *      Set the physical protection on the specified range of this map
1406  *      as requested.
1407  *
1408  *      This function may not be called from an interrupt if the map is
1409  *      not the kernel_pmap.
1410  */
1411 void
1412 pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
1413 {
1414         vpte_t *ptbase;
1415         vm_offset_t pdnxt, ptpaddr;
1416         vm_pindex_t sindex, eindex;
1417         pmap_inval_info info;
1418
1419         if (pmap == NULL)
1420                 return;
1421
1422         if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
1423                 pmap_remove(pmap, sva, eva);
1424                 return;
1425         }
1426
1427         if (prot & VM_PROT_WRITE)
1428                 return;
1429
1430         pmap_inval_init(&info);
1431
1432         ptbase = get_ptbase(pmap);
1433
1434         sindex = (sva >> PAGE_SHIFT);
1435         eindex = (eva >> PAGE_SHIFT);
1436
1437         for (; sindex < eindex; sindex = pdnxt) {
1438
1439                 unsigned pdirindex;
1440
1441                 pdnxt = ((sindex + NPTEPG) & ~(NPTEPG - 1));
1442
1443                 pdirindex = sindex / NPDEPG;
1444                 if (((ptpaddr = pmap->pm_pdir[pdirindex]) & VPTE_PS) != 0) {
1445                         pmap_inval_add(&info, pmap, -1);
1446                         pmap->pm_pdir[pdirindex] &= ~(VPTE_M|VPTE_W);
1447                         pmap->pm_stats.resident_count -= NBPDR / PAGE_SIZE;
1448                         continue;
1449                 }
1450
1451                 /*
1452                  * Weed out invalid mappings. Note: we assume that the page
1453                  * directory table is always allocated, and in kernel virtual.
1454                  */
1455                 if (ptpaddr == 0)
1456                         continue;
1457
1458                 if (pdnxt > eindex) {
1459                         pdnxt = eindex;
1460                 }
1461
1462                 for (; sindex != pdnxt; sindex++) {
1463
1464                         unsigned pbits;
1465                         vm_page_t m;
1466
1467                         /* XXX this isn't optimal */
1468                         pmap_inval_add(&info, pmap, i386_ptob(sindex));
1469                         pbits = ptbase[sindex];
1470
1471                         if (pbits & PG_MANAGED) {
1472                                 m = NULL;
1473                                 if (pbits & VPTE_A) {
1474                                         m = PHYS_TO_VM_PAGE(pbits);
1475                                         vm_page_flag_set(m, PG_REFERENCED);
1476                                         pbits &= ~VPTE_A;
1477                                 }
1478                                 if (pbits & VPTE_M) {
1479                                         if (pmap_track_modified(i386_ptob(sindex))) {
1480                                                 if (m == NULL)
1481                                                         m = PHYS_TO_VM_PAGE(pbits);
1482                                                 vm_page_dirty(m);
1483                                                 pbits &= ~VPTE_M;
1484                                         }
1485                                 }
1486                         }
1487
1488                         pbits &= ~VPTE_W;
1489
1490                         if (pbits != ptbase[sindex]) {
1491                                 ptbase[sindex] = pbits;
1492                         }
1493                 }
1494         }
1495         pmap_inval_flush(&info);
1496 }
1497
1498 /*
1499  * Enter a managed page into a pmap.  If the page is not wired related pmap
1500  * data can be destroyed at any time for later demand-operation.
1501  *
1502  * Insert the vm_page (m) at virtual address (v) in (pmap), with the
1503  * specified protection, and wire the mapping if requested.
1504  *
1505  * NOTE: This routine may not lazy-evaluate or lose information.  The
1506  * page must actually be inserted into the given map NOW.
1507  *
1508  * NOTE: When entering a page at a KVA address, the pmap must be the
1509  * kernel_pmap.
1510  */
1511 void
1512 pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
1513            boolean_t wired)
1514 {
1515         vm_paddr_t pa;
1516         vpte_t *pte;
1517         vm_paddr_t opa;
1518         vm_offset_t origpte, newpte;
1519         vm_page_t mpte;
1520         pmap_inval_info info;
1521
1522         if (pmap == NULL)
1523                 return;
1524
1525         va &= VPTE_FRAME;
1526
1527         /*
1528          * Get the page table page.   The kernel_pmap's page table pages
1529          * are preallocated and have no associated vm_page_t.
1530          */
1531         if (pmap == &kernel_pmap)
1532                 mpte = NULL;
1533         else
1534                 mpte = pmap_allocpte(pmap, va);
1535
1536         pmap_inval_init(&info);
1537         pte = pmap_pte(pmap, va);
1538
1539         /*
1540          * Page Directory table entry not valid, we need a new PT page
1541          * and pmap_allocpte() didn't give us one.  Oops!
1542          */
1543         if (pte == NULL) {
1544                 panic("pmap_enter: invalid page directory pmap=%p, va=0x%p\n",
1545                       pmap, (void *)va);
1546         }
1547
1548         pa = VM_PAGE_TO_PHYS(m) & VPTE_FRAME;
1549         pmap_inval_add(&info, pmap, va); /* XXX non-optimal */
1550         origpte = *pte;
1551         opa = origpte & VPTE_FRAME;
1552
1553         if (origpte & VPTE_PS)
1554                 panic("pmap_enter: attempted pmap_enter on 4MB page");
1555
1556         /*
1557          * Mapping has not changed, must be protection or wiring change.
1558          */
1559         if (origpte && (opa == pa)) {
1560                 /*
1561                  * Wiring change, just update stats. We don't worry about
1562                  * wiring PT pages as they remain resident as long as there
1563                  * are valid mappings in them. Hence, if a user page is wired,
1564                  * the PT page will be also.
1565                  */
1566                 if (wired && ((origpte & VPTE_W) == 0))
1567                         pmap->pm_stats.wired_count++;
1568                 else if (!wired && (origpte & VPTE_W))
1569                         pmap->pm_stats.wired_count--;
1570
1571 #if defined(PMAP_DIAGNOSTIC)
1572                 if (pmap_nw_modified((pt_entry_t) origpte)) {
1573                         kprintf(
1574         "pmap_enter: modified page not writable: va: 0x%x, pte: 0x%x\n",
1575                             va, origpte);
1576                 }
1577 #endif
1578
1579                 /*
1580                  * Remove the extra pte reference.  Note that we cannot
1581                  * optimize the RO->RW case because we have adjusted the
1582                  * wiring count above and may need to adjust the wiring
1583                  * bits below.
1584                  */
1585                 if (mpte)
1586                         mpte->hold_count--;
1587
1588                 /*
1589                  * We might be turning off write access to the page,
1590                  * so we go ahead and sense modify status.
1591                  */
1592                 if (origpte & PG_MANAGED) {
1593                         if ((origpte & VPTE_M) && pmap_track_modified(va)) {
1594                                 vm_page_t om;
1595                                 om = PHYS_TO_VM_PAGE(opa);
1596                                 vm_page_dirty(om);
1597                         }
1598                         pa |= PG_MANAGED;
1599                 }
1600                 goto validate;
1601         } 
1602         /*
1603          * Mapping has changed, invalidate old range and fall through to
1604          * handle validating new mapping.
1605          */
1606         if (opa) {
1607                 int err;
1608                 err = pmap_remove_pte(pmap, pte, va, &info);
1609                 if (err)
1610                         panic("pmap_enter: pte vanished, va: 0x%x", va);
1611         }
1612
1613         /*
1614          * Enter on the PV list if part of our managed memory. Note that we
1615          * raise IPL while manipulating pv_table since pmap_enter can be
1616          * called at interrupt time.
1617          */
1618         if (pmap_initialized && 
1619             (m->flags & (PG_FICTITIOUS|PG_UNMANAGED)) == 0) {
1620                 pmap_insert_entry(pmap, va, mpte, m);
1621                 pa |= PG_MANAGED;
1622         }
1623
1624         /*
1625          * Increment counters
1626          */
1627         pmap->pm_stats.resident_count++;
1628         if (wired)
1629                 pmap->pm_stats.wired_count++;
1630
1631 validate:
1632         /*
1633          * Now validate mapping with desired protection/wiring.
1634          */
1635         newpte = (vm_offset_t) (pa | pte_prot(pmap, prot) | VPTE_V);
1636
1637         if (wired)
1638                 newpte |= VPTE_W;
1639         newpte |= VPTE_U;
1640
1641         /*
1642          * if the mapping or permission bits are different, we need
1643          * to update the pte.
1644          */
1645         if ((origpte & ~(VPTE_M|VPTE_A)) != newpte) {
1646                 *pte = newpte | VPTE_A;
1647         }
1648         pmap_inval_flush(&info);
1649 }
1650
1651 /*
1652  * This is a quick version of pmap_enter().  It is used only under the 
1653  * following conditions:
1654  *
1655  * (1) The pmap is not the kernel_pmap
1656  * (2) The page is not to be wired into the map
1657  * (3) The page is to mapped read-only in the pmap (initially that is)
1658  * (4) The calling procedure is responsible for flushing the TLB
1659  * (5) The page is always managed
1660  * (6) There is no prior mapping at the VA
1661  */
1662
1663 static vm_page_t
1664 pmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_page_t mpte)
1665 {
1666         vpte_t *pte;
1667         vm_paddr_t pa;
1668         pmap_inval_info info;
1669
1670         KKASSERT(pmap != &kernel_pmap);
1671         pmap_inval_init(&info);
1672
1673         KKASSERT(va >= VM_MIN_USER_ADDRESS && va < VM_MAX_USER_ADDRESS);
1674
1675         /*
1676          * Instantiate the page table page if required
1677          */
1678         unsigned ptepindex;
1679         vm_offset_t ptepa;
1680
1681         /*
1682          * Calculate pagetable page index
1683          */
1684         ptepindex = va >> PDRSHIFT;
1685         if (mpte && (mpte->pindex == ptepindex)) {
1686                 mpte->hold_count++;
1687         } else {
1688 retry:
1689                 /*
1690                  * Get the page directory entry
1691                  */
1692                 ptepa = (vm_offset_t) pmap->pm_pdir[ptepindex];
1693
1694                 /*
1695                  * If the page table page is mapped, we just increment
1696                  * the hold count, and activate it.
1697                  */
1698                 if (ptepa) {
1699                         if (ptepa & VPTE_PS)
1700                                 panic("pmap_enter_quick: unexpected mapping into 4MB page");
1701                         if (pmap->pm_ptphint &&
1702                                 (pmap->pm_ptphint->pindex == ptepindex)) {
1703                                 mpte = pmap->pm_ptphint;
1704                         } else {
1705                                 mpte = pmap_page_lookup( pmap->pm_pteobj, ptepindex);
1706                                 pmap->pm_ptphint = mpte;
1707                         }
1708                         if (mpte == NULL)
1709                                 goto retry;
1710                         mpte->hold_count++;
1711                 } else {
1712                         mpte = _pmap_allocpte(pmap, ptepindex);
1713                 }
1714         }
1715
1716         /*
1717          * Ok, now that the page table page has been validated, get the pte.
1718          * If the pte is already mapped undo mpte's hold_count and
1719          * just return.
1720          */
1721         pte = pmap_pte(pmap, va);
1722         if (*pte) {
1723                 if (mpte)
1724                         pmap_unwire_pte_hold(pmap, mpte, &info);
1725                 return 0;
1726         }
1727
1728         /*
1729          * Enter on the PV list if part of our managed memory. Note that we
1730          * raise IPL while manipulating pv_table since pmap_enter can be
1731          * called at interrupt time.
1732          */
1733         if ((m->flags & (PG_FICTITIOUS|PG_UNMANAGED)) == 0)
1734                 pmap_insert_entry(pmap, va, mpte, m);
1735
1736         /*
1737          * Increment counters
1738          */
1739         pmap->pm_stats.resident_count++;
1740
1741         pa = VM_PAGE_TO_PHYS(m);
1742
1743         /*
1744          * Now validate mapping with RO protection
1745          */
1746         if (m->flags & (PG_FICTITIOUS|PG_UNMANAGED))
1747                 *pte = pa | VPTE_V | VPTE_U;
1748         else
1749                 *pte = pa | VPTE_V | VPTE_U | VPTE_MANAGED;
1750
1751         return mpte;
1752 }
1753
1754 vm_paddr_t
1755 pmap_extract(pmap_t pmap, vm_offset_t va)
1756 {
1757         vm_paddr_t rtval;
1758         vpte_t pte;
1759
1760         if (pmap && (pte = pmap->pm_pdir[va >> SEG_SHIFT]) != 0) {
1761                 if (pte & VPTE_PS) {
1762                         rtval = pte & ~((vpte_t)(1 << SEG_SHIFT) - 1);
1763                         rtval |= va & SEG_MASK;
1764                 } else {
1765                         pte = *(get_ptbase(pmap) + (va >> PAGE_SHIFT));
1766                         rtval = (pte & VPTE_FRAME) | (va & PAGE_MASK);
1767                 }
1768                 return(rtval);
1769         }
1770         return(0);
1771 }
1772
1773 #define MAX_INIT_PT (96)
1774
1775 /*
1776  * This routine preloads the ptes for a given object into the specified pmap.
1777  * This eliminates the blast of soft faults on process startup and
1778  * immediately after an mmap.
1779  */
1780 static int pmap_object_init_pt_callback(vm_page_t p, void *data);
1781
1782 void
1783 pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_prot_t prot,
1784                     vm_object_t object, vm_pindex_t pindex, 
1785                     vm_size_t size, int limit)
1786 {
1787         struct rb_vm_page_scan_info info;
1788         int psize;
1789
1790         /*
1791          * We can't preinit if read access isn't set or there is no pmap
1792          * or object.
1793          */
1794         if ((prot & VM_PROT_READ) == 0 || pmap == NULL || object == NULL)
1795                 return;
1796
1797         /*
1798          * We can't preinit if the pmap is not the current pmap
1799          */
1800         if (curproc == NULL || pmap != vmspace_pmap(curproc->p_vmspace))
1801                 return;
1802
1803         psize = size >> PAGE_SHIFT;
1804
1805         if ((object->type != OBJT_VNODE) ||
1806                 ((limit & MAP_PREFAULT_PARTIAL) && (psize > MAX_INIT_PT) &&
1807                         (object->resident_page_count > MAX_INIT_PT))) {
1808                 return;
1809         }
1810
1811         if (psize + pindex > object->size) {
1812                 if (object->size < pindex)
1813                         return;           
1814                 psize = object->size - pindex;
1815         }
1816
1817         if (psize == 0)
1818                 return;
1819
1820         /*
1821          * Use a red-black scan to traverse the requested range and load
1822          * any valid pages found into the pmap.
1823          *
1824          * We cannot safely scan the object's memq unless we are in a
1825          * critical section since interrupts can remove pages from objects.
1826          */
1827         info.start_pindex = pindex;
1828         info.end_pindex = pindex + psize - 1;
1829         info.limit = limit;
1830         info.mpte = NULL;
1831         info.addr = addr;
1832         info.pmap = pmap;
1833
1834         crit_enter();
1835         vm_page_rb_tree_RB_SCAN(&object->rb_memq, rb_vm_page_scancmp,
1836                                 pmap_object_init_pt_callback, &info);
1837         crit_exit();
1838 }
1839
1840 static
1841 int
1842 pmap_object_init_pt_callback(vm_page_t p, void *data)
1843 {
1844         struct rb_vm_page_scan_info *info = data;
1845         vm_pindex_t rel_index;
1846         /*
1847          * don't allow an madvise to blow away our really
1848          * free pages allocating pv entries.
1849          */
1850         if ((info->limit & MAP_PREFAULT_MADVISE) &&
1851                 vmstats.v_free_count < vmstats.v_free_reserved) {
1852                     return(-1);
1853         }
1854         if (((p->valid & VM_PAGE_BITS_ALL) == VM_PAGE_BITS_ALL) &&
1855             (p->busy == 0) && (p->flags & (PG_BUSY | PG_FICTITIOUS)) == 0) {
1856                 if ((p->queue - p->pc) == PQ_CACHE)
1857                         vm_page_deactivate(p);
1858                 vm_page_busy(p);
1859                 rel_index = p->pindex - info->start_pindex;
1860                 info->mpte = pmap_enter_quick(info->pmap,
1861                                               info->addr + i386_ptob(rel_index),
1862                                               p, info->mpte);
1863                 vm_page_flag_set(p, PG_MAPPED);
1864                 vm_page_wakeup(p);
1865         }
1866         return(0);
1867 }
1868
1869 /*
1870  * pmap_prefault provides a quick way of clustering pagefaults into a
1871  * processes address space.  It is a "cousin" of pmap_object_init_pt, 
1872  * except it runs at page fault time instead of mmap time.
1873  */
1874 #define PFBAK 4
1875 #define PFFOR 4
1876 #define PAGEORDER_SIZE (PFBAK+PFFOR)
1877
1878 static int pmap_prefault_pageorder[] = {
1879         -PAGE_SIZE, PAGE_SIZE,
1880         -2 * PAGE_SIZE, 2 * PAGE_SIZE,
1881         -3 * PAGE_SIZE, 3 * PAGE_SIZE,
1882         -4 * PAGE_SIZE, 4 * PAGE_SIZE
1883 };
1884
1885 void
1886 pmap_prefault(pmap_t pmap, vm_offset_t addra, vm_map_entry_t entry)
1887 {
1888         int i;
1889         vm_offset_t starta;
1890         vm_offset_t addr;
1891         vm_pindex_t pindex;
1892         vm_page_t m, mpte;
1893         vm_object_t object;
1894
1895         /*
1896          * We do not currently prefault mappings that use virtual page
1897          * tables.  We do not prefault foreign pmaps.
1898          */
1899         if (entry->maptype == VM_MAPTYPE_VPAGETABLE)
1900                 return;
1901         if (curproc == NULL || (pmap != vmspace_pmap(curproc->p_vmspace)))
1902                 return;
1903
1904         object = entry->object.vm_object;
1905
1906         starta = addra - PFBAK * PAGE_SIZE;
1907         if (starta < entry->start)
1908                 starta = entry->start;
1909         else if (starta > addra)
1910                 starta = 0;
1911
1912         /*
1913          * critical section protection is required to maintain the 
1914          * page/object association, interrupts can free pages and remove 
1915          * them from their objects.
1916          */
1917         mpte = NULL;
1918         crit_enter();
1919         for (i = 0; i < PAGEORDER_SIZE; i++) {
1920                 vm_object_t lobject;
1921                 vpte_t *pte;
1922
1923                 addr = addra + pmap_prefault_pageorder[i];
1924                 if (addr > addra + (PFFOR * PAGE_SIZE))
1925                         addr = 0;
1926
1927                 if (addr < starta || addr >= entry->end)
1928                         continue;
1929
1930                 /*
1931                  * Make sure the page table page already exists
1932                  */
1933                 if ((*pmap_pde(pmap, addr)) == NULL) 
1934                         continue;
1935
1936                 /*
1937                  * Get a pointer to the pte and make sure that no valid page
1938                  * has been mapped.
1939                  */
1940                 pte = get_ptbase(pmap) + (addr >> PAGE_SHIFT);
1941                 if (*pte)
1942                         continue;
1943
1944                 /*
1945                  * Get the page to be mapped
1946                  */
1947                 pindex = ((addr - entry->start) + entry->offset) >> PAGE_SHIFT;
1948                 lobject = object;
1949
1950                 for (m = vm_page_lookup(lobject, pindex);
1951                     (!m && (lobject->type == OBJT_DEFAULT) &&
1952                      (lobject->backing_object));
1953                     lobject = lobject->backing_object
1954                 ) {
1955                         if (lobject->backing_object_offset & PAGE_MASK)
1956                                 break;
1957                         pindex += (lobject->backing_object_offset >> PAGE_SHIFT);
1958                         m = vm_page_lookup(lobject->backing_object, pindex);
1959                 }
1960
1961                 /*
1962                  * give-up when a page is not in memory
1963                  */
1964                 if (m == NULL)
1965                         break;
1966
1967                 /*
1968                  * If everything meets the requirements for pmap_enter_quick(),
1969                  * then enter the page.
1970                  */
1971
1972                 if (((m->valid & VM_PAGE_BITS_ALL) == VM_PAGE_BITS_ALL) &&
1973                         (m->busy == 0) &&
1974                     (m->flags & (PG_BUSY | PG_FICTITIOUS)) == 0) {
1975
1976                         if ((m->queue - m->pc) == PQ_CACHE) {
1977                                 vm_page_deactivate(m);
1978                         }
1979                         vm_page_busy(m);
1980                         mpte = pmap_enter_quick(pmap, addr, m, mpte);
1981                         vm_page_flag_set(m, PG_MAPPED);
1982                         vm_page_wakeup(m);
1983                 }
1984         }
1985         crit_exit();
1986 }
1987
1988 /*
1989  *      Routine:        pmap_change_wiring
1990  *      Function:       Change the wiring attribute for a map/virtual-address
1991  *                      pair.
1992  *      In/out conditions:
1993  *                      The mapping must already exist in the pmap.
1994  */
1995 void
1996 pmap_change_wiring(pmap_t pmap, vm_offset_t va, boolean_t wired)
1997 {
1998         vpte_t *pte;
1999
2000         if (pmap == NULL)
2001                 return;
2002
2003         pte = get_ptbase(pmap) + (va >> PAGE_SHIFT);
2004
2005         if (wired && (*pte & VPTE_W) == 0)
2006                 pmap->pm_stats.wired_count++;
2007         else if (!wired && (*pte & VPTE_W))
2008                 pmap->pm_stats.wired_count--;
2009
2010         /*
2011          * Wiring is not a hardware characteristic so there is no need to
2012          * invalidate TLB.  However, in an SMP environment we must use
2013          * a locked bus cycle to update the pte (if we are not using 
2014          * the pmap_inval_*() API that is)... it's ok to do this for simple
2015          * wiring changes.
2016          */
2017 #ifdef SMP
2018         if (wired)
2019                 atomic_set_int(pte, VPTE_W);
2020         else
2021                 atomic_clear_int(pte, VPTE_W);
2022 #else
2023         if (wired)
2024                 atomic_set_int_nonlocked(pte, VPTE_W);
2025         else
2026                 atomic_clear_int_nonlocked(pte, VPTE_W);
2027 #endif
2028 }
2029
2030 /*
2031  *      Copy the range specified by src_addr/len
2032  *      from the source map to the range dst_addr/len
2033  *      in the destination map.
2034  *
2035  *      This routine is only advisory and need not do anything.
2036  */
2037 void
2038 pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, 
2039         vm_size_t len, vm_offset_t src_addr)
2040 {
2041         pmap_inval_info info;
2042         vm_offset_t addr;
2043         vm_offset_t end_addr = src_addr + len;
2044         vm_offset_t pdnxt;
2045         vpte_t *src_frame;
2046         vpte_t *dst_frame;
2047         vm_page_t m;
2048
2049         if (dst_addr != src_addr)
2050                 return;
2051         if (dst_pmap->pm_pdir == NULL)
2052                 return;
2053         if (src_pmap->pm_pdir == NULL)
2054                 return;
2055
2056         src_frame = get_ptbase1(src_pmap);
2057         dst_frame = get_ptbase2(dst_pmap);
2058
2059         pmap_inval_init(&info);
2060         pmap_inval_add(&info, dst_pmap, -1);
2061         pmap_inval_add(&info, src_pmap, -1);
2062
2063         /*
2064          * critical section protection is required to maintain the page/object
2065          * association, interrupts can free pages and remove them from 
2066          * their objects.
2067          */
2068         crit_enter();
2069         for (addr = src_addr; addr < end_addr; addr = pdnxt) {
2070                 vpte_t *src_pte, *dst_pte;
2071                 vm_page_t dstmpte, srcmpte;
2072                 vm_offset_t srcptepaddr;
2073                 unsigned ptepindex;
2074
2075                 if (addr >= VM_MAX_USER_ADDRESS)
2076                         panic("pmap_copy: invalid to pmap_copy page tables\n");
2077
2078                 /*
2079                  * Don't let optional prefaulting of pages make us go
2080                  * way below the low water mark of free pages or way
2081                  * above high water mark of used pv entries.
2082                  */
2083                 if (vmstats.v_free_count < vmstats.v_free_reserved ||
2084                     pv_entry_count > pv_entry_high_water)
2085                         break;
2086                 
2087                 pdnxt = ((addr + PAGE_SIZE*NPTEPG) & ~(PAGE_SIZE*NPTEPG - 1));
2088                 ptepindex = addr >> PDRSHIFT;
2089
2090                 srcptepaddr = (vm_offset_t) src_pmap->pm_pdir[ptepindex];
2091                 if (srcptepaddr == 0)
2092                         continue;
2093                         
2094                 if (srcptepaddr & VPTE_PS) {
2095                         if (dst_pmap->pm_pdir[ptepindex] == 0) {
2096                                 dst_pmap->pm_pdir[ptepindex] = (pd_entry_t) srcptepaddr;
2097                                 dst_pmap->pm_stats.resident_count += NBPDR / PAGE_SIZE;
2098                         }
2099                         continue;
2100                 }
2101
2102                 srcmpte = vm_page_lookup(src_pmap->pm_pteobj, ptepindex);
2103                 if ((srcmpte == NULL) ||
2104                         (srcmpte->hold_count == 0) || (srcmpte->flags & PG_BUSY))
2105                         continue;
2106
2107                 if (pdnxt > end_addr)
2108                         pdnxt = end_addr;
2109
2110                 src_pte = src_frame + (addr >> PAGE_SHIFT);
2111                 dst_pte = dst_frame + (addr >> PAGE_SHIFT);
2112                 while (addr < pdnxt) {
2113                         vpte_t ptetemp;
2114                         ptetemp = *src_pte;
2115                         /*
2116                          * we only virtual copy managed pages
2117                          */
2118                         if ((ptetemp & PG_MANAGED) != 0) {
2119                                 /*
2120                                  * We have to check after allocpte for the
2121                                  * pte still being around...  allocpte can
2122                                  * block.
2123                                  */
2124                                 dstmpte = pmap_allocpte(dst_pmap, addr);
2125                                 if ((*dst_pte == 0) && (ptetemp = *src_pte)) {
2126                                         /*
2127                                          * Clear the modified and
2128                                          * accessed (referenced) bits
2129                                          * during the copy.
2130                                          */
2131                                         m = PHYS_TO_VM_PAGE(ptetemp);
2132                                         *dst_pte = ptetemp & ~(VPTE_M | VPTE_A);
2133                                         dst_pmap->pm_stats.resident_count++;
2134                                         pmap_insert_entry(dst_pmap, addr,
2135                                                 dstmpte, m);
2136                                 } else {
2137                                         pmap_unwire_pte_hold(dst_pmap, dstmpte, &info);
2138                                 }
2139                                 if (dstmpte->hold_count >= srcmpte->hold_count)
2140                                         break;
2141                         }
2142                         addr += PAGE_SIZE;
2143                         src_pte++;
2144                         dst_pte++;
2145                 }
2146         }
2147         crit_exit();
2148         pmap_inval_flush(&info);
2149 }       
2150
2151 /*
2152  * pmap_zero_page:
2153  *
2154  *      Zero the specified PA by mapping the page into KVM and clearing its
2155  *      contents.
2156  *
2157  *      This function may be called from an interrupt and no locking is
2158  *      required.
2159  */
2160 void
2161 pmap_zero_page(vm_paddr_t phys)
2162 {
2163         struct mdglobaldata *gd = mdcpu;
2164
2165         crit_enter();
2166         if (*(int *)gd->gd_CMAP3)
2167                 panic("pmap_zero_page: CMAP3 busy");
2168         *(int *)gd->gd_CMAP3 =
2169                     VPTE_V | VPTE_W | (phys & VPTE_FRAME) | VPTE_A | VPTE_M;
2170         madvise(gd->gd_CADDR3, PAGE_SIZE, MADV_INVAL);
2171
2172         bzero(gd->gd_CADDR3, PAGE_SIZE);
2173         *(int *) gd->gd_CMAP3 = 0;
2174         crit_exit();
2175 }
2176
2177 /*
2178  * pmap_page_assertzero:
2179  *
2180  *      Assert that a page is empty, panic if it isn't.
2181  */
2182 void
2183 pmap_page_assertzero(vm_paddr_t phys)
2184 {
2185         struct mdglobaldata *gd = mdcpu;
2186         int i;
2187
2188         crit_enter();
2189         if (*(int *)gd->gd_CMAP3)
2190                 panic("pmap_zero_page: CMAP3 busy");
2191         *(int *)gd->gd_CMAP3 =
2192                     VPTE_V | VPTE_R | VPTE_W | (phys & VPTE_FRAME) | VPTE_A | VPTE_M;
2193         madvise(gd->gd_CADDR3, PAGE_SIZE, MADV_INVAL);
2194         for (i = 0; i < PAGE_SIZE; i += 4) {
2195             if (*(int *)((char *)gd->gd_CADDR3 + i) != 0) {
2196                 panic("pmap_page_assertzero() @ %p not zero!\n",
2197                     (void *)gd->gd_CADDR3);
2198             }
2199         }
2200         *(int *) gd->gd_CMAP3 = 0;
2201         crit_exit();
2202 }
2203
2204 /*
2205  * pmap_zero_page:
2206  *
2207  *      Zero part of a physical page by mapping it into memory and clearing
2208  *      its contents with bzero.
2209  *
2210  *      off and size may not cover an area beyond a single hardware page.
2211  */
2212 void
2213 pmap_zero_page_area(vm_paddr_t phys, int off, int size)
2214 {
2215         struct mdglobaldata *gd = mdcpu;
2216
2217         crit_enter();
2218         if (*(int *) gd->gd_CMAP3)
2219                 panic("pmap_zero_page: CMAP3 busy");
2220         *(int *) gd->gd_CMAP3 = VPTE_V | VPTE_R | VPTE_W | (phys & VPTE_FRAME) | VPTE_A | VPTE_M;
2221         madvise(gd->gd_CADDR3, PAGE_SIZE, MADV_INVAL);
2222
2223         bzero((char *)gd->gd_CADDR3 + off, size);
2224         *(int *) gd->gd_CMAP3 = 0;
2225         crit_exit();
2226 }
2227
2228 /*
2229  * pmap_copy_page:
2230  *
2231  *      Copy the physical page from the source PA to the target PA.
2232  *      This function may be called from an interrupt.  No locking
2233  *      is required.
2234  */
2235 void
2236 pmap_copy_page(vm_paddr_t src, vm_paddr_t dst)
2237 {
2238         struct mdglobaldata *gd = mdcpu;
2239
2240         crit_enter();
2241         if (*(int *) gd->gd_CMAP1)
2242                 panic("pmap_copy_page: CMAP1 busy");
2243         if (*(int *) gd->gd_CMAP2)
2244                 panic("pmap_copy_page: CMAP2 busy");
2245
2246         *(int *) gd->gd_CMAP1 = VPTE_V | (src & PG_FRAME) | PG_A;
2247         *(int *) gd->gd_CMAP2 = VPTE_V | VPTE_R | VPTE_W | (dst & VPTE_FRAME) | VPTE_A | VPTE_M;
2248
2249         madvise(gd->gd_CADDR1, PAGE_SIZE, MADV_INVAL);
2250         madvise(gd->gd_CADDR2, PAGE_SIZE, MADV_INVAL);
2251
2252         bcopy(gd->gd_CADDR1, gd->gd_CADDR2, PAGE_SIZE);
2253
2254         *(int *) gd->gd_CMAP1 = 0;
2255         *(int *) gd->gd_CMAP2 = 0;
2256         crit_exit();
2257 }
2258
2259 /*
2260  * pmap_copy_page_frag:
2261  *
2262  *      Copy the physical page from the source PA to the target PA.
2263  *      This function may be called from an interrupt.  No locking
2264  *      is required.
2265  */
2266 void
2267 pmap_copy_page_frag(vm_paddr_t src, vm_paddr_t dst, size_t bytes)
2268 {
2269         struct mdglobaldata *gd = mdcpu;
2270
2271         crit_enter();
2272         if (*(int *) gd->gd_CMAP1)
2273                 panic("pmap_copy_page: CMAP1 busy");
2274         if (*(int *) gd->gd_CMAP2)
2275                 panic("pmap_copy_page: CMAP2 busy");
2276
2277         *(int *) gd->gd_CMAP1 = VPTE_V | (src & VPTE_FRAME) | VPTE_A;
2278         *(int *) gd->gd_CMAP2 = VPTE_V | VPTE_R | VPTE_W | (dst & VPTE_FRAME) | VPTE_A | VPTE_M;
2279
2280         madvise(gd->gd_CADDR1, PAGE_SIZE, MADV_INVAL);
2281         madvise(gd->gd_CADDR2, PAGE_SIZE, MADV_INVAL);
2282
2283         bcopy((char *)gd->gd_CADDR1 + (src & PAGE_MASK),
2284               (char *)gd->gd_CADDR2 + (dst & PAGE_MASK),
2285               bytes);
2286
2287         *(int *) gd->gd_CMAP1 = 0;
2288         *(int *) gd->gd_CMAP2 = 0;
2289         crit_exit();
2290 }
2291
2292 /*
2293  * Returns true if the pmap's pv is one of the first
2294  * 16 pvs linked to from this page.  This count may
2295  * be changed upwards or downwards in the future; it
2296  * is only necessary that true be returned for a small
2297  * subset of pmaps for proper page aging.
2298  */
2299 boolean_t
2300 pmap_page_exists_quick(pmap_t pmap, vm_page_t m)
2301 {
2302         pv_entry_t pv;
2303         int loops = 0;
2304
2305         if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
2306                 return FALSE;
2307
2308         crit_enter();
2309
2310         TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
2311                 if (pv->pv_pmap == pmap) {
2312                         crit_exit();
2313                         return TRUE;
2314                 }
2315                 loops++;
2316                 if (loops >= 16)
2317                         break;
2318         }
2319         crit_exit();
2320         return (FALSE);
2321 }
2322
2323 /*
2324  * Remove all pages from specified address space
2325  * this aids process exit speeds.  Also, this code
2326  * is special cased for current process only, but
2327  * can have the more generic (and slightly slower)
2328  * mode enabled.  This is much faster than pmap_remove
2329  * in the case of running down an entire address space.
2330  */
2331 void
2332 pmap_remove_pages(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
2333 {
2334         vpte_t *pte, tpte;
2335         pv_entry_t pv, npv;
2336         vm_page_t m;
2337         pmap_inval_info info;
2338         int iscurrentpmap;
2339
2340         if (curproc && pmap == vmspace_pmap(curproc->p_vmspace))
2341                 iscurrentpmap = 1;
2342         else
2343                 iscurrentpmap = 0;
2344
2345         pmap_inval_init(&info);
2346         crit_enter();
2347         for (pv = TAILQ_FIRST(&pmap->pm_pvlist); pv; pv = npv) {
2348                 if (pv->pv_va >= eva || pv->pv_va < sva) {
2349                         npv = TAILQ_NEXT(pv, pv_plist);
2350                         continue;
2351                 }
2352
2353                 pte = pmap_pte(pv->pv_pmap, pv->pv_va);
2354                 if (pmap->pm_active)
2355                         pmap_inval_add(&info, pv->pv_pmap, pv->pv_va);
2356                 tpte = *pte;
2357
2358                 /*
2359                  * We cannot remove wired pages from a process' mapping
2360                  * at this time
2361                  */
2362                 if (tpte & VPTE_W) {
2363                         npv = TAILQ_NEXT(pv, pv_plist);
2364                         continue;
2365                 }
2366                 *pte = 0;
2367
2368                 m = PHYS_TO_VM_PAGE(tpte);
2369
2370                 KASSERT(m < &vm_page_array[vm_page_array_size],
2371                         ("pmap_remove_pages: bad tpte %x", tpte));
2372
2373                 pv->pv_pmap->pm_stats.resident_count--;
2374
2375                 /*
2376                  * Update the vm_page_t clean and reference bits.
2377                  */
2378                 if (tpte & VPTE_M) {
2379                         vm_page_dirty(m);
2380                 }
2381
2382
2383                 npv = TAILQ_NEXT(pv, pv_plist);
2384                 TAILQ_REMOVE(&pv->pv_pmap->pm_pvlist, pv, pv_plist);
2385
2386                 m->md.pv_list_count--;
2387                 TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
2388                 if (TAILQ_FIRST(&m->md.pv_list) == NULL) {
2389                         vm_page_flag_clear(m, PG_MAPPED | PG_WRITEABLE);
2390                 }
2391
2392                 pmap_unuse_pt(pv->pv_pmap, pv->pv_va, pv->pv_ptem, &info);
2393                 free_pv_entry(pv);
2394         }
2395         pmap_inval_flush(&info);
2396         crit_exit();
2397 }
2398
2399 /*
2400  * pmap_testbit tests bits in pte's
2401  * note that the testbit/changebit routines are inline,
2402  * and a lot of things compile-time evaluate.
2403  */
2404 static boolean_t
2405 pmap_testbit(vm_page_t m, int bit)
2406 {
2407         pv_entry_t pv;
2408         vpte_t *pte;
2409
2410         if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
2411                 return FALSE;
2412
2413         if (TAILQ_FIRST(&m->md.pv_list) == NULL)
2414                 return FALSE;
2415
2416         crit_enter();
2417
2418         TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
2419                 /*
2420                  * if the bit being tested is the modified bit, then
2421                  * mark clean_map and ptes as never
2422                  * modified.
2423                  */
2424                 if (bit & (VPTE_A|VPTE_M)) {
2425                         if (!pmap_track_modified(pv->pv_va))
2426                                 continue;
2427                 }
2428
2429 #if defined(PMAP_DIAGNOSTIC)
2430                 if (!pv->pv_pmap) {
2431                         kprintf("Null pmap (tb) at va: 0x%x\n", pv->pv_va);
2432                         continue;
2433                 }
2434 #endif
2435                 pte = pmap_pte(pv->pv_pmap, pv->pv_va);
2436                 if (*pte & bit) {
2437                         crit_exit();
2438                         return TRUE;
2439                 }
2440         }
2441         crit_exit();
2442         return (FALSE);
2443 }
2444
2445 /*
2446  * this routine is used to modify bits in ptes
2447  */
2448 static __inline void
2449 pmap_changebit(vm_page_t m, int bit, boolean_t setem)
2450 {
2451         struct pmap_inval_info info;
2452         pv_entry_t pv;
2453         vpte_t *pte;
2454
2455         if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
2456                 return;
2457
2458         pmap_inval_init(&info);
2459         crit_enter();
2460
2461         /*
2462          * Loop over all current mappings setting/clearing as appropos If
2463          * setting RO do we need to clear the VAC?
2464          */
2465         TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
2466                 /*
2467                  * don't write protect pager mappings
2468                  */
2469                 if (!setem && (bit == VPTE_W)) {
2470                         if (!pmap_track_modified(pv->pv_va))
2471                                 continue;
2472                 }
2473
2474 #if defined(PMAP_DIAGNOSTIC)
2475                 if (!pv->pv_pmap) {
2476                         kprintf("Null pmap (cb) at va: 0x%x\n", pv->pv_va);
2477                         continue;
2478                 }
2479 #endif
2480
2481                 /*
2482                  * Careful here.  We can use a locked bus instruction to
2483                  * clear VPTE_A or VPTE_M safely but we need to synchronize
2484                  * with the target cpus when we mess with VPTE_W.
2485                  */
2486                 pte = pmap_pte(pv->pv_pmap, pv->pv_va);
2487                 if (bit == VPTE_W)
2488                         pmap_inval_add(&info, pv->pv_pmap, pv->pv_va);
2489
2490                 if (setem) {
2491 #ifdef SMP
2492                         atomic_set_int(pte, bit);
2493 #else
2494                         atomic_set_int_nonlocked(pte, bit);
2495 #endif
2496                 } else {
2497                         vm_offset_t pbits = *(vm_offset_t *)pte;
2498                         if (pbits & bit) {
2499                                 if (bit == VPTE_W) {
2500                                         if (pbits & VPTE_M) {
2501                                                 vm_page_dirty(m);
2502                                         }
2503 #ifdef SMP
2504                                         atomic_clear_int(pte, VPTE_M|VPTE_W);
2505 #else
2506                                         atomic_clear_int_nonlocked(pte, VPTE_M|VPTE_W);
2507 #endif
2508                                 } else {
2509 #ifdef SMP
2510                                         atomic_clear_int(pte, bit);
2511 #else
2512                                         atomic_clear_int_nonlocked(pte, bit);
2513 #endif
2514                                 }
2515                         }
2516                 }
2517         }
2518         pmap_inval_flush(&info);
2519         crit_exit();
2520 }
2521
2522 /*
2523  *      pmap_page_protect:
2524  *
2525  *      Lower the permission for all mappings to a given page.
2526  */
2527 void
2528 pmap_page_protect(vm_page_t m, vm_prot_t prot)
2529 {
2530         if ((prot & VM_PROT_WRITE) == 0) {
2531                 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2532                         pmap_changebit(m, VPTE_W, FALSE);
2533                 } else {
2534                         pmap_remove_all(m);
2535                 }
2536         }
2537 }
2538
2539 vm_paddr_t
2540 pmap_phys_address(int ppn)
2541 {
2542         return (i386_ptob(ppn));
2543 }
2544
2545 /*
2546  *      pmap_ts_referenced:
2547  *
2548  *      Return a count of reference bits for a page, clearing those bits.
2549  *      It is not necessary for every reference bit to be cleared, but it
2550  *      is necessary that 0 only be returned when there are truly no
2551  *      reference bits set.
2552  *
2553  *      XXX: The exact number of bits to check and clear is a matter that
2554  *      should be tested and standardized at some point in the future for
2555  *      optimal aging of shared pages.
2556  */
2557 int
2558 pmap_ts_referenced(vm_page_t m)
2559 {
2560         pv_entry_t pv, pvf, pvn;
2561         vpte_t *pte;
2562         int rtval = 0;
2563
2564         if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
2565                 return (rtval);
2566
2567         crit_enter();
2568
2569         if ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) {
2570
2571                 pvf = pv;
2572
2573                 do {
2574                         pvn = TAILQ_NEXT(pv, pv_list);
2575
2576                         TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
2577
2578                         TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list);
2579
2580                         if (!pmap_track_modified(pv->pv_va))
2581                                 continue;
2582
2583                         pte = pmap_pte(pv->pv_pmap, pv->pv_va);
2584
2585                         if (pte && (*pte & VPTE_A)) {
2586 #ifdef SMP
2587                                 atomic_clear_int(pte, VPTE_A);
2588 #else
2589                                 atomic_clear_int_nonlocked(pte, VPTE_A);
2590 #endif
2591                                 rtval++;
2592                                 if (rtval > 4) {
2593                                         break;
2594                                 }
2595                         }
2596                 } while ((pv = pvn) != NULL && pv != pvf);
2597         }
2598         crit_exit();
2599
2600         return (rtval);
2601 }
2602
2603 /*
2604  *      pmap_is_modified:
2605  *
2606  *      Return whether or not the specified physical page was modified
2607  *      in any physical maps.
2608  */
2609 boolean_t
2610 pmap_is_modified(vm_page_t m)
2611 {
2612         return pmap_testbit(m, VPTE_M);
2613 }
2614
2615 /*
2616  *      Clear the modify bits on the specified physical page.
2617  */
2618 void
2619 pmap_clear_modify(vm_page_t m)
2620 {
2621         pmap_changebit(m, VPTE_M, FALSE);
2622 }
2623
2624 /*
2625  *      pmap_clear_reference:
2626  *
2627  *      Clear the reference bit on the specified physical page.
2628  */
2629 void
2630 pmap_clear_reference(vm_page_t m)
2631 {
2632         pmap_changebit(m, VPTE_A, FALSE);
2633 }
2634
2635 /*
2636  * Miscellaneous support routines follow
2637  */
2638
2639 static void
2640 i386_protection_init(void)
2641 {
2642         int *kp, prot;
2643
2644         kp = protection_codes;
2645         for (prot = 0; prot < 8; prot++) {
2646                 if (prot & VM_PROT_READ)
2647                         *kp |= VPTE_R;
2648                 if (prot & VM_PROT_WRITE)
2649                         *kp |= VPTE_W;
2650                 if (prot & VM_PROT_EXECUTE)
2651                         *kp |= VPTE_X;
2652                 ++kp;
2653         }
2654 }
2655
2656 /*
2657  * Map a set of physical memory pages into the kernel virtual
2658  * address space. Return a pointer to where it is mapped. This
2659  * routine is intended to be used for mapping device memory,
2660  * NOT real memory.
2661  *
2662  * NOTE: we can't use pgeflag unless we invalidate the pages one at
2663  * a time.
2664  */
2665 void *
2666 pmap_mapdev(vm_paddr_t pa, vm_size_t size)
2667 {
2668         vm_offset_t va, tmpva, offset;
2669         vpte_t *pte;
2670
2671         offset = pa & PAGE_MASK;
2672         size = roundup(offset + size, PAGE_SIZE);
2673
2674         va = kmem_alloc_nofault(&kernel_map, size);
2675         if (!va)
2676                 panic("pmap_mapdev: Couldn't alloc kernel virtual memory");
2677
2678         pa = pa & VPTE_FRAME;
2679         for (tmpva = va; size > 0;) {
2680                 pte = KernelPTA + (tmpva >> PAGE_SHIFT);
2681                 *pte = pa | VPTE_R | VPTE_W | VPTE_V; /* | pgeflag; */
2682                 size -= PAGE_SIZE;
2683                 tmpva += PAGE_SIZE;
2684                 pa += PAGE_SIZE;
2685         }
2686         cpu_invltlb();
2687         smp_invltlb();
2688
2689         return ((void *)(va + offset));
2690 }
2691
2692 void
2693 pmap_unmapdev(vm_offset_t va, vm_size_t size)
2694 {
2695         vm_offset_t base, offset;
2696
2697         base = va & VPTE_FRAME;
2698         offset = va & PAGE_MASK;
2699         size = roundup(offset + size, PAGE_SIZE);
2700         pmap_qremove(va, size >> PAGE_SHIFT);
2701         kmem_free(&kernel_map, base, size);
2702 }
2703
2704 /*
2705  * perform the pmap work for mincore
2706  */
2707 int
2708 pmap_mincore(pmap_t pmap, vm_offset_t addr)
2709 {
2710         vpte_t *ptep, pte;
2711         vm_page_t m;
2712         int val = 0;
2713         
2714         ptep = pmap_pte(pmap, addr);
2715         if (ptep == 0) {
2716                 return 0;
2717         }
2718
2719         if ((pte = *ptep) != 0) {
2720                 vm_offset_t pa;
2721
2722                 val = MINCORE_INCORE;
2723                 if ((pte & VPTE_MANAGED) == 0)
2724                         return val;
2725
2726                 pa = pte & VPTE_FRAME;
2727
2728                 m = PHYS_TO_VM_PAGE(pa);
2729
2730                 /*
2731                  * Modified by us
2732                  */
2733                 if (pte & VPTE_M)
2734                         val |= MINCORE_MODIFIED|MINCORE_MODIFIED_OTHER;
2735                 /*
2736                  * Modified by someone
2737                  */
2738                 else if (m->dirty || pmap_is_modified(m))
2739                         val |= MINCORE_MODIFIED_OTHER;
2740                 /*
2741                  * Referenced by us
2742                  */
2743                 if (pte & VPTE_A)
2744                         val |= MINCORE_REFERENCED|MINCORE_REFERENCED_OTHER;
2745
2746                 /*
2747                  * Referenced by someone
2748                  */
2749                 else if ((m->flags & PG_REFERENCED) || pmap_ts_referenced(m)) {
2750                         val |= MINCORE_REFERENCED_OTHER;
2751                         vm_page_flag_set(m, PG_REFERENCED);
2752                 }
2753         } 
2754         return val;
2755 }
2756
2757 void
2758 pmap_activate(struct proc *p)
2759 {
2760         pmap_t  pmap;
2761
2762         pmap = vmspace_pmap(p->p_vmspace);
2763 #if defined(SMP)
2764         atomic_set_int(&pmap->pm_active, 1 << mycpu->gd_cpuid);
2765 #else
2766         pmap->pm_active |= 1;
2767 #endif
2768 #if defined(SWTCH_OPTIM_STATS)
2769         tlb_flush_count++;
2770 #endif
2771         panic("pmap_activate"); /* XXX store vmspace id in context */
2772 #if 0
2773         p->p_thread->td_pcb->pcb_cr3 = vtophys(pmap->pm_pdir);
2774         load_cr3(p->p_thread->td_pcb->pcb_cr3);
2775 #endif
2776 }
2777
2778 void
2779 pmap_deactivate(struct proc *p)
2780 {
2781         pmap_t  pmap;
2782
2783         pmap = vmspace_pmap(p->p_vmspace);
2784 #if defined(SMP)
2785         atomic_clear_int(&pmap->pm_active, 1 << mycpu->gd_cpuid);
2786 #else
2787         pmap->pm_active &= ~1;
2788 #endif
2789         /*
2790          * XXX - note we do not adjust %cr3.  The caller is expected to
2791          * activate a new pmap or do a thread-exit.
2792          */
2793 }
2794
2795 vm_offset_t
2796 pmap_addr_hint(vm_object_t obj, vm_offset_t addr, vm_size_t size)
2797 {
2798
2799         if ((obj == NULL) || (size < NBPDR) || (obj->type != OBJT_DEVICE)) {
2800                 return addr;
2801         }
2802
2803         addr = (addr + (NBPDR - 1)) & ~(NBPDR - 1);
2804         return addr;
2805 }
2806
2807
2808 #if defined(DEBUG)
2809
2810 static void     pads (pmap_t pm);
2811 void            pmap_pvdump (vm_paddr_t pa);
2812
2813 /* print address space of pmap*/
2814 static void
2815 pads(pmap_t pm)
2816 {
2817         vm_offset_t va;
2818         int i, j;
2819         vpte_t *ptep;
2820
2821         if (pm == &kernel_pmap)
2822                 return;
2823         for (i = 0; i < 1024; i++)
2824                 if (pm->pm_pdir[i])
2825                         for (j = 0; j < 1024; j++) {
2826                                 va = (i << PDRSHIFT) + (j << PAGE_SHIFT);
2827                                 if (pm == &kernel_pmap && va < KERNBASE)
2828                                         continue;
2829                                 if (pm != &kernel_pmap && va > UPT_MAX_ADDRESS)
2830                                         continue;
2831                                 ptep = pmap_pte(pm, va);
2832                                 if (ptep && (*ptep & VPTE_V)) {
2833                                         kprintf("%p:%x ",
2834                                                 (void *)va, (unsigned)*ptep);
2835                                 }
2836                         };
2837
2838 }
2839
2840 void
2841 pmap_pvdump(vm_paddr_t pa)
2842 {
2843         pv_entry_t pv;
2844         vm_page_t m;
2845
2846         kprintf("pa %08llx", (long long)pa);
2847         m = PHYS_TO_VM_PAGE(pa);
2848         TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
2849 #ifdef used_to_be
2850                 kprintf(" -> pmap %p, va %x, flags %x",
2851                     (void *)pv->pv_pmap, pv->pv_va, pv->pv_flags);
2852 #endif
2853                 kprintf(" -> pmap %p, va %x", (void *)pv->pv_pmap, pv->pv_va);
2854                 pads(pv->pv_pmap);
2855         }
2856         kprintf(" ");
2857 }
2858 #endif