]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/ia64/ia64/pmap.c
This commit was generated by cvs2svn to compensate for changes in r170331,
[FreeBSD/FreeBSD.git] / sys / ia64 / ia64 / 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  * Copyright (c) 1998,2000 Doug Rabson
9  * All rights reserved.
10  *
11  * This code is derived from software contributed to Berkeley by
12  * the Systems Programming Group of the University of Utah Computer
13  * Science Department and William Jolitz of UUNET Technologies Inc.
14  *
15  * Redistribution and use in source and binary forms, with or without
16  * modification, are permitted provided that the following conditions
17  * are met:
18  * 1. Redistributions of source code must retain the above copyright
19  *    notice, this list of conditions and the following disclaimer.
20  * 2. Redistributions in binary form must reproduce the above copyright
21  *    notice, this list of conditions and the following disclaimer in the
22  *    documentation and/or other materials provided with the distribution.
23  * 3. All advertising materials mentioning features or use of this software
24  *    must display the following acknowledgement:
25  *      This product includes software developed by the University of
26  *      California, Berkeley and its contributors.
27  * 4. Neither the name of the University nor the names of its contributors
28  *    may be used to endorse or promote products derived from this software
29  *    without specific prior written permission.
30  *
31  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
32  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
35  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
39  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
40  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41  * SUCH DAMAGE.
42  *
43  *      from:   @(#)pmap.c      7.7 (Berkeley)  5/12/91
44  *      from:   i386 Id: pmap.c,v 1.193 1998/04/19 15:22:48 bde Exp
45  *              with some ideas from NetBSD's alpha pmap
46  */
47
48 #include <sys/cdefs.h>
49 __FBSDID("$FreeBSD$");
50
51 #include <sys/param.h>
52 #include <sys/kernel.h>
53 #include <sys/lock.h>
54 #include <sys/mman.h>
55 #include <sys/mutex.h>
56 #include <sys/proc.h>
57 #include <sys/smp.h>
58 #include <sys/sysctl.h>
59 #include <sys/systm.h>
60
61 #include <vm/vm.h>
62 #include <vm/vm_page.h>
63 #include <vm/vm_map.h>
64 #include <vm/vm_object.h>
65 #include <vm/vm_pageout.h>
66 #include <vm/uma.h>
67
68 #include <machine/md_var.h>
69 #include <machine/pal.h>
70
71 /*
72  *      Manages physical address maps.
73  *
74  *      In addition to hardware address maps, this
75  *      module is called upon to provide software-use-only
76  *      maps which may or may not be stored in the same
77  *      form as hardware maps.  These pseudo-maps are
78  *      used to store intermediate results from copy
79  *      operations to and from address spaces.
80  *
81  *      Since the information managed by this module is
82  *      also stored by the logical address mapping module,
83  *      this module may throw away valid virtual-to-physical
84  *      mappings at almost any time.  However, invalidations
85  *      of virtual-to-physical mappings must be done as
86  *      requested.
87  *
88  *      In order to cope with hardware architectures which
89  *      make virtual-to-physical map invalidates expensive,
90  *      this module may delay invalidate or reduced protection
91  *      operations until such time as they are actually
92  *      necessary.  This module is given full information as
93  *      to which processors are currently using which maps,
94  *      and to when physical maps must be made correct.
95  */
96
97 /*
98  * Following the Linux model, region IDs are allocated in groups of
99  * eight so that a single region ID can be used for as many RRs as we
100  * want by encoding the RR number into the low bits of the ID.
101  *
102  * We reserve region ID 0 for the kernel and allocate the remaining
103  * IDs for user pmaps.
104  *
105  * Region 0..4
106  *      User virtually mapped
107  *
108  * Region 5
109  *      Kernel virtually mapped
110  *
111  * Region 6
112  *      Kernel physically mapped uncacheable
113  *
114  * Region 7
115  *      Kernel physically mapped cacheable
116  */
117
118 /* XXX move to a header. */
119 extern uint64_t ia64_gateway_page[];
120
121 MALLOC_DEFINE(M_PMAP, "PMAP", "PMAP Structures");
122
123 #ifndef PMAP_SHPGPERPROC
124 #define PMAP_SHPGPERPROC 200
125 #endif
126
127 #if !defined(DIAGNOSTIC)
128 #define PMAP_INLINE __inline
129 #else
130 #define PMAP_INLINE
131 #endif
132
133 #define pmap_accessed(lpte)             ((lpte)->pte & PTE_ACCESSED)
134 #define pmap_dirty(lpte)                ((lpte)->pte & PTE_DIRTY)
135 #define pmap_managed(lpte)              ((lpte)->pte & PTE_MANAGED)
136 #define pmap_ppn(lpte)                  ((lpte)->pte & PTE_PPN_MASK)
137 #define pmap_present(lpte)              ((lpte)->pte & PTE_PRESENT)
138 #define pmap_prot(lpte)                 (((lpte)->pte & PTE_PROT_MASK) >> 56)
139 #define pmap_wired(lpte)                ((lpte)->pte & PTE_WIRED)
140
141 #define pmap_clear_accessed(lpte)       (lpte)->pte &= ~PTE_ACCESSED
142 #define pmap_clear_dirty(lpte)          (lpte)->pte &= ~PTE_DIRTY
143 #define pmap_clear_present(lpte)        (lpte)->pte &= ~PTE_PRESENT
144 #define pmap_clear_wired(lpte)          (lpte)->pte &= ~PTE_WIRED
145
146 #define pmap_set_wired(lpte)            (lpte)->pte |= PTE_WIRED
147
148 /*
149  * The VHPT bucket head structure.
150  */
151 struct ia64_bucket {
152         uint64_t        chain;
153         struct mtx      mutex;
154         u_int           length;
155 };
156
157 /*
158  * Statically allocated kernel pmap
159  */
160 struct pmap kernel_pmap_store;
161
162 vm_offset_t virtual_avail;      /* VA of first avail page (after kernel bss) */
163 vm_offset_t virtual_end;        /* VA of last avail page (end of kernel AS) */
164
165 /*
166  * Kernel virtual memory management.
167  */
168 static int nkpt;
169 struct ia64_lpte ***ia64_kptdir;
170 #define KPTE_DIR0_INDEX(va) \
171         (((va) >> (3*PAGE_SHIFT-8)) & ((1<<(PAGE_SHIFT-3))-1))
172 #define KPTE_DIR1_INDEX(va) \
173         (((va) >> (2*PAGE_SHIFT-5)) & ((1<<(PAGE_SHIFT-3))-1))
174 #define KPTE_PTE_INDEX(va) \
175         (((va) >> PAGE_SHIFT) & ((1<<(PAGE_SHIFT-5))-1))
176 #define NKPTEPG         (PAGE_SIZE / sizeof(struct ia64_lpte))
177
178 vm_offset_t kernel_vm_end;
179
180 /* Values for ptc.e. XXX values for SKI. */
181 static uint64_t pmap_ptc_e_base = 0x100000000;
182 static uint64_t pmap_ptc_e_count1 = 3;
183 static uint64_t pmap_ptc_e_count2 = 2;
184 static uint64_t pmap_ptc_e_stride1 = 0x2000;
185 static uint64_t pmap_ptc_e_stride2 = 0x100000000;
186 struct mtx pmap_ptcmutex;
187
188 /*
189  * Data for the RID allocator
190  */
191 static int pmap_ridcount;
192 static int pmap_rididx;
193 static int pmap_ridmapsz;
194 static int pmap_ridmax;
195 static uint64_t *pmap_ridmap;
196 struct mtx pmap_ridmutex;
197
198 /*
199  * Data for the pv entry allocation mechanism
200  */
201 static uma_zone_t pvzone;
202 static int pv_entry_count = 0, pv_entry_max = 0, pv_entry_high_water = 0;
203
204 /*
205  * Data for allocating PTEs for user processes.
206  */
207 static uma_zone_t ptezone;
208
209 /*
210  * Virtual Hash Page Table (VHPT) data.
211  */
212 /* SYSCTL_DECL(_machdep); */
213 SYSCTL_NODE(_machdep, OID_AUTO, vhpt, CTLFLAG_RD, 0, "");
214
215 struct ia64_bucket *pmap_vhpt_bucket;
216
217 int pmap_vhpt_nbuckets;
218 SYSCTL_INT(_machdep_vhpt, OID_AUTO, nbuckets, CTLFLAG_RD,
219     &pmap_vhpt_nbuckets, 0, "");
220
221 uint64_t pmap_vhpt_base[MAXCPU];
222
223 int pmap_vhpt_log2size = 0;
224 TUNABLE_INT("machdep.vhpt.log2size", &pmap_vhpt_log2size);
225 SYSCTL_INT(_machdep_vhpt, OID_AUTO, log2size, CTLFLAG_RD,
226     &pmap_vhpt_log2size, 0, "");
227
228 static int pmap_vhpt_inserts;
229 SYSCTL_INT(_machdep_vhpt, OID_AUTO, inserts, CTLFLAG_RD,
230     &pmap_vhpt_inserts, 0, "");
231
232 static int pmap_vhpt_population(SYSCTL_HANDLER_ARGS);
233 SYSCTL_PROC(_machdep_vhpt, OID_AUTO, population, CTLTYPE_INT | CTLFLAG_RD,
234     NULL, 0, pmap_vhpt_population, "I", "");
235
236 static struct ia64_lpte *pmap_find_vhpt(vm_offset_t va);
237
238 static PMAP_INLINE void free_pv_entry(pv_entry_t pv);
239 static pv_entry_t get_pv_entry(pmap_t locked_pmap);
240
241 static void     pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va,
242                     vm_page_t m, vm_prot_t prot);
243 static pmap_t   pmap_install(pmap_t);
244 static void     pmap_invalidate_all(pmap_t pmap);
245 static int      pmap_remove_pte(pmap_t pmap, struct ia64_lpte *pte,
246                     vm_offset_t va, pv_entry_t pv, int freepte);
247 static boolean_t pmap_try_insert_pv_entry(pmap_t pmap, vm_offset_t va,
248                     vm_page_t m);
249
250 vm_offset_t
251 pmap_steal_memory(vm_size_t size)
252 {
253         vm_size_t bank_size;
254         vm_offset_t pa, va;
255
256         size = round_page(size);
257
258         bank_size = phys_avail[1] - phys_avail[0];
259         while (size > bank_size) {
260                 int i;
261                 for (i = 0; phys_avail[i+2]; i+= 2) {
262                         phys_avail[i] = phys_avail[i+2];
263                         phys_avail[i+1] = phys_avail[i+3];
264                 }
265                 phys_avail[i] = 0;
266                 phys_avail[i+1] = 0;
267                 if (!phys_avail[0])
268                         panic("pmap_steal_memory: out of memory");
269                 bank_size = phys_avail[1] - phys_avail[0];
270         }
271
272         pa = phys_avail[0];
273         phys_avail[0] += size;
274
275         va = IA64_PHYS_TO_RR7(pa);
276         bzero((caddr_t) va, size);
277         return va;
278 }
279
280 /*
281  *      Bootstrap the system enough to run with virtual memory.
282  */
283 void
284 pmap_bootstrap()
285 {
286         struct ia64_pal_result res;
287         struct ia64_lpte *pte;
288         vm_offset_t base, limit;
289         size_t size;
290         int i, j, count, ridbits;
291
292         /*
293          * Query the PAL Code to find the loop parameters for the
294          * ptc.e instruction.
295          */
296         res = ia64_call_pal_static(PAL_PTCE_INFO, 0, 0, 0);
297         if (res.pal_status != 0)
298                 panic("Can't configure ptc.e parameters");
299         pmap_ptc_e_base = res.pal_result[0];
300         pmap_ptc_e_count1 = res.pal_result[1] >> 32;
301         pmap_ptc_e_count2 = res.pal_result[1] & ((1L<<32) - 1);
302         pmap_ptc_e_stride1 = res.pal_result[2] >> 32;
303         pmap_ptc_e_stride2 = res.pal_result[2] & ((1L<<32) - 1);
304         if (bootverbose)
305                 printf("ptc.e base=0x%lx, count1=%ld, count2=%ld, "
306                        "stride1=0x%lx, stride2=0x%lx\n",
307                        pmap_ptc_e_base,
308                        pmap_ptc_e_count1,
309                        pmap_ptc_e_count2,
310                        pmap_ptc_e_stride1,
311                        pmap_ptc_e_stride2);
312         mtx_init(&pmap_ptcmutex, "Global PTC lock", NULL, MTX_SPIN);
313
314         /*
315          * Setup RIDs. RIDs 0..7 are reserved for the kernel.
316          *
317          * We currently need at least 19 bits in the RID because PID_MAX
318          * can only be encoded in 17 bits and we need RIDs for 5 regions
319          * per process. With PID_MAX equalling 99999 this means that we
320          * need to be able to encode 499995 (=5*PID_MAX).
321          * The Itanium processor only has 18 bits and the architected
322          * minimum is exactly that. So, we cannot use a PID based scheme
323          * in those cases. Enter pmap_ridmap...
324          * We should avoid the map when running on a processor that has
325          * implemented enough bits. This means that we should pass the
326          * process/thread ID to pmap. This we currently don't do, so we
327          * use the map anyway. However, we don't want to allocate a map
328          * that is large enough to cover the range dictated by the number
329          * of bits in the RID, because that may result in a RID map of
330          * 2MB in size for a 24-bit RID. A 64KB map is enough.
331          * The bottomline: we create a 32KB map when the processor only
332          * implements 18 bits (or when we can't figure it out). Otherwise
333          * we create a 64KB map.
334          */
335         res = ia64_call_pal_static(PAL_VM_SUMMARY, 0, 0, 0);
336         if (res.pal_status != 0) {
337                 if (bootverbose)
338                         printf("Can't read VM Summary - assuming 18 Region ID bits\n");
339                 ridbits = 18; /* guaranteed minimum */
340         } else {
341                 ridbits = (res.pal_result[1] >> 8) & 0xff;
342                 if (bootverbose)
343                         printf("Processor supports %d Region ID bits\n",
344                             ridbits);
345         }
346         if (ridbits > 19)
347                 ridbits = 19;
348
349         pmap_ridmax = (1 << ridbits);
350         pmap_ridmapsz = pmap_ridmax / 64;
351         pmap_ridmap = (uint64_t *)pmap_steal_memory(pmap_ridmax / 8);
352         pmap_ridmap[0] |= 0xff;
353         pmap_rididx = 0;
354         pmap_ridcount = 8;
355         mtx_init(&pmap_ridmutex, "RID allocator lock", NULL, MTX_DEF);
356
357         /*
358          * Allocate some memory for initial kernel 'page tables'.
359          */
360         ia64_kptdir = (void *)pmap_steal_memory(PAGE_SIZE);
361         nkpt = 0;
362         kernel_vm_end = VM_MIN_KERNEL_ADDRESS - VM_GATEWAY_SIZE;
363
364         for (i = 0; phys_avail[i+2]; i+= 2)
365                 ;
366         count = i+2;
367
368         /*
369          * Figure out a useful size for the VHPT, based on the size of
370          * physical memory and try to locate a region which is large
371          * enough to contain the VHPT (which must be a power of two in
372          * size and aligned to a natural boundary).
373          * We silently bump up the VHPT size to the minimum size if the
374          * user has set the tunable too small. Likewise, the VHPT size
375          * is silently capped to the maximum allowed.
376          */
377         TUNABLE_INT_FETCH("machdep.vhpt.log2size", &pmap_vhpt_log2size);
378         if (pmap_vhpt_log2size == 0) {
379                 pmap_vhpt_log2size = 15;
380                 size = 1UL << pmap_vhpt_log2size;
381                 while (size < Maxmem * 32) {
382                         pmap_vhpt_log2size++;
383                         size <<= 1;
384                 }
385         } else if (pmap_vhpt_log2size < 15)
386                 pmap_vhpt_log2size = 15;
387         if (pmap_vhpt_log2size > 61)
388                 pmap_vhpt_log2size = 61;
389
390         pmap_vhpt_base[0] = 0;
391         base = limit = 0;
392         size = 1UL << pmap_vhpt_log2size;
393         while (pmap_vhpt_base[0] == 0) {
394                 if (bootverbose)
395                         printf("Trying VHPT size 0x%lx\n", size);
396                 for (i = 0; i < count; i += 2) {
397                         base = (phys_avail[i] + size - 1) & ~(size - 1);
398                         limit = base + MAXCPU * size;
399                         if (limit <= phys_avail[i+1])
400                                 /*
401                                  * VHPT can fit in this region
402                                  */
403                                 break;
404                 }
405                 if (!phys_avail[i]) {
406                         /* Can't fit, try next smaller size. */
407                         pmap_vhpt_log2size--;
408                         size >>= 1;
409                 } else
410                         pmap_vhpt_base[0] = IA64_PHYS_TO_RR7(base);
411         }
412         if (pmap_vhpt_log2size < 15)
413                 panic("Can't find space for VHPT");
414
415         if (bootverbose)
416                 printf("Putting VHPT at 0x%lx\n", base);
417
418         if (base != phys_avail[i]) {
419                 /* Split this region. */
420                 if (bootverbose)
421                         printf("Splitting [%p-%p]\n", (void *)phys_avail[i],
422                             (void *)phys_avail[i+1]);
423                 for (j = count; j > i; j -= 2) {
424                         phys_avail[j] = phys_avail[j-2];
425                         phys_avail[j+1] = phys_avail[j-2+1];
426                 }
427                 phys_avail[i+1] = base;
428                 phys_avail[i+2] = limit;
429         } else
430                 phys_avail[i] = limit;
431
432         pmap_vhpt_nbuckets = size / sizeof(struct ia64_lpte);
433
434         pmap_vhpt_bucket = (void *)pmap_steal_memory(pmap_vhpt_nbuckets *
435             sizeof(struct ia64_bucket));
436         pte = (struct ia64_lpte *)pmap_vhpt_base[0];
437         for (i = 0; i < pmap_vhpt_nbuckets; i++) {
438                 pte[i].pte = 0;
439                 pte[i].itir = 0;
440                 pte[i].tag = 1UL << 63; /* Invalid tag */
441                 pte[i].chain = (uintptr_t)(pmap_vhpt_bucket + i);
442                 /* Stolen memory is zeroed! */
443                 mtx_init(&pmap_vhpt_bucket[i].mutex, "VHPT bucket lock", NULL,
444                     MTX_SPIN);
445         }
446
447         for (i = 1; i < MAXCPU; i++) {
448                 pmap_vhpt_base[i] = pmap_vhpt_base[i - 1] + size;
449                 bcopy((void *)pmap_vhpt_base[i - 1], (void *)pmap_vhpt_base[i],
450                     size);
451         }
452
453         __asm __volatile("mov cr.pta=%0;; srlz.i;;" ::
454             "r" (pmap_vhpt_base[0] + (1<<8) + (pmap_vhpt_log2size<<2) + 1));
455
456         virtual_avail = VM_MIN_KERNEL_ADDRESS;
457         virtual_end = VM_MAX_KERNEL_ADDRESS;
458
459         /*
460          * Initialize the kernel pmap (which is statically allocated).
461          */
462         PMAP_LOCK_INIT(kernel_pmap);
463         for (i = 0; i < 5; i++)
464                 kernel_pmap->pm_rid[i] = 0;
465         kernel_pmap->pm_active = 1;
466         TAILQ_INIT(&kernel_pmap->pm_pvlist);
467         PCPU_SET(current_pmap, kernel_pmap);
468
469         /*
470          * Region 5 is mapped via the vhpt.
471          */
472         ia64_set_rr(IA64_RR_BASE(5),
473                     (5 << 8) | (PAGE_SHIFT << 2) | 1);
474
475         /*
476          * Region 6 is direct mapped UC and region 7 is direct mapped
477          * WC. The details of this is controlled by the Alt {I,D}TLB
478          * handlers. Here we just make sure that they have the largest 
479          * possible page size to minimise TLB usage.
480          */
481         ia64_set_rr(IA64_RR_BASE(6), (6 << 8) | (IA64_ID_PAGE_SHIFT << 2));
482         ia64_set_rr(IA64_RR_BASE(7), (7 << 8) | (IA64_ID_PAGE_SHIFT << 2));
483
484         /*
485          * Clear out any random TLB entries left over from booting.
486          */
487         pmap_invalidate_all(kernel_pmap);
488
489         map_gateway_page();
490 }
491
492 static int
493 pmap_vhpt_population(SYSCTL_HANDLER_ARGS)
494 {
495         int count, error, i;
496
497         count = 0;
498         for (i = 0; i < pmap_vhpt_nbuckets; i++)
499                 count += pmap_vhpt_bucket[i].length;
500
501         error = SYSCTL_OUT(req, &count, sizeof(count));
502         return (error);
503 }
504
505 /*
506  *      Initialize a vm_page's machine-dependent fields.
507  */
508 void
509 pmap_page_init(vm_page_t m)
510 {
511
512         TAILQ_INIT(&m->md.pv_list);
513         m->md.pv_list_count = 0;
514 }
515
516 /*
517  *      Initialize the pmap module.
518  *      Called by vm_init, to initialize any structures that the pmap
519  *      system needs to map virtual memory.
520  */
521 void
522 pmap_init(void)
523 {
524         int shpgperproc = PMAP_SHPGPERPROC;
525
526         /*
527          * Initialize the address space (zone) for the pv entries.  Set a
528          * high water mark so that the system can recover from excessive
529          * numbers of pv entries.
530          */
531         pvzone = uma_zcreate("PV ENTRY", sizeof(struct pv_entry), NULL, NULL,
532             NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM | UMA_ZONE_NOFREE);
533         TUNABLE_INT_FETCH("vm.pmap.shpgperproc", &shpgperproc);
534         pv_entry_max = shpgperproc * maxproc + cnt.v_page_count;
535         TUNABLE_INT_FETCH("vm.pmap.pv_entries", &pv_entry_max);
536         pv_entry_high_water = 9 * (pv_entry_max / 10);
537
538         ptezone = uma_zcreate("PT ENTRY", sizeof (struct ia64_lpte), 
539             NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM|UMA_ZONE_NOFREE);
540 }
541
542
543 /***************************************************
544  * Manipulate TLBs for a pmap
545  ***************************************************/
546
547 #if 0
548 static __inline void
549 pmap_invalidate_page_locally(void *arg)
550 {
551         vm_offset_t va = (uintptr_t)arg;
552         struct ia64_lpte *pte;
553
554         pte = (struct ia64_lpte *)ia64_thash(va);
555         if (pte->tag == ia64_ttag(va))
556                 pte->tag = 1UL << 63;
557         ia64_ptc_l(va, PAGE_SHIFT << 2);
558 }
559
560 #ifdef SMP
561 static void
562 pmap_invalidate_page_1(void *arg)
563 {
564         void **args = arg;
565         pmap_t oldpmap;
566
567         critical_enter();
568         oldpmap = pmap_install(args[0]);
569         pmap_invalidate_page_locally(args[1]);
570         pmap_install(oldpmap);
571         critical_exit();
572 }
573 #endif
574
575 static void
576 pmap_invalidate_page(pmap_t pmap, vm_offset_t va)
577 {
578
579         KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(current_pmap)),
580                 ("invalidating TLB for non-current pmap"));
581
582 #ifdef SMP
583         if (mp_ncpus > 1) {
584                 void *args[2];
585                 args[0] = pmap;
586                 args[1] = (void *)va;
587                 smp_rendezvous(NULL, pmap_invalidate_page_1, NULL, args);
588         } else
589 #endif
590         pmap_invalidate_page_locally((void *)va);
591 }
592 #endif /* 0 */
593
594 static void
595 pmap_invalidate_page(pmap_t pmap, vm_offset_t va)
596 {
597         struct ia64_lpte *pte;
598         int i, vhpt_ofs;
599
600         KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(current_pmap)),
601                 ("invalidating TLB for non-current pmap"));
602
603         vhpt_ofs = ia64_thash(va) - pmap_vhpt_base[PCPU_GET(cpuid)];
604         critical_enter();
605         for (i = 0; i < MAXCPU; i++) {
606                 pte = (struct ia64_lpte *)(pmap_vhpt_base[i] + vhpt_ofs);
607                 if (pte->tag == ia64_ttag(va))
608                         pte->tag = 1UL << 63;
609         }
610         critical_exit();
611         mtx_lock_spin(&pmap_ptcmutex);
612         ia64_ptc_ga(va, PAGE_SHIFT << 2);
613         mtx_unlock_spin(&pmap_ptcmutex);
614 }
615
616 static void
617 pmap_invalidate_all_1(void *arg)
618 {
619         uint64_t addr;
620         int i, j;
621
622         critical_enter();
623         addr = pmap_ptc_e_base;
624         for (i = 0; i < pmap_ptc_e_count1; i++) {
625                 for (j = 0; j < pmap_ptc_e_count2; j++) {
626                         ia64_ptc_e(addr);
627                         addr += pmap_ptc_e_stride2;
628                 }
629                 addr += pmap_ptc_e_stride1;
630         }
631         critical_exit();
632 }
633
634 static void
635 pmap_invalidate_all(pmap_t pmap)
636 {
637
638         KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(current_pmap)),
639                 ("invalidating TLB for non-current pmap"));
640
641 #ifdef SMP
642         if (mp_ncpus > 1)
643                 smp_rendezvous(NULL, pmap_invalidate_all_1, NULL, NULL);
644         else
645 #endif
646         pmap_invalidate_all_1(NULL);
647 }
648
649 static uint32_t
650 pmap_allocate_rid(void)
651 {
652         uint64_t bit, bits;
653         int rid;
654
655         mtx_lock(&pmap_ridmutex);
656         if (pmap_ridcount == pmap_ridmax)
657                 panic("pmap_allocate_rid: All Region IDs used");
658
659         /* Find an index with a free bit. */
660         while ((bits = pmap_ridmap[pmap_rididx]) == ~0UL) {
661                 pmap_rididx++;
662                 if (pmap_rididx == pmap_ridmapsz)
663                         pmap_rididx = 0;
664         }
665         rid = pmap_rididx * 64;
666
667         /* Find a free bit. */
668         bit = 1UL;
669         while (bits & bit) {
670                 rid++;
671                 bit <<= 1;
672         }
673
674         pmap_ridmap[pmap_rididx] |= bit;
675         pmap_ridcount++;
676         mtx_unlock(&pmap_ridmutex);
677
678         return rid;
679 }
680
681 static void
682 pmap_free_rid(uint32_t rid)
683 {
684         uint64_t bit;
685         int idx;
686
687         idx = rid / 64;
688         bit = ~(1UL << (rid & 63));
689
690         mtx_lock(&pmap_ridmutex);
691         pmap_ridmap[idx] &= bit;
692         pmap_ridcount--;
693         mtx_unlock(&pmap_ridmutex);
694 }
695
696 /***************************************************
697  * Page table page management routines.....
698  ***************************************************/
699
700 void
701 pmap_pinit0(struct pmap *pmap)
702 {
703         /* kernel_pmap is the same as any other pmap. */
704         pmap_pinit(pmap);
705 }
706
707 /*
708  * Initialize a preallocated and zeroed pmap structure,
709  * such as one in a vmspace structure.
710  */
711 void
712 pmap_pinit(struct pmap *pmap)
713 {
714         int i;
715
716         PMAP_LOCK_INIT(pmap);
717         for (i = 0; i < 5; i++)
718                 pmap->pm_rid[i] = pmap_allocate_rid();
719         pmap->pm_active = 0;
720         TAILQ_INIT(&pmap->pm_pvlist);
721         bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
722 }
723
724 /***************************************************
725  * Pmap allocation/deallocation routines.
726  ***************************************************/
727
728 /*
729  * Release any resources held by the given physical map.
730  * Called when a pmap initialized by pmap_pinit is being released.
731  * Should only be called if the map contains no valid mappings.
732  */
733 void
734 pmap_release(pmap_t pmap)
735 {
736         int i;
737
738         for (i = 0; i < 5; i++)
739                 if (pmap->pm_rid[i])
740                         pmap_free_rid(pmap->pm_rid[i]);
741         PMAP_LOCK_DESTROY(pmap);
742 }
743
744 /*
745  * grow the number of kernel page table entries, if needed
746  */
747 void
748 pmap_growkernel(vm_offset_t addr)
749 {
750         struct ia64_lpte **dir1;
751         struct ia64_lpte *leaf;
752         vm_page_t nkpg;
753
754         while (kernel_vm_end <= addr) {
755                 if (nkpt == PAGE_SIZE/8 + PAGE_SIZE*PAGE_SIZE/64)
756                         panic("%s: out of kernel address space", __func__);
757
758                 dir1 = ia64_kptdir[KPTE_DIR0_INDEX(kernel_vm_end)];
759                 if (dir1 == NULL) {
760                         nkpg = vm_page_alloc(NULL, nkpt++,
761                             VM_ALLOC_NOOBJ|VM_ALLOC_INTERRUPT|VM_ALLOC_WIRED);
762                         if (!nkpg)
763                                 panic("%s: cannot add dir. page", __func__);
764
765                         dir1 = (struct ia64_lpte **) 
766                             IA64_PHYS_TO_RR7(VM_PAGE_TO_PHYS(nkpg));
767                         bzero(dir1, PAGE_SIZE);
768                         ia64_kptdir[KPTE_DIR0_INDEX(kernel_vm_end)] = dir1;
769                 }
770
771                 nkpg = vm_page_alloc(NULL, nkpt++,
772                     VM_ALLOC_NOOBJ|VM_ALLOC_INTERRUPT|VM_ALLOC_WIRED);
773                 if (!nkpg)
774                         panic("%s: cannot add PTE page", __func__);
775
776                 leaf = (struct ia64_lpte *)
777                     IA64_PHYS_TO_RR7(VM_PAGE_TO_PHYS(nkpg));
778                 bzero(leaf, PAGE_SIZE);
779                 dir1[KPTE_DIR1_INDEX(kernel_vm_end)] = leaf;
780
781                 kernel_vm_end += PAGE_SIZE * NKPTEPG;
782         }
783 }
784
785 /***************************************************
786  * page management routines.
787  ***************************************************/
788
789 /*
790  * free the pv_entry back to the free list
791  */
792 static PMAP_INLINE void
793 free_pv_entry(pv_entry_t pv)
794 {
795         pv_entry_count--;
796         uma_zfree(pvzone, pv);
797 }
798
799 /*
800  * get a new pv_entry, allocating a block from the system
801  * when needed.
802  */
803 static pv_entry_t
804 get_pv_entry(pmap_t locked_pmap)
805 {
806         static const struct timeval printinterval = { 60, 0 };
807         static struct timeval lastprint;
808         struct vpgqueues *vpq;
809         struct ia64_lpte *pte;
810         pmap_t oldpmap, pmap;
811         pv_entry_t allocated_pv, next_pv, pv;
812         vm_offset_t va;
813         vm_page_t m;
814
815         PMAP_LOCK_ASSERT(locked_pmap, MA_OWNED);
816         mtx_assert(&vm_page_queue_mtx, MA_OWNED);
817         allocated_pv = uma_zalloc(pvzone, M_NOWAIT);
818         if (allocated_pv != NULL) {
819                 pv_entry_count++;
820                 if (pv_entry_count > pv_entry_high_water)
821                         pagedaemon_wakeup();
822                 else
823                         return (allocated_pv);
824         }
825
826         /*
827          * Reclaim pv entries: At first, destroy mappings to inactive
828          * pages.  After that, if a pv entry is still needed, destroy
829          * mappings to active pages.
830          */
831         if (ratecheck(&lastprint, &printinterval))
832                 printf("Approaching the limit on PV entries, "
833                     "increase the vm.pmap.shpgperproc tunable.\n");
834         vpq = &vm_page_queues[PQ_INACTIVE];
835 retry:
836         TAILQ_FOREACH(m, &vpq->pl, pageq) {
837                 if (m->hold_count || m->busy)
838                         continue;
839                 TAILQ_FOREACH_SAFE(pv, &m->md.pv_list, pv_list, next_pv) {
840                         va = pv->pv_va;
841                         pmap = pv->pv_pmap;
842                         /* Avoid deadlock and lock recursion. */
843                         if (pmap > locked_pmap)
844                                 PMAP_LOCK(pmap);
845                         else if (pmap != locked_pmap && !PMAP_TRYLOCK(pmap))
846                                 continue;
847                         oldpmap = pmap_install(pmap);
848                         pte = pmap_find_vhpt(va);
849                         KASSERT(pte != NULL, ("pte"));
850                         pmap_remove_pte(pmap, pte, va, pv, 1);
851                         pmap_install(oldpmap);
852                         if (pmap != locked_pmap)
853                                 PMAP_UNLOCK(pmap);
854                         if (allocated_pv == NULL)
855                                 allocated_pv = pv;
856                         else
857                                 free_pv_entry(pv);
858                 }
859         }
860         if (allocated_pv == NULL) {
861                 if (vpq == &vm_page_queues[PQ_INACTIVE]) {
862                         vpq = &vm_page_queues[PQ_ACTIVE];
863                         goto retry;
864                 }
865                 panic("get_pv_entry: increase the vm.pmap.shpgperproc tunable");
866         }
867         return (allocated_pv);
868 }
869
870 /*
871  * Conditionally create a pv entry.
872  */
873 static boolean_t
874 pmap_try_insert_pv_entry(pmap_t pmap, vm_offset_t va, vm_page_t m)
875 {
876         pv_entry_t pv;
877
878         PMAP_LOCK_ASSERT(pmap, MA_OWNED);
879         mtx_assert(&vm_page_queue_mtx, MA_OWNED);
880         if (pv_entry_count < pv_entry_high_water && 
881             (pv = uma_zalloc(pvzone, M_NOWAIT)) != NULL) {
882                 pv_entry_count++;
883                 pv->pv_va = va;
884                 pv->pv_pmap = pmap;
885                 TAILQ_INSERT_TAIL(&pmap->pm_pvlist, pv, pv_plist);
886                 TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list);
887                 m->md.pv_list_count++;
888                 return (TRUE);
889         } else
890                 return (FALSE);
891 }
892
893 /*
894  * Add an ia64_lpte to the VHPT.
895  */
896 static void
897 pmap_enter_vhpt(struct ia64_lpte *pte, vm_offset_t va)
898 {
899         struct ia64_bucket *bckt;
900         struct ia64_lpte *vhpte;
901         uint64_t pte_pa;
902
903         /* Can fault, so get it out of the way. */
904         pte_pa = ia64_tpa((vm_offset_t)pte);
905
906         vhpte = (struct ia64_lpte *)ia64_thash(va);
907         bckt = (struct ia64_bucket *)vhpte->chain;
908
909         mtx_lock_spin(&bckt->mutex);
910         pte->chain = bckt->chain;
911         ia64_mf();
912         bckt->chain = pte_pa;
913
914         pmap_vhpt_inserts++;
915         bckt->length++;
916         mtx_unlock_spin(&bckt->mutex);
917 }
918
919 /*
920  * Remove the ia64_lpte matching va from the VHPT. Return zero if it
921  * worked or an appropriate error code otherwise.
922  */
923 static int
924 pmap_remove_vhpt(vm_offset_t va)
925 {
926         struct ia64_bucket *bckt;
927         struct ia64_lpte *pte;
928         struct ia64_lpte *lpte;
929         struct ia64_lpte *vhpte;
930         uint64_t chain, tag;
931
932         tag = ia64_ttag(va);
933         vhpte = (struct ia64_lpte *)ia64_thash(va);
934         bckt = (struct ia64_bucket *)vhpte->chain;
935
936         lpte = NULL;
937         mtx_lock_spin(&bckt->mutex);
938         chain = bckt->chain;
939         pte = (struct ia64_lpte *)IA64_PHYS_TO_RR7(chain);
940         while (chain != 0 && pte->tag != tag) {
941                 lpte = pte;
942                 chain = pte->chain;
943                 pte = (struct ia64_lpte *)IA64_PHYS_TO_RR7(chain);
944         }
945         if (chain == 0) {
946                 mtx_unlock_spin(&bckt->mutex);
947                 return (ENOENT);
948         }
949
950         /* Snip this pv_entry out of the collision chain. */
951         if (lpte == NULL)
952                 bckt->chain = pte->chain;
953         else
954                 lpte->chain = pte->chain;
955         ia64_mf();
956
957         bckt->length--;
958         mtx_unlock_spin(&bckt->mutex);
959         return (0);
960 }
961
962 /*
963  * Find the ia64_lpte for the given va, if any.
964  */
965 static struct ia64_lpte *
966 pmap_find_vhpt(vm_offset_t va)
967 {
968         struct ia64_bucket *bckt;
969         struct ia64_lpte *pte;
970         uint64_t chain, tag;
971
972         tag = ia64_ttag(va);
973         pte = (struct ia64_lpte *)ia64_thash(va);
974         bckt = (struct ia64_bucket *)pte->chain;
975
976         mtx_lock_spin(&bckt->mutex);
977         chain = bckt->chain;
978         pte = (struct ia64_lpte *)IA64_PHYS_TO_RR7(chain);
979         while (chain != 0 && pte->tag != tag) {
980                 chain = pte->chain;
981                 pte = (struct ia64_lpte *)IA64_PHYS_TO_RR7(chain);
982         }
983         mtx_unlock_spin(&bckt->mutex);
984         return ((chain != 0) ? pte : NULL);
985 }
986
987 /*
988  * Remove an entry from the list of managed mappings.
989  */
990 static int
991 pmap_remove_entry(pmap_t pmap, vm_page_t m, vm_offset_t va, pv_entry_t pv)
992 {
993         if (!pv) {
994                 if (m->md.pv_list_count < pmap->pm_stats.resident_count) {
995                         TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
996                                 if (pmap == pv->pv_pmap && va == pv->pv_va) 
997                                         break;
998                         }
999                 } else {
1000                         TAILQ_FOREACH(pv, &pmap->pm_pvlist, pv_plist) {
1001                                 if (va == pv->pv_va) 
1002                                         break;
1003                         }
1004                 }
1005         }
1006
1007         if (pv) {
1008                 TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
1009                 m->md.pv_list_count--;
1010                 if (TAILQ_FIRST(&m->md.pv_list) == NULL)
1011                         vm_page_flag_clear(m, PG_WRITEABLE);
1012
1013                 TAILQ_REMOVE(&pmap->pm_pvlist, pv, pv_plist);
1014                 free_pv_entry(pv);
1015                 return 0;
1016         } else {
1017                 return ENOENT;
1018         }
1019 }
1020
1021 /*
1022  * Create a pv entry for page at pa for
1023  * (pmap, va).
1024  */
1025 static void
1026 pmap_insert_entry(pmap_t pmap, vm_offset_t va, vm_page_t m)
1027 {
1028         pv_entry_t pv;
1029
1030         pv = get_pv_entry(pmap);
1031         pv->pv_pmap = pmap;
1032         pv->pv_va = va;
1033
1034         PMAP_LOCK_ASSERT(pmap, MA_OWNED);
1035         mtx_assert(&vm_page_queue_mtx, MA_OWNED);
1036         TAILQ_INSERT_TAIL(&pmap->pm_pvlist, pv, pv_plist);
1037         TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list);
1038         m->md.pv_list_count++;
1039 }
1040
1041 /*
1042  *      Routine:        pmap_extract
1043  *      Function:
1044  *              Extract the physical page address associated
1045  *              with the given map/virtual_address pair.
1046  */
1047 vm_paddr_t
1048 pmap_extract(pmap_t pmap, vm_offset_t va)
1049 {
1050         struct ia64_lpte *pte;
1051         pmap_t oldpmap;
1052         vm_paddr_t pa;
1053
1054         pa = 0;
1055         PMAP_LOCK(pmap);
1056         oldpmap = pmap_install(pmap);
1057         pte = pmap_find_vhpt(va);
1058         if (pte != NULL && pmap_present(pte))
1059                 pa = pmap_ppn(pte);
1060         pmap_install(oldpmap);
1061         PMAP_UNLOCK(pmap);
1062         return (pa);
1063 }
1064
1065 /*
1066  *      Routine:        pmap_extract_and_hold
1067  *      Function:
1068  *              Atomically extract and hold the physical page
1069  *              with the given pmap and virtual address pair
1070  *              if that mapping permits the given protection.
1071  */
1072 vm_page_t
1073 pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
1074 {
1075         struct ia64_lpte *pte;
1076         pmap_t oldpmap;
1077         vm_page_t m;
1078
1079         m = NULL;
1080         vm_page_lock_queues();
1081         PMAP_LOCK(pmap);
1082         oldpmap = pmap_install(pmap);
1083         pte = pmap_find_vhpt(va);
1084         if (pte != NULL && pmap_present(pte) &&
1085             (pmap_prot(pte) & prot) == prot) {
1086                 m = PHYS_TO_VM_PAGE(pmap_ppn(pte));
1087                 vm_page_hold(m);
1088         }
1089         vm_page_unlock_queues();
1090         pmap_install(oldpmap);
1091         PMAP_UNLOCK(pmap);
1092         return (m);
1093 }
1094
1095 /***************************************************
1096  * Low level mapping routines.....
1097  ***************************************************/
1098
1099 /*
1100  * Find the kernel lpte for mapping the given virtual address, which
1101  * must be in the part of region 5 which we can cover with our kernel
1102  * 'page tables'.
1103  */
1104 static struct ia64_lpte *
1105 pmap_find_kpte(vm_offset_t va)
1106 {
1107         struct ia64_lpte **dir1;
1108         struct ia64_lpte *leaf;
1109
1110         KASSERT((va >> 61) == 5,
1111                 ("kernel mapping 0x%lx not in region 5", va));
1112         KASSERT(va < kernel_vm_end,
1113                 ("kernel mapping 0x%lx out of range", va));
1114
1115         dir1 = ia64_kptdir[KPTE_DIR0_INDEX(va)];
1116         leaf = dir1[KPTE_DIR1_INDEX(va)];
1117         return (&leaf[KPTE_PTE_INDEX(va)]);
1118 }
1119
1120 /*
1121  * Find a pte suitable for mapping a user-space address. If one exists 
1122  * in the VHPT, that one will be returned, otherwise a new pte is
1123  * allocated.
1124  */
1125 static struct ia64_lpte *
1126 pmap_find_pte(vm_offset_t va)
1127 {
1128         struct ia64_lpte *pte;
1129
1130         if (va >= VM_MAXUSER_ADDRESS)
1131                 return pmap_find_kpte(va);
1132
1133         pte = pmap_find_vhpt(va);
1134         if (pte == NULL) {
1135                 pte = uma_zalloc(ptezone, M_NOWAIT | M_ZERO);
1136                 pte->tag = 1UL << 63;
1137         }
1138         return (pte);
1139 }
1140
1141 /*
1142  * Free a pte which is now unused. This simply returns it to the zone
1143  * allocator if it is a user mapping. For kernel mappings, clear the
1144  * valid bit to make it clear that the mapping is not currently used.
1145  */
1146 static void
1147 pmap_free_pte(struct ia64_lpte *pte, vm_offset_t va)
1148 {
1149         if (va < VM_MAXUSER_ADDRESS)
1150                 uma_zfree(ptezone, pte);
1151         else
1152                 pmap_clear_present(pte);
1153 }
1154
1155 static PMAP_INLINE void
1156 pmap_pte_prot(pmap_t pm, struct ia64_lpte *pte, vm_prot_t prot)
1157 {
1158         static long prot2ar[4] = {
1159                 PTE_AR_R,               /* VM_PROT_NONE */
1160                 PTE_AR_RW,              /* VM_PROT_WRITE */
1161                 PTE_AR_RX|PTE_ED,       /* VM_PROT_EXECUTE */
1162                 PTE_AR_RWX|PTE_ED       /* VM_PROT_WRITE|VM_PROT_EXECUTE */
1163         };
1164
1165         pte->pte &= ~(PTE_PROT_MASK | PTE_PL_MASK | PTE_AR_MASK | PTE_ED);
1166         pte->pte |= (uint64_t)(prot & VM_PROT_ALL) << 56;
1167         pte->pte |= (prot == VM_PROT_NONE || pm == kernel_pmap)
1168             ? PTE_PL_KERN : PTE_PL_USER;
1169         pte->pte |= prot2ar[(prot & VM_PROT_ALL) >> 1];
1170 }
1171
1172 /*
1173  * Set a pte to contain a valid mapping and enter it in the VHPT. If
1174  * the pte was orginally valid, then its assumed to already be in the
1175  * VHPT.
1176  * This functions does not set the protection bits.  It's expected
1177  * that those have been set correctly prior to calling this function.
1178  */
1179 static void
1180 pmap_set_pte(struct ia64_lpte *pte, vm_offset_t va, vm_offset_t pa,
1181     boolean_t wired, boolean_t managed)
1182 {
1183
1184         pte->pte &= PTE_PROT_MASK | PTE_PL_MASK | PTE_AR_MASK | PTE_ED;
1185         pte->pte |= PTE_PRESENT | PTE_MA_WB;
1186         pte->pte |= (managed) ? PTE_MANAGED : (PTE_DIRTY | PTE_ACCESSED);
1187         pte->pte |= (wired) ? PTE_WIRED : 0;
1188         pte->pte |= pa & PTE_PPN_MASK;
1189
1190         pte->itir = PAGE_SHIFT << 2;
1191
1192         pte->tag = ia64_ttag(va);
1193 }
1194
1195 /*
1196  * Remove the (possibly managed) mapping represented by pte from the
1197  * given pmap.
1198  */
1199 static int
1200 pmap_remove_pte(pmap_t pmap, struct ia64_lpte *pte, vm_offset_t va,
1201                 pv_entry_t pv, int freepte)
1202 {
1203         int error;
1204         vm_page_t m;
1205
1206         KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(current_pmap)),
1207                 ("removing pte for non-current pmap"));
1208
1209         /*
1210          * First remove from the VHPT.
1211          */
1212         error = pmap_remove_vhpt(va);
1213         if (error)
1214                 return (error);
1215
1216         pmap_invalidate_page(pmap, va);
1217
1218         if (pmap_wired(pte))
1219                 pmap->pm_stats.wired_count -= 1;
1220
1221         pmap->pm_stats.resident_count -= 1;
1222         if (pmap_managed(pte)) {
1223                 m = PHYS_TO_VM_PAGE(pmap_ppn(pte));
1224                 if (pmap_dirty(pte))
1225                         vm_page_dirty(m);
1226                 if (pmap_accessed(pte))
1227                         vm_page_flag_set(m, PG_REFERENCED);
1228
1229                 error = pmap_remove_entry(pmap, m, va, pv);
1230         }
1231         if (freepte)
1232                 pmap_free_pte(pte, va);
1233
1234         return (error);
1235 }
1236
1237 /*
1238  * Extract the physical page address associated with a kernel
1239  * virtual address.
1240  */
1241 vm_paddr_t
1242 pmap_kextract(vm_offset_t va)
1243 {
1244         struct ia64_lpte *pte;
1245         vm_offset_t gwpage;
1246
1247         KASSERT(va >= IA64_RR_BASE(5), ("Must be kernel VA"));
1248
1249         /* Regions 6 and 7 are direct mapped. */
1250         if (va >= IA64_RR_BASE(6))
1251                 return (IA64_RR_MASK(va));
1252
1253         /* EPC gateway page? */
1254         gwpage = (vm_offset_t)ia64_get_k5();
1255         if (va >= gwpage && va < gwpage + VM_GATEWAY_SIZE)
1256                 return (IA64_RR_MASK((vm_offset_t)ia64_gateway_page));
1257
1258         /* Bail out if the virtual address is beyond our limits. */
1259         if (va >= kernel_vm_end)
1260                 return (0);
1261
1262         pte = pmap_find_kpte(va);
1263         if (!pmap_present(pte))
1264                 return (0);
1265         return (pmap_ppn(pte) | (va & PAGE_MASK));
1266 }
1267
1268 /*
1269  * Add a list of wired pages to the kva this routine is only used for
1270  * temporary kernel mappings that do not need to have page modification
1271  * or references recorded.  Note that old mappings are simply written
1272  * over.  The page is effectively wired, but it's customary to not have
1273  * the PTE reflect that, nor update statistics.
1274  */
1275 void
1276 pmap_qenter(vm_offset_t va, vm_page_t *m, int count)
1277 {
1278         struct ia64_lpte *pte;
1279         int i;
1280
1281         for (i = 0; i < count; i++) {
1282                 pte = pmap_find_kpte(va);
1283                 if (pmap_present(pte))
1284                         pmap_invalidate_page(kernel_pmap, va);
1285                 else
1286                         pmap_enter_vhpt(pte, va);
1287                 pmap_pte_prot(kernel_pmap, pte, VM_PROT_ALL);
1288                 pmap_set_pte(pte, va, VM_PAGE_TO_PHYS(m[i]), FALSE, FALSE);
1289                 va += PAGE_SIZE;
1290         }
1291 }
1292
1293 /*
1294  * this routine jerks page mappings from the
1295  * kernel -- it is meant only for temporary mappings.
1296  */
1297 void
1298 pmap_qremove(vm_offset_t va, int count)
1299 {
1300         struct ia64_lpte *pte;
1301         int i;
1302
1303         for (i = 0; i < count; i++) {
1304                 pte = pmap_find_kpte(va);
1305                 if (pmap_present(pte)) {
1306                         pmap_remove_vhpt(va);
1307                         pmap_invalidate_page(kernel_pmap, va);
1308                         pmap_clear_present(pte);
1309                 }
1310                 va += PAGE_SIZE;
1311         }
1312 }
1313
1314 /*
1315  * Add a wired page to the kva.  As for pmap_qenter(), it's customary
1316  * to not have the PTE reflect that, nor update statistics.
1317  */
1318 void 
1319 pmap_kenter(vm_offset_t va, vm_offset_t pa)
1320 {
1321         struct ia64_lpte *pte;
1322
1323         pte = pmap_find_kpte(va);
1324         if (pmap_present(pte))
1325                 pmap_invalidate_page(kernel_pmap, va);
1326         else
1327                 pmap_enter_vhpt(pte, va);
1328         pmap_pte_prot(kernel_pmap, pte, VM_PROT_ALL);
1329         pmap_set_pte(pte, va, pa, FALSE, FALSE);
1330 }
1331
1332 /*
1333  * Remove a page from the kva
1334  */
1335 void
1336 pmap_kremove(vm_offset_t va)
1337 {
1338         struct ia64_lpte *pte;
1339
1340         pte = pmap_find_kpte(va);
1341         if (pmap_present(pte)) {
1342                 pmap_remove_vhpt(va);
1343                 pmap_invalidate_page(kernel_pmap, va);
1344                 pmap_clear_present(pte);
1345         }
1346 }
1347
1348 /*
1349  *      Used to map a range of physical addresses into kernel
1350  *      virtual address space.
1351  *
1352  *      The value passed in '*virt' is a suggested virtual address for
1353  *      the mapping. Architectures which can support a direct-mapped
1354  *      physical to virtual region can return the appropriate address
1355  *      within that region, leaving '*virt' unchanged. Other
1356  *      architectures should map the pages starting at '*virt' and
1357  *      update '*virt' with the first usable address after the mapped
1358  *      region.
1359  */
1360 vm_offset_t
1361 pmap_map(vm_offset_t *virt, vm_offset_t start, vm_offset_t end, int prot)
1362 {
1363         return IA64_PHYS_TO_RR7(start);
1364 }
1365
1366 /*
1367  * Remove a single page from a process address space
1368  */
1369 static void
1370 pmap_remove_page(pmap_t pmap, vm_offset_t va)
1371 {
1372         struct ia64_lpte *pte;
1373
1374         KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(current_pmap)),
1375                 ("removing page for non-current pmap"));
1376
1377         pte = pmap_find_vhpt(va);
1378         if (pte != NULL)
1379                 pmap_remove_pte(pmap, pte, va, 0, 1);
1380         return;
1381 }
1382
1383 /*
1384  *      Remove the given range of addresses from the specified map.
1385  *
1386  *      It is assumed that the start and end are properly
1387  *      rounded to the page size.
1388  */
1389 void
1390 pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
1391 {
1392         pmap_t oldpmap;
1393         vm_offset_t va;
1394         pv_entry_t npv, pv;
1395         struct ia64_lpte *pte;
1396
1397         if (pmap->pm_stats.resident_count == 0)
1398                 return;
1399
1400         vm_page_lock_queues();
1401         PMAP_LOCK(pmap);
1402         oldpmap = pmap_install(pmap);
1403
1404         /*
1405          * special handling of removing one page.  a very
1406          * common operation and easy to short circuit some
1407          * code.
1408          */
1409         if (sva + PAGE_SIZE == eva) {
1410                 pmap_remove_page(pmap, sva);
1411                 goto out;
1412         }
1413
1414         if (pmap->pm_stats.resident_count < ((eva - sva) >> PAGE_SHIFT)) {
1415                 TAILQ_FOREACH_SAFE(pv, &pmap->pm_pvlist, pv_plist, npv) {
1416                         va = pv->pv_va;
1417                         if (va >= sva && va < eva) {
1418                                 pte = pmap_find_vhpt(va);
1419                                 KASSERT(pte != NULL, ("pte"));
1420                                 pmap_remove_pte(pmap, pte, va, pv, 1);
1421                         }
1422                 }
1423         } else {
1424                 for (va = sva; va < eva; va += PAGE_SIZE) {
1425                         pte = pmap_find_vhpt(va);
1426                         if (pte != NULL)
1427                                 pmap_remove_pte(pmap, pte, va, 0, 1);
1428                 }
1429         }
1430
1431 out:
1432         vm_page_unlock_queues();
1433         pmap_install(oldpmap);
1434         PMAP_UNLOCK(pmap);
1435 }
1436
1437 /*
1438  *      Routine:        pmap_remove_all
1439  *      Function:
1440  *              Removes this physical page from
1441  *              all physical maps in which it resides.
1442  *              Reflects back modify bits to the pager.
1443  *
1444  *      Notes:
1445  *              Original versions of this routine were very
1446  *              inefficient because they iteratively called
1447  *              pmap_remove (slow...)
1448  */
1449
1450 void
1451 pmap_remove_all(vm_page_t m)
1452 {
1453         pmap_t oldpmap;
1454         pv_entry_t pv;
1455
1456 #if defined(DIAGNOSTIC)
1457         /*
1458          * XXX this makes pmap_page_protect(NONE) illegal for non-managed
1459          * pages!
1460          */
1461         if (m->flags & PG_FICTITIOUS) {
1462                 panic("pmap_page_protect: illegal for unmanaged page, va: 0x%lx", VM_PAGE_TO_PHYS(m));
1463         }
1464 #endif
1465         mtx_assert(&vm_page_queue_mtx, MA_OWNED);
1466         while ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) {
1467                 struct ia64_lpte *pte;
1468                 pmap_t pmap = pv->pv_pmap;
1469                 vm_offset_t va = pv->pv_va;
1470
1471                 PMAP_LOCK(pmap);
1472                 oldpmap = pmap_install(pmap);
1473                 pte = pmap_find_vhpt(va);
1474                 KASSERT(pte != NULL, ("pte"));
1475                 if (pmap_ppn(pte) != VM_PAGE_TO_PHYS(m))
1476                         panic("pmap_remove_all: pv_table for %lx is inconsistent", VM_PAGE_TO_PHYS(m));
1477                 pmap_remove_pte(pmap, pte, va, pv, 1);
1478                 pmap_install(oldpmap);
1479                 PMAP_UNLOCK(pmap);
1480         }
1481         vm_page_flag_clear(m, PG_WRITEABLE);
1482 }
1483
1484 /*
1485  *      Set the physical protection on the
1486  *      specified range of this map as requested.
1487  */
1488 void
1489 pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
1490 {
1491         pmap_t oldpmap;
1492         struct ia64_lpte *pte;
1493
1494         if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
1495                 pmap_remove(pmap, sva, eva);
1496                 return;
1497         }
1498
1499         if ((prot & (VM_PROT_WRITE|VM_PROT_EXECUTE)) ==
1500             (VM_PROT_WRITE|VM_PROT_EXECUTE))
1501                 return;
1502
1503         if ((sva & PAGE_MASK) || (eva & PAGE_MASK))
1504                 panic("pmap_protect: unaligned addresses");
1505
1506         vm_page_lock_queues();
1507         PMAP_LOCK(pmap);
1508         oldpmap = pmap_install(pmap);
1509         while (sva < eva) {
1510                 /* 
1511                  * If page is invalid, skip this page
1512                  */
1513                 pte = pmap_find_vhpt(sva);
1514                 if (pte == NULL) {
1515                         sva += PAGE_SIZE;
1516                         continue;
1517                 }
1518
1519                 if (pmap_prot(pte) != prot) {
1520                         if (pmap_managed(pte)) {
1521                                 vm_offset_t pa = pmap_ppn(pte);
1522                                 vm_page_t m = PHYS_TO_VM_PAGE(pa);
1523                                 if (pmap_dirty(pte)) {
1524                                         vm_page_dirty(m);
1525                                         pmap_clear_dirty(pte);
1526                                 }
1527                                 if (pmap_accessed(pte)) {
1528                                         vm_page_flag_set(m, PG_REFERENCED);
1529                                         pmap_clear_accessed(pte);
1530                                 }
1531                         }
1532                         pmap_pte_prot(pmap, pte, prot);
1533                         pmap_invalidate_page(pmap, sva);
1534                 }
1535
1536                 sva += PAGE_SIZE;
1537         }
1538         vm_page_unlock_queues();
1539         pmap_install(oldpmap);
1540         PMAP_UNLOCK(pmap);
1541 }
1542
1543 /*
1544  *      Insert the given physical page (p) at
1545  *      the specified virtual address (v) in the
1546  *      target physical map with the protection requested.
1547  *
1548  *      If specified, the page will be wired down, meaning
1549  *      that the related pte can not be reclaimed.
1550  *
1551  *      NB:  This is the only routine which MAY NOT lazy-evaluate
1552  *      or lose information.  That is, this routine must actually
1553  *      insert this page into the given map NOW.
1554  */
1555 void
1556 pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
1557     boolean_t wired)
1558 {
1559         pmap_t oldpmap;
1560         vm_offset_t pa;
1561         vm_offset_t opa;
1562         struct ia64_lpte origpte;
1563         struct ia64_lpte *pte;
1564         boolean_t managed;
1565
1566         vm_page_lock_queues();
1567         PMAP_LOCK(pmap);
1568         oldpmap = pmap_install(pmap);
1569
1570         va &= ~PAGE_MASK;
1571 #ifdef DIAGNOSTIC
1572         if (va > VM_MAX_KERNEL_ADDRESS)
1573                 panic("pmap_enter: toobig");
1574 #endif
1575
1576         /*
1577          * Find (or create) a pte for the given mapping.
1578          */
1579         while ((pte = pmap_find_pte(va)) == NULL) {
1580                 pmap_install(oldpmap);
1581                 PMAP_UNLOCK(pmap);
1582                 vm_page_unlock_queues();
1583                 VM_WAIT;
1584                 vm_page_lock_queues();
1585                 PMAP_LOCK(pmap);
1586                 oldpmap = pmap_install(pmap);
1587         }
1588         origpte = *pte;
1589         if (!pmap_present(pte)) {
1590                 opa = ~0UL;
1591                 pmap_enter_vhpt(pte, va);
1592         } else
1593                 opa = pmap_ppn(pte);
1594         managed = FALSE;
1595         pa = VM_PAGE_TO_PHYS(m);
1596
1597         /*
1598          * Mapping has not changed, must be protection or wiring change.
1599          */
1600         if (opa == pa) {
1601                 /*
1602                  * Wiring change, just update stats. We don't worry about
1603                  * wiring PT pages as they remain resident as long as there
1604                  * are valid mappings in them. Hence, if a user page is wired,
1605                  * the PT page will be also.
1606                  */
1607                 if (wired && !pmap_wired(&origpte))
1608                         pmap->pm_stats.wired_count++;
1609                 else if (!wired && pmap_wired(&origpte))
1610                         pmap->pm_stats.wired_count--;
1611
1612                 managed = (pmap_managed(&origpte)) ? TRUE : FALSE;
1613
1614                 /*
1615                  * We might be turning off write access to the page,
1616                  * so we go ahead and sense modify status.
1617                  */
1618                 if (managed && pmap_dirty(&origpte))
1619                         vm_page_dirty(m);
1620
1621                 pmap_invalidate_page(pmap, va);
1622                 goto validate;
1623         }
1624
1625         /*
1626          * Mapping has changed, invalidate old range and fall
1627          * through to handle validating new mapping.
1628          */
1629         if (opa != ~0UL) {
1630                 pmap_remove_pte(pmap, pte, va, 0, 0);
1631                 pmap_enter_vhpt(pte, va);
1632         }
1633
1634         /*
1635          * Enter on the PV list if part of our managed memory.
1636          */
1637         if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0) {
1638                 KASSERT(va < kmi.clean_sva || va >= kmi.clean_eva,
1639                     ("pmap_enter: managed mapping within the clean submap"));
1640                 pmap_insert_entry(pmap, va, m);
1641                 managed = TRUE;
1642         }
1643
1644         /*
1645          * Increment counters
1646          */
1647         pmap->pm_stats.resident_count++;
1648         if (wired)
1649                 pmap->pm_stats.wired_count++;
1650
1651 validate:
1652
1653         /*
1654          * Now validate mapping with desired protection/wiring. This
1655          * adds the pte to the VHPT if necessary.
1656          */
1657         pmap_pte_prot(pmap, pte, prot);
1658         pmap_set_pte(pte, va, pa, wired, managed);
1659
1660         if ((prot & VM_PROT_WRITE) != 0)
1661                 vm_page_flag_set(m, PG_WRITEABLE);
1662         vm_page_unlock_queues();
1663         pmap_install(oldpmap);
1664         PMAP_UNLOCK(pmap);
1665 }
1666
1667 /*
1668  * Maps a sequence of resident pages belonging to the same object.
1669  * The sequence begins with the given page m_start.  This page is
1670  * mapped at the given virtual address start.  Each subsequent page is
1671  * mapped at a virtual address that is offset from start by the same
1672  * amount as the page is offset from m_start within the object.  The
1673  * last page in the sequence is the page with the largest offset from
1674  * m_start that can be mapped at a virtual address less than the given
1675  * virtual address end.  Not every virtual page between start and end
1676  * is mapped; only those for which a resident page exists with the
1677  * corresponding offset from m_start are mapped.
1678  */
1679 void
1680 pmap_enter_object(pmap_t pmap, vm_offset_t start, vm_offset_t end,
1681     vm_page_t m_start, vm_prot_t prot)
1682 {
1683         pmap_t oldpmap;
1684         vm_page_t m;
1685         vm_pindex_t diff, psize;
1686
1687         VM_OBJECT_LOCK_ASSERT(m_start->object, MA_OWNED);
1688         psize = atop(end - start);
1689         m = m_start;
1690         PMAP_LOCK(pmap);
1691         oldpmap = pmap_install(pmap);
1692         while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) {
1693                 pmap_enter_quick_locked(pmap, start + ptoa(diff), m, prot);
1694                 m = TAILQ_NEXT(m, listq);
1695         }
1696         pmap_install(oldpmap);
1697         PMAP_UNLOCK(pmap);
1698 }
1699
1700 /*
1701  * this code makes some *MAJOR* assumptions:
1702  * 1. Current pmap & pmap exists.
1703  * 2. Not wired.
1704  * 3. Read access.
1705  * 4. No page table pages.
1706  * but is *MUCH* faster than pmap_enter...
1707  */
1708
1709 void
1710 pmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot)
1711 {
1712         pmap_t oldpmap;
1713
1714         PMAP_LOCK(pmap);
1715         oldpmap = pmap_install(pmap);
1716         pmap_enter_quick_locked(pmap, va, m, prot);
1717         pmap_install(oldpmap);
1718         PMAP_UNLOCK(pmap);
1719 }
1720
1721 static void
1722 pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m,
1723     vm_prot_t prot)
1724 {
1725         struct ia64_lpte *pte;
1726         boolean_t managed;
1727
1728         KASSERT(va < kmi.clean_sva || va >= kmi.clean_eva ||
1729             (m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) != 0,
1730             ("pmap_enter_quick_locked: managed mapping within the clean submap"));
1731         mtx_assert(&vm_page_queue_mtx, MA_OWNED);
1732         PMAP_LOCK_ASSERT(pmap, MA_OWNED);
1733
1734         if ((pte = pmap_find_pte(va)) == NULL)
1735                 return;
1736
1737         if (!pmap_present(pte)) {
1738                 /* Enter on the PV list if the page is managed. */
1739                 if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0) {
1740                         if (!pmap_try_insert_pv_entry(pmap, va, m)) {
1741                                 pmap_free_pte(pte, va);
1742                                 return;
1743                         }
1744                         managed = TRUE;
1745                 } else
1746                         managed = FALSE;
1747
1748                 /* Increment counters. */
1749                 pmap->pm_stats.resident_count++;
1750
1751                 /* Initialise with R/O protection and enter into VHPT. */
1752                 pmap_enter_vhpt(pte, va);
1753                 pmap_pte_prot(pmap, pte,
1754                     prot & (VM_PROT_READ | VM_PROT_EXECUTE));
1755                 pmap_set_pte(pte, va, VM_PAGE_TO_PHYS(m), FALSE, managed);
1756         }
1757 }
1758
1759 /*
1760  * pmap_object_init_pt preloads the ptes for a given object
1761  * into the specified pmap.  This eliminates the blast of soft
1762  * faults on process startup and immediately after an mmap.
1763  */
1764 void
1765 pmap_object_init_pt(pmap_t pmap, vm_offset_t addr,
1766                     vm_object_t object, vm_pindex_t pindex,
1767                     vm_size_t size)
1768 {
1769
1770         VM_OBJECT_LOCK_ASSERT(object, MA_OWNED);
1771         KASSERT(object->type == OBJT_DEVICE,
1772             ("pmap_object_init_pt: non-device object"));
1773 }
1774
1775 /*
1776  *      Routine:        pmap_change_wiring
1777  *      Function:       Change the wiring attribute for a map/virtual-address
1778  *                      pair.
1779  *      In/out conditions:
1780  *                      The mapping must already exist in the pmap.
1781  */
1782 void
1783 pmap_change_wiring(pmap, va, wired)
1784         register pmap_t pmap;
1785         vm_offset_t va;
1786         boolean_t wired;
1787 {
1788         pmap_t oldpmap;
1789         struct ia64_lpte *pte;
1790
1791         PMAP_LOCK(pmap);
1792         oldpmap = pmap_install(pmap);
1793
1794         pte = pmap_find_vhpt(va);
1795         KASSERT(pte != NULL, ("pte"));
1796         if (wired && !pmap_wired(pte)) {
1797                 pmap->pm_stats.wired_count++;
1798                 pmap_set_wired(pte);
1799         } else if (!wired && pmap_wired(pte)) {
1800                 pmap->pm_stats.wired_count--;
1801                 pmap_clear_wired(pte);
1802         }
1803
1804         pmap_install(oldpmap);
1805         PMAP_UNLOCK(pmap);
1806 }
1807
1808
1809
1810 /*
1811  *      Copy the range specified by src_addr/len
1812  *      from the source map to the range dst_addr/len
1813  *      in the destination map.
1814  *
1815  *      This routine is only advisory and need not do anything.
1816  */
1817
1818 void
1819 pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len,
1820           vm_offset_t src_addr)
1821 {
1822 }       
1823
1824
1825 /*
1826  *      pmap_zero_page zeros the specified hardware page by
1827  *      mapping it into virtual memory and using bzero to clear
1828  *      its contents.
1829  */
1830
1831 void
1832 pmap_zero_page(vm_page_t m)
1833 {
1834         vm_offset_t va = IA64_PHYS_TO_RR7(VM_PAGE_TO_PHYS(m));
1835         bzero((caddr_t) va, PAGE_SIZE);
1836 }
1837
1838
1839 /*
1840  *      pmap_zero_page_area zeros the specified hardware page by
1841  *      mapping it into virtual memory and using bzero to clear
1842  *      its contents.
1843  *
1844  *      off and size must reside within a single page.
1845  */
1846
1847 void
1848 pmap_zero_page_area(vm_page_t m, int off, int size)
1849 {
1850         vm_offset_t va = IA64_PHYS_TO_RR7(VM_PAGE_TO_PHYS(m));
1851         bzero((char *)(caddr_t)va + off, size);
1852 }
1853
1854
1855 /*
1856  *      pmap_zero_page_idle zeros the specified hardware page by
1857  *      mapping it into virtual memory and using bzero to clear
1858  *      its contents.  This is for the vm_idlezero process.
1859  */
1860
1861 void
1862 pmap_zero_page_idle(vm_page_t m)
1863 {
1864         vm_offset_t va = IA64_PHYS_TO_RR7(VM_PAGE_TO_PHYS(m));
1865         bzero((caddr_t) va, PAGE_SIZE);
1866 }
1867
1868
1869 /*
1870  *      pmap_copy_page copies the specified (machine independent)
1871  *      page by mapping the page into virtual memory and using
1872  *      bcopy to copy the page, one machine dependent page at a
1873  *      time.
1874  */
1875 void
1876 pmap_copy_page(vm_page_t msrc, vm_page_t mdst)
1877 {
1878         vm_offset_t src = IA64_PHYS_TO_RR7(VM_PAGE_TO_PHYS(msrc));
1879         vm_offset_t dst = IA64_PHYS_TO_RR7(VM_PAGE_TO_PHYS(mdst));
1880         bcopy((caddr_t) src, (caddr_t) dst, PAGE_SIZE);
1881 }
1882
1883 /*
1884  * Returns true if the pmap's pv is one of the first
1885  * 16 pvs linked to from this page.  This count may
1886  * be changed upwards or downwards in the future; it
1887  * is only necessary that true be returned for a small
1888  * subset of pmaps for proper page aging.
1889  */
1890 boolean_t
1891 pmap_page_exists_quick(pmap_t pmap, vm_page_t m)
1892 {
1893         pv_entry_t pv;
1894         int loops = 0;
1895
1896         if (m->flags & PG_FICTITIOUS)
1897                 return FALSE;
1898
1899         /*
1900          * Not found, check current mappings returning immediately if found.
1901          */
1902         mtx_assert(&vm_page_queue_mtx, MA_OWNED);
1903         TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
1904                 if (pv->pv_pmap == pmap) {
1905                         return TRUE;
1906                 }
1907                 loops++;
1908                 if (loops >= 16)
1909                         break;
1910         }
1911         return (FALSE);
1912 }
1913
1914 /*
1915  * Remove all pages from specified address space
1916  * this aids process exit speeds.  Also, this code
1917  * is special cased for current process only, but
1918  * can have the more generic (and slightly slower)
1919  * mode enabled.  This is much faster than pmap_remove
1920  * in the case of running down an entire address space.
1921  */
1922 void
1923 pmap_remove_pages(pmap_t pmap)
1924 {
1925         pmap_t oldpmap;
1926         pv_entry_t pv, npv;
1927
1928         if (pmap != vmspace_pmap(curthread->td_proc->p_vmspace)) {
1929                 printf("warning: pmap_remove_pages called with non-current pmap\n");
1930                 return;
1931         }
1932
1933         vm_page_lock_queues();
1934         PMAP_LOCK(pmap);
1935         oldpmap = pmap_install(pmap);
1936
1937         for (pv = TAILQ_FIRST(&pmap->pm_pvlist); pv; pv = npv) {
1938                 struct ia64_lpte *pte;
1939
1940                 npv = TAILQ_NEXT(pv, pv_plist);
1941
1942                 pte = pmap_find_vhpt(pv->pv_va);
1943                 KASSERT(pte != NULL, ("pte"));
1944                 if (!pmap_wired(pte))
1945                         pmap_remove_pte(pmap, pte, pv->pv_va, pv, 1);
1946         }
1947
1948         pmap_install(oldpmap);
1949         PMAP_UNLOCK(pmap);
1950         vm_page_unlock_queues();
1951 }
1952
1953 /*
1954  *      pmap_ts_referenced:
1955  *
1956  *      Return a count of reference bits for a page, clearing those bits.
1957  *      It is not necessary for every reference bit to be cleared, but it
1958  *      is necessary that 0 only be returned when there are truly no
1959  *      reference bits set.
1960  * 
1961  *      XXX: The exact number of bits to check and clear is a matter that
1962  *      should be tested and standardized at some point in the future for
1963  *      optimal aging of shared pages.
1964  */
1965 int
1966 pmap_ts_referenced(vm_page_t m)
1967 {
1968         struct ia64_lpte *pte;
1969         pmap_t oldpmap;
1970         pv_entry_t pv;
1971         int count = 0;
1972
1973         if (m->flags & PG_FICTITIOUS)
1974                 return 0;
1975
1976         TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
1977                 PMAP_LOCK(pv->pv_pmap);
1978                 oldpmap = pmap_install(pv->pv_pmap);
1979                 pte = pmap_find_vhpt(pv->pv_va);
1980                 KASSERT(pte != NULL, ("pte"));
1981                 if (pmap_accessed(pte)) {
1982                         count++;
1983                         pmap_clear_accessed(pte);
1984                         pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
1985                 }
1986                 pmap_install(oldpmap);
1987                 PMAP_UNLOCK(pv->pv_pmap);
1988         }
1989
1990         return count;
1991 }
1992
1993 /*
1994  *      pmap_is_modified:
1995  *
1996  *      Return whether or not the specified physical page was modified
1997  *      in any physical maps.
1998  */
1999 boolean_t
2000 pmap_is_modified(vm_page_t m)
2001 {
2002         struct ia64_lpte *pte;
2003         pmap_t oldpmap;
2004         pv_entry_t pv;
2005         boolean_t rv;
2006
2007         rv = FALSE;
2008         if (m->flags & PG_FICTITIOUS)
2009                 return (rv);
2010
2011         TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
2012                 PMAP_LOCK(pv->pv_pmap);
2013                 oldpmap = pmap_install(pv->pv_pmap);
2014                 pte = pmap_find_vhpt(pv->pv_va);
2015                 pmap_install(oldpmap);
2016                 KASSERT(pte != NULL, ("pte"));
2017                 rv = pmap_dirty(pte) ? TRUE : FALSE;
2018                 PMAP_UNLOCK(pv->pv_pmap);
2019                 if (rv)
2020                         break;
2021         }
2022
2023         return (rv);
2024 }
2025
2026 /*
2027  *      pmap_is_prefaultable:
2028  *
2029  *      Return whether or not the specified virtual address is elgible
2030  *      for prefault.
2031  */
2032 boolean_t
2033 pmap_is_prefaultable(pmap_t pmap, vm_offset_t addr)
2034 {
2035         struct ia64_lpte *pte;
2036
2037         pte = pmap_find_vhpt(addr);
2038         if (pte != NULL && pmap_present(pte))
2039                 return (FALSE);
2040         return (TRUE);
2041 }
2042
2043 /*
2044  *      Clear the modify bits on the specified physical page.
2045  */
2046 void
2047 pmap_clear_modify(vm_page_t m)
2048 {
2049         struct ia64_lpte *pte;
2050         pmap_t oldpmap;
2051         pv_entry_t pv;
2052
2053         if (m->flags & PG_FICTITIOUS)
2054                 return;
2055
2056         TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
2057                 PMAP_LOCK(pv->pv_pmap);
2058                 oldpmap = pmap_install(pv->pv_pmap);
2059                 pte = pmap_find_vhpt(pv->pv_va);
2060                 KASSERT(pte != NULL, ("pte"));
2061                 if (pmap_dirty(pte)) {
2062                         pmap_clear_dirty(pte);
2063                         pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
2064                 }
2065                 pmap_install(oldpmap);
2066                 PMAP_UNLOCK(pv->pv_pmap);
2067         }
2068 }
2069
2070 /*
2071  *      pmap_clear_reference:
2072  *
2073  *      Clear the reference bit on the specified physical page.
2074  */
2075 void
2076 pmap_clear_reference(vm_page_t m)
2077 {
2078         struct ia64_lpte *pte;
2079         pmap_t oldpmap;
2080         pv_entry_t pv;
2081
2082         if (m->flags & PG_FICTITIOUS)
2083                 return;
2084
2085         TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
2086                 PMAP_LOCK(pv->pv_pmap);
2087                 oldpmap = pmap_install(pv->pv_pmap);
2088                 pte = pmap_find_vhpt(pv->pv_va);
2089                 KASSERT(pte != NULL, ("pte"));
2090                 if (pmap_accessed(pte)) {
2091                         pmap_clear_accessed(pte);
2092                         pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
2093                 }
2094                 pmap_install(oldpmap);
2095                 PMAP_UNLOCK(pv->pv_pmap);
2096         }
2097 }
2098
2099 /*
2100  * Clear the write and modified bits in each of the given page's mappings.
2101  */
2102 void
2103 pmap_remove_write(vm_page_t m)
2104 {
2105         struct ia64_lpte *pte;
2106         pmap_t oldpmap, pmap;
2107         pv_entry_t pv;
2108         vm_prot_t prot;
2109
2110         mtx_assert(&vm_page_queue_mtx, MA_OWNED);
2111         if ((m->flags & PG_FICTITIOUS) != 0 ||
2112             (m->flags & PG_WRITEABLE) == 0)
2113                 return;
2114         TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
2115                 pmap = pv->pv_pmap;
2116                 PMAP_LOCK(pmap);
2117                 oldpmap = pmap_install(pmap);
2118                 pte = pmap_find_vhpt(pv->pv_va);
2119                 KASSERT(pte != NULL, ("pte"));
2120                 prot = pmap_prot(pte);
2121                 if ((prot & VM_PROT_WRITE) != 0) {
2122                         if (pmap_dirty(pte)) {
2123                                 vm_page_dirty(m);
2124                                 pmap_clear_dirty(pte);
2125                         }
2126                         prot &= ~VM_PROT_WRITE;
2127                         pmap_pte_prot(pmap, pte, prot);
2128                         pmap_invalidate_page(pmap, pv->pv_va);
2129                 }
2130                 pmap_install(oldpmap);
2131                 PMAP_UNLOCK(pmap);
2132         }
2133         vm_page_flag_clear(m, PG_WRITEABLE);
2134 }
2135
2136 /*
2137  * Map a set of physical memory pages into the kernel virtual
2138  * address space. Return a pointer to where it is mapped. This
2139  * routine is intended to be used for mapping device memory,
2140  * NOT real memory.
2141  */
2142 void *
2143 pmap_mapdev(vm_offset_t pa, vm_size_t size)
2144 {
2145         return (void*) IA64_PHYS_TO_RR6(pa);
2146 }
2147
2148 /*
2149  * 'Unmap' a range mapped by pmap_mapdev().
2150  */
2151 void
2152 pmap_unmapdev(vm_offset_t va, vm_size_t size)
2153 {
2154         return;
2155 }
2156
2157 /*
2158  * perform the pmap work for mincore
2159  */
2160 int
2161 pmap_mincore(pmap_t pmap, vm_offset_t addr)
2162 {
2163         pmap_t oldpmap;
2164         struct ia64_lpte *pte, tpte;
2165         int val = 0;
2166         
2167         PMAP_LOCK(pmap);
2168         oldpmap = pmap_install(pmap);
2169         pte = pmap_find_vhpt(addr);
2170         if (pte != NULL) {
2171                 tpte = *pte;
2172                 pte = &tpte;
2173         }
2174         pmap_install(oldpmap);
2175         PMAP_UNLOCK(pmap);
2176
2177         if (pte == NULL)
2178                 return 0;
2179
2180         if (pmap_present(pte)) {
2181                 vm_page_t m;
2182                 vm_offset_t pa;
2183
2184                 val = MINCORE_INCORE;
2185                 if (!pmap_managed(pte))
2186                         return val;
2187
2188                 pa = pmap_ppn(pte);
2189
2190                 m = PHYS_TO_VM_PAGE(pa);
2191
2192                 /*
2193                  * Modified by us
2194                  */
2195                 if (pmap_dirty(pte))
2196                         val |= MINCORE_MODIFIED|MINCORE_MODIFIED_OTHER;
2197                 else {
2198                         /*
2199                          * Modified by someone
2200                          */
2201                         vm_page_lock_queues();
2202                         if (pmap_is_modified(m))
2203                                 val |= MINCORE_MODIFIED_OTHER;
2204                         vm_page_unlock_queues();
2205                 }
2206                 /*
2207                  * Referenced by us
2208                  */
2209                 if (pmap_accessed(pte))
2210                         val |= MINCORE_REFERENCED|MINCORE_REFERENCED_OTHER;
2211                 else {
2212                         /*
2213                          * Referenced by someone
2214                          */
2215                         vm_page_lock_queues();
2216                         if (pmap_ts_referenced(m)) {
2217                                 val |= MINCORE_REFERENCED_OTHER;
2218                                 vm_page_flag_set(m, PG_REFERENCED);
2219                         }
2220                         vm_page_unlock_queues();
2221                 }
2222         } 
2223         return val;
2224 }
2225
2226 void
2227 pmap_activate(struct thread *td)
2228 {
2229         pmap_install(vmspace_pmap(td->td_proc->p_vmspace));
2230 }
2231
2232 pmap_t
2233 pmap_switch(pmap_t pm)
2234 {
2235         pmap_t prevpm;
2236         int i;
2237
2238         THREAD_LOCK_ASSERT(curthread, MA_OWNED);
2239         prevpm = PCPU_GET(current_pmap);
2240         if (prevpm == pm)
2241                 return (prevpm);
2242         if (prevpm != NULL)
2243                 atomic_clear_32(&prevpm->pm_active, PCPU_GET(cpumask));
2244         if (pm == NULL) {
2245                 for (i = 0; i < 5; i++) {
2246                         ia64_set_rr(IA64_RR_BASE(i),
2247                             (i << 8)|(PAGE_SHIFT << 2)|1);
2248                 }
2249         } else {
2250                 for (i = 0; i < 5; i++) {
2251                         ia64_set_rr(IA64_RR_BASE(i),
2252                             (pm->pm_rid[i] << 8)|(PAGE_SHIFT << 2)|1);
2253                 }
2254                 atomic_set_32(&pm->pm_active, PCPU_GET(cpumask));
2255         }
2256         PCPU_SET(current_pmap, pm);
2257         __asm __volatile("srlz.d");
2258         return (prevpm);
2259 }
2260
2261 static pmap_t
2262 pmap_install(pmap_t pm)
2263 {
2264         pmap_t prevpm;
2265         struct thread *td;
2266
2267         td = curthread;
2268         thread_lock(td);
2269         prevpm = pmap_switch(pm);
2270         thread_unlock(td);
2271
2272         return (prevpm);
2273 }
2274
2275 vm_offset_t
2276 pmap_addr_hint(vm_object_t obj, vm_offset_t addr, vm_size_t size)
2277 {
2278
2279         return addr;
2280 }
2281
2282 #include "opt_ddb.h"
2283
2284 #ifdef DDB
2285
2286 #include <ddb/ddb.h>
2287
2288 static const char*      psnames[] = {
2289         "1B",   "2B",   "4B",   "8B",
2290         "16B",  "32B",  "64B",  "128B",
2291         "256B", "512B", "1K",   "2K",
2292         "4K",   "8K",   "16K",  "32K",
2293         "64K",  "128K", "256K", "512K",
2294         "1M",   "2M",   "4M",   "8M",
2295         "16M",  "32M",  "64M",  "128M",
2296         "256M", "512M", "1G",   "2G"
2297 };
2298
2299 static void
2300 print_trs(int type)
2301 {
2302         struct ia64_pal_result res;
2303         int i, maxtr;
2304         struct {
2305                 pt_entry_t      pte;
2306                 uint64_t        itir;
2307                 uint64_t        ifa;
2308                 struct ia64_rr  rr;
2309         } buf;
2310         static const char *manames[] = {
2311                 "WB",   "bad",  "bad",  "bad",
2312                 "UC",   "UCE",  "WC",   "NaT",
2313         };
2314
2315         res = ia64_call_pal_static(PAL_VM_SUMMARY, 0, 0, 0);
2316         if (res.pal_status != 0) {
2317                 db_printf("Can't get VM summary\n");
2318                 return;
2319         }
2320
2321         if (type == 0)
2322                 maxtr = (res.pal_result[0] >> 40) & 0xff;
2323         else
2324                 maxtr = (res.pal_result[0] >> 32) & 0xff;
2325
2326         db_printf("V RID    Virtual Page  Physical Page PgSz ED AR PL D A MA  P KEY\n");
2327         for (i = 0; i <= maxtr; i++) {
2328                 bzero(&buf, sizeof(buf));
2329                 res = ia64_call_pal_stacked_physical
2330                         (PAL_VM_TR_READ, i, type, ia64_tpa((uint64_t) &buf));
2331                 if (!(res.pal_result[0] & 1))
2332                         buf.pte &= ~PTE_AR_MASK;
2333                 if (!(res.pal_result[0] & 2))
2334                         buf.pte &= ~PTE_PL_MASK;
2335                 if (!(res.pal_result[0] & 4))
2336                         pmap_clear_dirty(&buf);
2337                 if (!(res.pal_result[0] & 8))
2338                         buf.pte &= ~PTE_MA_MASK;
2339                 db_printf("%d %06x %013lx %013lx %4s %d  %d  %d  %d %d %-3s "
2340                     "%d %06x\n", (int)buf.ifa & 1, buf.rr.rr_rid,
2341                     buf.ifa >> 12, (buf.pte & PTE_PPN_MASK) >> 12,
2342                     psnames[(buf.itir & ITIR_PS_MASK) >> 2],
2343                     (buf.pte & PTE_ED) ? 1 : 0,
2344                     (int)(buf.pte & PTE_AR_MASK) >> 9,
2345                     (int)(buf.pte & PTE_PL_MASK) >> 7,
2346                     (pmap_dirty(&buf)) ? 1 : 0,
2347                     (pmap_accessed(&buf)) ? 1 : 0,
2348                     manames[(buf.pte & PTE_MA_MASK) >> 2],
2349                     (pmap_present(&buf)) ? 1 : 0,
2350                     (int)((buf.itir & ITIR_KEY_MASK) >> 8));
2351         }
2352 }
2353
2354 DB_COMMAND(itr, db_itr)
2355 {
2356         print_trs(0);
2357 }
2358
2359 DB_COMMAND(dtr, db_dtr)
2360 {
2361         print_trs(1);
2362 }
2363
2364 DB_COMMAND(rr, db_rr)
2365 {
2366         int i;
2367         uint64_t t;
2368         struct ia64_rr rr;
2369
2370         printf("RR RID    PgSz VE\n");
2371         for (i = 0; i < 8; i++) {
2372                 __asm __volatile ("mov %0=rr[%1]"
2373                                   : "=r"(t)
2374                                   : "r"(IA64_RR_BASE(i)));
2375                 *(uint64_t *) &rr = t;
2376                 printf("%d  %06x %4s %d\n",
2377                        i, rr.rr_rid, psnames[rr.rr_ps], rr.rr_ve);
2378         }
2379 }
2380
2381 DB_COMMAND(thash, db_thash)
2382 {
2383         if (!have_addr)
2384                 return;
2385
2386         db_printf("%p\n", (void *) ia64_thash(addr));
2387 }
2388
2389 DB_COMMAND(ttag, db_ttag)
2390 {
2391         if (!have_addr)
2392                 return;
2393
2394         db_printf("0x%lx\n", ia64_ttag(addr));
2395 }
2396
2397 DB_COMMAND(kpte, db_kpte)
2398 {
2399         struct ia64_lpte *pte;
2400
2401         if (!have_addr) {
2402                 db_printf("usage: kpte <kva>\n");
2403                 return;
2404         }
2405         if (addr < VM_MIN_KERNEL_ADDRESS) {
2406                 db_printf("kpte: error: invalid <kva>\n");
2407                 return;
2408         }
2409         pte = pmap_find_kpte(addr);
2410         db_printf("kpte at %p:\n", pte);
2411         db_printf("  pte  =%016lx\n", pte->pte);
2412         db_printf("  itir =%016lx\n", pte->itir);
2413         db_printf("  tag  =%016lx\n", pte->tag);
2414         db_printf("  chain=%016lx\n", pte->chain);
2415 }
2416
2417 #endif