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