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