1 /* $NetBSD: pmap.c,v 1.165 2010/10/15 15:55:53 tsutsui Exp $ */ 2 3 /*- 4 * Copyright (c) 1996 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Adam Glass and Gordon W. Ross. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Some notes: 34 * 35 * sun3s have contexts (8). In this pmap design, the kernel is mapped 36 * into all contexts. Processes take up a known portion of the context, 37 * and compete for the available contexts on a LRU basis. 38 * 39 * sun3s also have this evil "PMEG" crapola. Essentially each "context"'s 40 * address space is defined by the 2048 one-byte entries in the segment map. 41 * Each of these 1-byte entries points to a "Page Map Entry Group" (PMEG) 42 * which contains the mappings for that virtual segment. (This strange 43 * terminology invented by Sun and preserved here for consistency.) 44 * Each PMEG maps a segment of 128Kb length, with 16 pages of 8Kb each. 45 * 46 * As you might guess, these PMEGs are in short supply and heavy demand. 47 * PMEGs allocated to the kernel are "static" in the sense that they can't 48 * be stolen from it. PMEGs allocated to a particular segment of a 49 * pmap's virtual space will be fought over by the other pmaps. 50 */ 51 52 /* 53 * Cache management: 54 * All sun3 cache implementations are write-back. 55 * Flushes must be done before removing translations 56 * from the MMU because the cache uses the MMU. 57 */ 58 59 /* 60 * wanted attributes: 61 * pmegs that aren't needed by a pmap remain in the MMU. 62 * quick context switches between pmaps 63 * kernel is in all contexts 64 */ 65 66 /* 67 * Project1: Use a "null" context for processes that have not 68 * touched any user-space address recently. This is efficient 69 * for things that stay in the kernel for a while, waking up 70 * to handle some I/O then going back to sleep (i.e. nfsd). 71 * If and when such a process returns to user-mode, it will 72 * fault and be given a real context at that time. 73 * 74 * This also lets context switch be fast, because all we need 75 * to do there for the MMU is slam the context register. 76 * 77 * Project2: Use a private pool of PV elements. This pool can be 78 * fixed size because the total mapped virtual space supported by 79 * the MMU H/W (and this pmap) is fixed for all time. 80 */ 81 82 #include <sys/cdefs.h> 83 __KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.165 2010/10/15 15:55:53 tsutsui Exp $"); 84 85 #include "opt_ddb.h" 86 #include "opt_pmap_debug.h" 87 88 #include <sys/param.h> 89 #include <sys/systm.h> 90 #include <sys/proc.h> 91 #include <sys/malloc.h> 92 #include <sys/pool.h> 93 #include <sys/queue.h> 94 #include <sys/kcore.h> 95 96 #include <uvm/uvm.h> 97 98 #include <machine/cpu.h> 99 #include <machine/dvma.h> 100 #include <machine/idprom.h> 101 #include <machine/kcore.h> 102 #include <machine/mon.h> 103 #include <machine/pmap.h> 104 #include <machine/pte.h> 105 #include <machine/vmparam.h> 106 #include <m68k/cacheops.h> 107 108 #include <sun3/sun3/cache.h> 109 #include <sun3/sun3/control.h> 110 #include <sun3/sun3/fc.h> 111 #include <sun3/sun3/machdep.h> 112 #include <sun3/sun3/obmem.h> 113 114 #ifdef DDB 115 #include <ddb/db_output.h> 116 #else 117 #define db_printf printf 118 #endif 119 120 /* Verify this correspondence between definitions. */ 121 #if (PMAP_OBIO << PG_MOD_SHIFT) != PGT_OBIO 122 #error "PMAP_XXX definitions don't match pte.h!" 123 #endif 124 125 /* Type bits in a "pseudo" physical address. (XXX: pmap.h?) */ 126 #define PMAP_TYPE PMAP_VME32 127 128 /* 129 * Local convenience macros 130 */ 131 132 #define DVMA_MAP_END (DVMA_MAP_BASE + DVMA_MAP_AVAIL) 133 134 /* User segments from 0 to KERNBASE */ 135 #define NUSEG (KERNBASE3 / NBSG) 136 /* The remainder are kernel segments. */ 137 #define NKSEG (NSEGMAP - NUSEG) 138 139 #define VA_SEGNUM(x) ((u_int)(x) >> SEGSHIFT) 140 141 /* 142 * Only "main memory" pages are registered in the pv_lists. 143 * This macro is used to determine if a given pte refers to 144 * "main memory" or not. One slight hack here deserves more 145 * explanation: The Sun frame buffers all appear as PG_OBMEM 146 * devices but way up near the end of the address space. 147 * We do not want to consider these as "main memory" so the 148 * macro below treats the high bits of the PFN as type bits. 149 * 150 * Note that on the 3/60 only 16 bits of PFN are stored in the 151 * MMU and the top 3 bits read back as zero. This means a 152 * translation entered into the mmu for physical address 153 * 0xFF000000 will look like 0x1F000000 after one reads back 154 * the pte and converts the PFN to a physical address. 155 */ 156 #define MEM_BITS (PG_TYPE | PA_PGNUM(0xF8000000)) 157 #define IS_MAIN_MEM(pte) (((pte) & MEM_BITS) == 0) 158 159 /* Does this (pseudo) PA represent device space? */ 160 #define PA_DEV_MASK (0xF8000000 | PMAP_TYPE) 161 #define PA_IS_DEV(pa) ((pa) & PA_DEV_MASK) 162 163 /* 164 * Is there a Virtually Addressed Cache (VAC) alias problem 165 * if one page is mapped at both a1 and a2? 166 */ 167 #define BADALIAS(a1, a2) (((int)(a1) ^ (int)(a2)) & SEGOFSET) 168 169 170 /* 171 * Debugging support. 172 */ 173 #define PMD_ENTER 1 174 #define PMD_LINK 2 175 #define PMD_PROTECT 4 176 #define PMD_SWITCH 8 177 #define PMD_COW 0x10 178 #define PMD_MODBIT 0x20 179 #define PMD_REFBIT 0x40 180 #define PMD_WIRING 0x80 181 #define PMD_CONTEXT 0x100 182 #define PMD_CREATE 0x200 183 #define PMD_SEGMAP 0x400 184 #define PMD_SETPTE 0x800 185 #define PMD_FAULT 0x1000 186 #define PMD_KMAP 0x2000 187 188 #define PMD_REMOVE PMD_ENTER 189 #define PMD_UNLINK PMD_LINK 190 191 #ifdef PMAP_DEBUG 192 int pmap_debug = 0; 193 int pmap_db_watchva = -1; 194 int pmap_db_watchpmeg = -1; 195 #endif /* PMAP_DEBUG */ 196 197 /* 198 * Miscellaneous variables. 199 * 200 * For simplicity, this interface retains the variables 201 * that were used in the old interface (without NONCONTIG). 202 * These are set in pmap_bootstrap() and used in 203 * pmap_next_page(). 204 */ 205 vaddr_t virtual_avail, virtual_end; 206 paddr_t avail_start, avail_end; 207 #define managed(pa) (((pa) >= avail_start) && ((pa) < avail_end)) 208 209 /* used to skip the Sun3/50 video RAM */ 210 static vaddr_t hole_start, hole_size; 211 212 /* This is for pmap_next_page() */ 213 static paddr_t avail_next; 214 215 /* This is where we map a PMEG without a context. */ 216 static vaddr_t temp_seg_va; 217 218 /* 219 * Location to store virtual addresses 220 * to be used in copy/zero operations. 221 */ 222 vaddr_t tmp_vpages[2] = { 223 SUN3_MONSHORTSEG, 224 SUN3_MONSHORTSEG + PAGE_SIZE }; 225 int tmp_vpages_inuse; 226 227 static int pmap_version = 1; 228 static struct pmap kernel_pmap_store; 229 struct pmap *const kernel_pmap_ptr = &kernel_pmap_store; 230 #define kernel_pmap (kernel_pmap_ptr) 231 static u_char kernel_segmap[NSEGMAP]; 232 233 /* memory pool for pmap structures */ 234 struct pool pmap_pmap_pool; 235 236 /* statistics... */ 237 struct pmap_stats { 238 int ps_enter_firstpv; /* pv heads entered */ 239 int ps_enter_secondpv; /* pv nonheads entered */ 240 int ps_unlink_pvfirst; /* of pv_unlinks on head */ 241 int ps_unlink_pvsearch; /* of pv_unlink searches */ 242 int ps_pmeg_faultin; /* pmegs reloaded */ 243 int ps_changeprots; /* of calls to changeprot */ 244 int ps_changewire; /* useless wiring changes */ 245 int ps_npg_prot_all; /* of active pages protected */ 246 int ps_npg_prot_actual; /* pages actually affected */ 247 int ps_vac_uncached; /* non-cached due to bad alias */ 248 int ps_vac_recached; /* re-cached when bad alias gone */ 249 } pmap_stats; 250 251 #define pmap_lock(pmap) simple_lock(&pmap->pm_lock) 252 #define pmap_unlock(pmap) simple_unlock(&pmap->pm_lock) 253 #define pmap_add_ref(pmap) ++pmap->pm_refcount 254 #define pmap_del_ref(pmap) --pmap->pm_refcount 255 #define pmap_refcount(pmap) pmap->pm_refcount 256 257 #ifdef PMAP_DEBUG 258 #define CHECK_SPL() do { \ 259 if ((getsr() & PSL_IPL) < PSL_IPL4) \ 260 panic("pmap: bad spl, line %d", __LINE__); \ 261 } while (0) 262 #else /* PMAP_DEBUG */ 263 #define CHECK_SPL() (void)0 264 #endif /* PMAP_DEBUG */ 265 266 267 /* 268 * PV support. 269 * (i.e. Find all virtual mappings of a physical page.) 270 */ 271 272 int pv_initialized = 0; 273 274 /* One of these for each mapped virtual page. */ 275 struct pv_entry { 276 struct pv_entry *pv_next; 277 pmap_t pv_pmap; 278 vaddr_t pv_va; 279 }; 280 typedef struct pv_entry *pv_entry_t; 281 282 /* Table of PV list heads (per physical page). */ 283 static struct pv_entry **pv_head_tbl; 284 285 /* Free list of PV entries. */ 286 static struct pv_entry *pv_free_list; 287 288 /* Table of flags (per physical page). */ 289 static u_char *pv_flags_tbl; 290 291 /* These are as in the MMU but shifted by PV_SHIFT. */ 292 #define PV_SHIFT 24 293 #define PV_VALID 0x80 294 #define PV_WRITE 0x40 295 #define PV_SYSTEM 0x20 296 #define PV_NC 0x10 297 #define PV_PERM 0xF0 298 #define PV_TYPE 0x0C 299 #define PV_REF 0x02 300 #define PV_MOD 0x01 301 302 303 /* 304 * context structures, and queues 305 */ 306 307 struct context_state { 308 TAILQ_ENTRY(context_state) context_link; 309 int context_num; 310 struct pmap *context_upmap; 311 }; 312 typedef struct context_state *context_t; 313 314 #define INVALID_CONTEXT -1 /* impossible value */ 315 #define EMPTY_CONTEXT 0 316 #define FIRST_CONTEXT 1 317 #define has_context(pmap) ((pmap)->pm_ctxnum != EMPTY_CONTEXT) 318 319 TAILQ_HEAD(context_tailq, context_state) 320 context_free_queue, context_active_queue; 321 322 static struct context_state context_array[NCONTEXT]; 323 324 325 /* 326 * PMEG structures, queues, and macros 327 */ 328 #define PMEGQ_FREE 0 329 #define PMEGQ_INACTIVE 1 330 #define PMEGQ_ACTIVE 2 331 #define PMEGQ_KERNEL 3 332 #define PMEGQ_NONE 4 333 334 struct pmeg_state { 335 TAILQ_ENTRY(pmeg_state) pmeg_link; 336 int pmeg_index; 337 pmap_t pmeg_owner; 338 int pmeg_version; 339 vaddr_t pmeg_va; 340 int pmeg_wired; 341 int pmeg_reserved; 342 int pmeg_vpages; 343 int pmeg_qstate; 344 }; 345 346 typedef struct pmeg_state *pmeg_t; 347 348 #define PMEG_INVAL (NPMEG-1) 349 #define PMEG_NULL (pmeg_t) NULL 350 351 /* XXX - Replace pmeg_kernel_queue with pmeg_wired_queue ? */ 352 TAILQ_HEAD(pmeg_tailq, pmeg_state) 353 pmeg_free_queue, pmeg_inactive_queue, 354 pmeg_active_queue, pmeg_kernel_queue; 355 356 static struct pmeg_state pmeg_array[NPMEG]; 357 358 359 /* 360 * prototypes 361 */ 362 static int get_pte_pmeg(int, int); 363 static void set_pte_pmeg(int, int, int); 364 365 static void context_allocate(pmap_t); 366 static void context_free(pmap_t); 367 static void context_init(void); 368 369 static void pmeg_init(void); 370 static void pmeg_reserve(int); 371 372 static pmeg_t pmeg_allocate(pmap_t, vaddr_t); 373 static void pmeg_mon_init(vaddr_t, vaddr_t, int); 374 static void pmeg_release(pmeg_t); 375 static void pmeg_free(pmeg_t); 376 static pmeg_t pmeg_cache(pmap_t, vaddr_t); 377 static void pmeg_set_wiring(pmeg_t, vaddr_t, int); 378 379 static int pv_link (pmap_t, int, vaddr_t); 380 static void pv_unlink(pmap_t, int, vaddr_t); 381 static void pv_remove_all(paddr_t); 382 static void pv_changepte(paddr_t, int, int); 383 static u_int pv_syncflags(pv_entry_t); 384 static void pv_init(void); 385 386 static void pmeg_clean(pmeg_t); 387 static void pmeg_clean_free(void); 388 389 static void pmap_common_init(pmap_t); 390 static void pmap_kernel_init(pmap_t); 391 static void pmap_user_init(pmap_t); 392 static void pmap_page_upload(void); 393 394 static void pmap_enter_kernel(vaddr_t, int, bool); 395 static void pmap_enter_user(pmap_t, vaddr_t, int, bool); 396 397 static void pmap_protect1(pmap_t, vaddr_t, vaddr_t); 398 static void pmap_protect_mmu(pmap_t, vaddr_t, vaddr_t); 399 static void pmap_protect_noctx(pmap_t, vaddr_t, vaddr_t); 400 401 static void pmap_remove1(pmap_t, vaddr_t, vaddr_t); 402 static void pmap_remove_mmu(pmap_t, vaddr_t, vaddr_t); 403 static void pmap_remove_noctx(pmap_t, vaddr_t, vaddr_t); 404 405 static int pmap_fault_reload(struct pmap *, vaddr_t, int); 406 407 /* Called only from locore.s and pmap.c */ 408 void _pmap_switch(pmap_t); 409 410 #ifdef PMAP_DEBUG 411 void pmap_print(pmap_t); 412 void pv_print(paddr_t); 413 void pmeg_print(pmeg_t); 414 static void pmeg_verify_empty(vaddr_t); 415 #endif /* PMAP_DEBUG */ 416 void pmap_pinit(pmap_t); 417 void pmap_release(pmap_t); 418 419 /* 420 * Various in-line helper functions. 421 */ 422 423 static inline pmap_t 424 current_pmap(void) 425 { 426 struct vmspace *vm; 427 struct vm_map *map; 428 pmap_t pmap; 429 430 vm = curproc->p_vmspace; 431 map = &vm->vm_map; 432 pmap = vm_map_pmap(map); 433 434 return (pmap); 435 } 436 437 static inline struct pv_entry ** 438 pa_to_pvhead(paddr_t pa) 439 { 440 int idx; 441 442 idx = PA_PGNUM(pa); 443 #ifdef DIAGNOSTIC 444 if (PA_IS_DEV(pa) || (idx >= physmem)) 445 panic("pmap:pa_to_pvhead: bad pa=0x%lx", pa); 446 #endif 447 return (&pv_head_tbl[idx]); 448 } 449 450 static inline u_char * 451 pa_to_pvflags(paddr_t pa) 452 { 453 int idx; 454 455 idx = PA_PGNUM(pa); 456 #ifdef DIAGNOSTIC 457 if (PA_IS_DEV(pa) || (idx >= physmem)) 458 panic("pmap:pa_to_pvflags: bad pa=0x%lx", pa); 459 #endif 460 return (&pv_flags_tbl[idx]); 461 } 462 463 /* 464 * Save the MOD bit from the given PTE using its PA 465 */ 466 static inline void 467 save_modref_bits(int pte) 468 { 469 u_char *pv_flags; 470 471 pv_flags = pa_to_pvflags(PG_PA(pte)); 472 *pv_flags |= ((pte & PG_MODREF) >> PV_SHIFT); 473 } 474 475 static inline pmeg_t 476 pmeg_p(int sme) 477 { 478 #ifdef DIAGNOSTIC 479 if (sme < 0 || sme >= SEGINV) 480 panic("pmeg_p: bad sme"); 481 #endif 482 return &pmeg_array[sme]; 483 } 484 485 #define is_pmeg_wired(pmegp) (pmegp->pmeg_wired != 0) 486 487 static void 488 pmeg_set_wiring(pmeg_t pmegp, vaddr_t va, int flag) 489 { 490 int idx, mask; 491 492 idx = VA_PTE_NUM(va); 493 mask = 1 << idx; 494 495 if (flag) 496 pmegp->pmeg_wired |= mask; 497 else 498 pmegp->pmeg_wired &= ~mask; 499 } 500 501 /**************************************************************** 502 * Context management functions. 503 */ 504 505 /* part of pmap_bootstrap */ 506 static void 507 context_init(void) 508 { 509 int i; 510 511 TAILQ_INIT(&context_free_queue); 512 TAILQ_INIT(&context_active_queue); 513 514 /* Leave EMPTY_CONTEXT out of the free list. */ 515 context_array[0].context_upmap = kernel_pmap; 516 517 for (i = 1; i < NCONTEXT; i++) { 518 context_array[i].context_num = i; 519 context_array[i].context_upmap = NULL; 520 TAILQ_INSERT_TAIL(&context_free_queue, &context_array[i], 521 context_link); 522 #ifdef PMAP_DEBUG 523 if (pmap_debug & PMD_CONTEXT) 524 printf("context_init: sizeof(context_array[0])=%d\n", 525 sizeof(context_array[0])); 526 #endif 527 } 528 } 529 530 /* Get us a context (steal one if necessary). */ 531 static void 532 context_allocate(pmap_t pmap) 533 { 534 context_t context; 535 536 CHECK_SPL(); 537 538 #ifdef DIAGNOSTIC 539 if (pmap == kernel_pmap) 540 panic("context_allocate: kernel_pmap"); 541 if (has_context(pmap)) 542 panic("pmap: pmap already has context allocated to it"); 543 #endif 544 545 context = TAILQ_FIRST(&context_free_queue); 546 if (context == NULL) { 547 /* Steal the head of the active queue. */ 548 context = TAILQ_FIRST(&context_active_queue); 549 if (context == NULL) 550 panic("pmap: no contexts left?"); 551 #ifdef PMAP_DEBUG 552 if (pmap_debug & PMD_CONTEXT) 553 printf("context_allocate: steal ctx %d from pmap %p\n", 554 context->context_num, context->context_upmap); 555 #endif 556 context_free(context->context_upmap); 557 context = TAILQ_FIRST(&context_free_queue); 558 } 559 TAILQ_REMOVE(&context_free_queue, context, context_link); 560 561 #ifdef DIAGNOSTIC 562 if (context->context_upmap != NULL) 563 panic("pmap: context in use???"); 564 #endif 565 566 context->context_upmap = pmap; 567 pmap->pm_ctxnum = context->context_num; 568 569 TAILQ_INSERT_TAIL(&context_active_queue, context, context_link); 570 571 /* 572 * We could reload the MMU here, but that would 573 * artificially move PMEGs from the inactive queue 574 * to the active queue, so do lazy reloading. 575 * XXX - Need to reload wired pmegs though... 576 * XXX: Verify the context it is empty? 577 */ 578 } 579 580 /* 581 * Unload the context and put it on the free queue. 582 */ 583 static void 584 context_free(pmap_t pmap) 585 { 586 int saved_ctxnum, ctxnum; 587 int i, sme; 588 context_t contextp; 589 vaddr_t va; 590 591 CHECK_SPL(); 592 593 ctxnum = pmap->pm_ctxnum; 594 if (ctxnum < FIRST_CONTEXT || ctxnum >= NCONTEXT) 595 panic("pmap: context_free ctxnum"); 596 contextp = &context_array[ctxnum]; 597 598 /* Temporary context change. */ 599 saved_ctxnum = get_context(); 600 set_context(ctxnum); 601 602 /* Before unloading translations, flush cache. */ 603 #ifdef HAVECACHE 604 if (cache_size) 605 cache_flush_context(); 606 #endif 607 608 /* Unload MMU (but keep in SW segmap). */ 609 for (i = 0, va = 0; i < NUSEG; i++, va += NBSG) { 610 611 #if !defined(PMAP_DEBUG) 612 /* Short-cut using the S/W segmap (if !debug). */ 613 if (pmap->pm_segmap[i] == SEGINV) 614 continue; 615 #endif 616 617 /* Check the H/W segmap. */ 618 sme = get_segmap(va); 619 if (sme == SEGINV) 620 continue; 621 622 /* Found valid PMEG in the segmap. */ 623 #ifdef PMAP_DEBUG 624 if (pmap_debug & PMD_SEGMAP) 625 printf("pmap: set_segmap ctx=%d v=0x%lx old=0x%x " 626 "new=ff (cf)\n", ctxnum, va, sme); 627 #endif 628 #ifdef DIAGNOSTIC 629 if (sme != pmap->pm_segmap[i]) 630 panic("context_free: unknown sme at va=0x%lx", va); 631 #endif 632 /* Did cache flush above (whole context). */ 633 set_segmap(va, SEGINV); 634 /* In this case, do not clear pm_segmap. */ 635 /* XXX: Maybe inline this call? */ 636 pmeg_release(pmeg_p(sme)); 637 } 638 639 /* Restore previous context. */ 640 set_context(saved_ctxnum); 641 642 /* Dequeue, update, requeue. */ 643 TAILQ_REMOVE(&context_active_queue, contextp, context_link); 644 pmap->pm_ctxnum = EMPTY_CONTEXT; 645 contextp->context_upmap = NULL; 646 TAILQ_INSERT_TAIL(&context_free_queue, contextp, context_link); 647 } 648 649 650 /**************************************************************** 651 * PMEG management functions. 652 */ 653 654 static void 655 pmeg_init(void) 656 { 657 int x; 658 659 /* clear pmeg array, put it all on the free pmeq queue */ 660 661 TAILQ_INIT(&pmeg_free_queue); 662 TAILQ_INIT(&pmeg_inactive_queue); 663 TAILQ_INIT(&pmeg_active_queue); 664 TAILQ_INIT(&pmeg_kernel_queue); 665 666 memset(pmeg_array, 0, NPMEG*sizeof(struct pmeg_state)); 667 for (x = 0; x < NPMEG; x++) { 668 TAILQ_INSERT_TAIL(&pmeg_free_queue, &pmeg_array[x], pmeg_link); 669 pmeg_array[x].pmeg_qstate = PMEGQ_FREE; 670 pmeg_array[x].pmeg_index = x; 671 } 672 673 /* The last pmeg is not usable. */ 674 pmeg_reserve(SEGINV); 675 } 676 677 /* 678 * Reserve a pmeg (forever) for use by PROM, etc. 679 * Contents are left as-is. Called very early... 680 */ 681 void 682 pmeg_reserve(int sme) 683 { 684 pmeg_t pmegp; 685 686 /* Can not use pmeg_p() because it fails on SEGINV. */ 687 pmegp = &pmeg_array[sme]; 688 689 if (pmegp->pmeg_reserved) { 690 mon_printf("pmeg_reserve: already reserved\n"); 691 sunmon_abort(); 692 } 693 if (pmegp->pmeg_owner) { 694 mon_printf("pmeg_reserve: already owned\n"); 695 sunmon_abort(); 696 } 697 698 /* Owned by kernel, but not really usable... */ 699 pmegp->pmeg_owner = kernel_pmap; 700 pmegp->pmeg_reserved++; /* keep count, just in case */ 701 TAILQ_REMOVE(&pmeg_free_queue, pmegp, pmeg_link); 702 pmegp->pmeg_qstate = PMEGQ_NONE; 703 } 704 705 /* 706 * Examine PMEGs used by the monitor, and either 707 * reserve them (keep=1) or clear them (keep=0) 708 */ 709 static void 710 pmeg_mon_init(vaddr_t sva, vaddr_t eva, int keep) 711 { 712 vaddr_t pgva, endseg; 713 int pte, valid; 714 unsigned char sme; 715 716 #ifdef PMAP_DEBUG 717 if (pmap_debug & PMD_SEGMAP) 718 mon_printf("pmeg_mon_init(0x%x, 0x%x, %d)\n", 719 sva, eva, keep); 720 #endif 721 722 sva &= ~(NBSG - 1); 723 724 while (sva < eva) { 725 sme = get_segmap(sva); 726 if (sme != SEGINV) { 727 valid = 0; 728 endseg = sva + NBSG; 729 for (pgva = sva; pgva < endseg; pgva += PAGE_SIZE) { 730 pte = get_pte(pgva); 731 if (pte & PG_VALID) { 732 valid++; 733 } 734 } 735 #ifdef PMAP_DEBUG 736 if (pmap_debug & PMD_SEGMAP) 737 mon_printf(" sva=0x%x seg=0x%x valid=%d\n", 738 sva, sme, valid); 739 #endif 740 if (keep && valid) 741 pmeg_reserve(sme); 742 else 743 set_segmap(sva, SEGINV); 744 } 745 sva += NBSG; 746 } 747 } 748 749 /* 750 * This is used only during pmap_bootstrap, so we can 751 * get away with borrowing a slot in the segmap. 752 */ 753 static void 754 pmeg_clean(pmeg_t pmegp) 755 { 756 int sme; 757 vaddr_t va; 758 759 sme = get_segmap(0); 760 if (sme != SEGINV) 761 panic("pmeg_clean"); 762 763 sme = pmegp->pmeg_index; 764 set_segmap(0, sme); 765 766 for (va = 0; va < NBSG; va += PAGE_SIZE) 767 set_pte(va, PG_INVAL); 768 769 set_segmap(0, SEGINV); 770 } 771 772 /* 773 * This routine makes sure that pmegs on the pmeg_free_queue contain 774 * no valid ptes. It pulls things off the queue, cleans them, and 775 * puts them at the end. The ending condition is finding the first 776 * queue element at the head of the queue again. 777 */ 778 static void 779 pmeg_clean_free(void) 780 { 781 pmeg_t pmegp, pmegp_first; 782 783 pmegp = TAILQ_FIRST(&pmeg_free_queue); 784 if (pmegp == NULL) 785 panic("pmap: no free pmegs available to clean"); 786 787 pmegp_first = NULL; 788 789 for (;;) { 790 pmegp = TAILQ_FIRST(&pmeg_free_queue); 791 TAILQ_REMOVE(&pmeg_free_queue, pmegp, pmeg_link); 792 793 pmegp->pmeg_qstate = PMEGQ_NONE; 794 pmeg_clean(pmegp); 795 pmegp->pmeg_qstate = PMEGQ_FREE; 796 797 TAILQ_INSERT_TAIL(&pmeg_free_queue, pmegp, pmeg_link); 798 799 if (pmegp == pmegp_first) 800 break; 801 if (pmegp_first == NULL) 802 pmegp_first = pmegp; 803 } 804 } 805 806 /* 807 * Allocate a PMEG by whatever means necessary. 808 * (May invalidate some mappings!) 809 */ 810 static pmeg_t 811 pmeg_allocate(pmap_t pmap, vaddr_t va) 812 { 813 pmeg_t pmegp; 814 815 CHECK_SPL(); 816 817 #ifdef DIAGNOSTIC 818 if (va & SEGOFSET) { 819 panic("pmap:pmeg_allocate: va=0x%lx", va); 820 } 821 #endif 822 823 /* Get one onto the free list if necessary. */ 824 pmegp = TAILQ_FIRST(&pmeg_free_queue); 825 if (!pmegp) { 826 /* Try inactive queue... */ 827 pmegp = TAILQ_FIRST(&pmeg_inactive_queue); 828 if (!pmegp) { 829 /* Try active queue... */ 830 pmegp = TAILQ_FIRST(&pmeg_active_queue); 831 } 832 if (!pmegp) { 833 panic("pmeg_allocate: failed"); 834 } 835 836 /* 837 * Remove mappings to free-up a pmeg 838 * (so it will go onto the free list). 839 * XXX - Skip this one if it is wired? 840 */ 841 pmap_remove1(pmegp->pmeg_owner, 842 pmegp->pmeg_va, 843 pmegp->pmeg_va + NBSG); 844 } 845 846 /* OK, free list has something for us to take. */ 847 pmegp = TAILQ_FIRST(&pmeg_free_queue); 848 #ifdef DIAGNOSTIC 849 if (pmegp == NULL) 850 panic("pmeg_allocagte: still none free?"); 851 if ((pmegp->pmeg_qstate != PMEGQ_FREE) || 852 (pmegp->pmeg_index == SEGINV) || 853 (pmegp->pmeg_vpages)) 854 panic("pmeg_allocate: bad pmegp=%p", pmegp); 855 #endif 856 #ifdef PMAP_DEBUG 857 if (pmegp->pmeg_index == pmap_db_watchpmeg) { 858 db_printf("pmeg_allocate: watch pmegp=%p\n", pmegp); 859 Debugger(); 860 } 861 #endif 862 863 TAILQ_REMOVE(&pmeg_free_queue, pmegp, pmeg_link); 864 865 /* Reassign this PMEG for the caller. */ 866 pmegp->pmeg_owner = pmap; 867 pmegp->pmeg_version = pmap->pm_version; 868 pmegp->pmeg_va = va; 869 pmegp->pmeg_wired = 0; 870 pmegp->pmeg_reserved = 0; 871 pmegp->pmeg_vpages = 0; 872 if (pmap == kernel_pmap) { 873 TAILQ_INSERT_TAIL(&pmeg_kernel_queue, pmegp, pmeg_link); 874 pmegp->pmeg_qstate = PMEGQ_KERNEL; 875 } else { 876 TAILQ_INSERT_TAIL(&pmeg_active_queue, pmegp, pmeg_link); 877 pmegp->pmeg_qstate = PMEGQ_ACTIVE; 878 } 879 /* Caller will verify that it's empty (if debugging). */ 880 return pmegp; 881 } 882 883 /* 884 * Put pmeg on the inactive queue, leaving its contents intact. 885 * This happens when we loose our context. We may reclaim 886 * this pmeg later if it is still in the inactive queue. 887 */ 888 static void 889 pmeg_release(pmeg_t pmegp) 890 { 891 892 CHECK_SPL(); 893 894 #ifdef DIAGNOSTIC 895 if ((pmegp->pmeg_owner == kernel_pmap) || 896 (pmegp->pmeg_qstate != PMEGQ_ACTIVE)) 897 panic("pmeg_release: bad pmeg=%p", pmegp); 898 #endif 899 900 TAILQ_REMOVE(&pmeg_active_queue, pmegp, pmeg_link); 901 pmegp->pmeg_qstate = PMEGQ_INACTIVE; 902 TAILQ_INSERT_TAIL(&pmeg_inactive_queue, pmegp, pmeg_link); 903 } 904 905 /* 906 * Move the pmeg to the free queue from wherever it is. 907 * The pmeg will be clean. It might be in kernel_pmap. 908 */ 909 static void 910 pmeg_free(pmeg_t pmegp) 911 { 912 913 CHECK_SPL(); 914 915 #ifdef DIAGNOSTIC 916 /* Caller should verify that it's empty. */ 917 if (pmegp->pmeg_vpages != 0) 918 panic("pmeg_free: vpages"); 919 #endif 920 921 switch (pmegp->pmeg_qstate) { 922 case PMEGQ_ACTIVE: 923 TAILQ_REMOVE(&pmeg_active_queue, pmegp, pmeg_link); 924 break; 925 case PMEGQ_INACTIVE: 926 TAILQ_REMOVE(&pmeg_inactive_queue, pmegp, pmeg_link); 927 break; 928 case PMEGQ_KERNEL: 929 TAILQ_REMOVE(&pmeg_kernel_queue, pmegp, pmeg_link); 930 break; 931 default: 932 panic("pmeg_free: releasing bad pmeg"); 933 break; 934 } 935 936 #ifdef PMAP_DEBUG 937 if (pmegp->pmeg_index == pmap_db_watchpmeg) { 938 db_printf("pmeg_free: watch pmeg 0x%x\n", 939 pmegp->pmeg_index); 940 Debugger(); 941 } 942 #endif 943 944 pmegp->pmeg_owner = NULL; 945 pmegp->pmeg_qstate = PMEGQ_FREE; 946 TAILQ_INSERT_TAIL(&pmeg_free_queue, pmegp, pmeg_link); 947 } 948 949 /* 950 * Find a PMEG that was put on the inactive queue when we 951 * had our context stolen. If found, move to active queue. 952 */ 953 static pmeg_t 954 pmeg_cache(pmap_t pmap, vaddr_t va) 955 { 956 int sme, segnum; 957 pmeg_t pmegp; 958 959 CHECK_SPL(); 960 961 #ifdef DIAGNOSTIC 962 if (pmap == kernel_pmap) 963 panic("pmeg_cache: kernel_pmap"); 964 if (va & SEGOFSET) { 965 panic("pmap:pmeg_cache: va=0x%lx", va); 966 } 967 #endif 968 969 if (pmap->pm_segmap == NULL) 970 return PMEG_NULL; 971 972 segnum = VA_SEGNUM(va); 973 if (segnum > NUSEG) /* out of range */ 974 return PMEG_NULL; 975 976 sme = pmap->pm_segmap[segnum]; 977 if (sme == SEGINV) /* nothing cached */ 978 return PMEG_NULL; 979 980 pmegp = pmeg_p(sme); 981 982 #ifdef PMAP_DEBUG 983 if (pmegp->pmeg_index == pmap_db_watchpmeg) { 984 db_printf("pmeg_cache: watch pmeg 0x%x\n", pmegp->pmeg_index); 985 Debugger(); 986 } 987 #endif 988 989 /* 990 * Our segmap named a PMEG. If it is no longer ours, 991 * invalidate that entry in our segmap and return NULL. 992 */ 993 if ((pmegp->pmeg_owner != pmap) || 994 (pmegp->pmeg_version != pmap->pm_version) || 995 (pmegp->pmeg_va != va)) 996 { 997 #ifdef PMAP_DEBUG 998 db_printf("pmap:pmeg_cache: invalid pmeg: sme=0x%x\n", sme); 999 pmeg_print(pmegp); 1000 Debugger(); 1001 #endif 1002 pmap->pm_segmap[segnum] = SEGINV; 1003 return PMEG_NULL; /* cache lookup failed */ 1004 } 1005 1006 #ifdef DIAGNOSTIC 1007 /* Make sure it is on the inactive queue. */ 1008 if (pmegp->pmeg_qstate != PMEGQ_INACTIVE) 1009 panic("pmeg_cache: pmeg was taken: %p", pmegp); 1010 #endif 1011 1012 TAILQ_REMOVE(&pmeg_inactive_queue, pmegp, pmeg_link); 1013 pmegp->pmeg_qstate = PMEGQ_ACTIVE; 1014 TAILQ_INSERT_TAIL(&pmeg_active_queue, pmegp, pmeg_link); 1015 1016 return pmegp; 1017 } 1018 1019 #ifdef PMAP_DEBUG 1020 static void 1021 pmeg_verify_empty(vaddr_t va) 1022 { 1023 vaddr_t eva; 1024 int pte; 1025 1026 for (eva = va + NBSG; va < eva; va += PAGE_SIZE) { 1027 pte = get_pte(va); 1028 if (pte & PG_VALID) 1029 panic("pmeg_verify_empty"); 1030 } 1031 } 1032 #endif /* PMAP_DEBUG */ 1033 1034 1035 /**************************************************************** 1036 * Physical-to-virutal lookup support 1037 * 1038 * Need memory for the pv_alloc/pv_free list heads 1039 * and elements. We know how many to allocate since 1040 * there is one list head for each physical page, and 1041 * at most one element for each PMEG slot. 1042 */ 1043 static void 1044 pv_init(void) 1045 { 1046 int npp, nvp, sz; 1047 pv_entry_t pv; 1048 char *p; 1049 1050 /* total allocation size */ 1051 sz = 0; 1052 1053 /* 1054 * Data for each physical page. 1055 * Each "mod/ref" flag is a char. 1056 * Each PV head is a pointer. 1057 * Note physmem is in pages. 1058 */ 1059 npp = ALIGN(physmem); 1060 sz += (npp * sizeof(*pv_flags_tbl)); 1061 sz += (npp * sizeof(*pv_head_tbl)); 1062 1063 /* 1064 * Data for each virtual page (all PMEGs). 1065 * One pv_entry for each page frame. 1066 */ 1067 nvp = NPMEG * NPAGSEG; 1068 sz += (nvp * sizeof(*pv_free_list)); 1069 1070 /* Now allocate the whole thing. */ 1071 sz = m68k_round_page(sz); 1072 p = (char *)uvm_km_alloc(kernel_map, sz, 0, UVM_KMF_WIRED); 1073 if (p == NULL) 1074 panic("pmap:pv_init: alloc failed"); 1075 memset(p, 0, sz); 1076 1077 /* Now divide up the space. */ 1078 pv_flags_tbl = (void *) p; 1079 p += (npp * sizeof(*pv_flags_tbl)); 1080 pv_head_tbl = (void*) p; 1081 p += (npp * sizeof(*pv_head_tbl)); 1082 pv_free_list = (void *)p; 1083 p += (nvp * sizeof(*pv_free_list)); 1084 1085 /* Finally, make pv_free_list into a list. */ 1086 for (pv = pv_free_list; (char *)pv < p; pv++) 1087 pv->pv_next = &pv[1]; 1088 pv[-1].pv_next = 0; 1089 1090 pv_initialized++; 1091 } 1092 1093 /* 1094 * Set or clear bits in all PTEs mapping a page. 1095 * Also does syncflags work while we are there... 1096 */ 1097 static void 1098 pv_changepte(paddr_t pa, int set_bits, int clear_bits) 1099 { 1100 pv_entry_t *head, pv; 1101 u_char *pv_flags; 1102 pmap_t pmap; 1103 vaddr_t va; 1104 int pte, sme; 1105 int saved_ctx; 1106 bool in_ctx; 1107 u_int flags; 1108 1109 pv_flags = pa_to_pvflags(pa); 1110 head = pa_to_pvhead(pa); 1111 1112 /* If no mappings, no work to do. */ 1113 if (*head == NULL) 1114 return; 1115 1116 #ifdef DIAGNOSTIC 1117 /* This function should only clear these bits: */ 1118 if (clear_bits & ~(PG_WRITE | PG_NC | PG_REF | PG_MOD)) 1119 panic("pv_changepte: clear=0x%x", clear_bits); 1120 #endif 1121 1122 flags = 0; 1123 saved_ctx = get_context(); 1124 for (pv = *head; pv != NULL; pv = pv->pv_next) { 1125 pmap = pv->pv_pmap; 1126 va = pv->pv_va; 1127 1128 #ifdef DIAGNOSTIC 1129 if (pmap->pm_segmap == NULL) 1130 panic("pv_changepte: null segmap"); 1131 #endif 1132 1133 /* Is the PTE currently accessible in some context? */ 1134 in_ctx = false; 1135 sme = SEGINV; /* kill warning */ 1136 if (pmap == kernel_pmap) 1137 in_ctx = true; 1138 else if (has_context(pmap)) { 1139 /* PMEG may be inactive. */ 1140 set_context(pmap->pm_ctxnum); 1141 sme = get_segmap(va); 1142 if (sme != SEGINV) 1143 in_ctx = true; 1144 } 1145 1146 if (in_ctx == true) { 1147 /* 1148 * The PTE is in the current context. 1149 * Make sure PTE is up-to-date with VAC. 1150 */ 1151 #ifdef HAVECACHE 1152 if (cache_size) 1153 cache_flush_page(va); 1154 #endif 1155 pte = get_pte(va); 1156 } else { 1157 1158 /* 1159 * The PTE is not in any context. 1160 */ 1161 1162 sme = pmap->pm_segmap[VA_SEGNUM(va)]; 1163 #ifdef DIAGNOSTIC 1164 if (sme == SEGINV) 1165 panic("pv_changepte: SEGINV"); 1166 #endif 1167 pte = get_pte_pmeg(sme, VA_PTE_NUM(va)); 1168 } 1169 1170 #ifdef DIAGNOSTIC 1171 /* PV entries point only to valid mappings. */ 1172 if ((pte & PG_VALID) == 0) 1173 panic("pv_changepte: not PG_VALID at va=0x%lx", va); 1174 #endif 1175 /* Get these while it's easy. */ 1176 if (pte & PG_MODREF) { 1177 flags |= (pte & PG_MODREF); 1178 pte &= ~PG_MODREF; 1179 } 1180 1181 /* Finally, set and clear some bits. */ 1182 pte |= set_bits; 1183 pte &= ~clear_bits; 1184 1185 if (in_ctx == true) { 1186 /* Did cache flush above. */ 1187 set_pte(va, pte); 1188 } else { 1189 set_pte_pmeg(sme, VA_PTE_NUM(va), pte); 1190 } 1191 } 1192 set_context(saved_ctx); 1193 1194 *pv_flags |= (flags >> PV_SHIFT); 1195 } 1196 1197 /* 1198 * Return ref and mod bits from pvlist, 1199 * and turns off same in hardware PTEs. 1200 */ 1201 static u_int 1202 pv_syncflags(pv_entry_t pv) 1203 { 1204 pmap_t pmap; 1205 vaddr_t va; 1206 int pte, sme; 1207 int saved_ctx; 1208 bool in_ctx; 1209 u_int flags; 1210 1211 /* If no mappings, no work to do. */ 1212 if (pv == NULL) 1213 return (0); 1214 1215 flags = 0; 1216 saved_ctx = get_context(); 1217 for (; pv != NULL; pv = pv->pv_next) { 1218 pmap = pv->pv_pmap; 1219 va = pv->pv_va; 1220 sme = SEGINV; 1221 1222 #ifdef DIAGNOSTIC 1223 /* 1224 * Only the head may have a null pmap, and 1225 * we checked for that above. 1226 */ 1227 if (pmap->pm_segmap == NULL) 1228 panic("pv_syncflags: null segmap"); 1229 #endif 1230 1231 /* Is the PTE currently accessible in some context? */ 1232 in_ctx = false; 1233 if (pmap == kernel_pmap) 1234 in_ctx = true; 1235 else if (has_context(pmap)) { 1236 /* PMEG may be inactive. */ 1237 set_context(pmap->pm_ctxnum); 1238 sme = get_segmap(va); 1239 if (sme != SEGINV) 1240 in_ctx = true; 1241 } 1242 1243 if (in_ctx == true) { 1244 1245 /* 1246 * The PTE is in the current context. 1247 * Make sure PTE is up-to-date with VAC. 1248 */ 1249 1250 #ifdef HAVECACHE 1251 if (cache_size) 1252 cache_flush_page(va); 1253 #endif 1254 pte = get_pte(va); 1255 } else { 1256 1257 /* 1258 * The PTE is not in any context. 1259 */ 1260 1261 sme = pmap->pm_segmap[VA_SEGNUM(va)]; 1262 #ifdef DIAGNOSTIC 1263 if (sme == SEGINV) 1264 panic("pv_syncflags: SEGINV"); 1265 #endif 1266 pte = get_pte_pmeg(sme, VA_PTE_NUM(va)); 1267 } 1268 1269 #ifdef DIAGNOSTIC 1270 /* PV entries point only to valid mappings. */ 1271 if ((pte & PG_VALID) == 0) 1272 panic("pv_syncflags: not PG_VALID at va=0x%lx", va); 1273 #endif 1274 /* OK, do what we came here for... */ 1275 if (pte & PG_MODREF) { 1276 flags |= (pte & PG_MODREF); 1277 pte &= ~PG_MODREF; 1278 } 1279 1280 if (in_ctx == true) { 1281 /* Did cache flush above. */ 1282 set_pte(va, pte); 1283 } else { 1284 set_pte_pmeg(sme, VA_PTE_NUM(va), pte); 1285 } 1286 } 1287 set_context(saved_ctx); 1288 1289 return (flags >> PV_SHIFT); 1290 } 1291 1292 /* Remove all mappings for the physical page. */ 1293 static void 1294 pv_remove_all(paddr_t pa) 1295 { 1296 pv_entry_t *head, pv; 1297 pmap_t pmap; 1298 vaddr_t va; 1299 1300 CHECK_SPL(); 1301 1302 #ifdef PMAP_DEBUG 1303 if (pmap_debug & PMD_REMOVE) 1304 printf("pv_remove_all(0x%lx)\n", pa); 1305 #endif 1306 1307 head = pa_to_pvhead(pa); 1308 while ((pv = *head) != NULL) { 1309 pmap = pv->pv_pmap; 1310 va = pv->pv_va; 1311 pmap_remove1(pmap, va, va + PAGE_SIZE); 1312 #ifdef PMAP_DEBUG 1313 /* Make sure it went away. */ 1314 if (pv == *head) { 1315 db_printf("pv_remove_all: " 1316 "head unchanged for pa=0x%lx\n", pa); 1317 Debugger(); 1318 } 1319 #endif 1320 } 1321 } 1322 1323 /* 1324 * The pmap system is asked to lookup all mappings that point to a 1325 * given physical memory address. This function adds a new element 1326 * to the list of mappings maintained for the given physical address. 1327 * Returns PV_NC if the (new) pvlist says that the address cannot 1328 * be cached. 1329 */ 1330 static int 1331 pv_link(pmap_t pmap, int pte, vaddr_t va) 1332 { 1333 paddr_t pa; 1334 pv_entry_t *head, pv; 1335 u_char *pv_flags; 1336 int flags; 1337 1338 if (!pv_initialized) 1339 return 0; 1340 1341 CHECK_SPL(); 1342 1343 /* Only the non-cached bit is of interest here. */ 1344 flags = (pte & PG_NC) ? PV_NC : 0; 1345 pa = PG_PA(pte); 1346 1347 #ifdef PMAP_DEBUG 1348 if ((pmap_debug & PMD_LINK) || (va == pmap_db_watchva)) { 1349 printf("pv_link(%p, 0x%x, 0x%lx)\n", pmap, pte, va); 1350 /* pv_print(pa); */ 1351 } 1352 #endif 1353 1354 pv_flags = pa_to_pvflags(pa); 1355 head = pa_to_pvhead(pa); 1356 1357 #ifdef DIAGNOSTIC 1358 /* See if this mapping is already in the list. */ 1359 for (pv = *head; pv != NULL; pv = pv->pv_next) { 1360 if ((pv->pv_pmap == pmap) && (pv->pv_va == va)) 1361 panic("pv_link: duplicate entry for PA=0x%lx", pa); 1362 } 1363 #endif 1364 #ifdef HAVECACHE 1365 1366 /* 1367 * Does this new mapping cause VAC alias problems? 1368 */ 1369 1370 *pv_flags |= flags; 1371 if ((*pv_flags & PV_NC) == 0) { 1372 for (pv = *head; pv != NULL; pv = pv->pv_next) { 1373 if (BADALIAS(va, pv->pv_va)) { 1374 *pv_flags |= PV_NC; 1375 pv_changepte(pa, PG_NC, 0); 1376 pmap_stats.ps_vac_uncached++; 1377 break; 1378 } 1379 } 1380 } 1381 #endif 1382 1383 /* Allocate a PV element (pv_alloc()). */ 1384 pv = pv_free_list; 1385 if (pv == NULL) 1386 panic("pv_link: pv_alloc"); 1387 pv_free_list = pv->pv_next; 1388 pv->pv_next = 0; 1389 1390 /* Insert new entry at the head. */ 1391 pv->pv_pmap = pmap; 1392 pv->pv_va = va; 1393 pv->pv_next = *head; 1394 *head = pv; 1395 1396 return (*pv_flags & PV_NC); 1397 } 1398 1399 /* 1400 * pv_unlink is a helper function for pmap_remove. 1401 * It removes the appropriate (pmap, pa, va) entry. 1402 * 1403 * Once the entry is removed, if the pv_table head has the cache 1404 * inhibit bit set, see if we can turn that off; if so, walk the 1405 * pvlist and turn off PG_NC in each PTE. (The pvlist is by 1406 * definition nonempty, since it must have at least two elements 1407 * in it to have PV_NC set, and we only remove one here.) 1408 */ 1409 static void 1410 pv_unlink(pmap_t pmap, int pte, vaddr_t va) 1411 { 1412 paddr_t pa; 1413 pv_entry_t *head, *ppv, pv; 1414 u_char *pv_flags; 1415 1416 CHECK_SPL(); 1417 1418 pa = PG_PA(pte); 1419 #ifdef PMAP_DEBUG 1420 if ((pmap_debug & PMD_LINK) || (va == pmap_db_watchva)) { 1421 printf("pv_unlink(%p, 0x%x, 0x%lx)\n", pmap, pte, va); 1422 /* pv_print(pa); */ 1423 } 1424 #endif 1425 1426 pv_flags = pa_to_pvflags(pa); 1427 head = pa_to_pvhead(pa); 1428 1429 /* 1430 * Find the entry. 1431 */ 1432 ppv = head; 1433 pv = *ppv; 1434 while (pv) { 1435 if ((pv->pv_pmap == pmap) && (pv->pv_va == va)) 1436 goto found; 1437 ppv = &pv->pv_next; 1438 pv = pv->pv_next; 1439 } 1440 #ifdef PMAP_DEBUG 1441 db_printf("pv_unlink: not found (pa=0x%lx,va=0x%lx)\n", pa, va); 1442 Debugger(); 1443 #endif 1444 return; 1445 1446 found: 1447 /* Unlink this entry from the list and clear it. */ 1448 *ppv = pv->pv_next; 1449 pv->pv_pmap = NULL; 1450 pv->pv_va = 0; 1451 1452 /* Insert it on the head of the free list. (pv_free()) */ 1453 pv->pv_next = pv_free_list; 1454 pv_free_list = pv; 1455 pv = NULL; 1456 1457 /* Do any non-cached mappings remain? */ 1458 if ((*pv_flags & PV_NC) == 0) 1459 return; 1460 if ((pv = *head) == NULL) 1461 return; 1462 1463 /* 1464 * Have non-cached mappings. See if we can fix that now. 1465 */ 1466 va = pv->pv_va; 1467 for (pv = pv->pv_next; pv != NULL; pv = pv->pv_next) { 1468 /* If there is a DVMA mapping, leave it NC. */ 1469 if (va >= DVMA_MAP_BASE) 1470 return; 1471 /* If there are VAC alias problems, leave NC. */ 1472 if (BADALIAS(va, pv->pv_va)) 1473 return; 1474 } 1475 /* OK, there are no "problem" mappings. */ 1476 *pv_flags &= ~PV_NC; 1477 pv_changepte(pa, 0, PG_NC); 1478 pmap_stats.ps_vac_recached++; 1479 } 1480 1481 1482 /**************************************************************** 1483 * Bootstrap and Initialization, etc. 1484 */ 1485 1486 void 1487 pmap_common_init(pmap_t pmap) 1488 { 1489 memset(pmap, 0, sizeof(struct pmap)); 1490 pmap->pm_refcount = 1; 1491 pmap->pm_version = pmap_version++; 1492 pmap->pm_ctxnum = EMPTY_CONTEXT; 1493 simple_lock_init(&pmap->pm_lock); 1494 } 1495 1496 /* 1497 * Prepare the kernel for VM operations. 1498 * This is called by locore2.c:_vm_init() 1499 * after the "start/end" globals are set. 1500 * This function must NOT leave context zero. 1501 */ 1502 void 1503 pmap_bootstrap(vaddr_t nextva) 1504 { 1505 struct sunromvec *rvec; 1506 vaddr_t va, eva; 1507 int i, pte, sme; 1508 extern char etext[]; 1509 1510 nextva = m68k_round_page(nextva); 1511 rvec = romVectorPtr; 1512 1513 /* Steal some special-purpose, already mapped pages? */ 1514 1515 /* 1516 * Determine the range of kernel virtual space available. 1517 * It is segment-aligned to simplify PMEG management. 1518 */ 1519 virtual_avail = sun3_round_seg(nextva); 1520 virtual_end = VM_MAX_KERNEL_ADDRESS; 1521 1522 /* 1523 * Determine the range of physical memory available. 1524 * Physical memory at zero was remapped to KERNBASE. 1525 */ 1526 avail_start = nextva - KERNBASE3; 1527 if (rvec->romvecVersion < 1) { 1528 mon_printf("Warning: ancient PROM version=%d\n", 1529 rvec->romvecVersion); 1530 /* Guess that PROM version 0.X used two pages. */ 1531 avail_end = *rvec->memorySize - (2*PAGE_SIZE); 1532 } else { 1533 /* PROM version 1 or later. */ 1534 avail_end = *rvec->memoryAvail; 1535 } 1536 avail_end = m68k_trunc_page(avail_end); 1537 1538 /* 1539 * Report the actual amount of physical memory, 1540 * even though the PROM takes a few pages. 1541 */ 1542 physmem = (btoc(avail_end) + 0xF) & ~0xF; 1543 1544 /* 1545 * On the Sun3/50, the video frame buffer is located at 1546 * physical addres 1MB so we must step over it. 1547 */ 1548 if (cpu_machine_id == ID_SUN3_50) { 1549 hole_start = m68k_trunc_page(OBMEM_BW50_ADDR); 1550 hole_size = m68k_round_page(OBMEM_BW2_SIZE); 1551 if (avail_start > hole_start) { 1552 mon_printf("kernel too large for Sun3/50\n"); 1553 sunmon_abort(); 1554 } 1555 } 1556 1557 /* 1558 * Done allocating PAGES of virtual space, so 1559 * clean out the rest of the last used segment. 1560 */ 1561 for (va = nextva; va < virtual_avail; va += PAGE_SIZE) 1562 set_pte(va, PG_INVAL); 1563 1564 /* 1565 * Now that we are done stealing physical pages, etc. 1566 * figure out which PMEGs are used by those mappings 1567 * and either reserve them or clear them out. 1568 * -- but first, init PMEG management. 1569 * This puts all PMEGs in the free list. 1570 * We will allocte the in-use ones. 1571 */ 1572 pmeg_init(); 1573 1574 /* 1575 * Unmap user virtual segments. 1576 * VA range: [0 .. KERNBASE] 1577 */ 1578 for (va = 0; va < KERNBASE3; va += NBSG) 1579 set_segmap(va, SEGINV); 1580 1581 /* 1582 * Reserve PMEGS for kernel text/data/bss 1583 * and the misc pages taken above. 1584 * VA range: [KERNBASE .. virtual_avail] 1585 */ 1586 for ( ; va < virtual_avail; va += NBSG) { 1587 sme = get_segmap(va); 1588 if (sme == SEGINV) { 1589 mon_printf("kernel text/data/bss not mapped\n"); 1590 sunmon_abort(); 1591 } 1592 pmeg_reserve(sme); 1593 } 1594 1595 /* 1596 * Unmap kernel virtual space. Make sure to leave no valid 1597 * segmap entries in the MMU unless pmeg_array records them. 1598 * VA range: [vseg_avail .. virtual_end] 1599 */ 1600 for ( ; va < virtual_end; va += NBSG) 1601 set_segmap(va, SEGINV); 1602 1603 /* 1604 * Reserve PMEGs used by the PROM monitor (device mappings). 1605 * Free up any pmegs in this range which have no mappings. 1606 * VA range: [0x0FE00000 .. 0x0FF00000] 1607 */ 1608 pmeg_mon_init(SUN3_MONSTART, SUN3_MONEND, true); 1609 1610 /* 1611 * Unmap any pmegs left in DVMA space by the PROM. 1612 * DO NOT kill the last one! (owned by the PROM!) 1613 * VA range: [0x0FF00000 .. 0x0FFE0000] 1614 */ 1615 pmeg_mon_init(SUN3_MONEND, SUN3_MONSHORTSEG, false); 1616 1617 /* 1618 * MONSHORTSEG contains MONSHORTPAGE which is a data page 1619 * allocated by the PROM monitor. Reserve the segment, 1620 * but clear out all but the last PTE inside it. 1621 * Note we use this for tmp_vpages. 1622 */ 1623 va = SUN3_MONSHORTSEG; 1624 eva = SUN3_MONSHORTPAGE; 1625 sme = get_segmap(va); 1626 pmeg_reserve(sme); 1627 for ( ; va < eva; va += PAGE_SIZE) 1628 set_pte(va, PG_INVAL); 1629 1630 /* 1631 * Done reserving PMEGs and/or clearing out mappings. 1632 * 1633 * Now verify the mapping protections and such for the 1634 * important parts of the address space (in VA order). 1635 * Note that the Sun PROM usually leaves the memory 1636 * mapped with everything non-cached... 1637 */ 1638 1639 /* 1640 * Map the message buffer page at a constant location 1641 * (physical address zero) so its contents will be 1642 * preserved through a reboot. 1643 */ 1644 va = KERNBASE3; 1645 pte = get_pte(va); 1646 pte |= (PG_SYSTEM | PG_WRITE | PG_NC); 1647 set_pte(va, pte); 1648 va += PAGE_SIZE; 1649 /* Initialize msgbufaddr later, in machdep.c */ 1650 1651 /* Next is the tmpstack page. */ 1652 pte = get_pte(va); 1653 pte &= ~(PG_NC); 1654 pte |= (PG_SYSTEM | PG_WRITE); 1655 set_pte(va, pte); 1656 va += PAGE_SIZE; 1657 1658 /* 1659 * Next is the kernel text. 1660 * 1661 * Verify protection bits on kernel text/data/bss 1662 * All of kernel text, data, and bss are cached. 1663 * Text is read-only (except in db_write_ktext). 1664 */ 1665 eva = m68k_trunc_page(etext); 1666 while (va < eva) { 1667 pte = get_pte(va); 1668 if ((pte & (PG_VALID|PG_TYPE)) != PG_VALID) { 1669 mon_printf("invalid page at 0x%x\n", va); 1670 } 1671 pte &= ~(PG_WRITE|PG_NC); 1672 /* Kernel text is read-only */ 1673 pte |= (PG_SYSTEM); 1674 set_pte(va, pte); 1675 va += PAGE_SIZE; 1676 } 1677 /* data, bss, etc. */ 1678 while (va < nextva) { 1679 pte = get_pte(va); 1680 if ((pte & (PG_VALID|PG_TYPE)) != PG_VALID) { 1681 mon_printf("invalid page at 0x%x\n", va); 1682 } 1683 pte &= ~(PG_NC); 1684 pte |= (PG_SYSTEM | PG_WRITE); 1685 set_pte(va, pte); 1686 va += PAGE_SIZE; 1687 } 1688 1689 /* 1690 * Duplicate all mappings in the current context into 1691 * every other context. We have to let the PROM do the 1692 * actual segmap manipulation because we can only switch 1693 * the MMU context after we are sure that the kernel is 1694 * identically mapped in all contexts. The PROM can do 1695 * the job using hardware-dependent tricks... 1696 */ 1697 #ifdef DIAGNOSTIC 1698 /* Note: PROM setcxsegmap function needs sfc=dfs=FC_CONTROL */ 1699 if ((getsfc() != FC_CONTROL) || (getdfc() != FC_CONTROL)) { 1700 mon_printf("pmap_bootstrap: bad dfc or sfc\n"); 1701 sunmon_abort(); 1702 } 1703 /* Near the beginning of locore.s we set context zero. */ 1704 if (get_context() != 0) { 1705 mon_printf("pmap_bootstrap: not in context zero?\n"); 1706 sunmon_abort(); 1707 } 1708 #endif /* DIAGNOSTIC */ 1709 for (va = 0; va < (vaddr_t) (NBSG * NSEGMAP); va += NBSG) { 1710 /* Read the segmap entry from context zero... */ 1711 sme = get_segmap(va); 1712 /* ... then copy it into all other contexts. */ 1713 for (i = 1; i < NCONTEXT; i++) { 1714 (*rvec->setcxsegmap)(i, va, sme); 1715 } 1716 } 1717 1718 /* 1719 * Reserve a segment for the kernel to use to access a pmeg 1720 * that is not currently mapped into any context/segmap. 1721 * The kernel temporarily maps such a pmeg into this segment. 1722 * 1723 * XXX: Now that context zero is reserved as kernel-only, 1724 * we could borrow context zero for these temporary uses. 1725 */ 1726 temp_seg_va = virtual_avail; 1727 virtual_avail += NBSG; 1728 #ifdef DIAGNOSTIC 1729 if (temp_seg_va & SEGOFSET) { 1730 mon_printf("pmap_bootstrap: temp_seg_va\n"); 1731 sunmon_abort(); 1732 } 1733 #endif 1734 1735 /* Initialization for pmap_next_page() */ 1736 avail_next = avail_start; 1737 1738 uvmexp.pagesize = PAGE_SIZE; 1739 uvm_setpagesize(); 1740 1741 /* after setting up some structures */ 1742 1743 pmap_common_init(kernel_pmap); 1744 pmap_kernel_init(kernel_pmap); 1745 1746 context_init(); 1747 1748 pmeg_clean_free(); 1749 1750 pmap_page_upload(); 1751 } 1752 1753 /* 1754 * Give the kernel pmap a segmap, just so there are not 1755 * so many special cases required. Maybe faster too, 1756 * because this lets pmap_remove() and pmap_protect() 1757 * use a S/W copy of the segmap to avoid function calls. 1758 */ 1759 void 1760 pmap_kernel_init(pmap_t pmap) 1761 { 1762 vaddr_t va; 1763 int i, sme; 1764 1765 for (i=0, va=0; i < NSEGMAP; i++, va+=NBSG) { 1766 sme = get_segmap(va); 1767 kernel_segmap[i] = sme; 1768 } 1769 pmap->pm_segmap = kernel_segmap; 1770 } 1771 1772 1773 /**************************************************************** 1774 * PMAP interface functions. 1775 */ 1776 1777 /* 1778 * Support functions for vm_page_bootstrap(). 1779 */ 1780 1781 /* 1782 * How much virtual space does this kernel have? 1783 * (After mapping kernel text, data, etc.) 1784 */ 1785 void 1786 pmap_virtual_space(vaddr_t *v_start, vaddr_t *v_end) 1787 { 1788 *v_start = virtual_avail; 1789 *v_end = virtual_end; 1790 } 1791 1792 /* Provide memory to the VM system. */ 1793 static void 1794 pmap_page_upload(void) 1795 { 1796 int a, b, c, d; 1797 1798 if (hole_size) { 1799 /* 1800 * Supply the memory in two segments so the 1801 * reserved memory (3/50 video ram at 1MB) 1802 * can be carved from the front of the 2nd. 1803 */ 1804 a = atop(avail_start); 1805 b = atop(hole_start); 1806 uvm_page_physload(a, b, a, b, VM_FREELIST_DEFAULT); 1807 c = atop(hole_start + hole_size); 1808 d = atop(avail_end); 1809 uvm_page_physload(b, d, c, d, VM_FREELIST_DEFAULT); 1810 } else { 1811 a = atop(avail_start); 1812 d = atop(avail_end); 1813 uvm_page_physload(a, d, a, d, VM_FREELIST_DEFAULT); 1814 } 1815 } 1816 1817 /* 1818 * Initialize the pmap module. 1819 * Called by vm_init, to initialize any structures that the pmap 1820 * system needs to map virtual memory. 1821 */ 1822 void 1823 pmap_init(void) 1824 { 1825 pv_init(); 1826 1827 /* Initialize the pmap pool. */ 1828 pool_init(&pmap_pmap_pool, sizeof(struct pmap), 0, 0, 0, "pmappl", 1829 &pool_allocator_nointr, IPL_NONE); 1830 } 1831 1832 /* 1833 * Map a range of kernel virtual address space. 1834 * This might be used for device mappings, or to 1835 * record the mapping for kernel text/data/bss. 1836 * Return VA following the mapped range. 1837 */ 1838 vaddr_t 1839 pmap_map(vaddr_t va, paddr_t pa, paddr_t endpa, int prot) 1840 { 1841 int sz; 1842 1843 sz = endpa - pa; 1844 do { 1845 pmap_enter(kernel_pmap, va, pa, prot, 0); 1846 va += PAGE_SIZE; 1847 pa += PAGE_SIZE; 1848 sz -= PAGE_SIZE; 1849 } while (sz > 0); 1850 pmap_update(kernel_pmap); 1851 return(va); 1852 } 1853 1854 void 1855 pmap_user_init(pmap_t pmap) 1856 { 1857 int i; 1858 pmap->pm_segmap = malloc(sizeof(char)*NUSEG, M_VMPMAP, M_WAITOK); 1859 for (i = 0; i < NUSEG; i++) { 1860 pmap->pm_segmap[i] = SEGINV; 1861 } 1862 } 1863 1864 /* 1865 * Create and return a physical map. 1866 * 1867 * If the size specified for the map 1868 * is zero, the map is an actual physical 1869 * map, and may be referenced by the 1870 * hardware. 1871 * 1872 * If the size specified is non-zero, 1873 * the map will be used in software only, and 1874 * is bounded by that size. 1875 */ 1876 pmap_t 1877 pmap_create(void) 1878 { 1879 pmap_t pmap; 1880 1881 pmap = pool_get(&pmap_pmap_pool, PR_WAITOK); 1882 pmap_pinit(pmap); 1883 return pmap; 1884 } 1885 1886 /* 1887 * Release any resources held by the given physical map. 1888 * Called when a pmap initialized by pmap_pinit is being released. 1889 * Should only be called if the map contains no valid mappings. 1890 */ 1891 void 1892 pmap_release(struct pmap *pmap) 1893 { 1894 int s; 1895 1896 s = splvm(); 1897 1898 if (pmap == kernel_pmap) 1899 panic("pmap_release: kernel_pmap!"); 1900 1901 if (has_context(pmap)) { 1902 #ifdef PMAP_DEBUG 1903 if (pmap_debug & PMD_CONTEXT) 1904 printf("pmap_release(%p): free ctx %d\n", 1905 pmap, pmap->pm_ctxnum); 1906 #endif 1907 context_free(pmap); 1908 } 1909 free(pmap->pm_segmap, M_VMPMAP); 1910 pmap->pm_segmap = NULL; 1911 1912 splx(s); 1913 } 1914 1915 1916 /* 1917 * Retire the given physical map from service. 1918 * Should only be called if the map contains 1919 * no valid mappings. 1920 */ 1921 void 1922 pmap_destroy(pmap_t pmap) 1923 { 1924 int count; 1925 1926 #ifdef PMAP_DEBUG 1927 if (pmap_debug & PMD_CREATE) 1928 printf("pmap_destroy(%p)\n", pmap); 1929 #endif 1930 if (pmap == kernel_pmap) 1931 panic("pmap_destroy: kernel_pmap!"); 1932 pmap_lock(pmap); 1933 count = pmap_del_ref(pmap); 1934 pmap_unlock(pmap); 1935 if (count == 0) { 1936 pmap_release(pmap); 1937 pool_put(&pmap_pmap_pool, pmap); 1938 } 1939 } 1940 1941 /* 1942 * Add a reference to the specified pmap. 1943 */ 1944 void 1945 pmap_reference(pmap_t pmap) 1946 { 1947 pmap_lock(pmap); 1948 pmap_add_ref(pmap); 1949 pmap_unlock(pmap); 1950 } 1951 1952 1953 /* 1954 * Insert the given physical page (p) at 1955 * the specified virtual address (v) in the 1956 * target physical map with the protection requested. 1957 * 1958 * The physical address is page aligned, but may have some 1959 * low bits set indicating an OBIO or VME bus page, or just 1960 * that the non-cache bit should be set (i.e PMAP_NC). 1961 * 1962 * If specified, the page will be wired down, meaning 1963 * that the related pte can not be reclaimed. 1964 * 1965 * NB: This is the only routine which MAY NOT lazy-evaluate 1966 * or lose information. That is, this routine must actually 1967 * insert this page into the given map NOW. 1968 */ 1969 int 1970 pmap_enter(pmap_t pmap, vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags) 1971 { 1972 int new_pte, s; 1973 bool wired = (flags & PMAP_WIRED) != 0; 1974 1975 #ifdef PMAP_DEBUG 1976 if ((pmap_debug & PMD_ENTER) || 1977 (va == pmap_db_watchva)) 1978 printf("pmap_enter(%p, 0x%lx, 0x%lx, 0x%x, 0x%x)\n", 1979 pmap, va, pa, prot, wired); 1980 #endif 1981 1982 /* Get page-type bits from low part of the PA... */ 1983 new_pte = (pa & PMAP_SPEC) << PG_MOD_SHIFT; 1984 1985 /* ...now the valid and writable bits... */ 1986 new_pte |= PG_VALID; 1987 if (prot & VM_PROT_WRITE) 1988 new_pte |= PG_WRITE; 1989 if (flags & VM_PROT_ALL) { 1990 new_pte |= PG_REF; 1991 if (flags & VM_PROT_WRITE) { 1992 new_pte |= PG_MOD; 1993 } 1994 } 1995 1996 /* ...and finally the page-frame number. */ 1997 new_pte |= PA_PGNUM(pa); 1998 1999 /* 2000 * treatment varies significantly: 2001 * kernel ptes are in all contexts, and are always in the mmu 2002 * user ptes may not necessarily? be in the mmu. pmap may not 2003 * be in the mmu either. 2004 * 2005 */ 2006 s = splvm(); 2007 if (pmap == kernel_pmap) { 2008 new_pte |= PG_SYSTEM; 2009 pmap_enter_kernel(va, new_pte, wired); 2010 } else { 2011 pmap_enter_user(pmap, va, new_pte, wired); 2012 } 2013 splx(s); 2014 return 0; 2015 } 2016 2017 static void 2018 pmap_enter_kernel(vaddr_t pgva, int new_pte, bool wired) 2019 { 2020 pmap_t pmap = kernel_pmap; 2021 pmeg_t pmegp; 2022 int do_pv, old_pte, sme; 2023 vaddr_t segva; 2024 2025 /* 2026 keep in hardware only, since its mapped into all contexts anyway; 2027 need to handle possibly allocating additional pmegs 2028 need to make sure they cant be stolen from the kernel; 2029 map any new pmegs into all contexts, make sure rest of pmeg is null; 2030 deal with pv_stuff; possibly caching problems; 2031 must also deal with changes too. 2032 */ 2033 2034 /* 2035 * In detail: 2036 * 2037 * (a) lock pmap 2038 * (b) Is the VA in a already mapped segment, if so 2039 * look to see if that VA address is "valid". If it is, then 2040 * action is a change to an existing pte 2041 * (c) if not mapped segment, need to allocate pmeg 2042 * (d) if adding pte entry or changing physaddr of existing one, 2043 * use pv_stuff, for change, pmap_remove() possibly. 2044 * (e) change/add pte 2045 */ 2046 2047 #ifdef DIAGNOSTIC 2048 if ((pgva < virtual_avail) || (pgva >= DVMA_MAP_END)) 2049 panic("pmap_enter_kernel: bad va=0x%lx", pgva); 2050 if ((new_pte & (PG_VALID | PG_SYSTEM)) != (PG_VALID | PG_SYSTEM)) 2051 panic("pmap_enter_kernel: bad pte"); 2052 #endif 2053 2054 if (pgva >= DVMA_MAP_BASE) { 2055 /* This is DVMA space. Always want it non-cached. */ 2056 new_pte |= PG_NC; 2057 } 2058 2059 segva = sun3_trunc_seg(pgva); 2060 do_pv = true; 2061 2062 /* Do we have a PMEG? */ 2063 sme = get_segmap(segva); 2064 if (sme != SEGINV) { 2065 /* Found a PMEG in the segmap. Cool. */ 2066 pmegp = pmeg_p(sme); 2067 #ifdef DIAGNOSTIC 2068 /* Make sure it is the right PMEG. */ 2069 if (sme != pmap->pm_segmap[VA_SEGNUM(segva)]) 2070 panic("pmap_enter_kernel: wrong sme at VA=0x%lx", 2071 segva); 2072 /* Make sure it is ours. */ 2073 if (pmegp->pmeg_owner != pmap) 2074 panic("pmap_enter_kernel: MMU has bad pmeg 0x%x", sme); 2075 #endif 2076 } else { 2077 /* No PMEG in the segmap. Have to allocate one. */ 2078 pmegp = pmeg_allocate(pmap, segva); 2079 sme = pmegp->pmeg_index; 2080 pmap->pm_segmap[VA_SEGNUM(segva)] = sme; 2081 set_segmap_allctx(segva, sme); 2082 #ifdef PMAP_DEBUG 2083 pmeg_verify_empty(segva); 2084 if (pmap_debug & PMD_SEGMAP) { 2085 printf("pmap: set_segmap pmap=%p va=0x%lx sme=0x%x " 2086 "(ek)\n", pmap, segva, sme); 2087 } 2088 #endif 2089 /* There are no existing mappings to deal with. */ 2090 old_pte = 0; 2091 goto add_pte; 2092 } 2093 2094 /* 2095 * We have a PMEG. Is the VA already mapped to somewhere? 2096 * (a) if so, is it same pa? (really a protection change) 2097 * (b) if not same pa, then we have to unlink from old pa 2098 */ 2099 old_pte = get_pte(pgva); 2100 if ((old_pte & PG_VALID) == 0) 2101 goto add_pte; 2102 2103 /* Have valid translation. Flush cache before changing it. */ 2104 #ifdef HAVECACHE 2105 if (cache_size) { 2106 cache_flush_page(pgva); 2107 /* Get fresh mod/ref bits from write-back. */ 2108 old_pte = get_pte(pgva); 2109 } 2110 #endif 2111 2112 /* XXX - removing valid page here, way lame... -glass */ 2113 pmegp->pmeg_vpages--; 2114 2115 if (!IS_MAIN_MEM(old_pte)) { 2116 /* Was not main memory, so no pv_entry for it. */ 2117 goto add_pte; 2118 } 2119 2120 /* Old mapping was main memory. Save mod/ref bits. */ 2121 save_modref_bits(old_pte); 2122 2123 /* 2124 * If not changing the type or pfnum then re-use pv_entry. 2125 * Note we get here only with old_pte having PGT_OBMEM. 2126 */ 2127 if ((old_pte & (PG_TYPE|PG_FRAME)) == (new_pte & (PG_TYPE|PG_FRAME))) { 2128 do_pv = false; /* re-use pv_entry */ 2129 new_pte |= (old_pte & PG_NC); 2130 goto add_pte; 2131 } 2132 2133 /* OK, different type or PA, have to kill old pv_entry. */ 2134 pv_unlink(pmap, old_pte, pgva); 2135 2136 add_pte: /* can be destructive */ 2137 pmeg_set_wiring(pmegp, pgva, wired); 2138 2139 /* Anything but MAIN_MEM is mapped non-cached. */ 2140 if (!IS_MAIN_MEM(new_pte)) { 2141 new_pte |= PG_NC; 2142 do_pv = false; 2143 } 2144 if (do_pv == true) { 2145 if (pv_link(pmap, new_pte, pgva) & PV_NC) 2146 new_pte |= PG_NC; 2147 } 2148 #ifdef PMAP_DEBUG 2149 if ((pmap_debug & PMD_SETPTE) || (pgva == pmap_db_watchva)) { 2150 printf("pmap: set_pte pmap=%p va=0x%lx old=0x%x new=0x%x " 2151 "(ek)\n", pmap, pgva, old_pte, new_pte); 2152 } 2153 #endif 2154 /* cache flush done above */ 2155 set_pte(pgva, new_pte); 2156 pmegp->pmeg_vpages++; 2157 } 2158 2159 2160 static void 2161 pmap_enter_user(pmap_t pmap, vaddr_t pgva, int new_pte, bool wired) 2162 { 2163 int do_pv, old_pte, sme; 2164 vaddr_t segva; 2165 pmeg_t pmegp; 2166 2167 #ifdef DIAGNOSTIC 2168 if (pgva >= VM_MAXUSER_ADDRESS) 2169 panic("pmap_enter_user: bad va=0x%lx", pgva); 2170 if ((new_pte & (PG_VALID | PG_SYSTEM)) != PG_VALID) 2171 panic("pmap_enter_user: bad pte"); 2172 #endif 2173 #ifdef PMAP_DEBUG 2174 /* 2175 * Some user pages are wired here, and a later 2176 * call to pmap_unwire() will unwire them. 2177 * XXX - Need a separate list for wired user pmegs 2178 * so they can not be stolen from the active list. 2179 * XXX - Note: vm_fault.c assumes pmap_extract will 2180 * work on wired mappings, so must preserve them... 2181 * XXX: Maybe keep a list of wired PMEGs? 2182 */ 2183 if (wired && (pmap_debug & PMD_WIRING)) { 2184 db_printf("pmap_enter_user: attempt to wire user page, " 2185 "ignored\n"); 2186 Debugger(); 2187 } 2188 #endif 2189 2190 /* Validate this assumption. */ 2191 if (pmap != current_pmap()) { 2192 #ifdef PMAP_DEBUG 2193 /* Aparently, this never happens. */ 2194 db_printf("pmap_enter_user: not curlwp\n"); 2195 Debugger(); 2196 #endif 2197 /* Just throw it out (fault it in later). */ 2198 /* XXX: But must remember it if wired... */ 2199 return; 2200 } 2201 2202 segva = sun3_trunc_seg(pgva); 2203 do_pv = true; 2204 2205 /* 2206 * If this pmap was sharing the "empty" context, 2207 * allocate a real context for its exclusive use. 2208 */ 2209 if (!has_context(pmap)) { 2210 context_allocate(pmap); 2211 #ifdef PMAP_DEBUG 2212 if (pmap_debug & PMD_CONTEXT) 2213 printf("pmap_enter(%p) got context %d\n", 2214 pmap, pmap->pm_ctxnum); 2215 #endif 2216 set_context(pmap->pm_ctxnum); 2217 } else { 2218 #ifdef PMAP_DEBUG 2219 /* Make sure context is correct. */ 2220 if (pmap->pm_ctxnum != get_context()) { 2221 db_printf("pmap_enter_user: wrong context\n"); 2222 Debugger(); 2223 /* XXX: OK to proceed? */ 2224 set_context(pmap->pm_ctxnum); 2225 } 2226 #endif 2227 } 2228 2229 /* 2230 * We have a context. Do we have a PMEG? 2231 */ 2232 sme = get_segmap(segva); 2233 if (sme != SEGINV) { 2234 /* Found a PMEG in the segmap. Cool. */ 2235 pmegp = pmeg_p(sme); 2236 #ifdef DIAGNOSTIC 2237 /* Make sure it is the right PMEG. */ 2238 if (sme != pmap->pm_segmap[VA_SEGNUM(segva)]) 2239 panic("pmap_enter_user: wrong sme at VA=0x%lx", segva); 2240 /* Make sure it is ours. */ 2241 if (pmegp->pmeg_owner != pmap) 2242 panic("pmap_enter_user: MMU has bad pmeg 0x%x", sme); 2243 #endif 2244 } else { 2245 /* Not in the segmap. Try the S/W cache. */ 2246 pmegp = pmeg_cache(pmap, segva); 2247 if (pmegp) { 2248 /* Found PMEG in cache. Just reload it. */ 2249 sme = pmegp->pmeg_index; 2250 set_segmap(segva, sme); 2251 } else { 2252 /* PMEG not in cache, so allocate one. */ 2253 pmegp = pmeg_allocate(pmap, segva); 2254 sme = pmegp->pmeg_index; 2255 pmap->pm_segmap[VA_SEGNUM(segva)] = sme; 2256 set_segmap(segva, sme); 2257 #ifdef PMAP_DEBUG 2258 pmeg_verify_empty(segva); 2259 #endif 2260 } 2261 #ifdef PMAP_DEBUG 2262 if (pmap_debug & PMD_SEGMAP) { 2263 printf("pmap: set_segmap pmap=%p va=0x%lx sme=0x%x " 2264 "(eu)\n", pmap, segva, sme); 2265 } 2266 #endif 2267 } 2268 2269 /* 2270 * We have a PMEG. Is the VA already mapped to somewhere? 2271 * (a) if so, is it same pa? (really a protection change) 2272 * (b) if not same pa, then we have to unlink from old pa 2273 */ 2274 old_pte = get_pte(pgva); 2275 if ((old_pte & PG_VALID) == 0) 2276 goto add_pte; 2277 2278 /* Have valid translation. Flush cache before changing it. */ 2279 #ifdef HAVECACHE 2280 if (cache_size) { 2281 cache_flush_page(pgva); 2282 /* Get fresh mod/ref bits from write-back. */ 2283 old_pte = get_pte(pgva); 2284 } 2285 #endif 2286 2287 /* XXX - removing valid page here, way lame... -glass */ 2288 pmegp->pmeg_vpages--; 2289 2290 if (!IS_MAIN_MEM(old_pte)) { 2291 /* Was not main memory, so no pv_entry for it. */ 2292 goto add_pte; 2293 } 2294 2295 /* Old mapping was main memory. Save mod/ref bits. */ 2296 save_modref_bits(old_pte); 2297 2298 /* 2299 * If not changing the type or pfnum then re-use pv_entry. 2300 * Note we get here only with old_pte having PGT_OBMEM. 2301 */ 2302 if ((old_pte & (PG_TYPE|PG_FRAME)) == (new_pte & (PG_TYPE|PG_FRAME))) { 2303 do_pv = false; /* re-use pv_entry */ 2304 new_pte |= (old_pte & PG_NC); 2305 goto add_pte; 2306 } 2307 2308 /* OK, different type or PA, have to kill old pv_entry. */ 2309 pv_unlink(pmap, old_pte, pgva); 2310 2311 add_pte: 2312 /* XXX - Wiring changes on user pmaps? */ 2313 /* pmeg_set_wiring(pmegp, pgva, wired); */ 2314 2315 /* Anything but MAIN_MEM is mapped non-cached. */ 2316 if (!IS_MAIN_MEM(new_pte)) { 2317 new_pte |= PG_NC; 2318 do_pv = false; 2319 } 2320 if (do_pv == true) { 2321 if (pv_link(pmap, new_pte, pgva) & PV_NC) 2322 new_pte |= PG_NC; 2323 } 2324 #ifdef PMAP_DEBUG 2325 if ((pmap_debug & PMD_SETPTE) || (pgva == pmap_db_watchva)) { 2326 printf("pmap: set_pte pmap=%p va=0x%lx old=0x%x new=0x%x " 2327 "(eu)\n", pmap, pgva, old_pte, new_pte); 2328 } 2329 #endif 2330 /* cache flush done above */ 2331 set_pte(pgva, new_pte); 2332 pmegp->pmeg_vpages++; 2333 } 2334 2335 void 2336 pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags) 2337 { 2338 int new_pte, s; 2339 pmap_t pmap = kernel_pmap; 2340 pmeg_t pmegp; 2341 int sme; 2342 vaddr_t segva; 2343 2344 #ifdef PMAP_DEBUG 2345 if ((pmap_debug & PMD_ENTER) || 2346 (va == pmap_db_watchva)) 2347 printf("pmap_kenter_pa(0x%lx, 0x%lx, 0x%x)\n", 2348 va, pa, prot); 2349 #endif 2350 2351 /* Get page-type bits from low part of the PA... */ 2352 new_pte = (pa & PMAP_SPEC) << PG_MOD_SHIFT; 2353 2354 /* ...now the valid and writable bits... */ 2355 new_pte |= PG_SYSTEM|PG_VALID; 2356 if (prot & VM_PROT_WRITE) 2357 new_pte |= PG_WRITE; 2358 2359 /* ...and finally the page-frame number. */ 2360 new_pte |= PA_PGNUM(pa); 2361 2362 /* 2363 * keep in hardware only, since its mapped into all contexts anyway; 2364 * need to handle possibly allocating additional pmegs 2365 * need to make sure they cant be stolen from the kernel; 2366 * map any new pmegs into all contexts, make sure rest of pmeg is null; 2367 * must also deal with changes too. 2368 */ 2369 2370 /* 2371 * In detail: 2372 * 2373 * (a) lock pmap 2374 * (b) Is the VA in a already mapped segment, if so 2375 * look to see if that VA address is "valid". If it is, then 2376 * action is a change to an existing pte 2377 * (c) if not mapped segment, need to allocate pmeg 2378 * (d) change/add pte 2379 */ 2380 2381 #ifdef DIAGNOSTIC 2382 if ((va < virtual_avail) || (va >= DVMA_MAP_END)) 2383 panic("pmap_kenter_pa: bad va=0x%lx", va); 2384 #endif 2385 2386 if (va >= DVMA_MAP_BASE) { 2387 /* This is DVMA space. Always want it non-cached. */ 2388 new_pte |= PG_NC; 2389 } 2390 2391 segva = sun3_trunc_seg(va); 2392 2393 s = splvm(); 2394 2395 /* Do we have a PMEG? */ 2396 sme = get_segmap(segva); 2397 if (sme != SEGINV) { 2398 KASSERT((get_pte(va) & PG_VALID) == 0); 2399 2400 /* Found a PMEG in the segmap. Cool. */ 2401 pmegp = pmeg_p(sme); 2402 #ifdef DIAGNOSTIC 2403 /* Make sure it is the right PMEG. */ 2404 if (sme != pmap->pm_segmap[VA_SEGNUM(segva)]) 2405 panic("pmap_kenter_pa: wrong sme at VA=0x%lx", segva); 2406 /* Make sure it is ours. */ 2407 if (pmegp->pmeg_owner != pmap) 2408 panic("pmap_kenter_pa: MMU has bad pmeg 0x%x", sme); 2409 #endif 2410 } else { 2411 2412 /* No PMEG in the segmap. Have to allocate one. */ 2413 pmegp = pmeg_allocate(pmap, segva); 2414 sme = pmegp->pmeg_index; 2415 pmap->pm_segmap[VA_SEGNUM(segva)] = sme; 2416 set_segmap_allctx(segva, sme); 2417 #ifdef PMAP_DEBUG 2418 pmeg_verify_empty(segva); 2419 if (pmap_debug & PMD_SEGMAP) { 2420 printf("pmap: set_segmap pmap=%p va=0x%lx sme=0x%x " 2421 "(ek)\n", pmap, segva, sme); 2422 } 2423 #endif 2424 } 2425 2426 pmeg_set_wiring(pmegp, va, true); 2427 2428 /* Anything but MAIN_MEM is mapped non-cached. */ 2429 if (!IS_MAIN_MEM(new_pte)) { 2430 new_pte |= PG_NC; 2431 } 2432 #ifdef PMAP_DEBUG 2433 if ((pmap_debug & PMD_SETPTE) || (va == pmap_db_watchva)) { 2434 printf("pmap: set_pte pmap=%p va=0x%lx new=0x%x " 2435 "(ek)\n", pmap, va, new_pte); 2436 } 2437 #endif 2438 /* cache flush done above */ 2439 set_pte(va, new_pte); 2440 pmegp->pmeg_vpages++; 2441 splx(s); 2442 } 2443 2444 void 2445 pmap_kremove(vaddr_t va, vsize_t len) 2446 { 2447 pmap_t pmap = kernel_pmap; 2448 vaddr_t eva, neva, pgva, segva, segnum; 2449 int pte, sme; 2450 pmeg_t pmegp; 2451 #ifdef HAVECACHE 2452 int flush_by_page = 0; 2453 #endif 2454 int s; 2455 2456 s = splvm(); 2457 segnum = VA_SEGNUM(va); 2458 for (eva = va + len; va < eva; va = neva, segnum++) { 2459 neva = sun3_trunc_seg(va) + NBSG; 2460 if (neva > eva) { 2461 neva = eva; 2462 } 2463 if (pmap->pm_segmap[segnum] == SEGINV) { 2464 continue; 2465 } 2466 2467 segva = sun3_trunc_seg(va); 2468 sme = get_segmap(segva); 2469 pmegp = pmeg_p(sme); 2470 2471 #ifdef HAVECACHE 2472 if (cache_size) { 2473 2474 /* 2475 * If the range to be removed is larger than the cache, 2476 * it will be cheaper to flush this segment entirely. 2477 */ 2478 2479 if (cache_size < (eva - va)) { 2480 /* cheaper to flush whole segment */ 2481 cache_flush_segment(segva); 2482 } else { 2483 flush_by_page = 1; 2484 } 2485 } 2486 #endif 2487 2488 /* Invalidate the PTEs in the given range. */ 2489 for (pgva = va; pgva < neva; pgva += PAGE_SIZE) { 2490 pte = get_pte(pgva); 2491 if (pte & PG_VALID) { 2492 #ifdef HAVECACHE 2493 if (flush_by_page) { 2494 cache_flush_page(pgva); 2495 /* Get fresh mod/ref bits 2496 from write-back. */ 2497 pte = get_pte(pgva); 2498 } 2499 #endif 2500 #ifdef PMAP_DEBUG 2501 if ((pmap_debug & PMD_SETPTE) || 2502 (pgva == pmap_db_watchva)) { 2503 printf("pmap: set_pte pmap=%p va=0x%lx" 2504 " old=0x%x new=0x%x (rrmmu)\n", 2505 pmap, pgva, pte, PG_INVAL); 2506 } 2507 #endif 2508 set_pte(pgva, PG_INVAL); 2509 KASSERT(pmegp->pmeg_vpages > 0); 2510 pmegp->pmeg_vpages--; 2511 } 2512 } 2513 KASSERT(pmegp->pmeg_vpages >= 0); 2514 if (pmegp->pmeg_vpages == 0) { 2515 /* We are done with this pmeg. */ 2516 #ifdef PMAP_DEBUG 2517 if (is_pmeg_wired(pmegp)) { 2518 if (pmap_debug & PMD_WIRING) { 2519 db_printf("pmap: removing wired " 2520 "pmeg: %p\n", pmegp); 2521 Debugger(); 2522 } 2523 } 2524 if (pmap_debug & PMD_SEGMAP) { 2525 printf("pmap: set_segmap ctx=%d v=0x%lx " 2526 "old=0x%x new=ff (rm)\n", 2527 pmap->pm_ctxnum, segva, 2528 pmegp->pmeg_index); 2529 } 2530 pmeg_verify_empty(segva); 2531 #endif 2532 2533 /* Remove it from the MMU. */ 2534 set_segmap_allctx(segva, SEGINV); 2535 pmap->pm_segmap[VA_SEGNUM(segva)] = SEGINV; 2536 2537 /* Now, put it on the free list. */ 2538 pmeg_free(pmegp); 2539 } 2540 } 2541 splx(s); 2542 } 2543 2544 2545 /* 2546 * The trap handler calls this so we can try to resolve 2547 * user-level faults by reloading a PMEG. 2548 * If that does not prodce a valid mapping, 2549 * call vm_fault as usual. 2550 * 2551 * XXX: Merge this with the next function? 2552 */ 2553 int 2554 _pmap_fault(struct vm_map *map, vaddr_t va, vm_prot_t ftype) 2555 { 2556 pmap_t pmap; 2557 int rv; 2558 2559 pmap = vm_map_pmap(map); 2560 if (map == kernel_map) { 2561 /* Do not allow faults below the "managed" space. */ 2562 if (va < virtual_avail) { 2563 /* 2564 * Most pages below virtual_avail are read-only, 2565 * so I will assume it is a protection failure. 2566 */ 2567 return EACCES; 2568 } 2569 } else { 2570 /* User map. Try reload shortcut. */ 2571 if (pmap_fault_reload(pmap, va, ftype)) 2572 return 0; 2573 } 2574 rv = uvm_fault(map, va, ftype); 2575 2576 #ifdef PMAP_DEBUG 2577 if (pmap_debug & PMD_FAULT) { 2578 printf("pmap_fault(%p, 0x%lx, 0x%x) -> 0x%x\n", 2579 map, va, ftype, rv); 2580 } 2581 #endif 2582 2583 return (rv); 2584 } 2585 2586 /* 2587 * This is a shortcut used by the trap handler to 2588 * reload PMEGs into a user segmap without calling 2589 * the actual VM fault handler. Returns true if: 2590 * the PMEG was reloaded, and 2591 * it has a valid PTE at va. 2592 * Otherwise return zero and let VM code handle it. 2593 */ 2594 int 2595 pmap_fault_reload(pmap_t pmap, vaddr_t pgva, vm_prot_t ftype) 2596 { 2597 int rv, s, pte, chkpte, sme; 2598 vaddr_t segva; 2599 pmeg_t pmegp; 2600 2601 if (pgva >= VM_MAXUSER_ADDRESS) 2602 return (0); 2603 if (pmap->pm_segmap == NULL) { 2604 #ifdef PMAP_DEBUG 2605 db_printf("pmap_fault_reload: null segmap\n"); 2606 Debugger(); 2607 #endif 2608 return (0); 2609 } 2610 2611 /* Short-cut using the S/W segmap. */ 2612 if (pmap->pm_segmap[VA_SEGNUM(pgva)] == SEGINV) 2613 return (0); 2614 2615 segva = sun3_trunc_seg(pgva); 2616 chkpte = PG_VALID; 2617 if (ftype & VM_PROT_WRITE) 2618 chkpte |= PG_WRITE; 2619 rv = 0; 2620 2621 s = splvm(); 2622 2623 /* 2624 * Given that we faulted on a user-space address, we will 2625 * probably need a context. Get a context now so we can 2626 * try to resolve the fault with a segmap reload. 2627 */ 2628 if (!has_context(pmap)) { 2629 context_allocate(pmap); 2630 #ifdef PMAP_DEBUG 2631 if (pmap_debug & PMD_CONTEXT) 2632 printf("pmap_fault(%p) got context %d\n", 2633 pmap, pmap->pm_ctxnum); 2634 #endif 2635 set_context(pmap->pm_ctxnum); 2636 } else { 2637 #ifdef PMAP_DEBUG 2638 /* Make sure context is correct. */ 2639 if (pmap->pm_ctxnum != get_context()) { 2640 db_printf("pmap_fault_reload: wrong context\n"); 2641 Debugger(); 2642 /* XXX: OK to proceed? */ 2643 set_context(pmap->pm_ctxnum); 2644 } 2645 #endif 2646 } 2647 2648 sme = get_segmap(segva); 2649 if (sme == SEGINV) { 2650 /* See if there is something to reload. */ 2651 pmegp = pmeg_cache(pmap, segva); 2652 if (pmegp) { 2653 /* Found one! OK, reload it. */ 2654 pmap_stats.ps_pmeg_faultin++; 2655 sme = pmegp->pmeg_index; 2656 set_segmap(segva, sme); 2657 pte = get_pte(pgva); 2658 if (pte & chkpte) 2659 rv = 1; 2660 } 2661 } 2662 2663 splx(s); 2664 return (rv); 2665 } 2666 2667 2668 /* 2669 * Clear the modify bit for the given physical page. 2670 */ 2671 bool 2672 pmap_clear_modify(struct vm_page *pg) 2673 { 2674 paddr_t pa = VM_PAGE_TO_PHYS(pg); 2675 pv_entry_t *head; 2676 u_char *pv_flags; 2677 int s; 2678 bool rv; 2679 2680 pv_flags = pa_to_pvflags(pa); 2681 head = pa_to_pvhead(pa); 2682 2683 s = splvm(); 2684 *pv_flags |= pv_syncflags(*head); 2685 rv = *pv_flags & PV_MOD; 2686 *pv_flags &= ~PV_MOD; 2687 splx(s); 2688 return rv; 2689 } 2690 2691 /* 2692 * Tell whether the given physical page has been modified. 2693 */ 2694 bool 2695 pmap_is_modified(struct vm_page *pg) 2696 { 2697 paddr_t pa = VM_PAGE_TO_PHYS(pg); 2698 pv_entry_t *head; 2699 u_char *pv_flags; 2700 int s; 2701 bool rv; 2702 2703 pv_flags = pa_to_pvflags(pa); 2704 head = pa_to_pvhead(pa); 2705 2706 s = splvm(); 2707 if ((*pv_flags & PV_MOD) == 0) 2708 *pv_flags |= pv_syncflags(*head); 2709 rv = (*pv_flags & PV_MOD); 2710 splx(s); 2711 return (rv); 2712 } 2713 2714 /* 2715 * Clear the reference bit for the given physical page. 2716 * It's OK to just remove mappings if that's easier. 2717 */ 2718 bool 2719 pmap_clear_reference(struct vm_page *pg) 2720 { 2721 paddr_t pa = VM_PAGE_TO_PHYS(pg); 2722 pv_entry_t *head; 2723 u_char *pv_flags; 2724 int s; 2725 bool rv; 2726 2727 pv_flags = pa_to_pvflags(pa); 2728 head = pa_to_pvhead(pa); 2729 2730 s = splvm(); 2731 *pv_flags |= pv_syncflags(*head); 2732 rv = *pv_flags & PV_REF; 2733 *pv_flags &= ~PV_REF; 2734 splx(s); 2735 return rv; 2736 } 2737 2738 /* 2739 * Tell whether the given physical page has been referenced. 2740 * It's OK to just return false if page is not mapped. 2741 */ 2742 bool 2743 pmap_is_referenced(struct vm_page *pg) 2744 { 2745 paddr_t pa = VM_PAGE_TO_PHYS(pg); 2746 pv_entry_t *head; 2747 u_char *pv_flags; 2748 int s; 2749 bool rv; 2750 2751 pv_flags = pa_to_pvflags(pa); 2752 head = pa_to_pvhead(pa); 2753 2754 s = splvm(); 2755 if ((*pv_flags & PV_REF) == 0) 2756 *pv_flags |= pv_syncflags(*head); 2757 rv = (*pv_flags & PV_REF); 2758 splx(s); 2759 return (rv); 2760 } 2761 2762 2763 /* 2764 * This is called by locore.s:cpu_switch() when it is 2765 * switching to a new process. Load new translations. 2766 * Note: done in-line by locore.s unless PMAP_DEBUG 2767 * 2768 * Note that we do NOT allocate a context here, but 2769 * share the "kernel only" context until we really 2770 * need our own context for user-space mappings in 2771 * pmap_enter_user(). 2772 */ 2773 void 2774 _pmap_switch(pmap_t pmap) 2775 { 2776 set_context(pmap->pm_ctxnum); 2777 ICIA(); 2778 } 2779 2780 /* 2781 * Exported version of pmap_activate(). This is called from the 2782 * machine-independent VM code when a process is given a new pmap. 2783 * If (p == curlwp) do like cpu_switch would do; otherwise just 2784 * take this as notification that the process has a new pmap. 2785 */ 2786 void 2787 pmap_activate(struct lwp *l) 2788 { 2789 pmap_t pmap = l->l_proc->p_vmspace->vm_map.pmap; 2790 2791 if (l->l_proc == curproc) { 2792 _pmap_switch(pmap); 2793 } 2794 } 2795 2796 /* 2797 * Deactivate the address space of the specified process. 2798 */ 2799 void 2800 pmap_deactivate(struct lwp *l) 2801 { 2802 /* Nothing to do. */ 2803 } 2804 2805 /* 2806 * Routine: pmap_unwire 2807 * Function: Clear the wired attribute for a map/virtual-address 2808 * pair. 2809 * In/out conditions: 2810 * The mapping must already exist in the pmap. 2811 */ 2812 void 2813 pmap_unwire(pmap_t pmap, vaddr_t va) 2814 { 2815 int s, sme; 2816 int wiremask, ptenum; 2817 pmeg_t pmegp; 2818 2819 #ifdef PMAP_DEBUG 2820 if (pmap_debug & PMD_WIRING) 2821 printf("pmap_unwire(pmap=%p, va=0x%lx)\n", 2822 pmap, va); 2823 #endif 2824 /* 2825 * We are asked to unwire pages that were wired when 2826 * pmap_enter() was called and we ignored wiring. 2827 * (VM code appears to wire a stack page during fork.) 2828 */ 2829 if (pmap != kernel_pmap) { 2830 #ifdef PMAP_DEBUG 2831 if (pmap_debug & PMD_WIRING) { 2832 db_printf(" (user pmap -- ignored)\n"); 2833 Debugger(); 2834 } 2835 #endif 2836 return; 2837 } 2838 2839 ptenum = VA_PTE_NUM(va); 2840 wiremask = 1 << ptenum; 2841 2842 s = splvm(); 2843 sme = get_segmap(va); 2844 pmegp = pmeg_p(sme); 2845 pmegp->pmeg_wired &= ~wiremask; 2846 splx(s); 2847 } 2848 2849 /* 2850 * Copy the range specified by src_addr/len 2851 * from the source map to the range dst_addr/len 2852 * in the destination map. 2853 * 2854 * This routine is only advisory and need not do anything. 2855 */ 2856 void 2857 pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vaddr_t dst_addr, vsize_t len, 2858 vaddr_t src_addr) 2859 { 2860 } 2861 2862 /* 2863 * Routine: pmap_extract 2864 * Function: 2865 * Extract the physical page address associated 2866 * with the given map/virtual_address pair. 2867 * Returns zero if VA not valid. 2868 */ 2869 bool 2870 pmap_extract(pmap_t pmap, vaddr_t va, paddr_t *pap) 2871 { 2872 int s, sme, segnum, ptenum, pte; 2873 paddr_t pa; 2874 2875 pte = 0; 2876 s = splvm(); 2877 if (pmap == kernel_pmap) { 2878 sme = get_segmap(va); 2879 if (sme != SEGINV) 2880 pte = get_pte(va); 2881 } else { 2882 /* This is rare, so do it the easy way. */ 2883 segnum = VA_SEGNUM(va); 2884 sme = pmap->pm_segmap[segnum]; 2885 if (sme != SEGINV) { 2886 ptenum = VA_PTE_NUM(va); 2887 pte = get_pte_pmeg(sme, ptenum); 2888 } 2889 } 2890 splx(s); 2891 2892 if ((pte & PG_VALID) == 0) { 2893 #ifdef PMAP_DEBUG 2894 db_printf("pmap_extract: invalid va=0x%lx\n", va); 2895 Debugger(); 2896 #endif 2897 return (false); 2898 } 2899 pa = PG_PA(pte); 2900 #ifdef DIAGNOSTIC 2901 if (pte & PG_TYPE) { 2902 panic("pmap_extract: not main mem, va=0x%lx", va); 2903 } 2904 #endif 2905 if (pap != NULL) 2906 *pap = pa; 2907 return (true); 2908 } 2909 2910 2911 /* 2912 * pmap_page_protect: 2913 * 2914 * Lower the permission for all mappings to a given page. 2915 */ 2916 void 2917 pmap_page_protect(struct vm_page *pg, vm_prot_t prot) 2918 { 2919 paddr_t pa = VM_PAGE_TO_PHYS(pg); 2920 int s; 2921 2922 s = splvm(); 2923 #ifdef PMAP_DEBUG 2924 if (pmap_debug & PMD_PROTECT) 2925 printf("pmap_page_protect(0x%lx, 0x%x)\n", pa, prot); 2926 #endif 2927 switch (prot) { 2928 case VM_PROT_ALL: 2929 break; 2930 case VM_PROT_READ: 2931 case VM_PROT_READ|VM_PROT_EXECUTE: 2932 pv_changepte(pa, 0, PG_WRITE); 2933 break; 2934 default: 2935 /* remove mapping for all pmaps that have it */ 2936 pv_remove_all(pa); 2937 break; 2938 } 2939 splx(s); 2940 } 2941 2942 /* 2943 * Initialize a preallocated and zeroed pmap structure, 2944 * such as one in a vmspace structure. 2945 */ 2946 void 2947 pmap_pinit(pmap_t pmap) 2948 { 2949 pmap_common_init(pmap); 2950 pmap_user_init(pmap); 2951 } 2952 2953 /* 2954 * Reduce the permissions on the specified 2955 * range of this map as requested. 2956 * (Make pages read-only.) 2957 */ 2958 void 2959 pmap_protect(pmap_t pmap, vaddr_t sva, vaddr_t eva, vm_prot_t prot) 2960 { 2961 vaddr_t va, neva; 2962 int segnum; 2963 2964 /* If leaving writable, nothing to do. */ 2965 if (prot & VM_PROT_WRITE) 2966 return; 2967 2968 /* If removing all permissions, just unmap. */ 2969 if ((prot & VM_PROT_READ) == 0) { 2970 pmap_remove(pmap, sva, eva); 2971 return; 2972 } 2973 2974 #ifdef PMAP_DEBUG 2975 if ((pmap_debug & PMD_PROTECT) || 2976 ((sva <= pmap_db_watchva && eva > pmap_db_watchva))) 2977 printf("pmap_protect(%p, 0x%lx, 0x%lx)\n", pmap, sva, eva); 2978 #endif 2979 2980 KASSERT((pmap == kernel_pmap) ? 2981 sva >= virtual_avail && eva < DVMA_MAP_END : 2982 eva <= VM_MAXUSER_ADDRESS); 2983 va = sva; 2984 segnum = VA_SEGNUM(va); 2985 while (va < eva) { 2986 neva = sun3_trunc_seg(va) + NBSG; 2987 if (neva > eva) 2988 neva = eva; 2989 if (pmap->pm_segmap[segnum] != SEGINV) 2990 pmap_protect1(pmap, va, neva); 2991 va = neva; 2992 segnum++; 2993 } 2994 } 2995 2996 /* 2997 * Remove write permissions in given range. 2998 * (guaranteed to be within one segment) 2999 * similar to pmap_remove1() 3000 */ 3001 void 3002 pmap_protect1(pmap_t pmap, vaddr_t sva, vaddr_t eva) 3003 { 3004 int old_ctx, s, sme; 3005 bool in_ctx; 3006 3007 s = splvm(); 3008 3009 #ifdef DIAGNOSTIC 3010 if (sun3_trunc_seg(sva) != sun3_trunc_seg(eva-1)) 3011 panic("pmap_protect1: bad range!"); 3012 #endif 3013 3014 if (pmap == kernel_pmap) { 3015 sme = get_segmap(sva); 3016 if (sme != SEGINV) 3017 pmap_protect_mmu(pmap, sva, eva); 3018 goto out; 3019 } 3020 /* It is a user pmap. */ 3021 3022 /* There is a PMEG, but maybe not active. */ 3023 old_ctx = INVALID_CONTEXT; 3024 in_ctx = false; 3025 if (has_context(pmap)) { 3026 /* Temporary context change. */ 3027 old_ctx = get_context(); 3028 set_context(pmap->pm_ctxnum); 3029 sme = get_segmap(sva); 3030 if (sme != SEGINV) 3031 in_ctx = true; 3032 } 3033 3034 if (in_ctx == true) 3035 pmap_protect_mmu(pmap, sva, eva); 3036 else 3037 pmap_protect_noctx(pmap, sva, eva); 3038 3039 if (old_ctx != INVALID_CONTEXT) { 3040 /* Restore previous context. */ 3041 set_context(old_ctx); 3042 } 3043 3044 out: 3045 splx(s); 3046 } 3047 3048 /* 3049 * Remove write permissions, all in one PMEG, 3050 * where that PMEG is currently in the MMU. 3051 * The current context is already correct. 3052 */ 3053 void 3054 pmap_protect_mmu(pmap_t pmap, vaddr_t sva, vaddr_t eva) 3055 { 3056 pmeg_t pmegp; 3057 vaddr_t pgva, segva; 3058 int pte, sme; 3059 #ifdef HAVECACHE 3060 int flush_by_page = 0; 3061 #endif 3062 3063 CHECK_SPL(); 3064 3065 #ifdef DIAGNOSTIC 3066 if (pmap != kernel_pmap) { 3067 if (pmap->pm_ctxnum != get_context()) 3068 panic("pmap_protect_mmu: wrong context"); 3069 } 3070 #endif 3071 3072 segva = sun3_trunc_seg(sva); 3073 sme = get_segmap(segva); 3074 3075 #ifdef DIAGNOSTIC 3076 /* Make sure it is valid and known. */ 3077 if (sme == SEGINV) 3078 panic("pmap_protect_mmu: SEGINV"); 3079 if (pmap->pm_segmap && (pmap->pm_segmap[VA_SEGNUM(segva)] != sme)) 3080 panic("pmap_protect_mmu: incorrect sme, va=0x%lx", segva); 3081 #endif 3082 3083 pmegp = pmeg_p(sme); 3084 /* have pmeg, will travel */ 3085 3086 #ifdef DIAGNOSTIC 3087 /* Make sure we own the pmeg, right va, etc. */ 3088 if ((pmegp->pmeg_va != segva) || 3089 (pmegp->pmeg_owner != pmap) || 3090 (pmegp->pmeg_version != pmap->pm_version)) 3091 { 3092 panic("pmap_protect_mmu: bad pmeg=%p", pmegp); 3093 } 3094 if (pmegp->pmeg_vpages < 0) 3095 panic("pmap_protect_mmu: npages corrupted"); 3096 if (pmegp->pmeg_vpages == 0) 3097 panic("pmap_protect_mmu: no valid pages?"); 3098 #endif 3099 3100 #ifdef HAVECACHE 3101 if (cache_size) { 3102 /* 3103 * If the range to be removed is larger than the cache, 3104 * it will be cheaper to flush this segment entirely. 3105 */ 3106 if (cache_size < (eva - sva)) { 3107 /* cheaper to flush whole segment */ 3108 cache_flush_segment(segva); 3109 } else { 3110 flush_by_page = 1; 3111 } 3112 } 3113 #endif 3114 3115 /* Remove write permission in the given range. */ 3116 for (pgva = sva; pgva < eva; pgva += PAGE_SIZE) { 3117 pte = get_pte(pgva); 3118 if (pte & PG_VALID) { 3119 #ifdef HAVECACHE 3120 if (flush_by_page) { 3121 cache_flush_page(pgva); 3122 /* Get fresh mod/ref bits from write-back. */ 3123 pte = get_pte(pgva); 3124 } 3125 #endif 3126 if (IS_MAIN_MEM(pte)) { 3127 save_modref_bits(pte); 3128 } 3129 pte &= ~(PG_WRITE | PG_MODREF); 3130 set_pte(pgva, pte); 3131 } 3132 } 3133 } 3134 3135 /* 3136 * Remove write permissions, all in one PMEG, 3137 * where it is not currently in any context. 3138 */ 3139 void 3140 pmap_protect_noctx(pmap_t pmap, vaddr_t sva, vaddr_t eva) 3141 { 3142 int old_ctx, pte, sme, segnum; 3143 vaddr_t pgva, segva; 3144 3145 #ifdef DIAGNOSTIC 3146 /* Kernel always in a context (actually, in all contexts). */ 3147 if (pmap == kernel_pmap) 3148 panic("pmap_protect_noctx: kernel_pmap"); 3149 if (pmap->pm_segmap == NULL) 3150 panic("pmap_protect_noctx: null segmap"); 3151 #endif 3152 3153 segva = sun3_trunc_seg(sva); 3154 segnum = VA_SEGNUM(segva); 3155 sme = pmap->pm_segmap[segnum]; 3156 if (sme == SEGINV) 3157 return; 3158 3159 /* 3160 * Borrow the EMPTY_CONTEXT so we can access the PMEG 3161 * at its normal virtual address. 3162 */ 3163 old_ctx = get_context(); 3164 set_context(EMPTY_CONTEXT); 3165 set_segmap(segva, sme); 3166 3167 /* Remove write permission in the given range. */ 3168 for (pgva = sva; pgva < eva; pgva += PAGE_SIZE) { 3169 pte = get_pte(pgva); 3170 if (pte & PG_VALID) { 3171 /* No cache flush needed. */ 3172 if (IS_MAIN_MEM(pte)) { 3173 save_modref_bits(pte); 3174 } 3175 pte &= ~(PG_WRITE | PG_MODREF); 3176 set_pte(pgva, pte); 3177 } 3178 } 3179 3180 /* 3181 * Make the EMPTY_CONTEXT really empty again, and 3182 * restore the previous context. 3183 */ 3184 set_segmap(segva, SEGINV); 3185 set_context(old_ctx); 3186 } 3187 3188 3189 /* 3190 * Remove the given range of addresses from the specified map. 3191 * 3192 * It is assumed that the start and end are properly 3193 * rounded to the page size. 3194 */ 3195 void 3196 pmap_remove(pmap_t pmap, vaddr_t sva, vaddr_t eva) 3197 { 3198 vaddr_t va, neva; 3199 int segnum; 3200 3201 #ifdef PMAP_DEBUG 3202 if ((pmap_debug & PMD_REMOVE) || 3203 ((sva <= pmap_db_watchva && eva > pmap_db_watchva))) 3204 printf("pmap_remove(%p, 0x%lx, 0x%lx)\n", pmap, sva, eva); 3205 #endif 3206 3207 3208 KASSERT((pmap == kernel_pmap) ? 3209 sva >= virtual_avail && eva < DVMA_MAP_END : 3210 eva <= VM_MAXUSER_ADDRESS); 3211 va = sva; 3212 segnum = VA_SEGNUM(va); 3213 while (va < eva) { 3214 neva = sun3_trunc_seg(va) + NBSG; 3215 if (neva > eva) 3216 neva = eva; 3217 if (pmap->pm_segmap[segnum] != SEGINV) 3218 pmap_remove1(pmap, va, neva); 3219 va = neva; 3220 segnum++; 3221 } 3222 } 3223 3224 /* 3225 * Remove user mappings, all within one segment 3226 */ 3227 void 3228 pmap_remove1(pmap_t pmap, vaddr_t sva, vaddr_t eva) 3229 { 3230 int old_ctx, s, sme; 3231 bool in_ctx; 3232 3233 s = splvm(); 3234 3235 #ifdef DIAGNOSTIC 3236 if (sun3_trunc_seg(sva) != sun3_trunc_seg(eva-1)) 3237 panic("pmap_remove1: bad range!"); 3238 #endif 3239 3240 if (pmap == kernel_pmap) { 3241 sme = get_segmap(sva); 3242 if (sme != SEGINV) 3243 pmap_remove_mmu(pmap, sva, eva); 3244 goto out; 3245 } 3246 /* It is a user pmap. */ 3247 3248 /* There is a PMEG, but maybe not active. */ 3249 old_ctx = INVALID_CONTEXT; 3250 in_ctx = false; 3251 if (has_context(pmap)) { 3252 /* Temporary context change. */ 3253 old_ctx = get_context(); 3254 set_context(pmap->pm_ctxnum); 3255 sme = get_segmap(sva); 3256 if (sme != SEGINV) 3257 in_ctx = true; 3258 } 3259 3260 if (in_ctx == true) 3261 pmap_remove_mmu(pmap, sva, eva); 3262 else 3263 pmap_remove_noctx(pmap, sva, eva); 3264 3265 if (old_ctx != INVALID_CONTEXT) { 3266 /* Restore previous context. */ 3267 set_context(old_ctx); 3268 } 3269 3270 out: 3271 splx(s); 3272 } 3273 3274 /* 3275 * Remove some mappings, all in one PMEG, 3276 * where that PMEG is currently in the MMU. 3277 * The current context is already correct. 3278 * If no PTEs remain valid in the PMEG, free it. 3279 */ 3280 void 3281 pmap_remove_mmu(pmap_t pmap, vaddr_t sva, vaddr_t eva) 3282 { 3283 pmeg_t pmegp; 3284 vaddr_t pgva, segva; 3285 int pte, sme; 3286 #ifdef HAVECACHE 3287 int flush_by_page = 0; 3288 #endif 3289 3290 CHECK_SPL(); 3291 3292 #ifdef DIAGNOSTIC 3293 if (pmap != kernel_pmap) { 3294 if (pmap->pm_ctxnum != get_context()) 3295 panic("pmap_remove_mmu: wrong context"); 3296 } 3297 #endif 3298 3299 segva = sun3_trunc_seg(sva); 3300 sme = get_segmap(segva); 3301 3302 #ifdef DIAGNOSTIC 3303 /* Make sure it is valid and known. */ 3304 if (sme == SEGINV) 3305 panic("pmap_remove_mmu: SEGINV"); 3306 if (pmap->pm_segmap && (pmap->pm_segmap[VA_SEGNUM(segva)] != sme)) 3307 panic("pmap_remove_mmu: incorrect sme, va=0x%lx", segva); 3308 #endif 3309 3310 pmegp = pmeg_p(sme); 3311 /* have pmeg, will travel */ 3312 3313 #ifdef DIAGNOSTIC 3314 /* Make sure we own the pmeg, right va, etc. */ 3315 if ((pmegp->pmeg_va != segva) || 3316 (pmegp->pmeg_owner != pmap) || 3317 (pmegp->pmeg_version != pmap->pm_version)) 3318 { 3319 panic("pmap_remove_mmu: bad pmeg=%p", pmegp); 3320 } 3321 if (pmegp->pmeg_vpages < 0) 3322 panic("pmap_remove_mmu: npages corrupted"); 3323 if (pmegp->pmeg_vpages == 0) 3324 panic("pmap_remove_mmu: no valid pages?"); 3325 #endif 3326 3327 #ifdef HAVECACHE 3328 if (cache_size) { 3329 /* 3330 * If the range to be removed is larger than the cache, 3331 * it will be cheaper to flush this segment entirely. 3332 */ 3333 if (cache_size < (eva - sva)) { 3334 /* cheaper to flush whole segment */ 3335 cache_flush_segment(segva); 3336 } else { 3337 flush_by_page = 1; 3338 } 3339 } 3340 #endif 3341 3342 /* Invalidate the PTEs in the given range. */ 3343 for (pgva = sva; pgva < eva; pgva += PAGE_SIZE) { 3344 pte = get_pte(pgva); 3345 if (pte & PG_VALID) { 3346 #ifdef HAVECACHE 3347 if (flush_by_page) { 3348 cache_flush_page(pgva); 3349 /* Get fresh mod/ref bits from write-back. */ 3350 pte = get_pte(pgva); 3351 } 3352 #endif 3353 if (IS_MAIN_MEM(pte)) { 3354 save_modref_bits(pte); 3355 pv_unlink(pmap, pte, pgva); 3356 } 3357 #ifdef PMAP_DEBUG 3358 if ((pmap_debug & PMD_SETPTE) || 3359 (pgva == pmap_db_watchva)) { 3360 printf("pmap: set_pte pmap=%p va=0x%lx" 3361 " old=0x%x new=0x%x (rrmmu)\n", 3362 pmap, pgva, pte, PG_INVAL); 3363 } 3364 #endif 3365 set_pte(pgva, PG_INVAL); 3366 KASSERT(pmegp->pmeg_vpages > 0); 3367 pmegp->pmeg_vpages--; 3368 } 3369 } 3370 3371 KASSERT(pmegp->pmeg_vpages >= 0); 3372 if (pmegp->pmeg_vpages == 0) { 3373 /* We are done with this pmeg. */ 3374 if (is_pmeg_wired(pmegp)) { 3375 #ifdef PMAP_DEBUG 3376 if (pmap_debug & PMD_WIRING) { 3377 db_printf("pmap: removing wired pmeg: %p\n", 3378 pmegp); 3379 Debugger(); 3380 } 3381 #endif /* PMAP_DEBUG */ 3382 } 3383 3384 #ifdef PMAP_DEBUG 3385 if (pmap_debug & PMD_SEGMAP) { 3386 printf("pmap: set_segmap ctx=%d v=0x%lx old=0x%x " 3387 "new=ff (rm)\n", 3388 pmap->pm_ctxnum, segva, pmegp->pmeg_index); 3389 } 3390 pmeg_verify_empty(segva); 3391 #endif 3392 3393 /* Remove it from the MMU. */ 3394 if (kernel_pmap == pmap) { 3395 /* Did cache flush above. */ 3396 set_segmap_allctx(segva, SEGINV); 3397 } else { 3398 /* Did cache flush above. */ 3399 set_segmap(segva, SEGINV); 3400 } 3401 pmap->pm_segmap[VA_SEGNUM(segva)] = SEGINV; 3402 /* Now, put it on the free list. */ 3403 pmeg_free(pmegp); 3404 } 3405 } 3406 3407 /* 3408 * Remove some mappings, all in one PMEG, 3409 * where it is not currently in any context. 3410 */ 3411 void 3412 pmap_remove_noctx(pmap_t pmap, vaddr_t sva, vaddr_t eva) 3413 { 3414 pmeg_t pmegp; 3415 int old_ctx, pte, sme, segnum; 3416 vaddr_t pgva, segva; 3417 3418 CHECK_SPL(); 3419 3420 #ifdef DIAGNOSTIC 3421 /* Kernel always in a context (actually, in all contexts). */ 3422 if (pmap == kernel_pmap) 3423 panic("pmap_remove_noctx: kernel_pmap"); 3424 if (pmap->pm_segmap == NULL) 3425 panic("pmap_remove_noctx: null segmap"); 3426 #endif 3427 3428 segva = sun3_trunc_seg(sva); 3429 segnum = VA_SEGNUM(segva); 3430 sme = pmap->pm_segmap[segnum]; 3431 if (sme == SEGINV) 3432 return; 3433 pmegp = pmeg_p(sme); 3434 3435 /* 3436 * Borrow the EMPTY_CONTEXT so we can access the PMEG 3437 * at its normal virtual address. 3438 */ 3439 old_ctx = get_context(); 3440 set_context(EMPTY_CONTEXT); 3441 set_segmap(segva, sme); 3442 3443 /* Invalidate the PTEs in the given range. */ 3444 for (pgva = sva; pgva < eva; pgva += PAGE_SIZE) { 3445 pte = get_pte(pgva); 3446 if (pte & PG_VALID) { 3447 /* No cache flush needed. */ 3448 if (IS_MAIN_MEM(pte)) { 3449 save_modref_bits(pte); 3450 pv_unlink(pmap, pte, pgva); 3451 } 3452 #ifdef PMAP_DEBUG 3453 if ((pmap_debug & PMD_SETPTE) || 3454 (pgva == pmap_db_watchva)) { 3455 printf("pmap: set_pte pmap=%p va=0x%lx" 3456 " old=0x%x new=0x%x (rrncx)\n", 3457 pmap, pgva, pte, PG_INVAL); 3458 } 3459 #endif 3460 set_pte(pgva, PG_INVAL); 3461 KASSERT(pmegp->pmeg_vpages > 0); 3462 pmegp->pmeg_vpages--; 3463 } 3464 } 3465 3466 /* 3467 * Make the EMPTY_CONTEXT really empty again, and 3468 * restore the previous context. 3469 */ 3470 set_segmap(segva, SEGINV); 3471 set_context(old_ctx); 3472 3473 KASSERT(pmegp->pmeg_vpages >= 0); 3474 if (pmegp->pmeg_vpages == 0) { 3475 /* We are done with this pmeg. */ 3476 if (is_pmeg_wired(pmegp)) { 3477 #ifdef PMAP_DEBUG 3478 if (pmap_debug & PMD_WIRING) { 3479 db_printf("pmap: removing wired pmeg: %p\n", 3480 pmegp); 3481 Debugger(); 3482 } 3483 #endif /* PMAP_DEBUG */ 3484 } 3485 3486 pmap->pm_segmap[segnum] = SEGINV; 3487 pmeg_free(pmegp); 3488 } 3489 } 3490 3491 3492 /* 3493 * Count resident pages in this pmap. 3494 * See: kern_sysctl.c:pmap_resident_count 3495 */ 3496 segsz_t 3497 pmap_resident_pages(pmap_t pmap) 3498 { 3499 int i, sme, pages; 3500 pmeg_t pmeg; 3501 3502 if (pmap->pm_segmap == 0) 3503 return (0); 3504 3505 pages = 0; 3506 for (i = 0; i < NUSEG; i++) { 3507 sme = pmap->pm_segmap[i]; 3508 if (sme != SEGINV) { 3509 pmeg = pmeg_p(sme); 3510 pages += pmeg->pmeg_vpages; 3511 } 3512 } 3513 return (pages); 3514 } 3515 3516 /* 3517 * Count wired pages in this pmap. 3518 * See vm_mmap.c:pmap_wired_count 3519 */ 3520 segsz_t 3521 pmap_wired_pages(pmap_t pmap) 3522 { 3523 int i, mask, sme, pages; 3524 pmeg_t pmeg; 3525 3526 if (pmap->pm_segmap == 0) 3527 return (0); 3528 3529 pages = 0; 3530 for (i = 0; i < NUSEG; i++) { 3531 sme = pmap->pm_segmap[i]; 3532 if (sme != SEGINV) { 3533 pmeg = pmeg_p(sme); 3534 mask = 0x8000; 3535 do { 3536 if (pmeg->pmeg_wired & mask) 3537 pages++; 3538 mask = (mask >> 1); 3539 } while (mask); 3540 } 3541 } 3542 return (pages); 3543 } 3544 3545 3546 /* 3547 * pmap_copy_page copies the specified (machine independent) 3548 * page by mapping the page into virtual memory and using 3549 * bcopy to copy the page, one machine dependent page at a 3550 * time. 3551 */ 3552 void 3553 pmap_copy_page(paddr_t src, paddr_t dst) 3554 { 3555 int pte; 3556 int s; 3557 3558 s = splvm(); 3559 3560 #ifdef PMAP_DEBUG 3561 if (pmap_debug & PMD_COW) 3562 printf("pmap_copy_page: 0x%lx -> 0x%lx\n", src, dst); 3563 #endif 3564 3565 #ifdef DIAGNOSTIC 3566 if (tmp_vpages_inuse) 3567 panic("pmap_copy_page: vpages inuse"); 3568 tmp_vpages_inuse++; 3569 #endif 3570 3571 /* PG_PERM is short for (PG_VALID|PG_WRITE|PG_SYSTEM|PG_NC) */ 3572 /* All mappings to vmp_vpages are non-cached, so no flush. */ 3573 pte = PG_PERM | PA_PGNUM(src); 3574 set_pte(tmp_vpages[0], pte); 3575 pte = PG_PERM | PA_PGNUM(dst); 3576 set_pte(tmp_vpages[1], pte); 3577 copypage((char *) tmp_vpages[0], (char *) tmp_vpages[1]); 3578 set_pte(tmp_vpages[0], PG_INVAL); 3579 set_pte(tmp_vpages[0], PG_INVAL); 3580 3581 #ifdef DIAGNOSTIC 3582 tmp_vpages_inuse--; 3583 #endif 3584 3585 splx(s); 3586 } 3587 3588 /* 3589 * pmap_zero_page zeros the specified (machine independent) 3590 * page by mapping the page into virtual memory and using 3591 * bzero to clear its contents, one machine dependent page 3592 * at a time. 3593 */ 3594 void 3595 pmap_zero_page(paddr_t pa) 3596 { 3597 int pte; 3598 int s; 3599 3600 s = splvm(); 3601 3602 #ifdef PMAP_DEBUG 3603 if (pmap_debug & PMD_COW) 3604 printf("pmap_zero_page: 0x%lx\n", pa); 3605 #endif 3606 3607 #ifdef DIAGNOSTIC 3608 if (tmp_vpages_inuse) 3609 panic("pmap_zero_page: vpages inuse"); 3610 tmp_vpages_inuse++; 3611 #endif 3612 3613 /* PG_PERM is short for (PG_VALID|PG_WRITE|PG_SYSTEM|PG_NC) */ 3614 /* All mappings to vmp_vpages are non-cached, so no flush. */ 3615 pte = PG_PERM | PA_PGNUM(pa); 3616 set_pte(tmp_vpages[0], pte); 3617 zeropage((char *) tmp_vpages[0]); 3618 set_pte(tmp_vpages[0], PG_INVAL); 3619 3620 #ifdef DIAGNOSTIC 3621 tmp_vpages_inuse--; 3622 #endif 3623 3624 splx(s); 3625 } 3626 3627 /* 3628 * Find first virtual address >= *va that is 3629 * least likely to cause cache aliases. 3630 * (This will just seg-align mappings.) 3631 */ 3632 void 3633 pmap_prefer(vaddr_t fo, vaddr_t *va) 3634 { 3635 long d; 3636 3637 d = fo - *va; 3638 d &= SEGOFSET; 3639 *va += d; 3640 } 3641 3642 /* 3643 * Fill in the sun3x-specific part of the kernel core header 3644 * for dumpsys(). (See machdep.c for the rest.) 3645 */ 3646 void 3647 pmap_kcore_hdr(struct sun3_kcore_hdr *sh) 3648 { 3649 vaddr_t va; 3650 u_char *cp, *ep; 3651 3652 sh->segshift = SEGSHIFT; 3653 sh->pg_frame = PG_FRAME; 3654 sh->pg_valid = PG_VALID; 3655 3656 /* Copy the kernel segmap (256 bytes). */ 3657 va = KERNBASE3; 3658 cp = sh->ksegmap; 3659 ep = cp + sizeof(sh->ksegmap); 3660 do { 3661 *cp = get_segmap(va); 3662 va += NBSG; 3663 cp++; 3664 } while (cp < ep); 3665 } 3666 3667 /* 3668 * Copy the pagemap RAM into the passed buffer (one page) 3669 * starting at OFF in the pagemap RAM. 3670 */ 3671 void 3672 pmap_get_pagemap(int *pt, int off) 3673 { 3674 vaddr_t va, va_end; 3675 int sme, sme_end; /* SegMap Entry numbers */ 3676 3677 sme = (off >> 6); /* PMEG to start on */ 3678 sme_end = sme + 128; /* where to stop */ 3679 va_end = temp_seg_va + NBSG; 3680 3681 do { 3682 set_segmap(temp_seg_va, sme); 3683 va = temp_seg_va; 3684 do { 3685 *pt++ = get_pte(va); 3686 va += PAGE_SIZE; 3687 } while (va < va_end); 3688 sme++; 3689 } while (sme < sme_end); 3690 set_segmap(temp_seg_va, SEGINV); 3691 } 3692 3693 3694 /* 3695 * Helper functions for changing unloaded PMEGs 3696 * XXX: These should go away. (Borrow context zero instead.) 3697 */ 3698 3699 #ifdef DIAGNOSTIC 3700 static int temp_seg_inuse; 3701 #endif 3702 3703 static int 3704 get_pte_pmeg(int pmeg_num, int page_num) 3705 { 3706 vaddr_t va; 3707 int pte; 3708 3709 CHECK_SPL(); 3710 #ifdef DIAGNOSTIC 3711 if (temp_seg_inuse) 3712 panic("get_pte_pmeg: temp_seg_inuse"); 3713 temp_seg_inuse++; 3714 #endif 3715 3716 va = temp_seg_va; 3717 set_segmap(temp_seg_va, pmeg_num); 3718 va += PAGE_SIZE*page_num; 3719 pte = get_pte(va); 3720 set_segmap(temp_seg_va, SEGINV); 3721 3722 #ifdef DIAGNOSTIC 3723 temp_seg_inuse--; 3724 #endif 3725 return pte; 3726 } 3727 3728 static void 3729 set_pte_pmeg(int pmeg_num, int page_num, int pte) 3730 { 3731 vaddr_t va; 3732 3733 CHECK_SPL(); 3734 #ifdef DIAGNOSTIC 3735 if (temp_seg_inuse) 3736 panic("set_pte_pmeg: temp_seg_inuse"); 3737 temp_seg_inuse++; 3738 #endif 3739 3740 /* We never access data in temp_seg_va so no need to flush. */ 3741 va = temp_seg_va; 3742 set_segmap(temp_seg_va, pmeg_num); 3743 va += PAGE_SIZE*page_num; 3744 set_pte(va, pte); 3745 set_segmap(temp_seg_va, SEGINV); 3746 3747 #ifdef DIAGNOSTIC 3748 temp_seg_inuse--; 3749 #endif 3750 } 3751 3752 /* 3753 * Routine: pmap_procwr 3754 * 3755 * Function: 3756 * Synchronize caches corresponding to [addr, addr+len) in p. 3757 */ 3758 void 3759 pmap_procwr(struct proc *p, vaddr_t va, size_t len) 3760 { 3761 (void)cachectl1(0x80000004, va, len, p); 3762 } 3763 3764 3765 #ifdef PMAP_DEBUG 3766 /* Things to call from the debugger. */ 3767 3768 void 3769 pmap_print(pmap_t pmap) 3770 { 3771 db_printf(" pm_ctxnum=%d\n", pmap->pm_ctxnum); 3772 db_printf(" pm_version=0x%x\n", pmap->pm_version); 3773 db_printf(" pm_segmap=%p\n", pmap->pm_segmap); 3774 } 3775 3776 void 3777 pmeg_print(pmeg_t pmegp) 3778 { 3779 db_printf("link_next=%p link_prev=%p\n", 3780 TAILQ_NEXT(pmegp, pmeg_link), 3781 TAILQ_PREV(pmegp, pmeg_tailq, pmeg_link)); 3782 db_printf("index=0x%x owner=%p own_vers=0x%x\n", 3783 pmegp->pmeg_index, pmegp->pmeg_owner, pmegp->pmeg_version); 3784 db_printf("va=0x%lx wired=0x%x reserved=0x%x vpgs=0x%x qstate=0x%x\n", 3785 pmegp->pmeg_va, pmegp->pmeg_wired, 3786 pmegp->pmeg_reserved, pmegp->pmeg_vpages, 3787 pmegp->pmeg_qstate); 3788 } 3789 3790 void 3791 pv_print(paddr_t pa) 3792 { 3793 pv_entry_t pv; 3794 int idx; 3795 3796 idx = PA_PGNUM(pa); 3797 if (idx >= physmem) { 3798 db_printf("bad address\n"); 3799 return; 3800 } 3801 db_printf("pa=0x%lx, flags=0x%x\n", 3802 pa, pv_flags_tbl[idx]); 3803 3804 pv = pv_head_tbl[idx]; 3805 while (pv) { 3806 db_printf(" pv_entry %p pmap %p va 0x%lx next %p\n", 3807 pv, pv->pv_pmap, pv->pv_va, pv->pv_next); 3808 pv = pv->pv_next; 3809 } 3810 } 3811 #endif /* PMAP_DEBUG */ 3812