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