1 /* 2 * Copyright (c) 1992 OMRON Corporation. 3 * Copyright (c) 1991 Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * the Systems Programming Group of the University of Utah Computer 8 * Science Department. 9 * 10 * %sccs.include.redist.c% 11 * 12 * OMRON: $Id: pmap.c,v 1.2 92/06/14 06:19:40 moti Exp $ 13 * 14 * from: hp300/hp300/pmap.c 7.9 (Berkeley) 6/5/92 15 * 16 * @(#)pmap.c 7.1 (Berkeley) 06/15/92 17 */ 18 19 /* 20 * LUNA physical map management code taken from: 21 * HP9000/300 series physical map management code. 22 * 23 * XXX will only work for PAGE_SIZE == NBPG (i.e. 4096 bytes). 24 * Hence, there is no point in defining DYNPGSIZE. 25 */ 26 27 /* 28 * Manages physical address maps. 29 * 30 * In addition to hardware address maps, this 31 * module is called upon to provide software-use-only 32 * maps which may or may not be stored in the same 33 * form as hardware maps. These pseudo-maps are 34 * used to store intermediate results from copy 35 * operations to and from address spaces. 36 * 37 * Since the information managed by this module is 38 * also stored by the logical address mapping module, 39 * this module may throw away valid virtual-to-physical 40 * mappings at almost any time. However, invalidations 41 * of virtual-to-physical mappings must be done as 42 * requested. 43 * 44 * In order to cope with hardware architectures which 45 * make virtual-to-physical map invalidates expensive, 46 * this module may delay invalidate or reduced protection 47 * operations until such time as they are actually 48 * necessary. This module is given full information as 49 * to which processors are currently using which maps, 50 * and to when physical maps must be made correct. 51 */ 52 53 #include "param.h" 54 #include "proc.h" 55 #include "malloc.h" 56 #include "user.h" 57 58 #include "pte.h" 59 60 #include "vm/vm.h" 61 #include "vm/vm_kern.h" 62 #include "vm/vm_page.h" 63 64 #include "../include/cpu.h" 65 66 #ifdef DEBUG 67 struct { 68 int collectscans; 69 int collectpages; 70 int kpttotal; 71 int kptinuse; 72 int kptmaxuse; 73 } kpt_stats; 74 struct { 75 int kernel; /* entering kernel mapping */ 76 int user; /* entering user mapping */ 77 int ptpneeded; /* needed to allocate a PT page */ 78 int pwchange; /* no mapping change, just wiring or protection */ 79 int wchange; /* no mapping change, just wiring */ 80 int mchange; /* was mapped but mapping to different page */ 81 int managed; /* a managed page */ 82 int firstpv; /* first mapping for this PA */ 83 int secondpv; /* second mapping for this PA */ 84 int ci; /* cache inhibited */ 85 int unmanaged; /* not a managed page */ 86 int flushes; /* cache flushes */ 87 } enter_stats; 88 struct { 89 int calls; 90 int removes; 91 int pvfirst; 92 int pvsearch; 93 int ptinvalid; 94 int uflushes; 95 int sflushes; 96 } remove_stats; 97 struct { 98 int calls; 99 int pages; 100 int alreadyro; 101 int alreadyrw; 102 } protect_stats; 103 104 int debugmap = 0; 105 int pmapdebug = 0x2000; 106 #define PDB_FOLLOW 0x0001 107 #define PDB_INIT 0x0002 108 #define PDB_ENTER 0x0004 109 #define PDB_REMOVE 0x0008 110 #define PDB_CREATE 0x0010 111 #define PDB_PTPAGE 0x0020 112 #define PDB_CACHE 0x0040 113 #define PDB_BITS 0x0080 114 #define PDB_COLLECT 0x0100 115 #define PDB_PROTECT 0x0200 116 #define PDB_SEGTAB 0x0400 117 #define PDB_PARANOIA 0x2000 118 #define PDB_WIRING 0x4000 119 #define PDB_PVDUMP 0x8000 120 121 extern vm_offset_t pager_sva, pager_eva; 122 #endif 123 124 /* 125 * Get STEs and PTEs for user/kernel address space 126 */ 127 #define pmap_ste(m, v) (&((m)->pm_stab[(vm_offset_t)(v) >> SG_ISHIFT])) 128 #define pmap_pte(m, v) (&((m)->pm_ptab[(vm_offset_t)(v) >> PG_SHIFT])) 129 130 #define pmap_ste_v(m, v) (pmap_ste(m, v)->sg_v) 131 132 #define pmap_pte_pa(pte) (*(int *)(pte) & PG_FRAME) 133 #define pmap_pte_w(pte) ((pte)->pg_w) 134 #define pmap_pte_ci(pte) ((pte)->pg_ci) 135 #define pmap_pte_m(pte) ((pte)->pg_m) 136 #define pmap_pte_u(pte) ((pte)->pg_u) 137 #define pmap_pte_prot(pte) ((pte)->pg_prot) 138 #define pmap_pte_v(pte) ((pte)->pg_v) 139 #define pmap_pte_set_w(pte, v) ((pte)->pg_w = (v)) 140 #define pmap_pte_set_prot(pte, v) ((pte)->pg_prot = (v)) 141 142 /* 143 * Given a map and a machine independent protection code, 144 * convert to a vax protection code. 145 */ 146 #define pte_prot(m, p) (protection_codes[p]) 147 int protection_codes[8]; 148 149 /* 150 * Kernel page table page management. 151 */ 152 struct kpt_page { 153 struct kpt_page *kpt_next; /* link on either used or free list */ 154 vm_offset_t kpt_va; /* always valid kernel VA */ 155 vm_offset_t kpt_pa; /* PA of this page (for speed) */ 156 }; 157 struct kpt_page *kpt_free_list, *kpt_used_list; 158 struct kpt_page *kpt_pages; 159 160 /* 161 * Kernel segment/page table and page table map. 162 * The page table map gives us a level of indirection we need to dynamically 163 * expand the page table. It is essentially a copy of the segment table 164 * with PTEs instead of STEs. All are initialized in locore at boot time. 165 * Sysmap will initially contain VM_KERNEL_PT_PAGES pages of PTEs. 166 * Segtabzero is an empty segment table which all processes share til they 167 * reference something. 168 */ 169 st_entry_t *Sysseg; 170 pt_entry_t *Sysmap, *Sysptmap; 171 st_entry_t *Segtabzero, *Segtabzeropa; 172 vm_size_t Sysptsize = VM_KERNEL_PT_PAGES; 173 174 struct pmap kernel_pmap_store; 175 vm_map_t pt_map; 176 177 vm_offset_t avail_start; /* PA of first available physical page */ 178 vm_offset_t avail_end; /* PA of last available physical page */ 179 vm_size_t mem_size; /* memory size in bytes */ 180 vm_offset_t virtual_avail; /* VA of first avail page (after kernel bss)*/ 181 vm_offset_t virtual_end; /* VA of last avail page (end of kernel AS) */ 182 vm_offset_t vm_first_phys; /* PA of first managed page */ 183 vm_offset_t vm_last_phys; /* PA just past last managed page */ 184 #if defined(DYNPGSIZE) 185 int lunapagesperpage; /* PAGE_SIZE / LUNA_PAGE_SIZE */ 186 #endif 187 boolean_t pmap_initialized = FALSE; /* Has pmap_init completed? */ 188 char *pmap_attributes; /* reference and modify bits */ 189 190 boolean_t pmap_testbit(); 191 void pmap_enter_ptpage(); 192 193 extern struct physmap io_physmap[]; /* LUNA: io mapping information */ 194 195 /* 196 * Bootstrap memory allocator. This function allows for early dynamic 197 * memory allocation until the virtual memory system has been bootstrapped. 198 * After that point, either kmem_alloc or malloc should be used. This 199 * function works by stealing pages from the (to be) managed page pool, 200 * stealing virtual address space, then mapping the pages and zeroing them. 201 * 202 * It should be used from pmap_bootstrap till vm_page_startup, afterwards 203 * it cannot be used, and will generate a panic if tried. Note that this 204 * memory will never be freed, and in essence it is wired down. 205 */ 206 void * 207 pmap_bootstrap_alloc(size) { 208 vm_offset_t val; 209 int i; 210 extern boolean_t vm_page_startup_initialized; 211 212 if (vm_page_startup_initialized) 213 panic("pmap_bootstrap_alloc: called after startup initialized"); 214 size = round_page(size); 215 val = virtual_avail; 216 217 virtual_avail = pmap_map(virtual_avail, avail_start, 218 avail_start + size, VM_PROT_READ|VM_PROT_WRITE); 219 avail_start += size; 220 221 blkclr ((caddr_t) val, size); 222 return ((void *) val); 223 } 224 225 /* 226 * Initialize the pmap module. 227 * Called by vm_init, to initialize any structures that the pmap 228 * system needs to map virtual memory. 229 */ 230 void 231 pmap_init(phys_start, phys_end) 232 vm_offset_t phys_start, phys_end; 233 { 234 vm_offset_t addr, addr2; 235 vm_size_t npg, s; 236 int rv, index; 237 extern char kstack[]; 238 239 #ifdef DEBUG 240 if (pmapdebug & PDB_FOLLOW) 241 printf("pmap_init(%x, %x)\n", phys_start, phys_end); 242 #endif 243 /* 244 * Now that kernel map has been allocated, we can mark as 245 * unavailable regions which we have mapped in locore. 246 */ 247 for(index = 0; io_physmap[index].pm_phys; index++) 248 { 249 addr = io_physmap[index].pm_phys; 250 (void) vm_map_find(kernel_map, NULL, (vm_offset_t) 0, 251 &addr, luna_round_page(io_physmap[index].pm_size), FALSE); 252 if (addr != io_physmap[index].pm_phys) 253 goto bogons; 254 } 255 256 addr = (vm_offset_t) Sysmap; 257 vm_object_reference(kernel_object); 258 (void) vm_map_find(kernel_map, kernel_object, addr, 259 &addr, LUNA_MAX_PTSIZE, FALSE); 260 /* 261 * If this fails it is probably because the static portion of 262 * the kernel page table isn't big enough and we overran the 263 * page table map. Need to adjust pmap_size() in luna_init.c. 264 */ 265 if (addr != (vm_offset_t)Sysmap) 266 goto bogons; 267 268 addr = (vm_offset_t) kstack; 269 vm_object_reference(kernel_object); 270 (void) vm_map_find(kernel_map, kernel_object, addr, 271 &addr, luna_ptob(UPAGES), FALSE); 272 if (addr != (vm_offset_t)kstack) 273 bogons: 274 panic("pmap_init: bogons in the VM system!\n"); 275 276 #ifdef DEBUG 277 if (pmapdebug & PDB_INIT) { 278 printf("pmap_init: Sysseg %x, Sysmap %x, Sysptmap %x\n", 279 Sysseg, Sysmap, Sysptmap); 280 printf(" pstart %x, pend %x, vstart %x, vend %x\n", 281 avail_start, avail_end, virtual_avail, virtual_end); 282 } 283 #endif 284 285 /* 286 * Allocate memory for random pmap data structures. Includes the 287 * initial segment table, pv_head_table and pmap_attributes. 288 */ 289 npg = atop(phys_end - phys_start); 290 s = (vm_size_t) (LUNA_STSIZE + sizeof(struct pv_entry) * npg + npg); 291 s = round_page(s); 292 addr = (vm_offset_t) kmem_alloc(kernel_map, s); 293 Segtabzero = (st_entry_t *) addr; 294 Segtabzeropa = (st_entry_t *) pmap_extract(kernel_pmap, addr); 295 addr += LUNA_STSIZE; 296 pv_table = (pv_entry_t) addr; 297 addr += sizeof(struct pv_entry) * npg; 298 pmap_attributes = (char *) addr; 299 #ifdef DEBUG 300 if (pmapdebug & PDB_INIT) 301 printf("pmap_init: %x bytes: npg %x s0 %x(%x) tbl %x atr %x\n", 302 s, npg, Segtabzero, Segtabzeropa, 303 pv_table, pmap_attributes); 304 #endif 305 306 /* 307 * Allocate physical memory for kernel PT pages and their management. 308 * We need 1 PT page per possible task plus some slop. 309 */ 310 npg = min(atop(LUNA_MAX_KPTSIZE), maxproc+16); 311 s = ptoa(npg) + round_page(npg * sizeof(struct kpt_page)); 312 313 /* 314 * Verify that space will be allocated in region for which 315 * we already have kernel PT pages. 316 */ 317 addr = 0; 318 rv = vm_map_find(kernel_map, NULL, 0, &addr, s, TRUE); 319 if (rv != KERN_SUCCESS || addr + s >= (vm_offset_t)Sysmap) 320 panic("pmap_init: kernel PT too small"); 321 vm_map_remove(kernel_map, addr, addr + s); 322 323 /* 324 * Now allocate the space and link the pages together to 325 * form the KPT free list. 326 */ 327 addr = (vm_offset_t) kmem_alloc(kernel_map, s); 328 s = ptoa(npg); 329 addr2 = addr + s; 330 kpt_pages = &((struct kpt_page *)addr2)[npg]; 331 kpt_free_list = (struct kpt_page *) 0; 332 do { 333 addr2 -= LUNA_PAGE_SIZE; 334 (--kpt_pages)->kpt_next = kpt_free_list; 335 kpt_free_list = kpt_pages; 336 kpt_pages->kpt_va = addr2; 337 kpt_pages->kpt_pa = pmap_extract(kernel_pmap, addr2); 338 } while (addr != addr2); 339 #ifdef DEBUG 340 kpt_stats.kpttotal = atop(s); 341 if (pmapdebug & PDB_INIT) 342 printf("pmap_init: KPT: %d pages from %x to %x\n", 343 atop(s), addr, addr + s); 344 #endif 345 346 /* 347 * Slightly modified version of kmem_suballoc() to get page table 348 * map where we want it. 349 */ 350 addr = LUNA_PTBASE; 351 s = min(LUNA_PTMAXSIZE, maxproc*LUNA_MAX_PTSIZE); 352 addr2 = addr + s; 353 rv = vm_map_find(kernel_map, NULL, 0, &addr, s, TRUE); 354 if (rv != KERN_SUCCESS) 355 panic("pmap_init: cannot allocate space for PT map"); 356 pmap_reference(vm_map_pmap(kernel_map)); 357 pt_map = vm_map_create(vm_map_pmap(kernel_map), addr, addr2, TRUE); 358 if (pt_map == NULL) 359 panic("pmap_init: cannot create pt_map"); 360 rv = vm_map_submap(kernel_map, addr, addr2, pt_map); 361 if (rv != KERN_SUCCESS) 362 panic("pmap_init: cannot map range to pt_map"); 363 #ifdef DEBUG 364 if (pmapdebug & PDB_INIT) 365 printf("pmap_init: pt_map [%x - %x)\n", addr, addr2); 366 #endif 367 368 /* 369 * Now it is safe to enable pv_table recording. 370 */ 371 vm_first_phys = phys_start; 372 vm_last_phys = phys_end; 373 pmap_initialized = TRUE; 374 } 375 376 /* 377 * Used to map a range of physical addresses into kernel 378 * virtual address space. 379 * 380 * For now, VM is already on, we only need to map the 381 * specified memory. 382 */ 383 vm_offset_t 384 pmap_map(virt, start, end, prot) 385 vm_offset_t virt; 386 vm_offset_t start; 387 vm_offset_t end; 388 int prot; 389 { 390 #ifdef DEBUG 391 if (pmapdebug & PDB_FOLLOW) 392 printf("pmap_map(%x, %x, %x, %x)\n", virt, start, end, prot); 393 #endif 394 while (start < end) { 395 pmap_enter(kernel_pmap, virt, start, prot, FALSE); 396 virt += PAGE_SIZE; 397 start += PAGE_SIZE; 398 } 399 return(virt); 400 } 401 402 /* 403 * Create and return a physical map. 404 * 405 * If the size specified for the map 406 * is zero, the map is an actual physical 407 * map, and may be referenced by the 408 * hardware. 409 * 410 * If the size specified is non-zero, 411 * the map will be used in software only, and 412 * is bounded by that size. 413 */ 414 pmap_t 415 pmap_create(size) 416 vm_size_t size; 417 { 418 register pmap_t pmap; 419 420 #ifdef DEBUG 421 if (pmapdebug & (PDB_FOLLOW|PDB_CREATE)) 422 printf("pmap_create(%x)\n", size); 423 #endif 424 /* 425 * Software use map does not need a pmap 426 */ 427 if (size) 428 return(NULL); 429 430 /* XXX: is it ok to wait here? */ 431 pmap = (pmap_t) malloc(sizeof *pmap, M_VMPMAP, M_WAITOK); 432 #ifdef notifwewait 433 if (pmap == NULL) 434 panic("pmap_create: cannot allocate a pmap"); 435 #endif 436 bzero(pmap, sizeof(*pmap)); 437 pmap_pinit(pmap); 438 return (pmap); 439 } 440 441 /* 442 * Initialize a preallocated and zeroed pmap structure, 443 * such as one in a vmspace structure. 444 */ 445 void 446 pmap_pinit(pmap) 447 register struct pmap *pmap; 448 { 449 450 #ifdef DEBUG 451 if (pmapdebug & (PDB_FOLLOW|PDB_CREATE)) 452 printf("pmap_pinit(%x)\n", pmap); 453 #endif 454 /* 455 * No need to allocate page table space yet but we do need a 456 * valid segment table. Initially, we point everyone at the 457 * "null" segment table. On the first pmap_enter, a real 458 * segment table will be allocated. 459 */ 460 pmap->pm_stab = Segtabzero; 461 pmap->pm_stpa = Segtabzeropa; 462 pmap->pm_stchanged = TRUE; 463 pmap->pm_count = 1; 464 simple_lock_init(&pmap->pm_lock); 465 } 466 467 /* 468 * Retire the given physical map from service. 469 * Should only be called if the map contains 470 * no valid mappings. 471 */ 472 void 473 pmap_destroy(pmap) 474 register pmap_t pmap; 475 { 476 int count; 477 478 #ifdef DEBUG 479 if (pmapdebug & PDB_FOLLOW) 480 printf("pmap_destroy(%x)\n", pmap); 481 #endif 482 if (pmap == NULL) 483 return; 484 485 simple_lock(&pmap->pm_lock); 486 count = --pmap->pm_count; 487 simple_unlock(&pmap->pm_lock); 488 if (count == 0) { 489 pmap_release(pmap); 490 free((caddr_t)pmap, M_VMPMAP); 491 } 492 } 493 494 /* 495 * Release any resources held by the given physical map. 496 * Called when a pmap initialized by pmap_pinit is being released. 497 * Should only be called if the map contains no valid mappings. 498 */ 499 void 500 pmap_release(pmap) 501 register struct pmap *pmap; 502 { 503 504 #ifdef DEBUG 505 if (pmapdebug & PDB_FOLLOW) 506 printf("pmap_release(%x)\n", pmap); 507 #endif 508 #ifdef notdef /* DIAGNOSTIC */ 509 /* count would be 0 from pmap_destroy... */ 510 simple_lock(&pmap->pm_lock); 511 if (pmap->pm_count != 1) 512 panic("pmap_release count"); 513 #endif 514 if (pmap->pm_ptab) 515 kmem_free_wakeup(pt_map, (vm_offset_t)pmap->pm_ptab, 516 LUNA_MAX_PTSIZE); 517 if (pmap->pm_stab != Segtabzero) 518 kmem_free(kernel_map, (vm_offset_t)pmap->pm_stab, LUNA_STSIZE); 519 } 520 521 /* 522 * Add a reference to the specified pmap. 523 */ 524 void 525 pmap_reference(pmap) 526 pmap_t pmap; 527 { 528 #ifdef DEBUG 529 if (pmapdebug & PDB_FOLLOW) 530 printf("pmap_reference(%x)\n", pmap); 531 #endif 532 if (pmap != NULL) { 533 simple_lock(&pmap->pm_lock); 534 pmap->pm_count++; 535 simple_unlock(&pmap->pm_lock); 536 } 537 } 538 539 /* 540 * Remove the given range of addresses from the specified map. 541 * 542 * It is assumed that the start and end are properly 543 * rounded to the page size. 544 */ 545 void 546 pmap_remove(pmap, sva, eva) 547 register pmap_t pmap; 548 vm_offset_t sva, eva; 549 { 550 register vm_offset_t pa, va; 551 register pt_entry_t *pte; 552 register pv_entry_t pv, npv; 553 pmap_t ptpmap; 554 int *ste, s, bits; 555 boolean_t firstpage = TRUE; 556 boolean_t flushcache = FALSE; 557 #ifdef DEBUG 558 pt_entry_t opte; 559 560 if (pmapdebug & (PDB_FOLLOW|PDB_REMOVE|PDB_PROTECT)) 561 printf("pmap_remove(%x, %x, %x)\n", pmap, sva, eva); 562 #endif 563 564 if (pmap == NULL) 565 return; 566 567 #ifdef DEBUG 568 remove_stats.calls++; 569 #endif 570 for (va = sva; va < eva; va += PAGE_SIZE) { 571 /* 572 * Weed out invalid mappings. 573 * Note: we assume that the segment table is always allocated. 574 */ 575 if (!pmap_ste_v(pmap, va)) { 576 /* XXX: avoid address wrap around */ 577 if (va >= luna_trunc_seg(VM_MAX_ADDRESS)) 578 break; 579 va = luna_round_seg(va + PAGE_SIZE) - PAGE_SIZE; 580 continue; 581 } 582 pte = pmap_pte(pmap, va); 583 pa = pmap_pte_pa(pte); 584 if (pa == 0) 585 continue; 586 #ifdef DEBUG 587 opte = *pte; 588 remove_stats.removes++; 589 #endif 590 /* 591 * Update statistics 592 */ 593 if (pmap_pte_w(pte)) 594 pmap->pm_stats.wired_count--; 595 pmap->pm_stats.resident_count--; 596 597 /* 598 * Invalidate the PTEs. 599 * XXX: should cluster them up and invalidate as many 600 * as possible at once. 601 */ 602 #ifdef DEBUG 603 if (pmapdebug & PDB_REMOVE) 604 printf("remove: invalidating pte at %x\n", pte); 605 remove_stats.sflushes++; 606 #endif 607 #if defined(DYNPGSIZE) 608 { 609 register int ix = 0; 610 611 bits = 0; 612 do { 613 bits |= *(int *)pte & (PG_U|PG_M); 614 *(int *)pte++ = PG_NV; 615 TBIS(va + ix * LUNA_PAGE_SIZE); 616 } while (++ix != lunapagesperpage); 617 } 618 #else 619 bits = *(int *)pte & (PG_U|PG_M); 620 *(int *)pte = PG_NV; 621 TBIS(va); 622 #endif 623 /* 624 * For user mappings decrement the wiring count on 625 * the PT page. We do this after the PTE has been 626 * invalidated because vm_map_pageable winds up in 627 * pmap_pageable which clears the modify bit for the 628 * PT page. 629 */ 630 if (pmap != kernel_pmap) { 631 pte = pmap_pte(pmap, va); 632 vm_map_pageable(pt_map, trunc_page(pte), 633 round_page(pte+1), TRUE); 634 #ifdef DEBUG 635 if (pmapdebug & PDB_WIRING) 636 pmap_check_wiring("remove", trunc_page(pte)); 637 #endif 638 } 639 /* 640 * Remove from the PV table (raise IPL since we 641 * may be called at interrupt time). 642 */ 643 if (pa < vm_first_phys || pa >= vm_last_phys) 644 continue; 645 pv = pa_to_pvh(pa); 646 ste = (int *)0; 647 s = splimp(); 648 /* 649 * If it is the first entry on the list, it is actually 650 * in the header and we must copy the following entry up 651 * to the header. Otherwise we must search the list for 652 * the entry. In either case we free the now unused entry. 653 */ 654 if (pmap == pv->pv_pmap && va == pv->pv_va) { 655 ste = (int *)pv->pv_ptste; 656 ptpmap = pv->pv_ptpmap; 657 npv = pv->pv_next; 658 if (npv) { 659 *pv = *npv; 660 free((caddr_t)npv, M_VMPVENT); 661 } else 662 pv->pv_pmap = NULL; 663 #ifdef DEBUG 664 remove_stats.pvfirst++; 665 #endif 666 } else { 667 for (npv = pv->pv_next; npv; npv = npv->pv_next) { 668 #ifdef DEBUG 669 remove_stats.pvsearch++; 670 #endif 671 if (pmap == npv->pv_pmap && va == npv->pv_va) 672 break; 673 pv = npv; 674 } 675 #ifdef DEBUG 676 if (npv == NULL) 677 panic("pmap_remove: PA not in pv_tab"); 678 #endif 679 ste = (int *)npv->pv_ptste; 680 ptpmap = npv->pv_ptpmap; 681 pv->pv_next = npv->pv_next; 682 free((caddr_t)npv, M_VMPVENT); 683 pv = pa_to_pvh(pa); 684 } 685 /* 686 * If only one mapping left we no longer need to cache inhibit 687 */ 688 if (pv->pv_pmap && 689 pv->pv_next == NULL && (pv->pv_flags & PV_CI)) { 690 #ifdef DEBUG 691 if (pmapdebug & PDB_CACHE) 692 printf("remove: clearing CI for pa %x\n", pa); 693 #endif 694 pv->pv_flags &= ~PV_CI; 695 pmap_changebit(pa, PG_CI, FALSE); 696 #ifdef DEBUG 697 if ((pmapdebug & (PDB_CACHE|PDB_PVDUMP)) == 698 (PDB_CACHE|PDB_PVDUMP)) 699 pmap_pvdump(pa); 700 #endif 701 } 702 703 /* 704 * If this was a PT page we must also remove the 705 * mapping from the associated segment table. 706 */ 707 if (ste) { 708 #ifdef DEBUG 709 remove_stats.ptinvalid++; 710 if (pmapdebug & (PDB_REMOVE|PDB_PTPAGE)) { 711 printf("remove: ste was %x@%x pte was %x@%x\n", 712 *ste, ste, 713 *(int *)&opte, pmap_pte(pmap, va)); 714 } 715 #endif 716 *ste = SG_NV; 717 /* 718 * If it was a user PT page, we decrement the 719 * reference count on the segment table as well, 720 * freeing it if it is now empty. 721 */ 722 if (ptpmap != kernel_pmap) { 723 #ifdef DEBUG 724 if (pmapdebug & (PDB_REMOVE|PDB_SEGTAB)) 725 printf("remove: stab %x, refcnt %d\n", 726 ptpmap->pm_stab, 727 ptpmap->pm_sref - 1); 728 if ((pmapdebug & PDB_PARANOIA) && 729 ptpmap->pm_stab != (st_entry_t *)trunc_page(ste)) 730 panic("remove: bogus ste"); 731 #endif 732 if (--(ptpmap->pm_sref) == 0) { 733 #ifdef DEBUG 734 if (pmapdebug&(PDB_REMOVE|PDB_SEGTAB)) 735 printf("remove: free stab %x\n", 736 ptpmap->pm_stab); 737 #endif 738 kmem_free(kernel_map, 739 (vm_offset_t)ptpmap->pm_stab, 740 LUNA_STSIZE); 741 ptpmap->pm_stab = Segtabzero; 742 ptpmap->pm_stpa = Segtabzeropa; 743 ptpmap->pm_stchanged = TRUE; 744 /* 745 * XXX may have changed segment table 746 * pointer for current process so 747 * update now to reload hardware. 748 */ 749 if (ptpmap == curproc->p_vmspace->vm_map.pmap) 750 PMAP_ACTIVATE(ptpmap, 751 (struct pcb *)curproc->p_addr, 1); 752 } 753 } 754 if (ptpmap == kernel_pmap) 755 TBIAS(); 756 else 757 TBIAU(); 758 pv->pv_flags &= ~PV_PTPAGE; 759 ptpmap->pm_ptpages--; 760 } 761 /* 762 * Update saved attributes for managed page 763 */ 764 pmap_attributes[pa_index(pa)] |= bits; 765 splx(s); 766 } 767 } 768 769 /* 770 * pmap_page_protect: 771 * 772 * Lower the permission for all mappings to a given page. 773 */ 774 void 775 pmap_page_protect(pa, prot) 776 vm_offset_t pa; 777 vm_prot_t prot; 778 { 779 register pv_entry_t pv; 780 int s; 781 782 #ifdef DEBUG 783 if ((pmapdebug & (PDB_FOLLOW|PDB_PROTECT)) || 784 prot == VM_PROT_NONE && (pmapdebug & PDB_REMOVE)) 785 printf("pmap_page_protect(%x, %x)\n", pa, prot); 786 #endif 787 if (pa < vm_first_phys || pa >= vm_last_phys) 788 return; 789 790 switch (prot) { 791 case VM_PROT_ALL: 792 break; 793 /* copy_on_write */ 794 case VM_PROT_READ: 795 case VM_PROT_READ|VM_PROT_EXECUTE: 796 pmap_changebit(pa, PG_RO, TRUE); 797 break; 798 /* remove_all */ 799 default: 800 pv = pa_to_pvh(pa); 801 s = splimp(); 802 while (pv->pv_pmap != NULL) { 803 #ifdef DEBUG 804 if (!pmap_ste_v(pv->pv_pmap, pv->pv_va) || 805 pmap_pte_pa(pmap_pte(pv->pv_pmap,pv->pv_va)) != pa) 806 panic("pmap_page_protect: bad mapping"); 807 #endif 808 pmap_remove(pv->pv_pmap, pv->pv_va, 809 pv->pv_va + PAGE_SIZE); 810 } 811 splx(s); 812 break; 813 } 814 } 815 816 /* 817 * Set the physical protection on the 818 * specified range of this map as requested. 819 */ 820 void 821 pmap_protect(pmap, sva, eva, prot) 822 register pmap_t pmap; 823 vm_offset_t sva, eva; 824 vm_prot_t prot; 825 { 826 register pt_entry_t *pte; 827 register vm_offset_t va; 828 int lunaprot; 829 boolean_t firstpage = TRUE; 830 831 #ifdef DEBUG 832 if (pmapdebug & (PDB_FOLLOW|PDB_PROTECT)) 833 printf("pmap_protect(%x, %x, %x, %x)\n", pmap, sva, eva, prot); 834 protect_stats.calls++; 835 #endif 836 if (pmap == NULL) 837 return; 838 839 if ((prot & VM_PROT_READ) == VM_PROT_NONE) { 840 pmap_remove(pmap, sva, eva); 841 return; 842 } 843 if (prot & VM_PROT_WRITE) 844 return; 845 846 pte = pmap_pte(pmap, sva); 847 lunaprot = pte_prot(pmap, prot) == PG_RO ? 1 : 0; 848 for (va = sva; va < eva; va += PAGE_SIZE) { 849 /* 850 * Page table page is not allocated. 851 * Skip it, we don't want to force allocation 852 * of unnecessary PTE pages just to set the protection. 853 */ 854 if (!pmap_ste_v(pmap, va)) { 855 /* XXX: avoid address wrap around */ 856 if (va >= luna_trunc_seg((vm_offset_t)-1)) 857 break; 858 va = luna_round_seg(va + PAGE_SIZE) - PAGE_SIZE; 859 #if defined(DYNPGSIZE) 860 pte = pmap_pte(pmap, va) + lunapagesperpage; 861 #else 862 pte = pmap_pte(pmap, va) + 1; 863 #endif 864 continue; 865 } 866 /* 867 * Page not valid. Again, skip it. 868 * Should we do this? Or set protection anyway? 869 */ 870 if (!pmap_pte_v(pte)) { 871 #if defined(DYNPGSIZE) 872 pte += lunapagesperpage; 873 #else 874 pte++; 875 #endif 876 continue; 877 } 878 #if defined(DYNPGSIZE) 879 { 880 register int ix = 0; 881 882 do { 883 /* 884 * Clear caches as necessary if making RO. 885 * XXX clear VAC? Doesn't seem to be needed. 886 */ 887 #ifdef DEBUG 888 protect_stats.pages++; 889 if (lunaprot && pmap_pte_prot(pte)) 890 protect_stats.alreadyro++; 891 if (!lunaprot && !pmap_pte_prot(pte)) 892 protect_stats.alreadyrw++; 893 #endif 894 pmap_pte_set_prot(pte++, lunaprot); 895 TBIS(va + ix * LUNA_PAGE_SIZE); 896 } while (++ix != lunapagesperpage); 897 } 898 #else 899 /* 900 * Clear caches as necessary if making RO. 901 * XXX clear VAC? Doesn't seem to be needed. 902 */ 903 #ifdef DEBUG 904 protect_stats.pages++; 905 if (lunaprot && pmap_pte_prot(pte)) 906 protect_stats.alreadyro++; 907 if (!lunaprot && !pmap_pte_prot(pte)) 908 protect_stats.alreadyrw++; 909 #endif 910 pmap_pte_set_prot(pte++, lunaprot); 911 TBIS(va); 912 #endif 913 } 914 } 915 916 /* 917 * Insert the given physical page (p) at 918 * the specified virtual address (v) in the 919 * target physical map with the protection requested. 920 * 921 * If specified, the page will be wired down, meaning 922 * that the related pte can not be reclaimed. 923 * 924 * NB: This is the only routine which MAY NOT lazy-evaluate 925 * or lose information. That is, this routine must actually 926 * insert this page into the given map NOW. 927 */ 928 void 929 pmap_enter(pmap, va, pa, prot, wired) 930 register pmap_t pmap; 931 vm_offset_t va; 932 register vm_offset_t pa; 933 vm_prot_t prot; 934 boolean_t wired; 935 { 936 register pt_entry_t *pte; 937 register int npte; 938 vm_offset_t opa; 939 boolean_t cacheable = TRUE; 940 boolean_t checkpv = TRUE; 941 942 #ifdef DEBUG 943 if (pmapdebug & (PDB_FOLLOW|PDB_ENTER)) 944 printf("pmap_enter(%x, %x, %x, %x, %x)\n", 945 pmap, va, pa, prot, wired); 946 #endif 947 if (pmap == NULL) 948 return; 949 950 #ifdef DEBUG 951 if (pmap == kernel_pmap) 952 enter_stats.kernel++; 953 else 954 enter_stats.user++; 955 #endif 956 /* 957 * For user mapping, allocate kernel VM resources if necessary. 958 */ 959 if (pmap->pm_ptab == NULL) 960 pmap->pm_ptab = (pt_entry_t *) 961 kmem_alloc_wait(pt_map, LUNA_MAX_PTSIZE); 962 963 /* 964 * Segment table entry not valid, we need a new PT page 965 */ 966 if (!pmap_ste_v(pmap, va)) 967 pmap_enter_ptpage(pmap, va); 968 969 pte = pmap_pte(pmap, va); 970 opa = pmap_pte_pa(pte); 971 #ifdef DEBUG 972 if (pmapdebug & PDB_ENTER) 973 printf("enter: pte %x, *pte %x\n", pte, *(int *)pte); 974 #endif 975 976 /* 977 * Mapping has not changed, must be protection or wiring change. 978 */ 979 if (opa == pa) { 980 #ifdef DEBUG 981 enter_stats.pwchange++; 982 #endif 983 /* 984 * Wiring change, just update stats. 985 * We don't worry about wiring PT pages as they remain 986 * resident as long as there are valid mappings in them. 987 * Hence, if a user page is wired, the PT page will be also. 988 */ 989 if (wired && !pmap_pte_w(pte) || !wired && pmap_pte_w(pte)) { 990 #ifdef DEBUG 991 if (pmapdebug & PDB_ENTER) 992 printf("enter: wiring change -> %x\n", wired); 993 #endif 994 if (wired) 995 pmap->pm_stats.wired_count++; 996 else 997 pmap->pm_stats.wired_count--; 998 #ifdef DEBUG 999 enter_stats.wchange++; 1000 #endif 1001 } 1002 /* 1003 * Retain cache inhibition status 1004 */ 1005 checkpv = FALSE; 1006 if (pmap_pte_ci(pte)) 1007 cacheable = FALSE; 1008 goto validate; 1009 } 1010 1011 /* 1012 * Mapping has changed, invalidate old range and fall through to 1013 * handle validating new mapping. 1014 */ 1015 if (opa) { 1016 #ifdef DEBUG 1017 if (pmapdebug & PDB_ENTER) 1018 printf("enter: removing old mapping %x\n", va); 1019 #endif 1020 pmap_remove(pmap, va, va + PAGE_SIZE); 1021 #ifdef DEBUG 1022 enter_stats.mchange++; 1023 #endif 1024 } 1025 1026 /* 1027 * If this is a new user mapping, increment the wiring count 1028 * on this PT page. PT pages are wired down as long as there 1029 * is a valid mapping in the page. 1030 */ 1031 if (pmap != kernel_pmap) 1032 vm_map_pageable(pt_map, trunc_page(pte), 1033 round_page(pte+1), FALSE); 1034 1035 /* 1036 * Enter on the PV list if part of our managed memory 1037 * Note that we raise IPL while manipulating pv_table 1038 * since pmap_enter can be called at interrupt time. 1039 */ 1040 if (pa >= vm_first_phys && pa < vm_last_phys) { 1041 register pv_entry_t pv, npv; 1042 int s; 1043 1044 #ifdef DEBUG 1045 enter_stats.managed++; 1046 #endif 1047 pv = pa_to_pvh(pa); 1048 s = splimp(); 1049 #ifdef DEBUG 1050 if (pmapdebug & PDB_ENTER) 1051 printf("enter: pv at %x: %x/%x/%x\n", 1052 pv, pv->pv_va, pv->pv_pmap, pv->pv_next); 1053 #endif 1054 /* 1055 * No entries yet, use header as the first entry 1056 */ 1057 if (pv->pv_pmap == NULL) { 1058 #ifdef DEBUG 1059 enter_stats.firstpv++; 1060 #endif 1061 pv->pv_va = va; 1062 pv->pv_pmap = pmap; 1063 pv->pv_next = NULL; 1064 pv->pv_ptste = NULL; 1065 pv->pv_ptpmap = NULL; 1066 pv->pv_flags = 0; 1067 } 1068 /* 1069 * There is at least one other VA mapping this page. 1070 * Place this entry after the header. 1071 */ 1072 else { 1073 #ifdef DEBUG 1074 for (npv = pv; npv; npv = npv->pv_next) 1075 if (pmap == npv->pv_pmap && va == npv->pv_va) 1076 panic("pmap_enter: already in pv_tab"); 1077 #endif 1078 npv = (pv_entry_t) 1079 malloc(sizeof *npv, M_VMPVENT, M_NOWAIT); 1080 npv->pv_va = va; 1081 npv->pv_pmap = pmap; 1082 npv->pv_next = pv->pv_next; 1083 npv->pv_ptste = NULL; 1084 npv->pv_ptpmap = NULL; 1085 pv->pv_next = npv; 1086 #ifdef DEBUG 1087 if (!npv->pv_next) 1088 enter_stats.secondpv++; 1089 #endif 1090 } 1091 splx(s); 1092 } 1093 /* 1094 * Assumption: if it is not part of our managed memory 1095 * then it must be device memory which may be volitile. 1096 */ 1097 else if (pmap_initialized) { 1098 checkpv = cacheable = FALSE; 1099 #ifdef DEBUG 1100 enter_stats.unmanaged++; 1101 #endif 1102 } 1103 1104 /* 1105 * Increment counters 1106 */ 1107 pmap->pm_stats.resident_count++; 1108 if (wired) 1109 pmap->pm_stats.wired_count++; 1110 1111 validate: 1112 /* 1113 * Now validate mapping with desired protection/wiring. 1114 * Assume uniform modified and referenced status for all 1115 * LUNA pages in a MACH page. 1116 */ 1117 npte = (pa & PG_FRAME) | pte_prot(pmap, prot) | PG_V; 1118 npte |= (*(int *)pte & (PG_M|PG_U)); 1119 if (wired) 1120 npte |= PG_W; 1121 if (!checkpv && !cacheable) 1122 npte |= PG_CI; 1123 #ifdef DEBUG 1124 if (pmapdebug & PDB_ENTER) 1125 printf("enter: new pte value %x\n", npte); 1126 #endif 1127 #if defined(DYNPGSIZE) 1128 { 1129 register int ix = 0; 1130 1131 do { 1132 *(int *)pte++ = npte; 1133 TBIS(va); 1134 npte += LUNA_PAGE_SIZE; 1135 va += LUNA_PAGE_SIZE; 1136 } while (++ix != lunapagesperpage); 1137 } 1138 #else 1139 *(int *)pte = npte; 1140 TBIS(va); 1141 #endif 1142 /* 1143 * The following is executed if we are entering a second 1144 * (or greater) mapping for a physical page and the mappings 1145 * may create an aliasing problem. In this case we must 1146 * cache inhibit the descriptors involved and flush any 1147 * external VAC. 1148 */ 1149 if (checkpv && !cacheable) { 1150 pmap_changebit(pa, PG_CI, TRUE); 1151 #ifdef DEBUG 1152 enter_stats.flushes++; 1153 #endif 1154 #ifdef DEBUG 1155 if ((pmapdebug & (PDB_CACHE|PDB_PVDUMP)) == 1156 (PDB_CACHE|PDB_PVDUMP)) 1157 pmap_pvdump(pa); 1158 #endif 1159 } 1160 #ifdef DEEBUG 1161 if ((pmapdebug & PDB_WIRING) && pmap != kernel_pmap) { 1162 #if defined(DYNPGSIZE) 1163 va -= PAGE_SIZE; 1164 #endif 1165 pmap_check_wiring("enter", trunc_page(pmap_pte(pmap, va))); 1166 } 1167 #endif 1168 } 1169 1170 /* 1171 * Routine: pmap_change_wiring 1172 * Function: Change the wiring attribute for a map/virtual-address 1173 * pair. 1174 * In/out conditions: 1175 * The mapping must already exist in the pmap. 1176 */ 1177 void 1178 pmap_change_wiring(pmap, va, wired) 1179 register pmap_t pmap; 1180 vm_offset_t va; 1181 boolean_t wired; 1182 { 1183 register pt_entry_t *pte; 1184 1185 #ifdef DEBUG 1186 if (pmapdebug & PDB_FOLLOW) 1187 printf("pmap_change_wiring(%x, %x, %x)\n", pmap, va, wired); 1188 #endif 1189 if (pmap == NULL) 1190 return; 1191 1192 pte = pmap_pte(pmap, va); 1193 #ifdef DEBUG 1194 /* 1195 * Page table page is not allocated. 1196 * Should this ever happen? Ignore it for now, 1197 * we don't want to force allocation of unnecessary PTE pages. 1198 */ 1199 if (!pmap_ste_v(pmap, va)) { 1200 if (pmapdebug & PDB_PARANOIA) 1201 printf("pmap_change_wiring: invalid STE for %x\n", va); 1202 return; 1203 } 1204 /* 1205 * Page not valid. Should this ever happen? 1206 * Just continue and change wiring anyway. 1207 */ 1208 if (!pmap_pte_v(pte)) { 1209 if (pmapdebug & PDB_PARANOIA) 1210 printf("pmap_change_wiring: invalid PTE for %x\n", va); 1211 } 1212 #endif 1213 if (wired && !pmap_pte_w(pte) || !wired && pmap_pte_w(pte)) { 1214 if (wired) 1215 pmap->pm_stats.wired_count++; 1216 else 1217 pmap->pm_stats.wired_count--; 1218 } 1219 /* 1220 * Wiring is not a hardware characteristic so there is no need 1221 * to invalidate TLB. 1222 */ 1223 #if defined(DYNPGSIZE) 1224 { 1225 register int ix = 0; 1226 1227 do { 1228 pmap_pte_set_w(pte++, wired); 1229 } while (++ix != lunapagesperpage); 1230 } 1231 #else 1232 pmap_pte_set_w(pte, wired); 1233 #endif 1234 } 1235 1236 /* 1237 * Routine: pmap_extract 1238 * Function: 1239 * Extract the physical page address associated 1240 * with the given map/virtual_address pair. 1241 */ 1242 1243 vm_offset_t 1244 pmap_extract(pmap, va) 1245 register pmap_t pmap; 1246 vm_offset_t va; 1247 { 1248 register vm_offset_t pa; 1249 1250 #ifdef DEBUG 1251 if (pmapdebug & PDB_FOLLOW) 1252 printf("pmap_extract(%x, %x) -> ", pmap, va); 1253 #endif 1254 pa = 0; 1255 if (pmap && pmap_ste_v(pmap, va)) 1256 pa = *(int *)pmap_pte(pmap, va); 1257 if (pa) 1258 pa = (pa & PG_FRAME) | (va & ~PG_FRAME); 1259 #ifdef DEBUG 1260 if (pmapdebug & PDB_FOLLOW) 1261 printf("%x\n", pa); 1262 #endif 1263 return(pa); 1264 } 1265 1266 /* 1267 * Copy the range specified by src_addr/len 1268 * from the source map to the range dst_addr/len 1269 * in the destination map. 1270 * 1271 * This routine is only advisory and need not do anything. 1272 */ 1273 void pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr) 1274 pmap_t dst_pmap; 1275 pmap_t src_pmap; 1276 vm_offset_t dst_addr; 1277 vm_size_t len; 1278 vm_offset_t src_addr; 1279 { 1280 #ifdef DEBUG 1281 if (pmapdebug & PDB_FOLLOW) 1282 printf("pmap_copy(%x, %x, %x, %x, %x)\n", 1283 dst_pmap, src_pmap, dst_addr, len, src_addr); 1284 #endif 1285 } 1286 1287 /* 1288 * Require that all active physical maps contain no 1289 * incorrect entries NOW. [This update includes 1290 * forcing updates of any address map caching.] 1291 * 1292 * Generally used to insure that a thread about 1293 * to run will see a semantically correct world. 1294 */ 1295 void pmap_update() 1296 { 1297 #ifdef DEBUG 1298 if (pmapdebug & PDB_FOLLOW) 1299 printf("pmap_update()\n"); 1300 #endif 1301 TBIA(); 1302 } 1303 1304 /* 1305 * Routine: pmap_collect 1306 * Function: 1307 * Garbage collects the physical map system for 1308 * pages which are no longer used. 1309 * Success need not be guaranteed -- that is, there 1310 * may well be pages which are not referenced, but 1311 * others may be collected. 1312 * Usage: 1313 * Called by the pageout daemon when pages are scarce. 1314 */ 1315 void 1316 pmap_collect(pmap) 1317 pmap_t pmap; 1318 { 1319 register vm_offset_t pa; 1320 register pv_entry_t pv; 1321 register int *pte; 1322 vm_offset_t kpa; 1323 int s; 1324 1325 #ifdef DEBUG 1326 int *ste; 1327 int opmapdebug; 1328 #endif 1329 if (pmap != kernel_pmap) 1330 return; 1331 1332 #ifdef DEBUG 1333 if (pmapdebug & PDB_FOLLOW) 1334 printf("pmap_collect(%x)\n", pmap); 1335 kpt_stats.collectscans++; 1336 #endif 1337 s = splimp(); 1338 for (pa = vm_first_phys; pa < vm_last_phys; pa += PAGE_SIZE) { 1339 register struct kpt_page *kpt, **pkpt; 1340 1341 /* 1342 * Locate physical pages which are being used as kernel 1343 * page table pages. 1344 */ 1345 pv = pa_to_pvh(pa); 1346 if (pv->pv_pmap != kernel_pmap || !(pv->pv_flags & PV_PTPAGE)) 1347 continue; 1348 do { 1349 if (pv->pv_ptste && pv->pv_ptpmap == kernel_pmap) 1350 break; 1351 } while (pv = pv->pv_next); 1352 if (pv == NULL) 1353 continue; 1354 #ifdef DEBUG 1355 if (pv->pv_va < (vm_offset_t)Sysmap || 1356 pv->pv_va >= (vm_offset_t)Sysmap + LUNA_MAX_PTSIZE) 1357 printf("collect: kernel PT VA out of range\n"); 1358 else 1359 goto ok; 1360 pmap_pvdump(pa); 1361 continue; 1362 ok: 1363 #endif 1364 pte = (int *)(pv->pv_va + LUNA_PAGE_SIZE); 1365 while (--pte >= (int *)pv->pv_va && *pte == PG_NV) 1366 ; 1367 if (pte >= (int *)pv->pv_va) 1368 continue; 1369 1370 #ifdef DEBUG 1371 if (pmapdebug & (PDB_PTPAGE|PDB_COLLECT)) { 1372 printf("collect: freeing KPT page at %x (ste %x@%x)\n", 1373 pv->pv_va, *(int *)pv->pv_ptste, pv->pv_ptste); 1374 opmapdebug = pmapdebug; 1375 pmapdebug |= PDB_PTPAGE; 1376 } 1377 1378 ste = (int *)pv->pv_ptste; 1379 #endif 1380 /* 1381 * If all entries were invalid we can remove the page. 1382 * We call pmap_remove to take care of invalidating ST 1383 * and Sysptmap entries. 1384 */ 1385 kpa = pmap_extract(pmap, pv->pv_va); 1386 pmap_remove(pmap, pv->pv_va, pv->pv_va + LUNA_PAGE_SIZE); 1387 /* 1388 * Use the physical address to locate the original 1389 * (kmem_alloc assigned) address for the page and put 1390 * that page back on the free list. 1391 */ 1392 for (pkpt = &kpt_used_list, kpt = *pkpt; 1393 kpt != (struct kpt_page *)0; 1394 pkpt = &kpt->kpt_next, kpt = *pkpt) 1395 if (kpt->kpt_pa == kpa) 1396 break; 1397 #ifdef DEBUG 1398 if (kpt == (struct kpt_page *)0) 1399 panic("pmap_collect: lost a KPT page"); 1400 if (pmapdebug & (PDB_PTPAGE|PDB_COLLECT)) 1401 printf("collect: %x (%x) to free list\n", 1402 kpt->kpt_va, kpa); 1403 #endif 1404 *pkpt = kpt->kpt_next; 1405 kpt->kpt_next = kpt_free_list; 1406 kpt_free_list = kpt; 1407 #ifdef DEBUG 1408 kpt_stats.kptinuse--; 1409 kpt_stats.collectpages++; 1410 if (pmapdebug & (PDB_PTPAGE|PDB_COLLECT)) 1411 pmapdebug = opmapdebug; 1412 1413 if (*ste) 1414 printf("collect: kernel STE at %x still valid (%x)\n", 1415 ste, *ste); 1416 ste = (int *)&Sysptmap[(st_entry_t *)ste-pmap_ste(kernel_pmap, 0)]; 1417 if (*ste) 1418 printf("collect: kernel PTmap at %x still valid (%x)\n", 1419 ste, *ste); 1420 #endif 1421 } 1422 splx(s); 1423 } 1424 1425 void 1426 pmap_activate(pmap, pcbp) 1427 register pmap_t pmap; 1428 struct pcb *pcbp; 1429 { 1430 #ifdef DEBUG 1431 if (pmapdebug & (PDB_FOLLOW|PDB_SEGTAB)) 1432 printf("pmap_activate(%x, %x)\n", pmap, pcbp); 1433 #endif 1434 PMAP_ACTIVATE(pmap, pcbp, pmap == curproc->p_vmspace->vm_map.pmap); 1435 } 1436 1437 /* 1438 * pmap_zero_page zeros the specified (machine independent) 1439 * page by mapping the page into virtual memory and using 1440 * bzero to clear its contents, one machine dependent page 1441 * at a time. 1442 * 1443 * XXX this is a bad implementation for virtual cache machines 1444 * (320/350) because pmap_enter doesn't cache-inhibit the temporary 1445 * kernel mapping and we wind up with data cached for that KVA. 1446 * It is probably a win for physical cache machines (370/380) 1447 * as the cache loading is not wasted. 1448 */ 1449 void 1450 pmap_zero_page(phys) 1451 vm_offset_t phys; 1452 { 1453 register vm_offset_t kva; 1454 extern caddr_t CADDR1; 1455 1456 #ifdef DEBUG 1457 if (pmapdebug & PDB_FOLLOW) 1458 printf("pmap_zero_page(%x)\n", phys); 1459 #endif 1460 kva = (vm_offset_t) CADDR1; 1461 #if defined(DYNPGSIZE) 1462 { 1463 register int ix = 0; 1464 1465 do { 1466 pmap_enter(kernel_pmap, kva, phys, 1467 VM_PROT_READ|VM_PROT_WRITE, TRUE); 1468 bzero((caddr_t)kva, LUNA_PAGE_SIZE); 1469 pmap_remove(kernel_pmap, kva, kva+LUNA_PAGE_SIZE); 1470 phys += LUNA_PAGE_SIZE; 1471 } while (++ix != lunapagesperpage); 1472 } 1473 #else 1474 pmap_enter(kernel_pmap, kva, phys, VM_PROT_READ|VM_PROT_WRITE, TRUE); 1475 bzero((caddr_t)kva, LUNA_PAGE_SIZE); 1476 pmap_remove(kernel_pmap, kva, kva+PAGE_SIZE); 1477 #endif 1478 } 1479 1480 /* 1481 * pmap_copy_page copies the specified (machine independent) 1482 * page by mapping the page into virtual memory and using 1483 * bcopy to copy the page, one machine dependent page at a 1484 * time. 1485 * 1486 * 1487 * XXX this is a bad implementation for virtual cache machines 1488 * (320/350) because pmap_enter doesn't cache-inhibit the temporary 1489 * kernel mapping and we wind up with data cached for that KVA. 1490 * It is probably a win for physical cache machines (370/380) 1491 * as the cache loading is not wasted. 1492 */ 1493 void 1494 pmap_copy_page(src, dst) 1495 vm_offset_t src, dst; 1496 { 1497 register vm_offset_t skva, dkva; 1498 extern caddr_t CADDR1, CADDR2; 1499 1500 #ifdef DEBUG 1501 if (pmapdebug & PDB_FOLLOW) 1502 printf("pmap_copy_page(%x, %x)\n", src, dst); 1503 #endif 1504 skva = (vm_offset_t) CADDR1; 1505 dkva = (vm_offset_t) CADDR2; 1506 #if defined(DYNPGSIZE) 1507 { 1508 register int ix = 0; 1509 1510 do { 1511 pmap_enter(kernel_pmap, skva, src, VM_PROT_READ, TRUE); 1512 pmap_enter(kernel_pmap, dkva, dst, 1513 VM_PROT_READ|VM_PROT_WRITE, TRUE); 1514 bcopy((caddr_t)skva, (caddr_t)dkva, PAGE_SIZE); 1515 /* CADDR1 and CADDR2 are virtually contiguous */ 1516 pmap_remove(kernel_pmap, skva, skva+2*LUNA_PAGE_SIZE); 1517 src += LUNA_PAGE_SIZE; 1518 dst += LUNA_PAGE_SIZE; 1519 } while (++ix != lunapagesperpage); 1520 } 1521 #else 1522 pmap_enter(kernel_pmap, skva, src, VM_PROT_READ, TRUE); 1523 pmap_enter(kernel_pmap, dkva, dst, VM_PROT_READ|VM_PROT_WRITE, TRUE); 1524 bcopy((caddr_t)skva, (caddr_t)dkva, PAGE_SIZE); 1525 /* CADDR1 and CADDR2 are virtually contiguous */ 1526 pmap_remove(kernel_pmap, skva, skva+2*PAGE_SIZE); 1527 #endif 1528 } 1529 1530 /* 1531 * Routine: pmap_pageable 1532 * Function: 1533 * Make the specified pages (by pmap, offset) 1534 * pageable (or not) as requested. 1535 * 1536 * A page which is not pageable may not take 1537 * a fault; therefore, its page table entry 1538 * must remain valid for the duration. 1539 * 1540 * This routine is merely advisory; pmap_enter 1541 * will specify that these pages are to be wired 1542 * down (or not) as appropriate. 1543 */ 1544 void 1545 pmap_pageable(pmap, sva, eva, pageable) 1546 pmap_t pmap; 1547 vm_offset_t sva, eva; 1548 boolean_t pageable; 1549 { 1550 #ifdef DEBUG 1551 if (pmapdebug & PDB_FOLLOW) 1552 printf("pmap_pageable(%x, %x, %x, %x)\n", 1553 pmap, sva, eva, pageable); 1554 #endif 1555 /* 1556 * If we are making a PT page pageable then all valid 1557 * mappings must be gone from that page. Hence it should 1558 * be all zeros and there is no need to clean it. 1559 * Assumptions: 1560 * - we are called with only one page at a time 1561 * - PT pages have only one pv_table entry 1562 */ 1563 if (pmap == kernel_pmap && pageable && sva + PAGE_SIZE == eva) { 1564 register pv_entry_t pv; 1565 register vm_offset_t pa; 1566 1567 #ifdef DEBUG 1568 if ((pmapdebug & (PDB_FOLLOW|PDB_PTPAGE)) == PDB_PTPAGE) 1569 printf("pmap_pageable(%x, %x, %x, %x)\n", 1570 pmap, sva, eva, pageable); 1571 #endif 1572 if (!pmap_ste_v(pmap, sva)) 1573 return; 1574 pa = pmap_pte_pa(pmap_pte(pmap, sva)); 1575 if (pa < vm_first_phys || pa >= vm_last_phys) 1576 return; 1577 pv = pa_to_pvh(pa); 1578 if (pv->pv_ptste == NULL) 1579 return; 1580 #ifdef DEBUG 1581 if (pv->pv_va != sva || pv->pv_next) { 1582 printf("pmap_pageable: bad PT page va %x next %x\n", 1583 pv->pv_va, pv->pv_next); 1584 return; 1585 } 1586 #endif 1587 /* 1588 * Mark it unmodified to avoid pageout 1589 */ 1590 pmap_changebit(pa, PG_M, FALSE); 1591 #ifdef DEBUG 1592 if (pmapdebug & PDB_PTPAGE) 1593 printf("pmap_pageable: PT page %x(%x) unmodified\n", 1594 sva, *(int *)pmap_pte(pmap, sva)); 1595 if (pmapdebug & PDB_WIRING) 1596 pmap_check_wiring("pageable", sva); 1597 #endif 1598 } 1599 } 1600 1601 /* 1602 * Clear the modify bits on the specified physical page. 1603 */ 1604 1605 void 1606 pmap_clear_modify(pa) 1607 vm_offset_t pa; 1608 { 1609 #ifdef DEBUG 1610 if (pmapdebug & PDB_FOLLOW) 1611 printf("pmap_clear_modify(%x)\n", pa); 1612 #endif 1613 pmap_changebit(pa, PG_M, FALSE); 1614 } 1615 1616 /* 1617 * pmap_clear_reference: 1618 * 1619 * Clear the reference bit on the specified physical page. 1620 */ 1621 1622 void pmap_clear_reference(pa) 1623 vm_offset_t pa; 1624 { 1625 #ifdef DEBUG 1626 if (pmapdebug & PDB_FOLLOW) 1627 printf("pmap_clear_reference(%x)\n", pa); 1628 #endif 1629 pmap_changebit(pa, PG_U, FALSE); 1630 } 1631 1632 /* 1633 * pmap_is_referenced: 1634 * 1635 * Return whether or not the specified physical page is referenced 1636 * by any physical maps. 1637 */ 1638 1639 boolean_t 1640 pmap_is_referenced(pa) 1641 vm_offset_t pa; 1642 { 1643 #ifdef DEBUG 1644 if (pmapdebug & PDB_FOLLOW) { 1645 boolean_t rv = pmap_testbit(pa, PG_U); 1646 printf("pmap_is_referenced(%x) -> %c\n", pa, "FT"[rv]); 1647 return(rv); 1648 } 1649 #endif 1650 return(pmap_testbit(pa, PG_U)); 1651 } 1652 1653 /* 1654 * pmap_is_modified: 1655 * 1656 * Return whether or not the specified physical page is modified 1657 * by any physical maps. 1658 */ 1659 1660 boolean_t 1661 pmap_is_modified(pa) 1662 vm_offset_t pa; 1663 { 1664 #ifdef DEBUG 1665 if (pmapdebug & PDB_FOLLOW) { 1666 boolean_t rv = pmap_testbit(pa, PG_M); 1667 printf("pmap_is_modified(%x) -> %c\n", pa, "FT"[rv]); 1668 return(rv); 1669 } 1670 #endif 1671 return(pmap_testbit(pa, PG_M)); 1672 } 1673 1674 vm_offset_t 1675 pmap_phys_address(ppn) 1676 int ppn; 1677 { 1678 return(luna_ptob(ppn)); 1679 } 1680 1681 /* 1682 * Miscellaneous support routines follow 1683 */ 1684 1685 /* static */ 1686 boolean_t 1687 pmap_testbit(pa, bit) 1688 register vm_offset_t pa; 1689 int bit; 1690 { 1691 register pv_entry_t pv; 1692 register int *pte; 1693 int s; 1694 1695 if (pa < vm_first_phys || pa >= vm_last_phys) 1696 return(FALSE); 1697 1698 pv = pa_to_pvh(pa); 1699 s = splimp(); 1700 /* 1701 * Check saved info first 1702 */ 1703 if (pmap_attributes[pa_index(pa)] & bit) { 1704 splx(s); 1705 return(TRUE); 1706 } 1707 /* 1708 * Not found, check current mappings returning 1709 * immediately if found. 1710 */ 1711 if (pv->pv_pmap != NULL) { 1712 for (; pv; pv = pv->pv_next) { 1713 pte = (int *) pmap_pte(pv->pv_pmap, pv->pv_va); 1714 #if defined(DYNPGSIZE) 1715 { 1716 register int ix = 0; 1717 1718 do { 1719 if (*pte++ & bit) { 1720 splx(s); 1721 return(TRUE); 1722 } 1723 } while (++ix != lunapagesperpage); 1724 } 1725 #else 1726 if (*pte & bit) { 1727 splx(s); 1728 return(TRUE); 1729 } 1730 #endif 1731 } 1732 } 1733 splx(s); 1734 return(FALSE); 1735 } 1736 1737 /* static */ 1738 pmap_changebit(pa, bit, setem) 1739 register vm_offset_t pa; 1740 int bit; 1741 boolean_t setem; 1742 { 1743 register pv_entry_t pv; 1744 register int *pte, npte; 1745 vm_offset_t va; 1746 int s; 1747 boolean_t firstpage = TRUE; 1748 1749 #ifdef DEBUG 1750 if (pmapdebug & PDB_BITS) 1751 printf("pmap_changebit(%x, %x, %s)\n", 1752 pa, bit, setem ? "set" : "clear"); 1753 #endif 1754 if (pa < vm_first_phys || pa >= vm_last_phys) 1755 return; 1756 1757 pv = pa_to_pvh(pa); 1758 s = splimp(); 1759 /* 1760 * Clear saved attributes (modify, reference) 1761 */ 1762 if (!setem) 1763 pmap_attributes[pa_index(pa)] &= ~bit; 1764 /* 1765 * Loop over all current mappings setting/clearing as appropos 1766 * If setting RO do we need to clear the VAC? 1767 */ 1768 if (pv->pv_pmap != NULL) { 1769 #ifdef DEBUG 1770 int toflush = 0; 1771 #endif 1772 for (; pv; pv = pv->pv_next) { 1773 #ifdef DEBUG 1774 toflush |= (pv->pv_pmap == kernel_pmap) ? 2 : 1; 1775 #endif 1776 va = pv->pv_va; 1777 1778 /* 1779 * XXX don't write protect pager mappings 1780 */ 1781 if (bit == PG_RO) { 1782 extern vm_offset_t pager_sva, pager_eva; 1783 1784 if (va >= pager_sva && va < pager_eva) 1785 continue; 1786 } 1787 1788 pte = (int *) pmap_pte(pv->pv_pmap, va); 1789 #if defined(DYNPGSIZE) 1790 { 1791 register int ix = 0; 1792 1793 do { 1794 if (setem) 1795 npte = *pte | bit; 1796 else 1797 npte = *pte & ~bit; 1798 if (*pte != npte) { 1799 *pte = npte; 1800 TBIS(va); 1801 } 1802 va += LUNA_PAGE_SIZE; 1803 pte++; 1804 } while (++ix != lunapagesperpage); 1805 } 1806 #else 1807 if (setem) 1808 npte = *pte | bit; 1809 else 1810 npte = *pte & ~bit; 1811 if (*pte != npte) { 1812 *pte = npte; 1813 TBIS(va); 1814 } 1815 #endif 1816 } 1817 } 1818 splx(s); 1819 } 1820 1821 /* static */ 1822 void 1823 pmap_enter_ptpage(pmap, va) 1824 register pmap_t pmap; 1825 register vm_offset_t va; 1826 { 1827 register vm_offset_t ptpa; 1828 register pv_entry_t pv; 1829 st_entry_t *ste; 1830 int s; 1831 1832 #ifdef DEBUG 1833 if (pmapdebug & (PDB_FOLLOW|PDB_ENTER|PDB_PTPAGE)) 1834 printf("pmap_enter_ptpage: pmap %x, va %x\n", pmap, va); 1835 enter_stats.ptpneeded++; 1836 #endif 1837 /* 1838 * Allocate a segment table if necessary. Note that it is allocated 1839 * from kernel_map and not pt_map. This keeps user page tables 1840 * aligned on segment boundaries in the kernel address space. 1841 * The segment table is wired down. It will be freed whenever the 1842 * reference count drops to zero. 1843 */ 1844 if (pmap->pm_stab == Segtabzero) { 1845 pmap->pm_stab = (st_entry_t *) 1846 kmem_alloc(kernel_map, LUNA_STSIZE); 1847 pmap->pm_stpa = (st_entry_t *) 1848 pmap_extract(kernel_pmap, (vm_offset_t)pmap->pm_stab); 1849 pmap->pm_stchanged = TRUE; 1850 /* 1851 * XXX may have changed segment table pointer for current 1852 * process so update now to reload hardware. 1853 */ 1854 if (pmap == curproc->p_vmspace->vm_map.pmap) 1855 PMAP_ACTIVATE(pmap, (struct pcb *)curproc->p_addr, 1); 1856 #ifdef DEBUG 1857 if (pmapdebug & (PDB_ENTER|PDB_PTPAGE|PDB_SEGTAB)) 1858 printf("enter: pmap %x stab %x(%x)\n", 1859 pmap, pmap->pm_stab, pmap->pm_stpa); 1860 #endif 1861 } 1862 1863 ste = pmap_ste(pmap, va); 1864 va = trunc_page((vm_offset_t)pmap_pte(pmap, va)); 1865 1866 /* 1867 * In the kernel we allocate a page from the kernel PT page 1868 * free list and map it into the kernel page table map (via 1869 * pmap_enter). 1870 */ 1871 if (pmap == kernel_pmap) { 1872 register struct kpt_page *kpt; 1873 1874 s = splimp(); 1875 if ((kpt = kpt_free_list) == (struct kpt_page *)0) { 1876 /* 1877 * No PT pages available. 1878 * Try once to free up unused ones. 1879 */ 1880 #ifdef DEBUG 1881 if (pmapdebug & PDB_COLLECT) 1882 printf("enter: no KPT pages, collecting...\n"); 1883 #endif 1884 pmap_collect(kernel_pmap); 1885 if ((kpt = kpt_free_list) == (struct kpt_page *)0) 1886 panic("pmap_enter_ptpage: can't get KPT page"); 1887 } 1888 #ifdef DEBUG 1889 if (++kpt_stats.kptinuse > kpt_stats.kptmaxuse) 1890 kpt_stats.kptmaxuse = kpt_stats.kptinuse; 1891 #endif 1892 kpt_free_list = kpt->kpt_next; 1893 kpt->kpt_next = kpt_used_list; 1894 kpt_used_list = kpt; 1895 ptpa = kpt->kpt_pa; 1896 bzero(kpt->kpt_va, LUNA_PAGE_SIZE); 1897 pmap_enter(pmap, va, ptpa, VM_PROT_DEFAULT, TRUE); 1898 #ifdef DEBUG 1899 if (pmapdebug & (PDB_ENTER|PDB_PTPAGE)) { 1900 int ix = pmap_ste(pmap, va) - pmap_ste(pmap, 0); 1901 1902 printf("enter: add &Sysptmap[%d]: %x (KPT page %x)\n", 1903 ix, *(int *)&Sysptmap[ix], kpt->kpt_va); 1904 } 1905 #endif 1906 splx(s); 1907 } 1908 /* 1909 * For user processes we just simulate a fault on that location 1910 * letting the VM system allocate a zero-filled page. 1911 */ 1912 else { 1913 #ifdef DEBUG 1914 if (pmapdebug & (PDB_ENTER|PDB_PTPAGE)) 1915 printf("enter: about to fault UPT pg at %x\n", va); 1916 s = vm_fault(pt_map, va, VM_PROT_READ|VM_PROT_WRITE, FALSE); 1917 if (s != KERN_SUCCESS) { 1918 printf("vm_fault(pt_map, %x, RW, 0) -> %d\n", va, s); 1919 panic("pmap_enter: vm_fault failed"); 1920 } 1921 #else 1922 if (vm_fault(pt_map, va, VM_PROT_READ|VM_PROT_WRITE, FALSE) 1923 != KERN_SUCCESS) 1924 panic("pmap_enter: vm_fault failed"); 1925 #endif 1926 ptpa = pmap_extract(kernel_pmap, va); 1927 #ifdef DEBUG 1928 PHYS_TO_VM_PAGE(ptpa)->ptpage = TRUE; 1929 #endif 1930 } 1931 /* 1932 * Locate the PV entry in the kernel for this PT page and 1933 * record the STE address. This is so that we can invalidate 1934 * the STE when we remove the mapping for the page. 1935 */ 1936 pv = pa_to_pvh(ptpa); 1937 s = splimp(); 1938 if (pv) { 1939 pv->pv_flags |= PV_PTPAGE; 1940 do { 1941 if (pv->pv_pmap == kernel_pmap && pv->pv_va == va) 1942 break; 1943 } while (pv = pv->pv_next); 1944 } 1945 #ifdef DEBUG 1946 if (pv == NULL) 1947 panic("pmap_enter_ptpage: PT page not entered"); 1948 #endif 1949 pv->pv_ptste = ste; 1950 pv->pv_ptpmap = pmap; 1951 #ifdef DEBUG 1952 if (pmapdebug & (PDB_ENTER|PDB_PTPAGE)) 1953 printf("enter: new PT page at PA %x, ste at %x\n", ptpa, ste); 1954 #endif 1955 1956 /* 1957 * Map the new PT page into the segment table. 1958 * Also increment the reference count on the segment table if this 1959 * was a user page table page. Note that we don't use vm_map_pageable 1960 * to keep the count like we do for PT pages, this is mostly because 1961 * it would be difficult to identify ST pages in pmap_pageable to 1962 * release them. We also avoid the overhead of vm_map_pageable. 1963 */ 1964 *(int *)ste = (ptpa & SG_FRAME) | SG_RW | SG_V; 1965 if (pmap != kernel_pmap) { 1966 pmap->pm_sref++; 1967 #ifdef DEBUG 1968 if (pmapdebug & (PDB_ENTER|PDB_PTPAGE|PDB_SEGTAB)) 1969 printf("enter: stab %x refcnt %d\n", 1970 pmap->pm_stab, pmap->pm_sref); 1971 #endif 1972 } 1973 /* 1974 * Flush stale TLB info. 1975 */ 1976 if (pmap == kernel_pmap) 1977 TBIAS(); 1978 else 1979 TBIAU(); 1980 pmap->pm_ptpages++; 1981 splx(s); 1982 } 1983 1984 #ifdef DEBUG 1985 pmap_pvdump(pa) 1986 vm_offset_t pa; 1987 { 1988 register pv_entry_t pv; 1989 1990 printf("pa %x", pa); 1991 for (pv = pa_to_pvh(pa); pv; pv = pv->pv_next) 1992 printf(" -> pmap %x, va %x, ptste %x, ptpmap %x, flags %x", 1993 pv->pv_pmap, pv->pv_va, pv->pv_ptste, pv->pv_ptpmap, 1994 pv->pv_flags); 1995 printf("\n"); 1996 } 1997 1998 pmap_check_wiring(str, va) 1999 char *str; 2000 vm_offset_t va; 2001 { 2002 vm_map_entry_t entry; 2003 register int count, *pte; 2004 2005 va = trunc_page(va); 2006 if (!pmap_ste_v(kernel_pmap, va) || 2007 !pmap_pte_v(pmap_pte(kernel_pmap, va))) 2008 return; 2009 2010 if (!vm_map_lookup_entry(pt_map, va, &entry)) { 2011 printf("wired_check: entry for %x not found\n", va); 2012 return; 2013 } 2014 count = 0; 2015 for (pte = (int *)va; pte < (int *)(va+PAGE_SIZE); pte++) 2016 if (*pte) 2017 count++; 2018 if (entry->wired_count != count) 2019 printf("*%s*: %x: w%d/a%d\n", 2020 str, va, entry->wired_count, count); 2021 } 2022 #endif 2023