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