pmap.c revision 85024
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 * $FreeBSD: head/sys/ia64/ia64/pmap.c 85024 2001-10-16 08:03:16Z dfr $
47 */
48
49/*
50 *	Manages physical address maps.
51 *
52 *	In addition to hardware address maps, this
53 *	module is called upon to provide software-use-only
54 *	maps which may or may not be stored in the same
55 *	form as hardware maps.  These pseudo-maps are
56 *	used to store intermediate results from copy
57 *	operations to and from address spaces.
58 *
59 *	Since the information managed by this module is
60 *	also stored by the logical address mapping module,
61 *	this module may throw away valid virtual-to-physical
62 *	mappings at almost any time.  However, invalidations
63 *	of virtual-to-physical mappings must be done as
64 *	requested.
65 *
66 *	In order to cope with hardware architectures which
67 *	make virtual-to-physical map invalidates expensive,
68 *	this module may delay invalidate or reduced protection
69 *	operations until such time as they are actually
70 *	necessary.  This module is given full information as
71 *	to which processors are currently using which maps,
72 *	and to when physical maps must be made correct.
73 */
74
75/*
76 * Following the Linux model, region IDs are allocated in groups of
77 * eight so that a single region ID can be used for as many RRs as we
78 * want by encoding the RR number into the low bits of the ID.
79 *
80 * We reserve region ID 0 for the kernel and allocate the remaining
81 * IDs for user pmaps.
82 *
83 * Region 0..4
84 *	User virtually mapped
85 *
86 * Region 5
87 *	Kernel virtually mapped
88 *
89 * Region 6
90 *	Kernel physically mapped uncacheable
91 *
92 * Region 7
93 *	Kernel physically mapped cacheable
94 */
95
96#include <sys/param.h>
97#include <sys/kernel.h>
98#include <sys/lock.h>
99#include <sys/malloc.h>
100#include <sys/mman.h>
101#include <sys/msgbuf.h>
102#include <sys/mutex.h>
103#include <sys/proc.h>
104#include <sys/sx.h>
105#include <sys/systm.h>
106#include <sys/vmmeter.h>
107
108#include <vm/vm.h>
109#include <vm/vm_param.h>
110#include <vm/vm_kern.h>
111#include <vm/vm_page.h>
112#include <vm/vm_map.h>
113#include <vm/vm_object.h>
114#include <vm/vm_extern.h>
115#include <vm/vm_pageout.h>
116#include <vm/vm_pager.h>
117#include <vm/vm_zone.h>
118
119#include <sys/user.h>
120
121#include <machine/pal.h>
122#include <machine/md_var.h>
123
124MALLOC_DEFINE(M_PMAP, "PMAP", "PMAP Structures");
125
126#ifndef PMAP_SHPGPERPROC
127#define PMAP_SHPGPERPROC 200
128#endif
129
130#if defined(DIAGNOSTIC)
131#define PMAP_DIAGNOSTIC
132#endif
133
134#define MINPV 2048
135
136#if 0
137#define PMAP_DIAGNOSTIC
138#define PMAP_DEBUG
139#endif
140
141#if !defined(PMAP_DIAGNOSTIC)
142#define PMAP_INLINE __inline
143#else
144#define PMAP_INLINE
145#endif
146
147#if 0
148
149static void
150pmap_break(void)
151{
152}
153
154/* #define PMAP_DEBUG_VA(va) if ((va) == 0x120058000) pmap_break(); else */
155
156#endif
157
158#ifndef PMAP_DEBUG_VA
159#define PMAP_DEBUG_VA(va) do {} while(0)
160#endif
161
162/*
163 * Get PDEs and PTEs for user/kernel address space
164 */
165#define pmap_pte_w(pte)		((pte)->pte_ig & PTE_IG_WIRED)
166#define pmap_pte_managed(pte)	((pte)->pte_ig & PTE_IG_MANAGED)
167#define pmap_pte_v(pte)		((pte)->pte_p)
168#define pmap_pte_pa(pte)	(((pte)->pte_ppn) << 12)
169#define pmap_pte_prot(pte)	(((pte)->pte_ar << 2) | (pte)->pte_pl)
170
171#define pmap_pte_set_w(pte, v) ((v)?((pte)->pte_ig |= PTE_IG_WIRED) \
172				:((pte)->pte_ig &= ~PTE_IG_WIRED))
173#define pmap_pte_set_prot(pte, v) do {		\
174    (pte)->pte_ar = v >> 2;			\
175    (pte)->pte_pl = v & 3;			\
176} while (0)
177
178/*
179 * Given a map and a machine independent protection code,
180 * convert to an ia64 protection code.
181 */
182#define pte_prot(m, p)		(protection_codes[m == pmap_kernel() ? 0 : 1][p])
183int	protection_codes[2][8];
184
185/*
186 * Return non-zero if this pmap is currently active
187 */
188#define pmap_isactive(pmap)	(pmap->pm_active)
189
190/*
191 * Statically allocated kernel pmap
192 */
193static struct pmap kernel_pmap_store;
194pmap_t kernel_pmap;
195
196vm_offset_t avail_start;	/* PA of first available physical page */
197vm_offset_t avail_end;		/* PA of last available physical page */
198vm_offset_t virtual_avail;	/* VA of first avail page (after kernel bss) */
199vm_offset_t virtual_end;	/* VA of last avail page (end of kernel AS) */
200static boolean_t pmap_initialized = FALSE;	/* Has pmap_init completed? */
201
202
203vm_offset_t kernel_vm_end;
204
205/*
206 * Values for ptc.e. XXX values for SKI.
207 */
208static u_int64_t pmap_ptc_e_base = 0x100000000;
209static u_int64_t pmap_ptc_e_count1 = 3;
210static u_int64_t pmap_ptc_e_count2 = 2;
211static u_int64_t pmap_ptc_e_stride1 = 0x2000;
212static u_int64_t pmap_ptc_e_stride2 = 0x100000000;
213
214/*
215 * Data for the RID allocator
216 */
217static int pmap_nextrid;
218static int pmap_ridbits = 18;
219
220/*
221 * Data for the pv entry allocation mechanism
222 */
223static vm_zone_t pvzone;
224static struct vm_zone pvzone_store;
225static struct vm_object pvzone_obj;
226static int pv_entry_count = 0, pv_entry_max = 0, pv_entry_high_water = 0;
227static int pmap_pagedaemon_waken = 0;
228static struct pv_entry *pvinit;
229static struct pv_entry *pvbootentries;
230static int pvbootnext, pvbootmax;
231
232
233static PMAP_INLINE void	free_pv_entry __P((pv_entry_t pv));
234static pv_entry_t get_pv_entry __P((void));
235static void	ia64_protection_init __P((void));
236
237static void	pmap_remove_all __P((vm_page_t m));
238static void	pmap_enter_quick __P((pmap_t pmap, vm_offset_t va, vm_page_t m));
239
240vm_offset_t
241pmap_steal_memory(vm_size_t size)
242{
243	vm_size_t bank_size;
244	vm_offset_t pa, va;
245
246	size = round_page(size);
247
248	bank_size = phys_avail[1] - phys_avail[0];
249	while (size > bank_size) {
250		int i;
251		for (i = 0; phys_avail[i+2]; i+= 2) {
252			phys_avail[i] = phys_avail[i+2];
253			phys_avail[i+1] = phys_avail[i+3];
254		}
255		phys_avail[i] = 0;
256		phys_avail[i+1] = 0;
257		if (!phys_avail[0])
258			panic("pmap_steal_memory: out of memory");
259		bank_size = phys_avail[1] - phys_avail[0];
260	}
261
262	pa = phys_avail[0];
263	phys_avail[0] += size;
264
265	va = IA64_PHYS_TO_RR7(pa);
266	bzero((caddr_t) va, size);
267	return va;
268}
269
270/*
271 *	Bootstrap the system enough to run with virtual memory.
272 */
273void
274pmap_bootstrap()
275{
276	int i;
277	struct ia64_pal_result res;
278
279	/*
280	 * Query the PAL Code to find the loop parameters for the
281	 * ptc.e instruction.
282	 */
283	res = ia64_call_pal_static(PAL_PTCE_INFO, 0, 0, 0);
284	if (res.pal_status != 0)
285		panic("Can't configure ptc.e parameters");
286	pmap_ptc_e_base = res.pal_result[0];
287	pmap_ptc_e_count1 = res.pal_result[1] >> 32;
288	pmap_ptc_e_count2 = res.pal_result[1] & ((1L<<32) - 1);
289	pmap_ptc_e_stride1 = res.pal_result[2] >> 32;
290	pmap_ptc_e_stride2 = res.pal_result[2] & ((1L<<32) - 1);
291	if (bootverbose)
292		printf("ptc.e base=0x%lx, count1=%ld, count2=%ld, "
293		       "stride1=0x%lx, stride2=0x%lx\n",
294		       pmap_ptc_e_base,
295		       pmap_ptc_e_count1,
296		       pmap_ptc_e_count2,
297		       pmap_ptc_e_stride1,
298		       pmap_ptc_e_stride2);
299
300	/*
301	 * Setup RIDs. We use the bits above pmap_ridbits for a
302	 * generation counter, saving generation zero for
303	 * 'invalid'. RIDs 0..7 are reserved for the kernel.
304	 */
305	pmap_nextrid = (1 << pmap_ridbits) + 8;
306
307	avail_start = phys_avail[0];
308	for (i = 0; phys_avail[i+2]; i+= 2) ;
309	avail_end = phys_avail[i+1];
310
311	virtual_avail = IA64_RR_BASE(5);
312	virtual_end = IA64_RR_BASE(6)-1;
313
314	/*
315	 * Initialize protection array.
316	 */
317	ia64_protection_init();
318
319	/*
320	 * The kernel's pmap is statically allocated so we don't have to use
321	 * pmap_create, which is unlikely to work correctly at this part of
322	 * the boot sequence (XXX and which no longer exists).
323	 */
324	kernel_pmap = &kernel_pmap_store;
325	kernel_pmap->pm_rid = 0;
326	kernel_pmap->pm_count = 1;
327	kernel_pmap->pm_active = 1;
328	TAILQ_INIT(&kernel_pmap->pm_pvlist);
329
330	/*
331	 * Region 5 is mapped via the vhpt.
332	 */
333	ia64_set_rr(IA64_RR_BASE(5),
334		    (5 << 8) | (PAGE_SHIFT << 2) | 1);
335
336	/*
337	 * Region 6 is direct mapped UC and region 7 is direct mapped
338	 * WC. The details of this is controlled by the Alt {I,D}TLB
339	 * handlers. Here we just make sure that they have the largest
340	 * possible page size to minimise TLB usage.
341	 */
342	ia64_set_rr(IA64_RR_BASE(6), (6 << 8) | (28 << 2));
343	ia64_set_rr(IA64_RR_BASE(7), (7 << 8) | (28 << 2));
344
345	/*
346	 * Set up proc0's PCB.
347	 */
348#if 0
349	thread0->td_pcb->pcb_hw.apcb_asn = 0;
350#endif
351
352	/*
353	 * Reserve some memory for allocating pvs while bootstrapping
354	 * the pv allocator. We need to have enough to cover mapping
355	 * the kmem_alloc region used to allocate the initial_pvs in
356	 * pmap_init. In general, the size of this region is
357	 * appoximately (# physical pages) * (size of pv entry).
358	 */
359	pvbootmax = ((physmem * sizeof(struct pv_entry)) >> PAGE_SHIFT) + 128;
360	pvbootentries = (struct pv_entry *)
361		pmap_steal_memory(pvbootmax * sizeof(struct pv_entry));
362	pvbootnext = 0;
363}
364
365/*
366 *	Initialize the pmap module.
367 *	Called by vm_init, to initialize any structures that the pmap
368 *	system needs to map virtual memory.
369 *	pmap_init has been enhanced to support in a fairly consistant
370 *	way, discontiguous physical memory.
371 */
372void
373pmap_init(phys_start, phys_end)
374	vm_offset_t phys_start, phys_end;
375{
376	int i;
377	int initial_pvs;
378
379	/*
380	 * Allocate memory for random pmap data structures.  Includes the
381	 * pv_head_table.
382	 */
383
384	for(i = 0; i < vm_page_array_size; i++) {
385		vm_page_t m;
386
387		m = &vm_page_array[i];
388		TAILQ_INIT(&m->md.pv_list);
389		m->md.pv_list_count = 0;
390 	}
391
392	/*
393	 * init the pv free list
394	 */
395	initial_pvs = vm_page_array_size;
396	if (initial_pvs < MINPV)
397		initial_pvs = MINPV;
398	pvzone = &pvzone_store;
399	pvinit = (struct pv_entry *) kmem_alloc(kernel_map,
400		initial_pvs * sizeof (struct pv_entry));
401	zbootinit(pvzone, "PV ENTRY", sizeof (struct pv_entry), pvinit,
402		  vm_page_array_size);
403
404	/*
405	 * Now it is safe to enable pv_table recording.
406	 */
407	pmap_initialized = TRUE;
408}
409
410/*
411 * Initialize the address space (zone) for the pv_entries.  Set a
412 * high water mark so that the system can recover from excessive
413 * numbers of pv entries.
414 */
415void
416pmap_init2()
417{
418	int shpgperproc = PMAP_SHPGPERPROC;
419
420	TUNABLE_INT_FETCH("vm.pmap.shpgperproc", &shpgperproc);
421	pv_entry_max = shpgperproc * maxproc + vm_page_array_size;
422	pv_entry_high_water = 9 * (pv_entry_max / 10);
423	zinitna(pvzone, &pvzone_obj, NULL, 0, pv_entry_max, ZONE_INTERRUPT, 1);
424}
425
426
427/***************************************************
428 * Manipulate TLBs for a pmap
429 ***************************************************/
430
431static void
432pmap_invalidate_rid(pmap_t pmap)
433{
434	KASSERT(pmap != kernel_pmap,
435		("changing kernel_pmap's RID"));
436	KASSERT(pmap == PCPU_GET(current_pmap),
437		("invalidating RID of non-current pmap"));
438	pmap_remove_pages(pmap, IA64_RR_BASE(0), IA64_RR_BASE(5));
439	pmap->pm_rid = 0;
440}
441
442static void
443pmap_invalidate_page(pmap_t pmap, vm_offset_t va)
444{
445	KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(current_pmap)),
446		("invalidating TLB for non-current pmap"));
447	ia64_ptc_l(va, PAGE_SHIFT << 2);
448}
449
450static void
451pmap_invalidate_all(pmap_t pmap)
452{
453	u_int64_t addr;
454	int i, j;
455	critical_t psr;
456
457	KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(current_pmap)),
458		("invalidating TLB for non-current pmap"));
459
460	psr = critical_enter();
461	addr = pmap_ptc_e_base;
462	for (i = 0; i < pmap_ptc_e_count1; i++) {
463		for (j = 0; j < pmap_ptc_e_count2; j++) {
464			ia64_ptc_e(addr);
465			addr += pmap_ptc_e_stride2;
466		}
467		addr += pmap_ptc_e_stride1;
468	}
469	critical_exit(psr);
470}
471
472static void
473pmap_get_rid(pmap_t pmap)
474{
475	if ((pmap_nextrid & ((1 << pmap_ridbits) - 1)) == 0) {
476		/*
477		 * Start a new ASN generation.
478		 *
479		 * Invalidate all per-process mappings and I-cache
480		 */
481		pmap_nextrid += 8;
482
483		/*
484		 * Since we are about to start re-using ASNs, we must
485		 * clear out the TLB.
486		 * with the ASN.
487		 */
488#if 0
489		IA64_TBIAP();
490		ia64_pal_imb();	/* XXX overkill? */
491#endif
492	}
493	pmap->pm_rid = pmap_nextrid;
494	pmap_nextrid += 8;
495}
496
497/***************************************************
498 * Low level helper routines.....
499 ***************************************************/
500
501/*
502 * Install a pte into the VHPT
503 */
504static PMAP_INLINE void
505pmap_install_pte(struct ia64_lpte *vhpte, struct ia64_lpte *pte)
506{
507	u_int64_t *vhp, *p;
508
509	/* invalidate the pte */
510	atomic_set_64(&vhpte->pte_tag, 1L << 63);
511	ia64_mf();			/* make sure everyone sees */
512
513	vhp = (u_int64_t *) vhpte;
514	p = (u_int64_t *) pte;
515
516	vhp[0] = p[0];
517	vhp[1] = p[1];
518	vhp[2] = p[2];			/* sets ti to one */
519
520	ia64_mf();
521}
522
523/*
524 * Compare essential parts of pte.
525 */
526static PMAP_INLINE int
527pmap_equal_pte(struct ia64_lpte *pte1, struct ia64_lpte *pte2)
528{
529	return *(u_int64_t *) pte1 == *(u_int64_t *) pte2;
530}
531
532/*
533 * this routine defines the region(s) of memory that should
534 * not be tested for the modified bit.
535 */
536static PMAP_INLINE int
537pmap_track_modified(vm_offset_t va)
538{
539	if ((va < kmi.clean_sva) || (va >= kmi.clean_eva))
540		return 1;
541	else
542		return 0;
543}
544
545/*
546 * Create the U area for a new process.
547 * This routine directly affects the fork perf for a process.
548 */
549void
550pmap_new_proc(struct proc *p)
551{
552	struct user *up;
553
554	/*
555	 * Use contigmalloc for user area so that we can use a region
556	 * 7 address for it which makes it impossible to accidentally
557	 * lose when recording a trapframe.
558	 */
559	up = contigmalloc(UAREA_PAGES * PAGE_SIZE, M_PMAP,
560			  M_WAITOK,
561			  0ul,
562			  256*1024*1024 - 1,
563			  PAGE_SIZE,
564			  256*1024*1024);
565
566	p->p_md.md_uservirt = up;
567	p->p_uarea = (struct user *)
568		IA64_PHYS_TO_RR7(ia64_tpa((u_int64_t) up));
569}
570
571/*
572 * Dispose the U area for a process that has exited.
573 * This routine directly impacts the exit perf of a process.
574 */
575void
576pmap_dispose_proc(p)
577	struct proc *p;
578{
579	contigfree(p->p_md.md_uservirt, UAREA_PAGES * PAGE_SIZE, M_PMAP);
580	p->p_md.md_uservirt = 0;
581	p->p_uarea = 0;
582}
583
584/*
585 * Allow the U area for a process to be prejudicially paged out.
586 */
587void
588pmap_swapout_proc(p)
589	struct proc *p;
590{
591}
592
593/*
594 * Bring the U area for a specified process back in.
595 */
596void
597pmap_swapin_proc(p)
598	struct proc *p;
599{
600}
601
602/*
603 * Create the KSTACK for a new thread.
604 * This routine directly affects the fork perf for a process/thread.
605 */
606void
607pmap_new_thread(struct thread *td)
608{
609	vm_offset_t *ks;
610
611	/*
612	 * Use contigmalloc for user area so that we can use a region
613	 * 7 address for it which makes it impossible to accidentally
614	 * lose when recording a trapframe.
615	 */
616	ks = contigmalloc(KSTACK_PAGES * PAGE_SIZE, M_PMAP,
617			  M_WAITOK,
618			  0ul,
619			  256*1024*1024 - 1,
620			  PAGE_SIZE,
621			  256*1024*1024);
622
623	td->td_md.md_kstackvirt = ks;
624	td->td_kstack = IA64_PHYS_TO_RR7(ia64_tpa((u_int64_t)ks));
625}
626
627/*
628 * Dispose the KSTACK for a thread that has exited.
629 * This routine directly impacts the exit perf of a process/thread.
630 */
631void
632pmap_dispose_thread(td)
633	struct thread *td;
634{
635	contigfree(td->td_md.md_kstackvirt, KSTACK_PAGES * PAGE_SIZE, M_PMAP);
636	td->td_md.md_kstackvirt = 0;
637	td->td_kstack = 0;
638}
639
640/*
641 * Allow the KSTACK for a thread to be prejudicially paged out.
642 */
643void
644pmap_swapout_thread(td)
645	struct thread *td;
646{
647}
648
649/*
650 * Bring the KSTACK for a specified thread back in.
651 */
652void
653pmap_swapin_thread(td)
654	struct thread *td;
655{
656}
657/***************************************************
658 * Page table page management routines.....
659 ***************************************************/
660
661void
662pmap_pinit0(pmap)
663	struct pmap *pmap;
664{
665	/*
666	 * kernel_pmap is the same as any other pmap.
667	 */
668	pmap_pinit(pmap);
669	pmap->pm_flags = 0;
670	pmap->pm_rid = 0;
671	pmap->pm_count = 1;
672	pmap->pm_ptphint = NULL;
673	pmap->pm_active = 0;
674	TAILQ_INIT(&pmap->pm_pvlist);
675	bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
676}
677
678/*
679 * Initialize a preallocated and zeroed pmap structure,
680 * such as one in a vmspace structure.
681 */
682void
683pmap_pinit(pmap)
684	register struct pmap *pmap;
685{
686	pmap->pm_flags = 0;
687	pmap->pm_rid = 0;
688	pmap->pm_count = 1;
689	pmap->pm_ptphint = NULL;
690	pmap->pm_active = 0;
691	TAILQ_INIT(&pmap->pm_pvlist);
692	bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
693}
694
695/*
696 * Wire in kernel global address entries.  To avoid a race condition
697 * between pmap initialization and pmap_growkernel, this procedure
698 * should be called after the vmspace is attached to the process
699 * but before this pmap is activated.
700 */
701void
702pmap_pinit2(pmap)
703	struct pmap *pmap;
704{
705}
706
707/***************************************************
708* Pmap allocation/deallocation routines.
709 ***************************************************/
710
711/*
712 * Release any resources held by the given physical map.
713 * Called when a pmap initialized by pmap_pinit is being released.
714 * Should only be called if the map contains no valid mappings.
715 */
716void
717pmap_release(pmap_t pmap)
718{
719#if defined(DIAGNOSTIC)
720	if (object->ref_count != 1)
721		panic("pmap_release: pteobj reference count != 1");
722#endif
723}
724
725/*
726 * grow the number of kernel page table entries, if needed
727 */
728void
729pmap_growkernel(vm_offset_t addr)
730{
731}
732
733/*
734 *	Retire the given physical map from service.
735 *	Should only be called if the map contains
736 *	no valid mappings.
737 */
738void
739pmap_destroy(pmap_t pmap)
740{
741	int count;
742
743	if (pmap == NULL)
744		return;
745
746	count = --pmap->pm_count;
747	if (count == 0) {
748		pmap_release(pmap);
749		panic("destroying a pmap is not yet implemented");
750	}
751}
752
753/*
754 *	Add a reference to the specified pmap.
755 */
756void
757pmap_reference(pmap_t pmap)
758{
759	if (pmap != NULL) {
760		pmap->pm_count++;
761	}
762}
763
764/***************************************************
765* page management routines.
766 ***************************************************/
767
768/*
769 * free the pv_entry back to the free list
770 */
771static PMAP_INLINE void
772free_pv_entry(pv_entry_t pv)
773{
774	pv_entry_count--;
775	zfree(pvzone, pv);
776}
777
778/*
779 * get a new pv_entry, allocating a block from the system
780 * when needed.
781 * the memory allocation is performed bypassing the malloc code
782 * because of the possibility of allocations at interrupt time.
783 */
784static pv_entry_t
785get_pv_entry(void)
786{
787	/*
788	 * We can get called a few times really early before
789	 * pmap_init() has finished allocating the pvzone (mostly as a
790	 * result of the call to kmem_alloc() in pmap_init(). We allow
791	 * a small number of entries to be allocated statically to
792	 * cover this.
793	 */
794	if (!pvinit) {
795		if (pvbootnext == pvbootmax)
796			panic("get_pv_entry: called too many times"
797			      " before pmap_init is finished");
798		return &pvbootentries[pvbootnext++];
799	}
800
801	pv_entry_count++;
802	if (pv_entry_high_water &&
803		(pv_entry_count > pv_entry_high_water) &&
804		(pmap_pagedaemon_waken == 0)) {
805		pmap_pagedaemon_waken = 1;
806		wakeup (&vm_pages_needed);
807	}
808	return (pv_entry_t) IA64_PHYS_TO_RR7(vtophys(zalloc(pvzone)));
809}
810
811/*
812 * Add a pv_entry to the VHPT.
813 */
814static void
815pmap_enter_vhpt(pv_entry_t pv)
816{
817	struct ia64_lpte *vhpte;
818
819	vhpte = (struct ia64_lpte *) ia64_thash(pv->pv_va);
820
821	pv->pv_pte.pte_chain = vhpte->pte_chain;
822	vhpte->pte_chain = ia64_tpa((vm_offset_t) pv);
823
824	if (!vhpte->pte_p && pv->pv_pte.pte_p)
825		pmap_install_pte(vhpte, &pv->pv_pte);
826	else
827		ia64_mf();
828}
829
830/*
831 * Update VHPT after pv->pv_pte has changed.
832 */
833static void
834pmap_update_vhpt(pv_entry_t pv)
835{
836	struct ia64_lpte *vhpte;
837
838	vhpte = (struct ia64_lpte *) ia64_thash(pv->pv_va);
839
840	if ((!vhpte->pte_p || vhpte->pte_tag == pv->pv_pte.pte_tag)
841	    && pv->pv_pte.pte_p)
842		pmap_install_pte(vhpte, &pv->pv_pte);
843}
844
845/*
846 * Remove a pv_entry from the VHPT. Return true if it worked.
847 */
848static int
849pmap_remove_vhpt(pv_entry_t pv)
850{
851	struct ia64_lpte *pte;
852	struct ia64_lpte *lpte;
853	struct ia64_lpte *vhpte;
854	u_int64_t tag;
855
856	vhpte = (struct ia64_lpte *) ia64_thash(pv->pv_va);
857
858	/*
859	 * If the VHPTE is invalid, there can't be a collision chain.
860	 */
861	if (!vhpte->pte_p) {
862		KASSERT(!vhpte->pte_chain, ("bad vhpte"));
863		return 0;
864	}
865
866	lpte = vhpte;
867	pte = (struct ia64_lpte *) IA64_PHYS_TO_RR7(vhpte->pte_chain);
868	tag = ia64_ttag(pv->pv_va);
869
870	while (pte->pte_tag != tag) {
871		lpte = pte;
872		if (pte->pte_chain)
873			pte = (struct ia64_lpte *) IA64_PHYS_TO_RR7(pte->pte_chain);
874		else
875			return 0; /* error here? */
876	}
877
878	/*
879	 * Snip this pv_entry out of the collision chain.
880	 */
881	lpte->pte_chain = pte->pte_chain;
882
883	/*
884	 * If the VHPTE matches as well, change it to map the first
885	 * element from the chain if there is one.
886	 */
887	if (vhpte->pte_tag == tag) {
888		if (vhpte->pte_chain) {
889			pte = (struct ia64_lpte *)
890				IA64_PHYS_TO_RR7(vhpte->pte_chain);
891			pmap_install_pte(vhpte, pte);
892		} else {
893			vhpte->pte_p = 0;
894			ia64_mf();
895		}
896	}
897
898	return 1;
899}
900
901/*
902 * Make a pv_entry_t which maps the given virtual address. The pte
903 * will be initialised with pte_p = 0. The function pmap_set_pv()
904 * should be called to change the value of the pte.
905 * Must be called at splvm().
906 */
907static pv_entry_t
908pmap_make_pv(pmap_t pmap, vm_offset_t va)
909{
910	pv_entry_t pv;
911
912	pv = get_pv_entry();
913	bzero(pv, sizeof(*pv));
914	pv->pv_va = va;
915	pv->pv_pmap = pmap;
916
917	pv->pv_pte.pte_p = 0;		/* invalid for now */
918	pv->pv_pte.pte_ma = PTE_MA_WB;	/* cacheable, write-back */
919	pv->pv_pte.pte_a = 0;
920	pv->pv_pte.pte_d = 0;
921	pv->pv_pte.pte_pl = 0;		/* privilege level 0 */
922	pv->pv_pte.pte_ar = 3;		/* read/write/execute */
923	pv->pv_pte.pte_ppn = 0;		/* physical address */
924	pv->pv_pte.pte_ed = 0;
925	pv->pv_pte.pte_ig = 0;
926
927	pv->pv_pte.pte_ps = PAGE_SHIFT;	/* page size */
928	pv->pv_pte.pte_key = 0;		/* protection key */
929
930	pv->pv_pte.pte_tag = ia64_ttag(va);
931
932	pmap_enter_vhpt(pv);
933
934	TAILQ_INSERT_TAIL(&pmap->pm_pvlist, pv, pv_plist);
935	pmap->pm_stats.resident_count++;
936
937	return pv;
938}
939
940/*
941 * Initialise a pv_entry_t with a given physical address and
942 * protection code. If the passed vm_page_t is non-zero, the entry is
943 * added to its list of mappings.
944 * Must be called at splvm().
945 */
946static void
947pmap_set_pv(pmap_t pmap, pv_entry_t pv, vm_offset_t pa,
948	    int prot, vm_page_t m)
949{
950	if (pv->pv_pte.pte_p && pv->pv_pte.pte_ig & PTE_IG_MANAGED) {
951		vm_offset_t opa = pv->pv_pte.pte_ppn << 12;
952		vm_page_t om = PHYS_TO_VM_PAGE(opa);
953
954		if (pv->pv_pte.pte_d)
955			if (pmap_track_modified(pv->pv_va))
956				vm_page_dirty(om);
957		if (pv->pv_pte.pte_a)
958			vm_page_flag_set(om, PG_REFERENCED);
959
960		TAILQ_REMOVE(&om->md.pv_list, pv, pv_list);
961		om->md.pv_list_count--;
962
963		if (TAILQ_FIRST(&om->md.pv_list) == NULL)
964			vm_page_flag_clear(om, PG_MAPPED | PG_WRITEABLE);
965	}
966
967	pv->pv_pte.pte_p = 1;		/* set to valid */
968
969	/*
970	 * Only track access/modify for managed pages.
971	 */
972	if (m) {
973		pv->pv_pte.pte_a = 0;
974		pv->pv_pte.pte_d = 0;
975	} else {
976		pv->pv_pte.pte_a = 1;
977		pv->pv_pte.pte_d = 1;
978	}
979
980	pv->pv_pte.pte_pl = prot & 3;	/* privilege level */
981	pv->pv_pte.pte_ar = prot >> 2;	/* access rights */
982	pv->pv_pte.pte_ppn = pa >> 12;	/* physical address */
983
984	if (m) {
985		pv->pv_pte.pte_ig |= PTE_IG_MANAGED;
986		TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list);
987		m->md.pv_list_count++;
988	}
989
990	/*
991	 * Update the VHPT entry if it needs to change.
992	 */
993	pmap_update_vhpt(pv);
994}
995
996/*
997 * Remove a mapping represented by a particular pv_entry_t. If the
998 * passed vm_page_t is non-zero, then the entry is removed from it.
999 * Must be called at splvm().
1000 */
1001static int
1002pmap_remove_pv(pmap_t pmap, pv_entry_t pv, vm_page_t m)
1003{
1004	int rtval;
1005
1006	/*
1007	 * First remove from the VHPT.
1008	 */
1009	rtval = pmap_remove_vhpt(pv);
1010	if (!rtval)
1011		return rtval;
1012
1013	if ((pv->pv_pte.pte_ig & PTE_IG_MANAGED) && m) {
1014		if (pv->pv_pte.pte_d)
1015			if (pmap_track_modified(pv->pv_va))
1016				vm_page_dirty(m);
1017		if (pv->pv_pte.pte_a)
1018			vm_page_flag_set(m, PG_REFERENCED);
1019
1020		TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
1021		m->md.pv_list_count--;
1022
1023		if (TAILQ_FIRST(&m->md.pv_list) == NULL)
1024			vm_page_flag_clear(m, PG_MAPPED | PG_WRITEABLE);
1025	}
1026
1027	TAILQ_REMOVE(&pmap->pm_pvlist, pv, pv_plist);
1028	pmap->pm_stats.resident_count--;
1029
1030	free_pv_entry(pv);
1031
1032	return (rtval);
1033}
1034
1035/*
1036 * Find a pv given a pmap and virtual address.
1037 */
1038static pv_entry_t
1039pmap_find_pv(pmap_t pmap, vm_offset_t va)
1040{
1041	struct ia64_lpte *pte;
1042	u_int64_t tag;
1043
1044	pte = (struct ia64_lpte *) ia64_thash(va);
1045	if (!pte->pte_chain)
1046		return 0;
1047
1048	tag = ia64_ttag(va);
1049	pte = (struct ia64_lpte *) IA64_PHYS_TO_RR7(pte->pte_chain);
1050
1051	while (pte->pte_tag != tag) {
1052		if (pte->pte_chain)
1053			pte = (struct ia64_lpte *) IA64_PHYS_TO_RR7(pte->pte_chain);
1054		else
1055			return 0;
1056	}
1057
1058	return (pv_entry_t) pte;	/* XXX wrong va */
1059}
1060
1061/*
1062 *	Routine:	pmap_extract
1063 *	Function:
1064 *		Extract the physical page address associated
1065 *		with the given map/virtual_address pair.
1066 */
1067vm_offset_t
1068pmap_extract(pmap, va)
1069	register pmap_t pmap;
1070	vm_offset_t va;
1071{
1072	pv_entry_t pv = pmap_find_pv(pmap, va);
1073	if (pv)
1074		return pmap_pte_pa(&pv->pv_pte);
1075	else
1076		return 0;
1077}
1078
1079/***************************************************
1080 * Low level mapping routines.....
1081 ***************************************************/
1082
1083/*
1084 * Add a list of wired pages to the kva
1085 * this routine is only used for temporary
1086 * kernel mappings that do not need to have
1087 * page modification or references recorded.
1088 * Note that old mappings are simply written
1089 * over.  The page *must* be wired.
1090 */
1091void
1092pmap_qenter(vm_offset_t va, vm_page_t *m, int count)
1093{
1094	int i, inval;
1095	pv_entry_t pv;
1096
1097	for (i = 0; i < count; i++) {
1098		vm_offset_t tva = va + i * PAGE_SIZE;
1099		pv = pmap_find_pv(kernel_pmap, tva);
1100		inval = 0;
1101		if (!pv)
1102			pv = pmap_make_pv(kernel_pmap, tva);
1103		else
1104			inval = 1;
1105
1106		PMAP_DEBUG_VA(va);
1107		pmap_set_pv(kernel_pmap, pv,
1108			    VM_PAGE_TO_PHYS(m[i]),
1109			    (PTE_AR_RWX<<2) | PTE_PL_KERN, 0);
1110		if (inval)
1111			pmap_invalidate_page(kernel_pmap, tva);
1112	}
1113}
1114
1115/*
1116 * this routine jerks page mappings from the
1117 * kernel -- it is meant only for temporary mappings.
1118 */
1119void
1120pmap_qremove(va, count)
1121	vm_offset_t va;
1122	int count;
1123{
1124	int i;
1125	pv_entry_t pv;
1126
1127	for (i = 0; i < count; i++) {
1128		pv = pmap_find_pv(kernel_pmap, va);
1129		PMAP_DEBUG_VA(va);
1130		if (pv) {
1131			pmap_remove_pv(kernel_pmap, pv, 0);
1132			pmap_invalidate_page(kernel_pmap, va);
1133		}
1134		va += PAGE_SIZE;
1135	}
1136}
1137
1138/*
1139 * Add a wired page to the kva.
1140 */
1141void
1142pmap_kenter(vm_offset_t va, vm_offset_t pa)
1143{
1144	pv_entry_t pv;
1145
1146	pv = pmap_find_pv(kernel_pmap, va);
1147	if (!pv)
1148		pv = pmap_make_pv(kernel_pmap, va);
1149	pmap_set_pv(kernel_pmap, pv,
1150		    pa, (PTE_AR_RWX<<2) | PTE_PL_KERN, 0);
1151	pmap_invalidate_page(kernel_pmap, va);
1152}
1153
1154/*
1155 * Remove a page from the kva
1156 */
1157void
1158pmap_kremove(vm_offset_t va)
1159{
1160	pv_entry_t pv;
1161
1162	pv = pmap_find_pv(kernel_pmap, va);
1163	if (pv) {
1164		pmap_remove_pv(kernel_pmap, pv, 0);
1165		pmap_invalidate_page(kernel_pmap, va);
1166	}
1167}
1168
1169/*
1170 *	Used to map a range of physical addresses into kernel
1171 *	virtual address space.
1172 *
1173 *	The value passed in '*virt' is a suggested virtual address for
1174 *	the mapping. Architectures which can support a direct-mapped
1175 *	physical to virtual region can return the appropriate address
1176 *	within that region, leaving '*virt' unchanged. Other
1177 *	architectures should map the pages starting at '*virt' and
1178 *	update '*virt' with the first usable address after the mapped
1179 *	region.
1180 */
1181vm_offset_t
1182pmap_map(vm_offset_t *virt, vm_offset_t start, vm_offset_t end, int prot)
1183{
1184	return IA64_PHYS_TO_RR7(start);
1185}
1186
1187/*
1188 * This routine is very drastic, but can save the system
1189 * in a pinch.
1190 */
1191void
1192pmap_collect()
1193{
1194	int i;
1195	vm_page_t m;
1196	static int warningdone = 0;
1197
1198	if (pmap_pagedaemon_waken == 0)
1199		return;
1200
1201	if (warningdone < 5) {
1202		printf("pmap_collect: collecting pv entries -- suggest increasing PMAP_SHPGPERPROC\n");
1203		warningdone++;
1204	}
1205
1206	for(i = 0; i < vm_page_array_size; i++) {
1207		m = &vm_page_array[i];
1208		if (m->wire_count || m->hold_count || m->busy ||
1209		    (m->flags & PG_BUSY))
1210			continue;
1211		pmap_remove_all(m);
1212	}
1213	pmap_pagedaemon_waken = 0;
1214}
1215
1216/*
1217 * Remove a single page from a process address space
1218 */
1219static void
1220pmap_remove_page(pmap_t pmap, vm_offset_t va)
1221{
1222	pv_entry_t pv;
1223	vm_page_t m;
1224	int rtval;
1225	int s;
1226
1227	KASSERT((pmap == kernel_pmap || pmap == PCPU_GET(current_pmap)),
1228		("removing page for non-current pmap"));
1229
1230	s = splvm();
1231
1232	pv = pmap_find_pv(pmap, va);
1233
1234	rtval = 0;
1235	if (pv) {
1236		m = PHYS_TO_VM_PAGE(pmap_pte_pa(&pv->pv_pte));
1237		rtval = pmap_remove_pv(pmap, pv, m);
1238		pmap_invalidate_page(pmap, va);
1239	}
1240
1241	splx(s);
1242	return;
1243}
1244
1245/*
1246 *	Remove the given range of addresses from the specified map.
1247 *
1248 *	It is assumed that the start and end are properly
1249 *	rounded to the page size.
1250 */
1251void
1252pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
1253{
1254	pmap_t oldpmap;
1255	vm_offset_t va, nva;
1256
1257	if (pmap == NULL)
1258		return;
1259
1260	if (pmap->pm_stats.resident_count == 0)
1261		return;
1262
1263	oldpmap = pmap_install(pmap);
1264
1265	/*
1266	 * special handling of removing one page.  a very
1267	 * common operation and easy to short circuit some
1268	 * code.
1269	 */
1270	if (sva + PAGE_SIZE == eva) {
1271		pmap_remove_page(pmap, sva);
1272		pmap_install(oldpmap);
1273		return;
1274	}
1275
1276	if (atop(eva - sva) < pmap->pm_stats.resident_count) {
1277		for (va = sva; va < eva; va = nva) {
1278			pmap_remove_page(pmap, va);
1279			nva = va + PAGE_SIZE;
1280		}
1281	} else {
1282		pv_entry_t pv, pvnext;
1283		int s;
1284
1285		s = splvm();
1286		for (pv = TAILQ_FIRST(&pmap->pm_pvlist);
1287			pv;
1288			pv = pvnext) {
1289			pvnext = TAILQ_NEXT(pv, pv_plist);
1290			if (pv->pv_va >= sva && pv->pv_va < eva) {
1291				vm_page_t m = PHYS_TO_VM_PAGE(pmap_pte_pa(&pv->pv_pte));
1292				va = pv->pv_va;
1293				pmap_remove_pv(pmap, pv, m);
1294				pmap_invalidate_page(pmap, va);
1295			}
1296		}
1297		splx(s);
1298	}
1299	pmap_install(oldpmap);
1300}
1301
1302/*
1303 *	Routine:	pmap_remove_all
1304 *	Function:
1305 *		Removes this physical page from
1306 *		all physical maps in which it resides.
1307 *		Reflects back modify bits to the pager.
1308 *
1309 *	Notes:
1310 *		Original versions of this routine were very
1311 *		inefficient because they iteratively called
1312 *		pmap_remove (slow...)
1313 */
1314
1315static void
1316pmap_remove_all(vm_page_t m)
1317{
1318	pmap_t oldpmap;
1319	register pv_entry_t pv;
1320	int nmodify;
1321	int s;
1322
1323	nmodify = 0;
1324#if defined(PMAP_DIAGNOSTIC)
1325	/*
1326	 * XXX this makes pmap_page_protect(NONE) illegal for non-managed
1327	 * pages!
1328	 */
1329	if (!pmap_initialized || (m->flags & PG_FICTITIOUS)) {
1330		panic("pmap_page_protect: illegal for unmanaged page, va: 0x%lx", VM_PAGE_TO_PHYS(m));
1331	}
1332#endif
1333
1334	s = splvm();
1335
1336	while ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) {
1337		vm_page_t m = PHYS_TO_VM_PAGE(pmap_pte_pa(&pv->pv_pte));
1338		vm_offset_t va = pv->pv_va;
1339		oldpmap = pmap_install(pv->pv_pmap);
1340		pmap_remove_pv(pv->pv_pmap, pv, m);
1341		pmap_invalidate_page(pv->pv_pmap, va);
1342		pmap_install(oldpmap);
1343	}
1344
1345	vm_page_flag_clear(m, PG_MAPPED | PG_WRITEABLE);
1346
1347	splx(s);
1348	return;
1349}
1350
1351/*
1352 *	Set the physical protection on the
1353 *	specified range of this map as requested.
1354 */
1355void
1356pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
1357{
1358	pmap_t oldpmap;
1359	pv_entry_t pv;
1360	int newprot;
1361
1362	if (pmap == NULL)
1363		return;
1364
1365	oldpmap = pmap_install(pmap);
1366
1367	if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
1368		pmap_remove(pmap, sva, eva);
1369		pmap_install(oldpmap);
1370		return;
1371	}
1372
1373	if (prot & VM_PROT_WRITE) {
1374		pmap_install(oldpmap);
1375		return;
1376	}
1377
1378	newprot = pte_prot(pmap, prot);
1379
1380	if ((sva & PAGE_MASK) || (eva & PAGE_MASK))
1381		panic("pmap_protect: unaligned addresses");
1382
1383	while (sva < eva) {
1384		/*
1385		 * If page is invalid, skip this page
1386		 */
1387		pv = pmap_find_pv(pmap, sva);
1388		if (!pv) {
1389			sva += PAGE_SIZE;
1390			continue;
1391		}
1392
1393		if (pmap_pte_prot(&pv->pv_pte) != newprot) {
1394			if (pv->pv_pte.pte_ig & PTE_IG_MANAGED) {
1395				vm_offset_t pa = pmap_pte_pa(&pv->pv_pte);
1396				vm_page_t m = PHYS_TO_VM_PAGE(pa);
1397				if (pv->pv_pte.pte_d) {
1398					if (pmap_track_modified(pv->pv_va))
1399						vm_page_dirty(m);
1400					pv->pv_pte.pte_d = 0;
1401				}
1402				if (pv->pv_pte.pte_a) {
1403					vm_page_flag_set(m, PG_REFERENCED);
1404					pv->pv_pte.pte_a = 0;
1405				}
1406			}
1407			pmap_pte_set_prot(&pv->pv_pte, newprot);
1408			pmap_update_vhpt(pv);
1409			pmap_invalidate_page(pmap, sva);
1410		}
1411
1412		sva += PAGE_SIZE;
1413	}
1414	pmap_install(oldpmap);
1415}
1416
1417/*
1418 *	Insert the given physical page (p) at
1419 *	the specified virtual address (v) in the
1420 *	target physical map with the protection requested.
1421 *
1422 *	If specified, the page will be wired down, meaning
1423 *	that the related pte can not be reclaimed.
1424 *
1425 *	NB:  This is the only routine which MAY NOT lazy-evaluate
1426 *	or lose information.  That is, this routine must actually
1427 *	insert this page into the given map NOW.
1428 */
1429void
1430pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
1431	   boolean_t wired)
1432{
1433	pmap_t oldpmap;
1434	vm_offset_t pa;
1435	pv_entry_t pv;
1436	vm_offset_t opa;
1437	struct ia64_lpte origpte;
1438
1439	if (pmap == NULL)
1440		return;
1441
1442	oldpmap = pmap_install(pmap);
1443
1444	va &= ~PAGE_MASK;
1445#ifdef PMAP_DIAGNOSTIC
1446	if (va > VM_MAX_KERNEL_ADDRESS)
1447		panic("pmap_enter: toobig");
1448#endif
1449
1450	pv = pmap_find_pv(pmap, va);
1451	if (!pv)
1452		pv = pmap_make_pv(pmap, va);
1453
1454	origpte = pv->pv_pte;
1455	if (origpte.pte_p)
1456		opa = pmap_pte_pa(&origpte);
1457	else
1458		opa = 0;
1459
1460	pa = VM_PAGE_TO_PHYS(m) & ~PAGE_MASK;
1461
1462	/*
1463	 * Mapping has not changed, must be protection or wiring change.
1464	 */
1465	if (origpte.pte_p && (opa == pa)) {
1466		/*
1467		 * Wiring change, just update stats. We don't worry about
1468		 * wiring PT pages as they remain resident as long as there
1469		 * are valid mappings in them. Hence, if a user page is wired,
1470		 * the PT page will be also.
1471		 */
1472		if (wired && ((origpte.pte_ig & PTE_IG_WIRED) == 0))
1473			pmap->pm_stats.wired_count++;
1474		else if (!wired && (origpte.pte_ig & PTE_IG_WIRED))
1475			pmap->pm_stats.wired_count--;
1476
1477		goto validate;
1478	}  else {
1479		/*
1480		 * Mapping has changed, invalidate old range and fall
1481		 * through to handle validating new mapping.
1482		 */
1483	}
1484
1485	/*
1486	 * Increment counters
1487	 */
1488	if (wired)
1489		pmap->pm_stats.wired_count++;
1490
1491validate:
1492	/*
1493	 * Now validate mapping with desired protection/wiring.
1494	 * This enters the pv_entry_t on the page's list if necessary.
1495	 */
1496	pmap_set_pv(pmap, pv, pa, pte_prot(pmap, prot), m);
1497
1498	if (wired)
1499		pv->pv_pte.pte_ig |= PTE_IG_WIRED;
1500
1501	/*
1502	 * if the mapping or permission bits are different, we need
1503	 * to invalidate the page.
1504	 */
1505	if (!pmap_equal_pte(&origpte, &pv->pv_pte)) {
1506		PMAP_DEBUG_VA(va);
1507		pmap_invalidate_page(pmap, va);
1508	}
1509
1510	pmap_install(oldpmap);
1511}
1512
1513/*
1514 * this code makes some *MAJOR* assumptions:
1515 * 1. Current pmap & pmap exists.
1516 * 2. Not wired.
1517 * 3. Read access.
1518 * 4. No page table pages.
1519 * 5. Tlbflush is deferred to calling procedure.
1520 * 6. Page IS managed.
1521 * but is *MUCH* faster than pmap_enter...
1522 */
1523
1524static void
1525pmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_page_t m)
1526{
1527	pv_entry_t pv;
1528	int s;
1529
1530	s = splvm();
1531
1532	pv = pmap_find_pv(pmap, va);
1533	if (!pv)
1534		pv = pmap_make_pv(pmap, va);
1535
1536	/*
1537	 * Enter on the PV list if part of our managed memory. Note that we
1538	 * raise IPL while manipulating pv_table since pmap_enter can be
1539	 * called at interrupt time.
1540	 */
1541	PMAP_DEBUG_VA(va);
1542	pmap_set_pv(pmap, pv, VM_PAGE_TO_PHYS(m),
1543		    (PTE_AR_R << 2) | PTE_PL_USER, m);
1544
1545	splx(s);
1546}
1547
1548/*
1549 * Make temporary mapping for a physical address. This is called
1550 * during dump.
1551 */
1552void *
1553pmap_kenter_temporary(vm_offset_t pa, int i)
1554{
1555	return (void *) IA64_PHYS_TO_RR7(pa - (i * PAGE_SIZE));
1556}
1557
1558#define MAX_INIT_PT (96)
1559/*
1560 * pmap_object_init_pt preloads the ptes for a given object
1561 * into the specified pmap.  This eliminates the blast of soft
1562 * faults on process startup and immediately after an mmap.
1563 */
1564void
1565pmap_object_init_pt(pmap_t pmap, vm_offset_t addr,
1566		    vm_object_t object, vm_pindex_t pindex,
1567		    vm_size_t size, int limit)
1568{
1569	pmap_t oldpmap;
1570	vm_offset_t tmpidx;
1571	int psize;
1572	vm_page_t p;
1573	int objpgs;
1574
1575	if (pmap == NULL || object == NULL)
1576		return;
1577
1578	oldpmap = pmap_install(pmap);
1579
1580	psize = ia64_btop(size);
1581
1582	if ((object->type != OBJT_VNODE) ||
1583		(limit && (psize > MAX_INIT_PT) &&
1584			(object->resident_page_count > MAX_INIT_PT))) {
1585		pmap_install(oldpmap);
1586		return;
1587	}
1588
1589	if (psize + pindex > object->size)
1590		psize = object->size - pindex;
1591
1592	/*
1593	 * if we are processing a major portion of the object, then scan the
1594	 * entire thing.
1595	 */
1596	if (psize > (object->resident_page_count >> 2)) {
1597		objpgs = psize;
1598
1599		for (p = TAILQ_FIRST(&object->memq);
1600		    ((objpgs > 0) && (p != NULL));
1601		    p = TAILQ_NEXT(p, listq)) {
1602
1603			tmpidx = p->pindex;
1604			if (tmpidx < pindex) {
1605				continue;
1606			}
1607			tmpidx -= pindex;
1608			if (tmpidx >= psize) {
1609				continue;
1610			}
1611			if (((p->valid & VM_PAGE_BITS_ALL) == VM_PAGE_BITS_ALL) &&
1612			    (p->flags & (PG_BUSY | PG_FICTITIOUS)) == 0) {
1613				if ((p->queue - p->pc) == PQ_CACHE)
1614					vm_page_deactivate(p);
1615				vm_page_busy(p);
1616				pmap_enter_quick(pmap,
1617						 addr + ia64_ptob(tmpidx), p);
1618				vm_page_flag_set(p, PG_MAPPED);
1619				vm_page_wakeup(p);
1620			}
1621			objpgs -= 1;
1622		}
1623	} else {
1624		/*
1625		 * else lookup the pages one-by-one.
1626		 */
1627		for (tmpidx = 0; tmpidx < psize; tmpidx += 1) {
1628			p = vm_page_lookup(object, tmpidx + pindex);
1629			if (p &&
1630			    ((p->valid & VM_PAGE_BITS_ALL) == VM_PAGE_BITS_ALL) &&
1631			    (p->flags & (PG_BUSY | PG_FICTITIOUS)) == 0) {
1632				if ((p->queue - p->pc) == PQ_CACHE)
1633					vm_page_deactivate(p);
1634				vm_page_busy(p);
1635				pmap_enter_quick(pmap,
1636						 addr + ia64_ptob(tmpidx), p);
1637				vm_page_flag_set(p, PG_MAPPED);
1638				vm_page_wakeup(p);
1639			}
1640		}
1641	}
1642	pmap_install(oldpmap);
1643	return;
1644}
1645
1646/*
1647 * pmap_prefault provides a quick way of clustering
1648 * pagefaults into a processes address space.  It is a "cousin"
1649 * of pmap_object_init_pt, except it runs at page fault time instead
1650 * of mmap time.
1651 */
1652#define PFBAK 4
1653#define PFFOR 4
1654#define PAGEORDER_SIZE (PFBAK+PFFOR)
1655
1656static int pmap_prefault_pageorder[] = {
1657	-PAGE_SIZE, PAGE_SIZE,
1658	-2 * PAGE_SIZE, 2 * PAGE_SIZE,
1659	-3 * PAGE_SIZE, 3 * PAGE_SIZE
1660	-4 * PAGE_SIZE, 4 * PAGE_SIZE
1661};
1662
1663void
1664pmap_prefault(pmap, addra, entry)
1665	pmap_t pmap;
1666	vm_offset_t addra;
1667	vm_map_entry_t entry;
1668{
1669	int i;
1670	vm_offset_t starta;
1671	vm_offset_t addr;
1672	vm_pindex_t pindex;
1673	vm_page_t m, mpte;
1674	vm_object_t object;
1675
1676	if (!curproc || (pmap != vmspace_pmap(curproc->p_vmspace)))
1677		return;
1678
1679	object = entry->object.vm_object;
1680
1681	starta = addra - PFBAK * PAGE_SIZE;
1682	if (starta < entry->start) {
1683		starta = entry->start;
1684	} else if (starta > addra) {
1685		starta = 0;
1686	}
1687
1688	mpte = NULL;
1689	for (i = 0; i < PAGEORDER_SIZE; i++) {
1690		vm_object_t lobject;
1691		pv_entry_t pv;
1692
1693		addr = addra + pmap_prefault_pageorder[i];
1694		if (addr > addra + (PFFOR * PAGE_SIZE))
1695			addr = 0;
1696
1697		if (addr < starta || addr >= entry->end)
1698			continue;
1699
1700		pv = pmap_find_pv(pmap, addr);
1701		if (pv)
1702			continue;
1703
1704		pindex = ((addr - entry->start) + entry->offset) >> PAGE_SHIFT;
1705		lobject = object;
1706		for (m = vm_page_lookup(lobject, pindex);
1707		    (!m && (lobject->type == OBJT_DEFAULT) && (lobject->backing_object));
1708		    lobject = lobject->backing_object) {
1709			if (lobject->backing_object_offset & PAGE_MASK)
1710				break;
1711			pindex += (lobject->backing_object_offset >> PAGE_SHIFT);
1712			m = vm_page_lookup(lobject->backing_object, pindex);
1713		}
1714
1715		/*
1716		 * give-up when a page is not in memory
1717		 */
1718		if (m == NULL)
1719			break;
1720
1721		if (((m->valid & VM_PAGE_BITS_ALL) == VM_PAGE_BITS_ALL) &&
1722		    (m->flags & (PG_BUSY | PG_FICTITIOUS)) == 0) {
1723
1724			if ((m->queue - m->pc) == PQ_CACHE) {
1725				vm_page_deactivate(m);
1726			}
1727			vm_page_busy(m);
1728			pmap_enter_quick(pmap, addr, m);
1729			vm_page_flag_set(m, PG_MAPPED);
1730			vm_page_wakeup(m);
1731		}
1732	}
1733}
1734
1735/*
1736 *	Routine:	pmap_change_wiring
1737 *	Function:	Change the wiring attribute for a map/virtual-address
1738 *			pair.
1739 *	In/out conditions:
1740 *			The mapping must already exist in the pmap.
1741 */
1742void
1743pmap_change_wiring(pmap, va, wired)
1744	register pmap_t pmap;
1745	vm_offset_t va;
1746	boolean_t wired;
1747{
1748	pmap_t oldpmap;
1749	pv_entry_t pv;
1750
1751	if (pmap == NULL)
1752		return;
1753
1754	oldpmap = pmap_install(pmap);
1755
1756	pv = pmap_find_pv(pmap, va);
1757
1758	if (wired && !pmap_pte_w(&pv->pv_pte))
1759		pmap->pm_stats.wired_count++;
1760	else if (!wired && pmap_pte_w(&pv->pv_pte))
1761		pmap->pm_stats.wired_count--;
1762
1763	/*
1764	 * Wiring is not a hardware characteristic so there is no need to
1765	 * invalidate TLB.
1766	 */
1767	pmap_pte_set_w(&pv->pv_pte, wired);
1768
1769	pmap_install(oldpmap);
1770}
1771
1772
1773
1774/*
1775 *	Copy the range specified by src_addr/len
1776 *	from the source map to the range dst_addr/len
1777 *	in the destination map.
1778 *
1779 *	This routine is only advisory and need not do anything.
1780 */
1781
1782void
1783pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len,
1784	  vm_offset_t src_addr)
1785{
1786}
1787
1788/*
1789 *	Routine:	pmap_kernel
1790 *	Function:
1791 *		Returns the physical map handle for the kernel.
1792 */
1793pmap_t
1794pmap_kernel()
1795{
1796	return (kernel_pmap);
1797}
1798
1799/*
1800 *	pmap_zero_page zeros the specified hardware page by
1801 *	mapping it into virtual memory and using bzero to clear
1802 *	its contents.
1803 */
1804
1805void
1806pmap_zero_page(vm_offset_t pa)
1807{
1808	vm_offset_t va = IA64_PHYS_TO_RR7(pa);
1809	bzero((caddr_t) va, PAGE_SIZE);
1810}
1811
1812
1813/*
1814 *	pmap_zero_page_area zeros the specified hardware page by
1815 *	mapping it into virtual memory and using bzero to clear
1816 *	its contents.
1817 *
1818 *	off and size must reside within a single page.
1819 */
1820
1821void
1822pmap_zero_page_area(vm_offset_t pa, int off, int size)
1823{
1824	vm_offset_t va = IA64_PHYS_TO_RR7(pa);
1825	bzero((char *)(caddr_t)va + off, size);
1826}
1827
1828/*
1829 *	pmap_copy_page copies the specified (machine independent)
1830 *	page by mapping the page into virtual memory and using
1831 *	bcopy to copy the page, one machine dependent page at a
1832 *	time.
1833 */
1834void
1835pmap_copy_page(vm_offset_t src, vm_offset_t dst)
1836{
1837	src = IA64_PHYS_TO_RR7(src);
1838	dst = IA64_PHYS_TO_RR7(dst);
1839	bcopy((caddr_t) src, (caddr_t) dst, PAGE_SIZE);
1840}
1841
1842
1843/*
1844 *	Routine:	pmap_pageable
1845 *	Function:
1846 *		Make the specified pages (by pmap, offset)
1847 *		pageable (or not) as requested.
1848 *
1849 *		A page which is not pageable may not take
1850 *		a fault; therefore, its page table entry
1851 *		must remain valid for the duration.
1852 *
1853 *		This routine is merely advisory; pmap_enter
1854 *		will specify that these pages are to be wired
1855 *		down (or not) as appropriate.
1856 */
1857void
1858pmap_pageable(pmap, sva, eva, pageable)
1859	pmap_t pmap;
1860	vm_offset_t sva, eva;
1861	boolean_t pageable;
1862{
1863}
1864
1865/*
1866 * this routine returns true if a physical page resides
1867 * in the given pmap.
1868 */
1869boolean_t
1870pmap_page_exists(pmap, m)
1871	pmap_t pmap;
1872	vm_page_t m;
1873{
1874	register pv_entry_t pv;
1875	int s;
1876
1877	if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
1878		return FALSE;
1879
1880	s = splvm();
1881
1882	/*
1883	 * Not found, check current mappings returning immediately if found.
1884	 */
1885	for (pv = TAILQ_FIRST(&m->md.pv_list);
1886		pv;
1887		pv = TAILQ_NEXT(pv, pv_list)) {
1888		if (pv->pv_pmap == pmap) {
1889			splx(s);
1890			return TRUE;
1891		}
1892	}
1893	splx(s);
1894	return (FALSE);
1895}
1896
1897#define PMAP_REMOVE_PAGES_CURPROC_ONLY
1898/*
1899 * Remove all pages from specified address space
1900 * this aids process exit speeds.  Also, this code
1901 * is special cased for current process only, but
1902 * can have the more generic (and slightly slower)
1903 * mode enabled.  This is much faster than pmap_remove
1904 * in the case of running down an entire address space.
1905 */
1906void
1907pmap_remove_pages(pmap, sva, eva)
1908	pmap_t pmap;
1909	vm_offset_t sva, eva;
1910{
1911	pv_entry_t pv, npv;
1912	int s;
1913
1914#ifdef PMAP_REMOVE_PAGES_CURPROC_ONLY
1915	if (!curproc || (pmap != vmspace_pmap(curproc->p_vmspace))) {
1916		printf("warning: pmap_remove_pages called with non-current pmap\n");
1917		return;
1918	}
1919#endif
1920
1921	s = splvm();
1922	for (pv = TAILQ_FIRST(&pmap->pm_pvlist);
1923		pv;
1924		pv = npv) {
1925		vm_page_t m;
1926
1927		npv = TAILQ_NEXT(pv, pv_plist);
1928
1929		if (pv->pv_va >= eva || pv->pv_va < sva) {
1930			continue;
1931		}
1932
1933/*
1934 * We cannot remove wired pages from a process' mapping at this time
1935 */
1936		if (pv->pv_pte.pte_ig & PTE_IG_WIRED) {
1937			continue;
1938		}
1939
1940		PMAP_DEBUG_VA(pv->pv_va);
1941
1942		m = PHYS_TO_VM_PAGE(pmap_pte_pa(&pv->pv_pte));
1943		pmap_remove_pv(pmap, pv, m);
1944	}
1945	splx(s);
1946
1947	pmap_invalidate_all(pmap);
1948}
1949
1950/*
1951 *      pmap_page_protect:
1952 *
1953 *      Lower the permission for all mappings to a given page.
1954 */
1955void
1956pmap_page_protect(vm_page_t m, vm_prot_t prot)
1957{
1958	pv_entry_t pv;
1959
1960	if ((prot & VM_PROT_WRITE) != 0)
1961		return;
1962	if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
1963		for (pv = TAILQ_FIRST(&m->md.pv_list);
1964		     pv;
1965		     pv = TAILQ_NEXT(pv, pv_list)) {
1966			int newprot = pte_prot(pv->pv_pmap, prot);
1967			pmap_t oldpmap = pmap_install(pv->pv_pmap);
1968			pmap_pte_set_prot(&pv->pv_pte, newprot);
1969			pmap_update_vhpt(pv);
1970			pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
1971			pmap_install(oldpmap);
1972		}
1973	} else {
1974		pmap_remove_all(m);
1975	}
1976}
1977
1978vm_offset_t
1979pmap_phys_address(ppn)
1980	int ppn;
1981{
1982	return (ia64_ptob(ppn));
1983}
1984
1985/*
1986 *	pmap_ts_referenced:
1987 *
1988 *	Return the count of reference bits for a page, clearing all of them.
1989 *
1990 */
1991int
1992pmap_ts_referenced(vm_page_t m)
1993{
1994	pv_entry_t pv;
1995	int count = 0;
1996
1997	if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
1998		return 0;
1999
2000	for (pv = TAILQ_FIRST(&m->md.pv_list);
2001		pv;
2002		pv = TAILQ_NEXT(pv, pv_list)) {
2003		if (pv->pv_pte.pte_a) {
2004			pmap_t oldpmap = pmap_install(pv->pv_pmap);
2005			count++;
2006			pv->pv_pte.pte_a = 0;
2007			pmap_update_vhpt(pv);
2008			pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
2009			pmap_install(oldpmap);
2010		}
2011	}
2012
2013	return count;
2014}
2015
2016#if 0
2017/*
2018 *	pmap_is_referenced:
2019 *
2020 *	Return whether or not the specified physical page was referenced
2021 *	in any physical maps.
2022 */
2023static boolean_t
2024pmap_is_referenced(vm_page_t m)
2025{
2026	pv_entry_t pv;
2027
2028	if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
2029		return FALSE;
2030
2031	for (pv = TAILQ_FIRST(&m->md.pv_list);
2032		pv;
2033		pv = TAILQ_NEXT(pv, pv_list)) {
2034		if (pv->pv_pte.pte_a) {
2035			return 1;
2036		}
2037	}
2038
2039	return 0;
2040}
2041#endif
2042
2043/*
2044 *	pmap_is_modified:
2045 *
2046 *	Return whether or not the specified physical page was modified
2047 *	in any physical maps.
2048 */
2049boolean_t
2050pmap_is_modified(vm_page_t m)
2051{
2052	pv_entry_t pv;
2053
2054	if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
2055		return FALSE;
2056
2057	for (pv = TAILQ_FIRST(&m->md.pv_list);
2058		pv;
2059		pv = TAILQ_NEXT(pv, pv_list)) {
2060		if (pv->pv_pte.pte_d) {
2061			return 1;
2062		}
2063	}
2064
2065	return 0;
2066}
2067
2068/*
2069 *	Clear the modify bits on the specified physical page.
2070 */
2071void
2072pmap_clear_modify(vm_page_t m)
2073{
2074	pv_entry_t pv;
2075
2076	if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
2077		return;
2078
2079	for (pv = TAILQ_FIRST(&m->md.pv_list);
2080		pv;
2081		pv = TAILQ_NEXT(pv, pv_list)) {
2082		if (pv->pv_pte.pte_d) {
2083			pmap_t oldpmap = pmap_install(pv->pv_pmap);
2084			pv->pv_pte.pte_d = 0;
2085			pmap_update_vhpt(pv);
2086			pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
2087			pmap_install(oldpmap);
2088		}
2089	}
2090}
2091
2092/*
2093 *	pmap_clear_reference:
2094 *
2095 *	Clear the reference bit on the specified physical page.
2096 */
2097void
2098pmap_clear_reference(vm_page_t m)
2099{
2100	pv_entry_t pv;
2101
2102	if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
2103		return;
2104
2105	for (pv = TAILQ_FIRST(&m->md.pv_list);
2106		pv;
2107		pv = TAILQ_NEXT(pv, pv_list)) {
2108		if (pv->pv_pte.pte_a) {
2109			pmap_t oldpmap = pmap_install(pv->pv_pmap);
2110			pv->pv_pte.pte_a = 0;
2111			pmap_update_vhpt(pv);
2112			pmap_invalidate_page(pv->pv_pmap, pv->pv_va);
2113			pmap_install(oldpmap);
2114		}
2115	}
2116}
2117
2118/*
2119 * Miscellaneous support routines follow
2120 */
2121
2122static void
2123ia64_protection_init()
2124{
2125	int prot, *kp, *up;
2126
2127	kp = protection_codes[0];
2128	up = protection_codes[1];
2129
2130	for (prot = 0; prot < 8; prot++) {
2131		switch (prot) {
2132		case VM_PROT_NONE | VM_PROT_NONE | VM_PROT_NONE:
2133			*kp++ = (PTE_AR_R << 2) | PTE_PL_KERN;
2134			*up++ = (PTE_AR_R << 2) | PTE_PL_KERN;
2135			break;
2136
2137		case VM_PROT_NONE | VM_PROT_NONE | VM_PROT_EXECUTE:
2138			*kp++ = (PTE_AR_X_RX << 2) | PTE_PL_KERN;
2139			*up++ = (PTE_AR_X_RX << 2) | PTE_PL_USER;
2140			break;
2141
2142		case VM_PROT_NONE | VM_PROT_WRITE | VM_PROT_NONE:
2143			*kp++ = (PTE_AR_RW << 2) | PTE_PL_KERN;
2144			*up++ = (PTE_AR_RW << 2) | PTE_PL_USER;
2145			break;
2146
2147		case VM_PROT_NONE | VM_PROT_WRITE | VM_PROT_EXECUTE:
2148			*kp++ = (PTE_AR_RWX << 2) | PTE_PL_KERN;
2149			*up++ = (PTE_AR_RWX << 2) | PTE_PL_USER;
2150			break;
2151
2152		case VM_PROT_READ | VM_PROT_NONE | VM_PROT_NONE:
2153			*kp++ = (PTE_AR_R << 2) | PTE_PL_KERN;
2154			*up++ = (PTE_AR_R << 2) | PTE_PL_USER;
2155			break;
2156
2157		case VM_PROT_READ | VM_PROT_NONE | VM_PROT_EXECUTE:
2158			*kp++ = (PTE_AR_RX << 2) | PTE_PL_KERN;
2159			*up++ = (PTE_AR_RX << 2) | PTE_PL_USER;
2160			break;
2161
2162		case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_NONE:
2163			*kp++ = (PTE_AR_RW << 2) | PTE_PL_KERN;
2164			*up++ = (PTE_AR_RW << 2) | PTE_PL_USER;
2165			break;
2166
2167		case VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE:
2168			*kp++ = (PTE_AR_RWX << 2) | PTE_PL_KERN;
2169			*up++ = (PTE_AR_RWX << 2) | PTE_PL_USER;
2170			break;
2171		}
2172	}
2173}
2174
2175/*
2176 * Map a set of physical memory pages into the kernel virtual
2177 * address space. Return a pointer to where it is mapped. This
2178 * routine is intended to be used for mapping device memory,
2179 * NOT real memory.
2180 */
2181void *
2182pmap_mapdev(pa, size)
2183	vm_offset_t pa;
2184	vm_size_t size;
2185{
2186	return (void*) IA64_PHYS_TO_RR6(pa);
2187}
2188
2189/*
2190 * 'Unmap' a range mapped by pmap_mapdev().
2191 */
2192void
2193pmap_unmapdev(vm_offset_t va, vm_size_t size)
2194{
2195	return;
2196}
2197
2198/*
2199 * perform the pmap work for mincore
2200 */
2201int
2202pmap_mincore(pmap, addr)
2203	pmap_t pmap;
2204	vm_offset_t addr;
2205{
2206	pv_entry_t pv;
2207	struct ia64_lpte *pte;
2208	int val = 0;
2209
2210	pv = pmap_find_pv(pmap, addr);
2211	if (pv == 0) {
2212		return 0;
2213	}
2214	pte = &pv->pv_pte;
2215
2216	if (pmap_pte_v(pte)) {
2217		vm_page_t m;
2218		vm_offset_t pa;
2219
2220		val = MINCORE_INCORE;
2221		if ((pte->pte_ig & PTE_IG_MANAGED) == 0)
2222			return val;
2223
2224		pa = pmap_pte_pa(pte);
2225
2226		m = PHYS_TO_VM_PAGE(pa);
2227
2228		/*
2229		 * Modified by us
2230		 */
2231		if (pte->pte_d)
2232			val |= MINCORE_MODIFIED|MINCORE_MODIFIED_OTHER;
2233		/*
2234		 * Modified by someone
2235		 */
2236		else if (pmap_is_modified(m))
2237			val |= MINCORE_MODIFIED_OTHER;
2238		/*
2239		 * Referenced by us
2240		 */
2241		if (pte->pte_a)
2242			val |= MINCORE_REFERENCED|MINCORE_REFERENCED_OTHER;
2243
2244		/*
2245		 * Referenced by someone
2246		 */
2247		else if (pmap_ts_referenced(m)) {
2248			val |= MINCORE_REFERENCED_OTHER;
2249			vm_page_flag_set(m, PG_REFERENCED);
2250		}
2251	}
2252	return val;
2253}
2254
2255void
2256pmap_activate(struct thread *td)
2257{
2258	pmap_install(vmspace_pmap(td->td_proc->p_vmspace));
2259}
2260
2261pmap_t
2262pmap_install(pmap_t pmap)
2263{
2264	pmap_t oldpmap;
2265	int rid;
2266
2267	oldpmap = PCPU_GET(current_pmap);
2268
2269	if (pmap == oldpmap || pmap == kernel_pmap)
2270		return pmap;
2271
2272	PCPU_SET(current_pmap, pmap);
2273	if (!pmap) {
2274		/*
2275		 * RIDs 0..4 have no mappings to make sure we generate
2276		 * page faults on accesses.
2277		 */
2278		ia64_set_rr(IA64_RR_BASE(0), (0 << 8)|(PAGE_SHIFT << 2)|1);
2279		ia64_set_rr(IA64_RR_BASE(1), (1 << 8)|(PAGE_SHIFT << 2)|1);
2280		ia64_set_rr(IA64_RR_BASE(2), (2 << 8)|(PAGE_SHIFT << 2)|1);
2281		ia64_set_rr(IA64_RR_BASE(3), (3 << 8)|(PAGE_SHIFT << 2)|1);
2282		ia64_set_rr(IA64_RR_BASE(4), (4 << 8)|(PAGE_SHIFT << 2)|1);
2283		return oldpmap;
2284	}
2285
2286	pmap->pm_active = 1;	/* XXX use bitmap for SMP */
2287
2288 reinstall:
2289	rid = pmap->pm_rid & ((1 << pmap_ridbits) - 1);
2290	ia64_set_rr(IA64_RR_BASE(0), ((rid + 0) << 8)|(PAGE_SHIFT << 2)|1);
2291	ia64_set_rr(IA64_RR_BASE(1), ((rid + 1) << 8)|(PAGE_SHIFT << 2)|1);
2292	ia64_set_rr(IA64_RR_BASE(2), ((rid + 2) << 8)|(PAGE_SHIFT << 2)|1);
2293	ia64_set_rr(IA64_RR_BASE(3), ((rid + 3) << 8)|(PAGE_SHIFT << 2)|1);
2294	ia64_set_rr(IA64_RR_BASE(4), ((rid + 4) << 8)|(PAGE_SHIFT << 2)|1);
2295
2296	/*
2297	 * If we need a new RID, get it now. Note that we need to
2298	 * remove our old mappings (if any) from the VHPT, so we will
2299	 * run on the old RID for a moment while we invalidate the old
2300	 * one. XXX maybe we should just clear out the VHPT when the
2301	 * RID generation rolls over.
2302	 */
2303	if ((pmap->pm_rid>>pmap_ridbits) != (pmap_nextrid>>pmap_ridbits)) {
2304		if (pmap->pm_rid)
2305			pmap_invalidate_rid(pmap);
2306		pmap_get_rid(pmap);
2307		goto reinstall;
2308	}
2309
2310	return oldpmap;
2311}
2312
2313vm_offset_t
2314pmap_addr_hint(vm_object_t obj, vm_offset_t addr, vm_size_t size)
2315{
2316
2317	return addr;
2318}
2319
2320#if 0
2321#if defined(PMAP_DEBUG)
2322pmap_pid_dump(int pid)
2323{
2324	pmap_t pmap;
2325	struct proc *p;
2326	int npte = 0;
2327	int index;
2328
2329	sx_slock(&allproc_lock);
2330	LIST_FOREACH(p, &allproc, p_list) {
2331		if (p->p_pid != pid)
2332			continue;
2333
2334		if (p->p_vmspace) {
2335			int i,j;
2336			index = 0;
2337			pmap = vmspace_pmap(p->p_vmspace);
2338			for(i = 0; i < 1024; i++) {
2339				pd_entry_t *pde;
2340				pt_entry_t *pte;
2341				unsigned base = i << PDRSHIFT;
2342
2343				pde = &pmap->pm_pdir[i];
2344				if (pde && pmap_pde_v(pde)) {
2345					for(j = 0; j < 1024; j++) {
2346						unsigned va = base + (j << PAGE_SHIFT);
2347						if (va >= (vm_offset_t) VM_MIN_KERNEL_ADDRESS) {
2348							if (index) {
2349								index = 0;
2350								printf("\n");
2351							}
2352							sx_sunlock(&allproc_lock);
2353							return npte;
2354						}
2355						pte = pmap_pte_quick( pmap, va);
2356						if (pte && pmap_pte_v(pte)) {
2357							vm_offset_t pa;
2358							vm_page_t m;
2359							pa = *(int *)pte;
2360							m = PHYS_TO_VM_PAGE(pa);
2361							printf("va: 0x%x, pt: 0x%x, h: %d, w: %d, f: 0x%x",
2362								va, pa, m->hold_count, m->wire_count, m->flags);
2363							npte++;
2364							index++;
2365							if (index >= 2) {
2366								index = 0;
2367								printf("\n");
2368							} else {
2369								printf(" ");
2370							}
2371						}
2372					}
2373				}
2374			}
2375		}
2376	}
2377	sx_sunlock(&allproc_lock);
2378	return npte;
2379}
2380#endif
2381
2382#if defined(DEBUG)
2383
2384static void	pads __P((pmap_t pm));
2385static void	pmap_pvdump __P((vm_page_t m));
2386
2387/* print address space of pmap*/
2388static void
2389pads(pm)
2390	pmap_t pm;
2391{
2392        int i, j;
2393	vm_offset_t va;
2394	pt_entry_t *ptep;
2395
2396	if (pm == kernel_pmap)
2397		return;
2398	for (i = 0; i < 1024; i++)
2399		if (pm->pm_pdir[i])
2400			for (j = 0; j < 1024; j++) {
2401				va = (i << PDRSHIFT) + (j << PAGE_SHIFT);
2402				if (pm == kernel_pmap && va < KERNBASE)
2403					continue;
2404				if (pm != kernel_pmap && va > UPT_MAX_ADDRESS)
2405					continue;
2406				ptep = pmap_pte_quick(pm, va);
2407				if (pmap_pte_v(ptep))
2408					printf("%x:%x ", va, *(int *) ptep);
2409			};
2410
2411}
2412
2413static void
2414pmap_pvdump(pa)
2415	vm_offset_t pa;
2416{
2417	pv_entry_t pv;
2418
2419	printf("pa %x", pa);
2420	m = PHYS_TO_VM_PAGE(pa);
2421	for (pv = TAILQ_FIRST(&m->md.pv_list);
2422		pv;
2423		pv = TAILQ_NEXT(pv, pv_list)) {
2424		printf(" -> pmap %x, va %x",
2425		    pv->pv_pmap, pv->pv_va);
2426		pads(pv->pv_pmap);
2427	}
2428	printf(" ");
2429}
2430#endif
2431#endif
2432