1 /* $NetBSD: pmap.c,v 1.380 2026/08/23 22:08:40 riastradh Exp $ */ 2 3 /* 4 * Copyright (c) 1996 5 * The President and Fellows of Harvard College. All rights reserved. 6 * Copyright (c) 1992, 1993 7 * The Regents of the University of California. All rights reserved. 8 * 9 * This software was developed by the Computer Systems Engineering group 10 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 11 * contributed to Berkeley. 12 * 13 * All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by Harvard University. 16 * This product includes software developed by the University of 17 * California, Lawrence Berkeley Laboratory. 18 * 19 * Redistribution and use in source and binary forms, with or without 20 * modification, are permitted provided that the following conditions 21 * are met: 22 * 23 * 1. Redistributions of source code must retain the above copyright 24 * notice, this list of conditions and the following disclaimer. 25 * 2. Redistributions in binary form must reproduce the above copyright 26 * notice, this list of conditions and the following disclaimer in the 27 * documentation and/or other materials provided with the distribution. 28 * 3. All advertising materials mentioning features or use of this software 29 * must display the following acknowledgement: 30 * This product includes software developed by Aaron Brown and 31 * Harvard University. 32 * This product includes software developed by the University of 33 * California, Berkeley and its contributors. 34 * 4. Neither the name of the University nor the names of its contributors 35 * may be used to endorse or promote products derived from this software 36 * without specific prior written permission. 37 * 38 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 39 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 41 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 42 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 43 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 44 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 45 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 46 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 47 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 48 * SUCH DAMAGE. 49 * 50 * @(#)pmap.c 8.4 (Berkeley) 2/5/94 51 * 52 */ 53 54 /* 55 * SPARC physical map management code. 56 */ 57 58 #include <sys/cdefs.h> 59 __KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.380 2026/08/23 22:08:40 riastradh Exp $"); 60 61 #include "opt_ddb.h" 62 #include "opt_kgdb.h" 63 #include "opt_sparc_arch.h" 64 65 #include <sys/param.h> 66 #include <sys/systm.h> 67 #include <sys/device.h> 68 #include <sys/proc.h> 69 #include <sys/queue.h> 70 #include <sys/pool.h> 71 #include <sys/exec.h> 72 #include <sys/core.h> 73 #include <sys/kcore.h> 74 #include <sys/kernel.h> 75 #include <sys/atomic.h> 76 77 #include <sys/exec_aout.h> /* for MID_* */ 78 79 #include <uvm/uvm.h> 80 81 #include <machine/autoconf.h> 82 #include <machine/bsd_openprom.h> 83 #include <machine/oldmon.h> 84 #include <machine/cpu.h> 85 #include <machine/ctlreg.h> 86 #include <machine/kcore.h> 87 #include <machine/locore.h> 88 89 #include <sparc/sparc/asm.h> 90 #include <sparc/sparc/cache.h> 91 #include <sparc/sparc/vaddrs.h> 92 #include <sparc/sparc/cpuvar.h> 93 94 /* 95 * The SPARCstation offers us the following challenges: 96 * 97 * 1. A virtual address cache. This is, strictly speaking, not 98 * part of the architecture, but the code below assumes one. 99 * This is a write-through cache on the 4c and a write-back cache 100 * on others. 101 * 102 * 2. (4/4c only) An MMU that acts like a cache. There is not enough 103 * space in the MMU to map everything all the time. Instead, we need 104 * to load MMU with the `working set' of translations for each 105 * process. The sun4m does not act like a cache; tables are maintained 106 * in physical memory. 107 * 108 * 3. Segmented virtual and physical spaces. The upper 12 bits of 109 * a virtual address (the virtual segment) index a segment table, 110 * giving a physical segment. The physical segment selects a 111 * `Page Map Entry Group' (PMEG) and the virtual page number---the 112 * next 5 or 6 bits of the virtual address---select the particular 113 * `Page Map Entry' for the page. We call the latter a PTE and 114 * call each Page Map Entry Group a pmeg (for want of a better name). 115 * Note that the sun4m has an unsegmented 36-bit physical space. 116 * 117 * Since there are no valid bits in the segment table, the only way 118 * to have an invalid segment is to make one full pmeg of invalid PTEs. 119 * We use the last one (since the ROM does as well) (sun4/4c only) 120 * 121 * 4. Discontiguous physical pages. The Mach VM expects physical pages 122 * to be in one sequential lump. 123 * 124 * 5. The MMU is always on: it is not possible to disable it. This is 125 * mainly a startup hassle. 126 */ 127 128 struct pmap_stats { 129 int ps_unlink_pvfirst; /* # of pv_unlinks on head */ 130 int ps_unlink_pvsearch; /* # of pv_unlink searches */ 131 int ps_changeprots; /* # of calls to changeprot */ 132 int ps_enter_firstpv; /* pv heads entered */ 133 int ps_enter_secondpv; /* pv nonheads entered */ 134 int ps_useless_changewire; /* useless wiring changes */ 135 int ps_npg_prot_all; /* # of active pages protected */ 136 int ps_npg_prot_actual; /* # pages actually affected */ 137 int ps_npmeg_free; /* # of free pmegs */ 138 int ps_npmeg_locked; /* # of pmegs on locked list */ 139 int ps_npmeg_lru; /* # of pmegs on lru list */ 140 } pmap_stats; 141 142 #if defined(SUN4) || defined(SUN4C) 143 struct evcnt mmu_stolenpmegs_evcnt = 144 EVCNT_INITIALIZER(EVCNT_TYPE_INTR,0,"mmu","stln pmgs"); 145 EVCNT_ATTACH_STATIC(mmu_stolenpmegs_evcnt); 146 147 struct evcnt mmu_pagein_evcnt = 148 EVCNT_INITIALIZER(EVCNT_TYPE_INTR,0,"mmu","pagein"); 149 EVCNT_ATTACH_STATIC(mmu_pagein_evcnt); 150 #endif /* SUN4 || SUN4C */ 151 152 #ifdef DEBUG 153 #define PDB_CREATE 0x0001 154 #define PDB_DESTROY 0x0002 155 #define PDB_REMOVE 0x0004 156 #define PDB_CHANGEPROT 0x0008 157 #define PDB_ENTER 0x0010 158 #define PDB_FOLLOW 0x0020 159 #define PDB_INITLOUD 0x0040 160 161 #define PDB_MMU_ALLOC 0x0100 162 #define PDB_MMU_STEAL 0x0200 163 #define PDB_CTX_ALLOC 0x0400 164 #define PDB_CTX_STEAL 0x0800 165 #define PDB_MMUREG_ALLOC 0x1000 166 #define PDB_MMUREG_STEAL 0x2000 167 #define PDB_CACHESTUFF 0x4000 168 #define PDB_SWITCHMAP 0x8000 169 #define PDB_SANITYCHK 0x10000 170 int pmapdebug = 0; 171 #define DPRINTF(level, fmt, ...) do { \ 172 if (pmapdebug & (level)) \ 173 printf("%s:%d: " fmt "\n", __func__, __LINE__, ##__VA_ARGS__); \ 174 } while (0) 175 #else 176 #define DPRINTF(level, fmt, ...) /* nothing */ 177 #endif 178 179 /* 180 * Bounds on managed physical addresses. Used by (MD) users 181 * of uvm_pglistalloc() to provide search hints. 182 */ 183 paddr_t vm_first_phys = (paddr_t)-1; 184 paddr_t vm_last_phys = 0; 185 psize_t vm_num_phys; 186 187 #define PMAP_LOCK() mutex_enter(&pmap_lock) 188 #define PMAP_UNLOCK() mutex_exit(&pmap_lock) 189 190 /* 191 * Flags in pvlist.pv_flags. Note that PV_MOD must be 1 and PV_REF must be 2 192 * since they must line up with the bits in the hardware PTEs (see pte.h). 193 * SUN4M bits are at a slightly different location in the PTE. 194 * 195 * Note: the REF, MOD and ANC flag bits occur only in the head of a pvlist. 196 * The NC bit is meaningful in each individual pv entry and reflects the 197 * requested non-cacheability at the time the entry was made through 198 * pv_link() or when subsequently altered by kvm_uncache() (but the latter 199 * does not happen in kernels as of the time of this writing (March 2001)). 200 */ 201 #define PV_MOD 1 /* page modified */ 202 #define PV_REF 2 /* page referenced */ 203 #define PV_NC 4 /* page cannot be cached */ 204 #define PV_REF4M 1 /* page referenced (SRMMU) */ 205 #define PV_MOD4M 2 /* page modified (SRMMU) */ 206 #define PV_ANC 0x10 /* page has incongruent aliases */ 207 208 static struct pool pv_pool; 209 210 /* 211 * pvhead(pte): find a VM page given a PTE entry. 212 */ 213 #if defined(SUN4) || defined(SUN4C) 214 static struct vm_page * 215 pvhead4_4c(u_int pte) 216 { 217 paddr_t pa = (pte & PG_PFNUM) << PGSHIFT; 218 219 return (PHYS_TO_VM_PAGE(pa)); 220 } 221 #endif 222 223 #if defined(SUN4M) || defined(SUN4D) 224 static struct vm_page * 225 pvhead4m(u_int pte) 226 { 227 paddr_t pa = (pte & SRMMU_PPNMASK) << SRMMU_PPNPASHIFT; 228 229 return (PHYS_TO_VM_PAGE(pa)); 230 } 231 #endif 232 233 /* 234 * Each virtual segment within each pmap is either valid or invalid. 235 * It is valid if pm_npte[VA_VSEG(va)] is not 0. This does not mean 236 * it is in the MMU, however; that is true iff pm_segmap[VA_VSEG(va)] 237 * does not point to the invalid PMEG. 238 * 239 * In the older SPARC architectures (sun4/sun4c), page tables are cached in 240 * the MMU. The following discussion applies to these architectures: 241 * 242 * If a virtual segment is valid and loaded, the correct PTEs appear 243 * in the MMU only. If it is valid and unloaded, the correct PTEs appear 244 * in the pm_pte[VA_VSEG(va)] only. However, some effort is made to keep 245 * the software copies consistent enough with the MMU so that libkvm can 246 * do user address translations. In particular, pv_changepte() and 247 * pmap_enu() maintain consistency, while less critical changes are 248 * not maintained. pm_pte[VA_VSEG(va)] always points to space for those 249 * PTEs. 250 * 251 * Each PMEG in the MMU is either free or contains PTEs corresponding to 252 * some pmap and virtual segment. If it contains some PTEs, it also contains 253 * reference and modify bits that belong in the pv_table. If we need 254 * to steal a PMEG from some process (if we need one and none are free) 255 * we must copy the ref and mod bits, and update pm_segmap in the other 256 * pmap to show that its virtual segment is no longer in the MMU. 257 * 258 * There are 128 PMEGs in a small Sun-4, of which only a few dozen are 259 * tied down permanently, leaving `about' 100 to be spread among 260 * running processes. These are managed as an LRU cache. Before 261 * calling the VM paging code for a user page fault, the fault handler 262 * calls mmu_load(pmap, va) to try to get a set of PTEs put into the 263 * MMU. mmu_load will check the validity of the segment and tell whether 264 * it did something. 265 * 266 * Since I hate the name PMEG I call this data structure an `mmu entry'. 267 * Each mmuentry is on exactly one of three `usage' lists: free, LRU, 268 * or locked. The locked list is only used for kernel mappings that need 269 * to be wired down. 270 * 271 * 272 * In the sun4m architecture using the SPARC Reference MMU (SRMMU), three 273 * levels of page tables are maintained in physical memory. We use the same 274 * structures as with the 3-level old-style MMU (pm_regmap, pm_segmap, 275 * rg_segmap, sg_pte, etc) to maintain kernel-edible page tables; we also 276 * build a parallel set of physical tables that can be used by the MMU. 277 * (XXX: This seems redundant, but is it necessary for the unified kernel?) 278 * 279 * If a virtual segment is valid, its entries will be in both parallel lists. 280 * If it is not valid, then its entry in the kernel tables will be zero, and 281 * its entry in the MMU tables will either be nonexistent or zero as well. 282 * 283 * The Reference MMU generally uses a Translation Look-aside Buffer (TLB) 284 * to cache the result of recently executed page table walks. When 285 * manipulating page tables, we need to ensure consistency of the 286 * in-memory and TLB copies of the page table entries. This is handled 287 * by flushing (and invalidating) a TLB entry when appropriate before 288 * altering an in-memory page table entry. 289 */ 290 struct mmuentry { 291 struct { 292 struct mmuentry *prev, *next; 293 } me_list; /* usage list link */ 294 TAILQ_ENTRY(mmuentry) me_pmchain; /* pmap owner link */ 295 struct pmap *me_pmap; /* pmap, if in use */ 296 u_short me_vreg; /* associated virtual region/segment */ 297 u_short me_vseg; /* associated virtual region/segment */ 298 u_short me_cookie; /* hardware SMEG/PMEG number */ 299 #ifdef DIAGNOSTIC 300 int *me_statp;/*XXX*/ 301 #endif 302 }; 303 struct mmuentry *mmusegments; /* allocated in pmap_bootstrap */ 304 struct mmuentry *mmuregions; /* allocated in pmap_bootstrap */ 305 306 #if defined(SUN4) || defined(SUN4C) 307 struct mmuentry segm_freelist, segm_lru, segm_locked; 308 #if defined(SUN4_MMU3L) 309 struct mmuentry region_freelist, region_lru, region_locked; 310 #endif 311 /* 312 * We use a double linked list looping through its static head (which 313 * always remains on the list), so we can remove any other member from 314 * a list without knowing which list it is on. 315 */ 316 static void inline 317 mmuq_remove(struct mmuentry *e) 318 { 319 e->me_list.next->me_list.prev = e->me_list.prev; 320 e->me_list.prev->me_list.next = e->me_list.next; 321 } 322 323 static void inline 324 mmuq_init(struct mmuentry *e) 325 { 326 memset(e, 0, sizeof(*e)); 327 e->me_list.next = e; 328 e->me_list.prev = e; 329 } 330 331 static inline struct mmuentry * 332 mmuq_first(struct mmuentry *head) 333 { 334 KASSERT(head->me_list.next != head); 335 return head->me_list.next; 336 } 337 338 static inline bool 339 mmuq_empty(struct mmuentry *head) 340 { 341 return head->me_list.next == head; 342 } 343 344 static inline void 345 mmuq_insert_tail(struct mmuentry *head, struct mmuentry *e) 346 { 347 e->me_list.prev = head->me_list.prev; 348 e->me_list.next = head; 349 head->me_list.prev->me_list.next = e; 350 head->me_list.prev = e; 351 } 352 #endif 353 354 355 int seginval; /* [4/4c] the invalid segment number */ 356 int reginval; /* [4/3mmu] the invalid region number */ 357 358 static kmutex_t pmap_lock; 359 static kmutex_t demap_lock; 360 static bool lock_available = false; /* demap_lock has been initialized */ 361 362 /* 363 * (sun4/4c) 364 * A context is simply a small number that dictates which set of 4096 365 * segment map entries the MMU uses. The Sun 4c has eight (SS1,IPC) or 366 * sixteen (SS2,IPX) such sets. These are allotted in an `almost MRU' fashion. 367 * (sun4m) 368 * A context is simply a small number that indexes the context table, the 369 * root-level page table mapping 4G areas. Each entry in this table points 370 * to a 1st-level region table. A SPARC reference MMU will usually use 16 371 * such contexts, but some offer as many as 64k contexts; the theoretical 372 * maximum is 2^32 - 1, but this would create overlarge context tables. 373 * 374 * Each context is either free or attached to a pmap. 375 * 376 * Since the virtual address cache is tagged by context, when we steal 377 * a context we have to flush (that part of) the cache. 378 */ 379 union ctxinfo { 380 union ctxinfo *c_nextfree; /* free list (if free) */ 381 struct pmap *c_pmap; /* pmap (if busy) */ 382 }; 383 384 static kmutex_t ctx_lock; /* lock for below, and {,de}activate */ 385 union ctxinfo *ctxinfo; /* allocated at in pmap_bootstrap */ 386 union ctxinfo *ctx_freelist; /* context free list */ 387 int ctx_kick; /* allocation rover when none free */ 388 int ctx_kickdir; /* ctx_kick roves both directions */ 389 int ncontext; /* sizeof ctx_freelist */ 390 391 static void ctx_alloc(struct pmap *); 392 static void ctx_free(struct pmap *); 393 394 /*void * vdumppages; -* 32KB worth of reserved dump pages */ 395 396 smeg_t tregion; /* [4/3mmu] Region for temporary mappings */ 397 398 static struct pmap kernel_pmap_store; /* the kernel's pmap */ 399 struct pmap *const kernel_pmap_ptr = &kernel_pmap_store; /* pmap_kernel() */ 400 struct regmap kernel_regmap_store[NKREG]; /* the kernel's regmap */ 401 struct segmap kernel_segmap_store[NKREG*NSEGRG];/* the kernel's segmaps */ 402 403 #if defined(SUN4M) || defined(SUN4D) 404 u_int *kernel_regtable_store; /* 1k of storage to map the kernel */ 405 u_int *kernel_segtable_store; /* 2k of storage to map the kernel */ 406 u_int *kernel_pagtable_store; /* 128k of storage to map the kernel */ 407 408 /* 409 * Memory pools and back-end supplier for SRMMU page tables. 410 * Share a pool between the level 2 and level 3 page tables, 411 * since these are equal in size. 412 */ 413 static struct pool L1_pool; 414 static struct pool L23_pool; 415 416 static void *pgt_page_alloc(struct pool *, int); 417 static void pgt_page_free(struct pool *, void *); 418 419 static struct pool_allocator pgt_page_allocator = { 420 pgt_page_alloc, pgt_page_free, 0, 421 }; 422 423 #endif /* SUN4M || SUN4D */ 424 425 #if defined(SUN4) || defined(SUN4C) 426 /* 427 * Memory pool for user and kernel PTE tables. 428 */ 429 static struct pool pte_pool; 430 #endif 431 432 struct memarr *pmemarr; /* physical memory regions */ 433 int npmemarr; /* number of entries in pmemarr */ 434 435 static paddr_t avail_start; /* first available physical page, other 436 than the `etext gap' defined below */ 437 static vaddr_t etext_gap_start;/* start of gap between text & data */ 438 static vaddr_t etext_gap_end; /* end of gap between text & data */ 439 static vaddr_t virtual_avail; /* first free kernel virtual address */ 440 static vaddr_t virtual_end; /* last free kernel virtual address */ 441 442 static void pmap_page_upload(void); 443 444 int mmu_has_hole; 445 446 vaddr_t prom_vstart; /* For /dev/kmem */ 447 vaddr_t prom_vend; 448 449 /* 450 * Memory pool for pmap structures. 451 */ 452 static struct pool_cache pmap_cache; 453 static int pmap_pmap_pool_ctor(void *, void *, int); 454 static void pmap_pmap_pool_dtor(void *, void *); 455 static struct pool segmap_pool; 456 457 #if defined(SUN4) 458 /* 459 * [sun4]: segfixmask: on some systems (4/110) "getsegmap()" returns a 460 * partly invalid value. getsegmap returns a 16 bit value on the sun4, 461 * but only the first 8 or so bits are valid (the rest are *supposed* to 462 * be zero. On the 4/110 the bits that are supposed to be zero are 463 * all one instead. e.g. KERNBASE is usually mapped by pmeg number zero. 464 * On a 4/300 getsegmap(KERNBASE) == 0x0000, but 465 * on a 4/100 getsegmap(KERNBASE) == 0xff00 466 * 467 * This confuses mmu_reservemon() and causes it to not reserve the PROM's 468 * pmegs. Then the PROM's pmegs get used during autoconfig and everything 469 * falls apart! (not very fun to debug, BTW.) 470 * 471 * solution: mask the invalid bits in the getsetmap macro. 472 */ 473 474 static u_int segfixmask = 0xffffffff; /* all bits valid to start */ 475 #else 476 #define segfixmask 0xffffffff /* It's in getsegmap's scope */ 477 #endif 478 479 /* 480 * pseudo-functions for mnemonic value 481 */ 482 #define getsegmap(va) (CPU_ISSUN4C \ 483 ? lduba(va, ASI_SEGMAP) \ 484 : (lduha(va, ASI_SEGMAP) & segfixmask)) 485 #define setsegmap(va, pmeg) (CPU_ISSUN4C \ 486 ? stba(va, ASI_SEGMAP, pmeg) \ 487 : stha(va, ASI_SEGMAP, pmeg)) 488 489 /* 3-level sun4 MMU only: */ 490 #define getregmap(va) ((unsigned)lduha((va)+2, ASI_REGMAP) >> 8) 491 #define setregmap(va, smeg) stha((va)+2, ASI_REGMAP, (smeg << 8)) 492 493 494 #if defined(SUN4M) || defined(SUN4D) 495 #if 0 496 #if VM_PROT_READ != 1 || VM_PROT_WRITE != 2 || VM_PROT_EXECUTE != 4 497 #error fix protection code translation table 498 #endif 499 #endif 500 /* 501 * Translation table for kernel vs. PTE protection bits. 502 */ 503 const u_int protection_codes[2][8] = { 504 /* kernel */ 505 { 506 PPROT_N_RX, /* VM_PROT_NONE | VM_PROT_NONE | VM_PROT_NONE */ 507 PPROT_N_RX, /* VM_PROT_NONE | VM_PROT_NONE | VM_PROT_READ */ 508 PPROT_N_RWX, /* VM_PROT_NONE | VM_PROT_WRITE | VM_PROT_NONE */ 509 PPROT_N_RWX, /* VM_PROT_NONE | VM_PROT_WRITE | VM_PROT_READ */ 510 PPROT_N_RX, /* VM_PROT_EXECUTE | VM_PROT_NONE | VM_PROT_NONE */ 511 PPROT_N_RX, /* VM_PROT_EXECUTE | VM_PROT_NONE | VM_PROT_READ */ 512 PPROT_N_RWX, /* VM_PROT_EXECUTE | VM_PROT_WRITE | VM_PROT_NONE */ 513 PPROT_N_RWX, /* VM_PROT_EXECUTE | VM_PROT_WRITE | VM_PROT_READ */ 514 }, 515 516 /* user */ 517 { 518 PPROT_N_RX, /* VM_PROT_NONE | VM_PROT_NONE | VM_PROT_NONE */ 519 PPROT_R_R, /* VM_PROT_NONE | VM_PROT_NONE | VM_PROT_READ */ 520 PPROT_RW_RW, /* VM_PROT_NONE | VM_PROT_WRITE | VM_PROT_NONE */ 521 PPROT_RW_RW, /* VM_PROT_NONE | VM_PROT_WRITE | VM_PROT_READ */ 522 PPROT_X_X, /* VM_PROT_EXECUTE | VM_PROT_NONE | VM_PROT_NONE */ 523 PPROT_RX_RX, /* VM_PROT_EXECUTE | VM_PROT_NONE | VM_PROT_READ */ 524 PPROT_RWX_RWX, /* VM_PROT_EXECUTE | VM_PROT_WRITE | VM_PROT_NONE */ 525 PPROT_RWX_RWX, /* VM_PROT_EXECUTE | VM_PROT_WRITE | VM_PROT_READ */ 526 } 527 }; 528 #define pte_kprot4m(prot) (protection_codes[0][(prot)]) 529 #define pte_uprot4m(prot) (protection_codes[1][(prot)]) 530 #define pte_prot4m(pm, prot) \ 531 (protection_codes[(pm) == pmap_kernel() ? 0 : 1][(prot)]) 532 533 void setpte4m(vaddr_t va, int pte); 534 void setpgt4m(int *ptep, int pte); 535 void setpgt4m_va(vaddr_t, int *, int, int, int, u_int); 536 int updatepte4m(vaddr_t, int *, int, int, int, u_int); 537 #endif /* SUN4M || SUN4D */ 538 539 #if defined(MULTIPROCESSOR) 540 #define PMAP_SET_CPUSET(pmap, cpi) \ 541 (pmap->pm_cpuset |= (1 << (cpi)->ci_cpuid)) 542 #define PMAP_CLR_CPUSET(pmap, cpi) \ 543 (pmap->pm_cpuset &= ~(1 << (cpi)->ci_cpuid)) 544 #define PMAP_CPUSET(pmap) (pmap->pm_cpuset) 545 #else 546 #define PMAP_SET_CPUSET(pmap, cpi) /* nothing */ 547 #define PMAP_CLR_CPUSET(pmap, cpi) /* nothing */ 548 #define PMAP_CPUSET(pmap) 1 /* XXX: 1 or 0? */ 549 #endif /* MULTIPROCESSOR */ 550 551 552 /* Function pointer messiness for supporting multiple sparc architectures 553 * within a single kernel: notice that there are two versions of many of the 554 * functions within this file/module, one for the sun4/sun4c and the other 555 * for the sun4m. For performance reasons (since things like pte bits don't 556 * map nicely between the two architectures), there are separate functions 557 * rather than unified functions which test the cputyp variable. If only 558 * one architecture is being used, then the non-suffixed function calls 559 * are macro-translated into the appropriate xxx4_4c or xxx4m call. If 560 * multiple architectures are defined, the calls translate to (*xxx_p), 561 * i.e. they indirect through function pointers initialized as appropriate 562 * to the run-time architecture in pmap_bootstrap. See also pmap.h. 563 */ 564 565 #if defined(SUN4M) || defined(SUN4D) 566 static void mmu_setup4m_L1(int, struct pmap *); 567 static void mmu_setup4m_L2(int, struct regmap *); 568 static void mmu_setup4m_L3(int, struct segmap *); 569 /*static*/ void mmu_reservemon4m(struct pmap *); 570 571 /*static*/ void pmap_changeprot4m(pmap_t, vaddr_t, vm_prot_t, int); 572 /*static*/ void pmap_rmk4m(struct pmap *, vaddr_t, vaddr_t, int, int); 573 /*static*/ void pmap_rmu4m(struct pmap *, vaddr_t, vaddr_t, int, int); 574 /*static*/ int pmap_enk4m(struct pmap *, vaddr_t, vm_prot_t, 575 int, struct vm_page *, int); 576 /*static*/ int pmap_enu4m(struct pmap *, vaddr_t, vm_prot_t, 577 int, struct vm_page *, int); 578 /*static*/ void pv_changepte4m(struct vm_page *, int, int); 579 /*static*/ int pv_syncflags4m(struct vm_page *); 580 /*static*/ int pv_link4m(struct vm_page *, struct pmap *, vaddr_t, u_int *); 581 /*static*/ void pv_unlink4m(struct vm_page *, struct pmap *, vaddr_t); 582 #endif 583 584 #if defined(SUN4) || defined(SUN4C) 585 /*static*/ void mmu_reservemon4_4c(int *, int *); 586 /*static*/ void pmap_changeprot4_4c(pmap_t, vaddr_t, vm_prot_t, int); 587 /*static*/ void pmap_rmk4_4c(struct pmap *, vaddr_t, vaddr_t, int, int); 588 /*static*/ void pmap_rmu4_4c(struct pmap *, vaddr_t, vaddr_t, int, int); 589 /*static*/ int pmap_enk4_4c(struct pmap *, vaddr_t, vm_prot_t, 590 int, struct vm_page *, int); 591 /*static*/ int pmap_enu4_4c(struct pmap *, vaddr_t, vm_prot_t, 592 int, struct vm_page *, int); 593 /*static*/ void pv_changepte4_4c(struct vm_page *, int, int); 594 /*static*/ int pv_syncflags4_4c(struct vm_page *); 595 /*static*/ int pv_link4_4c(struct vm_page *, struct pmap *, vaddr_t, u_int *); 596 /*static*/ void pv_unlink4_4c(struct vm_page *, struct pmap *, vaddr_t); 597 #endif 598 599 #if !(defined(SUN4M) || defined(SUN4D)) && (defined(SUN4) || defined(SUN4C)) 600 #define pmap_rmk pmap_rmk4_4c 601 #define pmap_rmu pmap_rmu4_4c 602 603 #elif (defined(SUN4M) || defined(SUN4D)) && !(defined(SUN4) || defined(SUN4C)) 604 #define pmap_rmk pmap_rmk4m 605 #define pmap_rmu pmap_rmu4m 606 607 #else /* must use function pointers */ 608 609 /* function pointer declarations */ 610 /* from pmap.h: */ 611 bool (*pmap_clear_modify_p)(struct vm_page *); 612 bool (*pmap_clear_reference_p)(struct vm_page *); 613 int (*pmap_enter_p)(pmap_t, vaddr_t, paddr_t, vm_prot_t, u_int); 614 bool (*pmap_extract_p)(pmap_t, vaddr_t, paddr_t *); 615 bool (*pmap_is_modified_p)(struct vm_page *); 616 bool (*pmap_is_referenced_p)(struct vm_page *); 617 void (*pmap_kenter_pa_p)(vaddr_t, paddr_t, vm_prot_t, u_int); 618 void (*pmap_kremove_p)(vaddr_t, vsize_t); 619 void (*pmap_kprotect_p)(vaddr_t, vsize_t, vm_prot_t); 620 void (*pmap_page_protect_p)(struct vm_page *, vm_prot_t); 621 void (*pmap_protect_p)(pmap_t, vaddr_t, vaddr_t, vm_prot_t); 622 /* local: */ 623 void (*pmap_rmk_p)(struct pmap *, vaddr_t, vaddr_t, int, int); 624 void (*pmap_rmu_p)(struct pmap *, vaddr_t, vaddr_t, int, int); 625 626 #define pmap_rmk (*pmap_rmk_p) 627 #define pmap_rmu (*pmap_rmu_p) 628 629 #endif 630 631 /* --------------------------------------------------------------*/ 632 633 /* 634 * Next we have some sun4m/4d-specific routines which have no 4/4c 635 * counterparts, or which are 4/4c macros. 636 */ 637 638 #if defined(SUN4M) || defined(SUN4D) 639 /* 640 * SP versions of the tlb flush operations. 641 * 642 * Turn off traps to prevent register window overflows from writing 643 * user windows to the wrong stack. Cf. tlb_flush_page_real() &c. 644 */ 645 static void 646 sp_tlb_flush(int va, int ctx, int lvl) 647 { 648 int opsr, octx; 649 650 va &= ~0xfff; 651 va |= lvl; 652 653 /* 654 * Turn off traps. 655 * 656 * Like setpsr((opsr = getpsr()) & ~PSR_ET); but we can shave 657 * off one instruction b/c we never disable traps recursively, 658 * so we can use the xor done by wrpsr itself to clear the 659 * bit. 660 * 661 * XXX: Add to asm.h? We can use this in cache.c too. 662 */ 663 opsr = getpsr(); /* KDASSERT(opsr & PSR_ET); */ 664 __asm volatile ("wr %0, %1, %%psr" 665 :: "r"(opsr), "n"(PSR_ET) : "memory"); 666 __asm volatile ("nop; nop; nop"); 667 668 octx = getcontext4m(); /* save context */ 669 670 /* Do the TLB flush in "ctx" */ 671 setcontext4m(ctx); 672 __asm volatile ("sta %%g0, [%0]%1" :: "r"(va), "n"(ASI_SRMMUFP)); 673 674 setcontext4m(octx); /* restore context */ 675 setpsr(opsr); /* turn traps on again */ 676 } 677 678 static inline void 679 sp_tlb_flush_all(void) 680 { 681 682 sta(ASI_SRMMUFP_LN, ASI_SRMMUFP, 0); 683 } 684 685 #if defined(MULTIPROCESSOR) 686 /* 687 * The SMP versions of the tlb flush routines. We only need to 688 * do a cross call for these on sun4m (Mbus) systems. sun4d systems 689 * have an Xbus which broadcasts TLB demaps in hardware. 690 */ 691 692 static inline void smp_tlb_flush_page (int va, int ctx, u_int cpuset); 693 static inline void smp_tlb_flush_segment (int va, int ctx, u_int cpuset); 694 static inline void smp_tlb_flush_region (int va, int ctx, u_int cpuset); 695 static inline void smp_tlb_flush_context (int ctx, u_int cpuset); 696 static inline void smp_tlb_flush_all (void); 697 698 static inline void 699 smp_tlb_flush_page(int va, int ctx, u_int cpuset) 700 { 701 702 if (CPU_ISSUN4D) { 703 sp_tlb_flush(va, ctx, ASI_SRMMUFP_L3); 704 } else 705 FXCALL3(sp_tlb_flush, ft_tlb_flush, va, ctx, ASI_SRMMUFP_L3, cpuset); 706 } 707 708 static inline void 709 smp_tlb_flush_segment(int va, int ctx, u_int cpuset) 710 { 711 712 if (CPU_ISSUN4D) { 713 sp_tlb_flush(va, ctx, ASI_SRMMUFP_L2); 714 } else 715 FXCALL3(sp_tlb_flush, ft_tlb_flush, va, ctx, ASI_SRMMUFP_L2, cpuset); 716 } 717 718 static inline void 719 smp_tlb_flush_region(int va, int ctx, u_int cpuset) 720 { 721 722 if (CPU_ISSUN4D) { 723 sp_tlb_flush(va, ctx, ASI_SRMMUFP_L1); 724 } else 725 FXCALL3(sp_tlb_flush, ft_tlb_flush, va, ctx, ASI_SRMMUFP_L1, cpuset); 726 } 727 728 static inline void 729 smp_tlb_flush_context(int ctx, u_int cpuset) 730 { 731 732 if (CPU_ISSUN4D) { 733 sp_tlb_flush(0, ctx, ASI_SRMMUFP_L0); 734 } else 735 FXCALL3(sp_tlb_flush, ft_tlb_flush, 0, ctx, ASI_SRMMUFP_L0, cpuset); 736 } 737 738 static inline void 739 smp_tlb_flush_all(void) 740 { 741 742 if (CPU_ISSUN4D) { 743 sp_tlb_flush_all(); 744 } else 745 XCALL0(sp_tlb_flush_all, CPUSET_ALL); 746 } 747 #endif /* MULTIPROCESSOR */ 748 749 #if defined(MULTIPROCESSOR) 750 #define tlb_flush_page(va,ctx,s) smp_tlb_flush_page(va,ctx,s) 751 #define tlb_flush_segment(va,ctx,s) smp_tlb_flush_segment(va,ctx,s) 752 #define tlb_flush_region(va,ctx,s) smp_tlb_flush_region(va,ctx,s) 753 #define tlb_flush_context(ctx,s) smp_tlb_flush_context(ctx,s) 754 #define tlb_flush_all() smp_tlb_flush_all() 755 #else 756 #define tlb_flush_page(va,ctx,s) sp_tlb_flush(va,ctx,ASI_SRMMUFP_L3) 757 #define tlb_flush_segment(va,ctx,s) sp_tlb_flush(va,ctx,ASI_SRMMUFP_L2) 758 #define tlb_flush_region(va,ctx,s) sp_tlb_flush(va,ctx,ASI_SRMMUFP_L1) 759 #define tlb_flush_context(ctx,s) sp_tlb_flush(0,ctx,ASI_SRMMUFP_L0) 760 #define tlb_flush_all() sp_tlb_flush_all() 761 #endif /* MULTIPROCESSOR */ 762 763 static u_int VA2PA(void *); 764 static u_long srmmu_bypass_read(u_long); 765 766 /* 767 * VA2PA(addr) -- converts a virtual address to a physical address using 768 * the MMU's currently-installed page tables. As a side effect, the address 769 * translation used may cause the associated pte to be encached. The correct 770 * context for VA must be set before this is called. 771 * 772 * This routine should work with any level of mapping, as it is used 773 * during bootup to interact with the ROM's initial L1 mapping of the kernel. 774 */ 775 static u_int 776 VA2PA(void *addr) 777 { 778 u_int pte; 779 780 /* 781 * We'll use that handy SRMMU flush/probe. 782 * Try each level in turn until we find a valid pte. Otherwise panic. 783 */ 784 785 pte = lda(((u_int)addr & ~0xfff) | ASI_SRMMUFP_L3, ASI_SRMMUFP); 786 /* Unlock fault status; required on Hypersparc modules */ 787 (void)lda(SRMMU_SFSR, ASI_SRMMU); 788 if ((pte & SRMMU_TETYPE) == SRMMU_TEPTE) 789 return (((pte & SRMMU_PPNMASK) << SRMMU_PPNPASHIFT) | 790 ((u_int)addr & 0xfff)); 791 792 /* A `TLB Flush Entire' is required before any L0, L1 or L2 probe */ 793 tlb_flush_all_real(); 794 795 pte = lda(((u_int)addr & ~0xfff) | ASI_SRMMUFP_L2, ASI_SRMMUFP); 796 if ((pte & SRMMU_TETYPE) == SRMMU_TEPTE) 797 return (((pte & SRMMU_PPNMASK) << SRMMU_PPNPASHIFT) | 798 ((u_int)addr & 0x3ffff)); 799 pte = lda(((u_int)addr & ~0xfff) | ASI_SRMMUFP_L1, ASI_SRMMUFP); 800 if ((pte & SRMMU_TETYPE) == SRMMU_TEPTE) 801 return (((pte & SRMMU_PPNMASK) << SRMMU_PPNPASHIFT) | 802 ((u_int)addr & 0xffffff)); 803 pte = lda(((u_int)addr & ~0xfff) | ASI_SRMMUFP_L0, ASI_SRMMUFP); 804 if ((pte & SRMMU_TETYPE) == SRMMU_TEPTE) 805 return (((pte & SRMMU_PPNMASK) << SRMMU_PPNPASHIFT) | 806 ((u_int)addr & 0xffffffff)); 807 808 #ifdef DIAGNOSTIC 809 panic("VA2PA: Asked to translate unmapped VA %p", addr); 810 #else 811 return (0); 812 #endif 813 } 814 815 /* 816 * Atomically update a PTE entry, coping with hardware updating the 817 * PTE at the same time we are. This is the procedure that is 818 * recommended in the SuperSPARC user's manual. 819 */ 820 int 821 updatepte4m(vaddr_t va, int *pte, int bic, int bis, int ctx, u_int cpuset) 822 { 823 int oldval, swapval; 824 volatile int *vpte = (volatile int *)pte; 825 bool can_lock = lock_available; 826 827 /* 828 * Can only be one of these happening in the system 829 * at any one time. 830 */ 831 if (__predict_true(can_lock)) 832 mutex_spin_enter(&demap_lock); 833 834 /* 835 * The idea is to loop swapping zero into the pte, flushing 836 * it, and repeating until it stays zero. At this point, 837 * there should be no more hardware accesses to this PTE 838 * so we can modify it without losing any mod/ref info. 839 */ 840 oldval = 0; 841 do { 842 swapval = 0; 843 swap(vpte, swapval); 844 tlb_flush_page(va, ctx, cpuset); 845 oldval |= swapval; 846 } while (__predict_false(*vpte != 0)); 847 848 swapval = (oldval & ~bic) | bis; 849 swap(vpte, swapval); 850 851 if (__predict_true(can_lock)) 852 mutex_spin_exit(&demap_lock); 853 854 return (oldval); 855 } 856 857 inline void 858 setpgt4m(int *ptep, int pte) 859 { 860 861 kpreempt_disable(); 862 swap(ptep, pte); 863 kpreempt_enable(); 864 } 865 866 inline void 867 setpgt4m_va(vaddr_t va, int *ptep, int pte, int pageflush, int ctx, 868 u_int cpuset) 869 { 870 871 #if defined(MULTIPROCESSOR) 872 updatepte4m(va, ptep, 0xffffffff, pte, pageflush ? ctx : 0, cpuset); 873 #else 874 kpreempt_disable(); 875 if (__predict_true(pageflush)) 876 tlb_flush_page(va, ctx, 0); 877 setpgt4m(ptep, pte); 878 kpreempt_enable(); 879 #endif /* MULTIPROCESSOR */ 880 } 881 882 /* Set the page table entry for va to pte. */ 883 void 884 setpte4m(vaddr_t va, int pte) 885 { 886 struct pmap *pm; 887 struct regmap *rp; 888 struct segmap *sp; 889 890 #ifdef DEBUG 891 if (getcontext4m() != 0) 892 panic("setpte4m: user context"); 893 #endif 894 895 pm = pmap_kernel(); 896 rp = &pm->pm_regmap[VA_VREG(va)]; 897 sp = &rp->rg_segmap[VA_VSEG(va)]; 898 899 tlb_flush_page(va, 0, CPUSET_ALL); 900 setpgt4m(sp->sg_pte + VA_SUN4M_VPG(va), pte); 901 } 902 903 /* 904 * Page table pool back-end. 905 */ 906 void * 907 pgt_page_alloc(struct pool *pp, int flags) 908 { 909 int cacheit = (CACHEINFO.c_flags & CACHE_PAGETABLES) != 0; 910 uint64_t ticket; 911 struct vm_page *pg; 912 vaddr_t va; 913 paddr_t pa; 914 915 /* Allocate a page of physical memory */ 916 while (ticket = uvm_wait_prepare(), 917 (pg = uvm_pagealloc(NULL, 0, NULL, 0)) == NULL && 918 (flags & PR_WAITOK) != 0) { 919 uvm_wait("pgtpg", ticket); 920 } 921 if (pg == NULL) { 922 KASSERT((flags & PR_WAITOK) == 0); 923 return NULL; 924 } 925 926 /* Allocate virtual memory */ 927 va = uvm_km_alloc(kernel_map, PAGE_SIZE, 0, UVM_KMF_VAONLY | 928 ((flags & PR_WAITOK) ? 0 : UVM_KMF_NOWAIT | UVM_KMF_TRYLOCK)); 929 if (va == 0) { 930 KASSERT((flags & PR_WAITOK) == 0); 931 uvm_pagefree(pg); 932 return (NULL); 933 } 934 935 /* 936 * On systems with a physical data cache we need to flush this page 937 * from the cache if the pagetables cannot be cached. 938 * On systems with a virtually indexed data cache, we only need 939 * to map it non-cacheable, since the page is not currently mapped. 940 */ 941 pa = VM_PAGE_TO_PHYS(pg); 942 if (cacheit == 0) 943 pcache_flush_page(pa, 1); 944 945 /* Map the page */ 946 pmap_kenter_pa(va, pa | (cacheit ? 0 : PMAP_NC), 947 VM_PROT_READ | VM_PROT_WRITE, 0); 948 pmap_update(pmap_kernel()); 949 950 return ((void *)va); 951 } 952 953 void 954 pgt_page_free(struct pool *pp, void *v) 955 { 956 vaddr_t va; 957 paddr_t pa; 958 bool rv __diagused; 959 960 va = (vaddr_t)v; 961 rv = pmap_extract(pmap_kernel(), va, &pa); 962 KASSERT(rv); 963 uvm_pagefree(PHYS_TO_VM_PAGE(pa)); 964 pmap_kremove(va, PAGE_SIZE); 965 uvm_km_free(kernel_map, va, PAGE_SIZE, UVM_KMF_VAONLY); 966 } 967 #endif /* SUN4M || SUN4D */ 968 969 /*----------------------------------------------------------------*/ 970 971 /* 972 * The following three macros are to be used in sun4/sun4c code only. 973 */ 974 #if defined(SUN4_MMU3L) 975 #define CTX_USABLE(pm,rp) ( \ 976 ((pm)->pm_ctx != NULL && \ 977 (!HASSUN4_MMU3L || (rp)->rg_smeg != reginval)) \ 978 ) 979 #else 980 #define CTX_USABLE(pm,rp) ((pm)->pm_ctx != NULL ) 981 #endif 982 983 #define GAP_WIDEN(pm,vr) do if (CPU_HAS_SUNMMU) { \ 984 if (vr + 1 == pm->pm_gap_start) \ 985 pm->pm_gap_start = vr; \ 986 if (vr == pm->pm_gap_end) \ 987 pm->pm_gap_end = vr + 1; \ 988 } while (0) 989 990 #define GAP_SHRINK(pm,vr) do if (CPU_HAS_SUNMMU) { \ 991 int x; \ 992 x = pm->pm_gap_start + (pm->pm_gap_end - pm->pm_gap_start) / 2; \ 993 if (vr > x) { \ 994 if (vr < pm->pm_gap_end) \ 995 pm->pm_gap_end = vr; \ 996 } else { \ 997 if (vr >= pm->pm_gap_start && x != pm->pm_gap_start) \ 998 pm->pm_gap_start = vr + 1; \ 999 } \ 1000 } while (0) 1001 1002 1003 static void get_phys_mem(void **); 1004 #if 0 /* not used */ 1005 void kvm_iocache(char *, int); 1006 #endif 1007 1008 #ifdef DEBUG 1009 void pm_check(char *, struct pmap *); 1010 void pm_check_k(char *, struct pmap *); 1011 void pm_check_u(char *, struct pmap *); 1012 #endif 1013 1014 /* 1015 * During the PMAP bootstrap, we can use a simple translation to map a 1016 * kernel virtual address to a psysical memory address (this is arranged 1017 * in locore). Usually, KERNBASE maps to physical address 0. This is always 1018 * the case on sun4 and sun4c machines. On sun4m machines -- if no memory is 1019 * installed in the bank corresponding to physical address 0 -- the PROM may 1020 * elect to load us at some other address, presumably at the start of 1021 * the first memory bank that is available. We set the up the variable 1022 * `va2pa_offset' to hold the physical address corresponding to KERNBASE. 1023 */ 1024 1025 static u_long va2pa_offset; 1026 #define PMAP_BOOTSTRAP_VA2PA(v) ((paddr_t)((u_long)(v) - va2pa_offset)) 1027 #define PMAP_BOOTSTRAP_PA2VA(p) ((vaddr_t)((u_long)(p) + va2pa_offset)) 1028 1029 /* 1030 * Grab physical memory list. 1031 * While here, compute `physmem'. 1032 */ 1033 void 1034 get_phys_mem(void **top) 1035 { 1036 struct memarr *mp; 1037 char *p; 1038 int i; 1039 1040 /* Load the memory descriptor array at the current kernel top */ 1041 p = (void *)ALIGN(*top); 1042 pmemarr = (struct memarr *)p; 1043 npmemarr = prom_makememarr(pmemarr, 1000, MEMARR_AVAILPHYS); 1044 1045 /* Update kernel top */ 1046 p += npmemarr * sizeof(struct memarr); 1047 *top = p; 1048 1049 for (physmem = 0, mp = pmemarr, i = npmemarr; --i >= 0; mp++) 1050 physmem += btoc(mp->len); 1051 } 1052 1053 1054 /* 1055 * Support functions for vm_page_bootstrap(). 1056 */ 1057 1058 /* 1059 * How much virtual space does this kernel have? 1060 * (After mapping kernel text, data, etc.) 1061 */ 1062 void 1063 pmap_virtual_space(vaddr_t *v_start, vaddr_t *v_end) 1064 { 1065 1066 *v_start = virtual_avail; 1067 *v_end = virtual_end; 1068 } 1069 1070 #ifdef PMAP_GROWKERNEL 1071 vaddr_t 1072 pmap_growkernel(vaddr_t eva) 1073 { 1074 struct regmap *rp; 1075 struct segmap *sp; 1076 int vr, evr, M, N, i; 1077 struct vm_page *pg; 1078 vaddr_t va; 1079 1080 if (eva <= virtual_end) 1081 return (virtual_end); 1082 1083 /* For now, only implemented for sun4/sun4c */ 1084 KASSERT(CPU_HAS_SUNMMU); 1085 1086 /* 1087 * Map in the next region(s) 1088 */ 1089 1090 /* Get current end-of-kernel */ 1091 vr = virtual_end >> RGSHIFT; 1092 evr = (eva + NBPRG - 1) >> RGSHIFT; 1093 eva = evr << RGSHIFT; 1094 1095 if (eva > VM_MAX_KERNEL_ADDRESS) 1096 panic("growkernel: grown too large: %lx", eva); 1097 1098 /* 1099 * Divide a region in N blocks of M segments, where each segment 1100 * block can have its PTEs mapped by one page. 1101 * N should come out to 1 for 8K pages and to 4 for 4K pages. 1102 */ 1103 M = NBPG / (NPTESG * sizeof(int)); 1104 N = (NBPRG/NBPSG) / M; 1105 1106 while (vr < evr) { 1107 rp = &pmap_kernel()->pm_regmap[vr]; 1108 for (i = 0; i < N; i++) { 1109 sp = &rp->rg_segmap[i * M]; 1110 va = (vaddr_t)sp->sg_pte; 1111 pg = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_USERESERVE); 1112 if (pg == NULL) 1113 panic("growkernel: out of memory"); 1114 pmap_kenter_pa(va, VM_PAGE_TO_PHYS(pg), 1115 VM_PROT_READ | VM_PROT_WRITE, 0); 1116 } 1117 } 1118 1119 virtual_end = eva; 1120 return (eva); 1121 } 1122 #endif 1123 1124 /* 1125 * Helper routine that hands off available physical pages to the VM system. 1126 */ 1127 static void 1128 pmap_page_upload(void) 1129 { 1130 int n; 1131 paddr_t pstart, pend; 1132 1133 /* First, the `etext gap' */ 1134 pstart = PMAP_BOOTSTRAP_VA2PA(etext_gap_start); 1135 pend = PMAP_BOOTSTRAP_VA2PA(etext_gap_end); 1136 1137 #ifdef DIAGNOSTIC 1138 if (avail_start <= pstart) 1139 panic("pmap_page_upload: etext gap overlap: %lx < %lx", 1140 (u_long)avail_start, (u_long)pstart); 1141 #endif 1142 if (etext_gap_start < etext_gap_end) { 1143 vm_first_phys = pstart; 1144 uvm_page_physload( 1145 atop(pstart), 1146 atop(pend), 1147 atop(pstart), 1148 atop(pend), VM_FREELIST_DEFAULT); 1149 } 1150 1151 for (n = 0; n < npmemarr; n++) { 1152 1153 pstart = pmemarr[n].addr; 1154 pend = pstart + pmemarr[n].len; 1155 1156 /* Update vm_{first_last}_phys */ 1157 if (vm_first_phys > pstart) 1158 vm_first_phys = pstart; 1159 if (vm_last_phys < pend) 1160 vm_last_phys = pend; 1161 1162 /* 1163 * Exclude any memory allocated for the kernel as computed 1164 * by pmap_bootstrap(), i.e. the range 1165 * [KERNBASE_PA, avail_start>. 1166 * Note that this will also exclude the `etext gap' range 1167 * already uploaded above. 1168 */ 1169 if (pstart < PMAP_BOOTSTRAP_VA2PA(KERNBASE)) { 1170 /* 1171 * This segment starts below the kernel load address. 1172 * Chop it off at the pstart of the kernel. 1173 */ 1174 paddr_t chop = PMAP_BOOTSTRAP_VA2PA(KERNBASE); 1175 1176 if (pend < chop) 1177 chop = pend; 1178 #ifdef DEBUG 1179 prom_printf("bootstrap gap: pstart %lx, chop %lx, pend %lx\n", 1180 pstart, chop, pend); 1181 #endif 1182 uvm_page_physload( 1183 atop(pstart), 1184 atop(chop), 1185 atop(pstart), 1186 atop(chop), 1187 VM_FREELIST_DEFAULT); 1188 1189 /* 1190 * Adjust the start address to reflect the 1191 * uploaded portion of this segment. 1192 */ 1193 pstart = chop; 1194 } 1195 1196 /* Skip the current kernel address range */ 1197 if (pstart <= avail_start && avail_start < pend) 1198 pstart = avail_start; 1199 1200 if (pstart == pend) 1201 continue; 1202 1203 /* Upload (the rest of) this segment */ 1204 uvm_page_physload( 1205 atop(pstart), 1206 atop(pend), 1207 atop(pstart), 1208 atop(pend), VM_FREELIST_DEFAULT); 1209 } 1210 1211 #if defined(MULTIPROCESSOR) 1212 { 1213 CPU_INFO_ITERATOR cpunum; 1214 struct cpu_info *cpi; 1215 1216 for (CPU_INFO_FOREACH(cpunum, cpi)) { 1217 if (cpi->ci_free_sva1) 1218 uvm_page_physload(atop(PMAP_BOOTSTRAP_VA2PA(cpi->ci_free_sva1)), 1219 atop(PMAP_BOOTSTRAP_VA2PA(cpi->ci_free_eva1)), 1220 atop(PMAP_BOOTSTRAP_VA2PA(cpi->ci_free_sva1)), 1221 atop(PMAP_BOOTSTRAP_VA2PA(cpi->ci_free_eva1)), 1222 VM_FREELIST_DEFAULT); 1223 if (cpi->ci_free_sva2) 1224 uvm_page_physload(atop(PMAP_BOOTSTRAP_VA2PA(cpi->ci_free_sva2)), 1225 atop(PMAP_BOOTSTRAP_VA2PA(cpi->ci_free_eva2)), 1226 atop(PMAP_BOOTSTRAP_VA2PA(cpi->ci_free_sva2)), 1227 atop(PMAP_BOOTSTRAP_VA2PA(cpi->ci_free_eva2)), 1228 VM_FREELIST_DEFAULT); 1229 } 1230 } 1231 #endif 1232 } 1233 1234 /* 1235 * This routine is used by mmrw() to validate access to `/dev/mem'. 1236 */ 1237 int 1238 pmap_pa_exists(paddr_t pa) 1239 { 1240 int nmem; 1241 struct memarr *mp; 1242 1243 for (mp = pmemarr, nmem = npmemarr; --nmem >= 0; mp++) { 1244 if (pa >= mp->addr && pa < mp->addr + mp->len) 1245 return 1; 1246 } 1247 1248 return 0; 1249 } 1250 1251 /* update pv_flags given a valid pte */ 1252 #define MR4_4C(pte) (((pte) >> PG_M_SHIFT) & (PV_MOD | PV_REF)) 1253 #define MR4M(pte) (((pte) >> PG_M_SHIFT4M) & (PV_MOD4M | PV_REF4M)) 1254 1255 /*----------------------------------------------------------------*/ 1256 1257 /* 1258 * Agree with the monitor ROM as to how many MMU entries are 1259 * to be reserved, and map all of its segments into all contexts. 1260 * 1261 * Unfortunately, while the Version 0 PROM had a nice linked list of 1262 * taken virtual memory, the Version 2 PROM provides instead a convoluted 1263 * description of *free* virtual memory. Rather than invert this, we 1264 * resort to two magic constants from the PROM vector description file. 1265 */ 1266 #if defined(SUN4) || defined(SUN4C) 1267 void 1268 mmu_reservemon4_4c(int *nrp, int *nsp) 1269 { 1270 u_int va = 0, eva = 0; 1271 int mmuseg, i, nr, ns, vr; 1272 int *pte; 1273 #if defined(SUN4_MMU3L) 1274 int mmureg, lastvr = 0; 1275 #endif 1276 struct regmap *rp; 1277 1278 #if defined(SUN4) 1279 if (CPU_ISSUN4) { 1280 prom_vstart = va = OLDMON_STARTVADDR; 1281 prom_vend = eva = OLDMON_ENDVADDR; 1282 } 1283 #endif 1284 #if defined(SUN4C) 1285 if (CPU_ISSUN4C) { 1286 prom_vstart = va = OPENPROM_STARTVADDR; 1287 prom_vend = eva = OPENPROM_ENDVADDR; 1288 } 1289 #endif 1290 ns = *nsp; 1291 nr = *nrp; 1292 while (va < eva) { 1293 vr = VA_VREG(va); 1294 rp = &pmap_kernel()->pm_regmap[vr]; 1295 1296 #if defined(SUN4_MMU3L) 1297 if (HASSUN4_MMU3L && vr != lastvr) { 1298 lastvr = vr; 1299 mmureg = getregmap(va); 1300 if (mmureg < nr) 1301 rp->rg_smeg = nr = mmureg; 1302 /* 1303 * On 3-level MMU machines, we distribute regions, 1304 * rather than segments, amongst the contexts. 1305 */ 1306 for (i = ncontext; --i > 0;) 1307 prom_setcontext(i, (void *)va, mmureg); 1308 } 1309 #endif 1310 mmuseg = getsegmap(va); 1311 if (mmuseg < ns) 1312 ns = mmuseg; 1313 1314 if (!HASSUN4_MMU3L) 1315 for (i = ncontext; --i > 0;) 1316 prom_setcontext(i, (void *)va, mmuseg); 1317 1318 if (mmuseg == seginval) { 1319 va += NBPSG; 1320 continue; 1321 } 1322 /* 1323 * Another PROM segment. Enter into region map. 1324 * Assume the entire segment is valid. 1325 */ 1326 rp->rg_nsegmap += 1; 1327 rp->rg_segmap[VA_VSEG(va)].sg_pmeg = mmuseg; 1328 rp->rg_segmap[VA_VSEG(va)].sg_npte = NPTESG; 1329 pte = rp->rg_segmap[VA_VSEG(va)].sg_pte; 1330 1331 /* PROM maps its memory user-accessible: fix it. */ 1332 for (i = NPTESG; --i >= 0; va += NBPG, pte++) { 1333 *pte = getpte4(va) | PG_S; 1334 setpte4(va, *pte); 1335 } 1336 } 1337 *nsp = ns; 1338 *nrp = nr; 1339 return; 1340 } 1341 #endif 1342 1343 #if defined(SUN4M) || defined(SUN4D) /* SRMMU versions of above */ 1344 1345 u_long 1346 srmmu_bypass_read(u_long paddr) 1347 { 1348 unsigned long v; 1349 1350 if (cpuinfo.mxcc) { 1351 /* 1352 * We're going to have to use MMU passthrough. If we're on 1353 * a Viking SuperSPARC with a MultiCache Controller, we 1354 * need to set the AC (Alternate Cacheable) bit in the MMU's 1355 * control register in order to not by-pass the cache. 1356 */ 1357 1358 unsigned long s = lda(SRMMU_PCR, ASI_SRMMU); 1359 1360 /* set MMU AC bit */ 1361 sta(SRMMU_PCR, ASI_SRMMU, s | VIKING_PCR_AC); 1362 v = lda(paddr, ASI_BYPASS); 1363 sta(SRMMU_PCR, ASI_SRMMU, s); 1364 } else 1365 v = lda(paddr, ASI_BYPASS); 1366 1367 return (v); 1368 } 1369 1370 1371 /* 1372 * Take the monitor's initial page table layout, convert it to 3rd-level pte's 1373 * (it starts out as a L1 mapping), and install it along with a set of kernel 1374 * mapping tables as the kernel's initial page table setup. Also create and 1375 * enable a context table. I suppose we also want to block user-mode access 1376 * to the new kernel/ROM mappings. 1377 */ 1378 1379 /* 1380 * mmu_reservemon4m(): Copies the existing (ROM) page tables to kernel space, 1381 * converting any L1/L2 PTEs to L3 PTEs. Does *not* copy the L1 entry mapping 1382 * the kernel at KERNBASE since we don't want to map 16M of physical 1383 * memory for the kernel. Thus the kernel must be installed later! 1384 * Also installs ROM mappings into the kernel pmap. 1385 * NOTE: This also revokes all user-mode access to the mapped regions. 1386 */ 1387 void 1388 mmu_reservemon4m(struct pmap *kpmap) 1389 { 1390 unsigned int rom_ctxtbl; 1391 int te; 1392 1393 #if !(defined(PROM_AT_F0) || defined(MSIIEP)) 1394 prom_vstart = OPENPROM_STARTVADDR; 1395 prom_vend = OPENPROM_ENDVADDR; 1396 #else /* OBP3/OFW in JavaStations */ 1397 prom_vstart = 0xf0000000; 1398 #if defined(MSIIEP) 1399 prom_vend = 0xf0800000; 1400 #else 1401 prom_vend = 0xf0080000; 1402 #endif 1403 #endif 1404 1405 /* 1406 * XXX: although the sun4m can handle 36 bits of physical 1407 * address space, we assume that all these page tables, etc 1408 * are in the lower 4G (32-bits) of address space, i.e. out of I/O 1409 * space. Eventually this should be changed to support the 36 bit 1410 * physical addressing, in case some crazed ROM designer decides to 1411 * stick the pagetables up there. In that case, we should use MMU 1412 * transparent mode, (i.e. ASI 0x20 to 0x2f) to access 1413 * physical memory. 1414 */ 1415 1416 rom_ctxtbl = (lda(SRMMU_CXTPTR,ASI_SRMMU) << SRMMU_PPNPASHIFT); 1417 1418 te = srmmu_bypass_read(rom_ctxtbl); /* i.e. context 0 */ 1419 1420 switch (te & SRMMU_TETYPE) { 1421 case SRMMU_TEINVALID: 1422 cpuinfo.ctx_tbl[0] = SRMMU_TEINVALID; 1423 panic("mmu_reservemon4m: no existing L0 mapping! " 1424 "(How are we running?"); 1425 break; 1426 case SRMMU_TEPTE: 1427 panic("mmu_reservemon4m: can't handle ROM 4G page size"); 1428 /* XXX: Should make this work, however stupid it is */ 1429 break; 1430 case SRMMU_TEPTD: 1431 mmu_setup4m_L1(te, kpmap); 1432 break; 1433 default: 1434 panic("mmu_reservemon4m: unknown pagetable entry type"); 1435 } 1436 } 1437 1438 /* regtblptd - PTD for region table to be remapped */ 1439 void 1440 mmu_setup4m_L1(int regtblptd, struct pmap *kpmap) 1441 { 1442 unsigned int regtblrover; 1443 int i; 1444 unsigned int te; 1445 struct regmap *rp; 1446 int j, k; 1447 1448 /* 1449 * Here we scan the region table to copy any entries which appear. 1450 * We are only concerned with regions in kernel space and above 1451 * (i.e. regions VA_VREG(KERNBASE)+1 to 0xff). We ignore the first 1452 * region (at VA_VREG(KERNBASE)), since that is the 16MB L1 mapping 1453 * that the ROM used to map the kernel in initially. Later, we will 1454 * rebuild a new L3 mapping for the kernel and install it before 1455 * switching to the new pagetables. 1456 */ 1457 regtblrover = 1458 ((regtblptd & ~SRMMU_TETYPE) << SRMMU_PPNPASHIFT) + 1459 (VA_VREG(KERNBASE)+1) * sizeof(long); /* kernel only */ 1460 1461 for (i = VA_VREG(KERNBASE) + 1; i < SRMMU_L1SIZE; 1462 i++, regtblrover += sizeof(long)) { 1463 1464 /* The region we're dealing with */ 1465 rp = &kpmap->pm_regmap[i]; 1466 1467 te = srmmu_bypass_read(regtblrover); 1468 switch(te & SRMMU_TETYPE) { 1469 case SRMMU_TEINVALID: 1470 break; 1471 1472 case SRMMU_TEPTE: 1473 #ifdef DEBUG 1474 prom_printf("mmu_setup4m_L1: " 1475 "converting region 0x%x from L1->L3\n", i); 1476 #endif 1477 /* 1478 * This region entry covers 64MB of memory -- or 1479 * (NSEGRG * NPTESG) pages -- which we must convert 1480 * into a 3-level description. 1481 */ 1482 1483 for (j = 0; j < SRMMU_L2SIZE; j++) { 1484 struct segmap *sp = &rp->rg_segmap[j]; 1485 1486 for (k = 0; k < SRMMU_L3SIZE; k++) { 1487 setpgt4m(&sp->sg_pte[k], 1488 (te & SRMMU_L1PPNMASK) | 1489 (j << SRMMU_L2PPNSHFT) | 1490 (k << SRMMU_L3PPNSHFT) | 1491 (te & SRMMU_PGBITSMSK) | 1492 ((te & SRMMU_PROT_MASK) | 1493 PPROT_U2S_OMASK) | 1494 SRMMU_TEPTE); 1495 } 1496 } 1497 break; 1498 1499 case SRMMU_TEPTD: 1500 mmu_setup4m_L2(te, rp); 1501 break; 1502 1503 default: 1504 panic("mmu_setup4m_L1: unknown pagetable entry type"); 1505 } 1506 } 1507 } 1508 1509 void 1510 mmu_setup4m_L2(int segtblptd, struct regmap *rp) 1511 { 1512 unsigned int segtblrover; 1513 int i, k; 1514 unsigned int te; 1515 struct segmap *sp; 1516 1517 segtblrover = (segtblptd & ~SRMMU_TETYPE) << SRMMU_PPNPASHIFT; 1518 for (i = 0; i < SRMMU_L2SIZE; i++, segtblrover += sizeof(long)) { 1519 1520 sp = &rp->rg_segmap[i]; 1521 1522 te = srmmu_bypass_read(segtblrover); 1523 switch(te & SRMMU_TETYPE) { 1524 case SRMMU_TEINVALID: 1525 break; 1526 1527 case SRMMU_TEPTE: 1528 #ifdef DEBUG 1529 prom_printf("mmu_setup4m_L2: converting L2 entry at segment 0x%x to L3\n",i); 1530 #endif 1531 /* 1532 * This segment entry covers 256KB of memory -- or 1533 * (NPTESG) pages -- which we must convert 1534 * into a 3-level description. 1535 */ 1536 for (k = 0; k < SRMMU_L3SIZE; k++) { 1537 setpgt4m(&sp->sg_pte[k], 1538 (te & SRMMU_L1PPNMASK) | 1539 (te & SRMMU_L2PPNMASK) | 1540 (k << SRMMU_L3PPNSHFT) | 1541 (te & SRMMU_PGBITSMSK) | 1542 ((te & SRMMU_PROT_MASK) | 1543 PPROT_U2S_OMASK) | 1544 SRMMU_TEPTE); 1545 } 1546 break; 1547 1548 case SRMMU_TEPTD: 1549 mmu_setup4m_L3(te, sp); 1550 break; 1551 1552 default: 1553 panic("mmu_setup4m_L2: unknown pagetable entry type"); 1554 } 1555 } 1556 } 1557 1558 void 1559 mmu_setup4m_L3(int pagtblptd, struct segmap *sp) 1560 { 1561 unsigned int pagtblrover; 1562 int i; 1563 unsigned int te; 1564 1565 pagtblrover = (pagtblptd & ~SRMMU_TETYPE) << SRMMU_PPNPASHIFT; 1566 for (i = 0; i < SRMMU_L3SIZE; i++, pagtblrover += sizeof(long)) { 1567 te = srmmu_bypass_read(pagtblrover); 1568 switch(te & SRMMU_TETYPE) { 1569 case SRMMU_TEINVALID: 1570 break; 1571 case SRMMU_TEPTE: 1572 setpgt4m(&sp->sg_pte[i], te | PPROT_U2S_OMASK); 1573 pmap_kernel()->pm_stats.resident_count++; 1574 break; 1575 case SRMMU_TEPTD: 1576 panic("mmu_setup4m_L3: PTD found in L3 page table"); 1577 default: 1578 panic("mmu_setup4m_L3: unknown pagetable entry type"); 1579 } 1580 } 1581 } 1582 #endif /* defined SUN4M || defined SUN4D */ 1583 1584 /*----------------------------------------------------------------*/ 1585 1586 #if defined(SUN4) || defined(SUN4C) 1587 /* 1588 * MMU management. 1589 */ 1590 static int me_alloc(struct mmuentry *, struct pmap *, int, int); 1591 static void me_free(struct pmap *, u_int); 1592 #if defined(SUN4_MMU3L) 1593 static int region_alloc(struct mmuentry *, struct pmap *, int); 1594 static void region_free(struct pmap *, u_int); 1595 #endif 1596 1597 1598 /* 1599 * Allocate an MMU entry (i.e., a PMEG). 1600 * If necessary, steal one from someone else. 1601 * Put it on the tail of the given queue 1602 * (which is either the LRU list or the locked list). 1603 * The locked list is not actually ordered, but this is easiest. 1604 * Also put it on the given (new) pmap's chain, 1605 * enter its pmeg number into that pmap's segmap, 1606 * and store the pmeg's new virtual segment number (me->me_vseg). 1607 * 1608 * This routine is large and complicated, but it must be fast 1609 * since it implements the dynamic allocation of MMU entries. 1610 */ 1611 1612 static inline int 1613 me_alloc(struct mmuentry *mh, struct pmap *newpm, int newvreg, int newvseg) 1614 { 1615 struct mmuentry *me; 1616 struct pmap *pm; 1617 int i, va, *ptep, pte; 1618 int ctx; 1619 struct regmap *rp; 1620 struct segmap *sp; 1621 1622 /* try free list first */ 1623 if (!mmuq_empty(&segm_freelist)) { 1624 me = mmuq_first(&segm_freelist); 1625 mmuq_remove(me); 1626 #ifdef DEBUG 1627 if (me->me_pmap != NULL) 1628 panic("me_alloc: freelist entry has pmap"); 1629 DPRINTF(PDB_MMU_ALLOC, 1630 "me_alloc: got pmeg %d", me->me_cookie); 1631 #endif 1632 mmuq_insert_tail(mh, me); 1633 1634 /* onto on pmap chain; pmap is already locked, if needed */ 1635 TAILQ_INSERT_TAIL(&newpm->pm_seglist, me, me_pmchain); 1636 #ifdef DIAGNOSTIC 1637 pmap_stats.ps_npmeg_free--; 1638 if (mh == &segm_locked) { 1639 pmap_stats.ps_npmeg_locked++; 1640 me->me_statp = &pmap_stats.ps_npmeg_locked; 1641 } else { 1642 pmap_stats.ps_npmeg_lru++; 1643 me->me_statp = &pmap_stats.ps_npmeg_lru; 1644 } 1645 #endif 1646 1647 /* into pmap segment table, with backpointers */ 1648 me->me_pmap = newpm; 1649 me->me_vseg = newvseg; 1650 me->me_vreg = newvreg; 1651 1652 return (me->me_cookie); 1653 } 1654 1655 /* no luck, take head of LRU list */ 1656 if (mmuq_empty(&segm_lru)) 1657 panic("me_alloc: all pmegs gone"); 1658 1659 me = mmuq_first(&segm_lru); 1660 pm = me->me_pmap; 1661 DPRINTF(PDB_MMU_ALLOC | PDB_MMU_STEAL, 1662 "me_alloc: stealing pmeg 0x%x from pmap %p", me->me_cookie, pm); 1663 1664 mmu_stolenpmegs_evcnt.ev_count++; 1665 1666 /* 1667 * Remove from LRU list, and insert at end of new list 1668 * (probably the LRU list again, but so what?). 1669 */ 1670 mmuq_remove(me); 1671 mmuq_insert_tail(mh, me); 1672 1673 #ifdef DIAGNOSTIC 1674 if (mh == &segm_locked) { 1675 pmap_stats.ps_npmeg_lru--; 1676 pmap_stats.ps_npmeg_locked++; 1677 me->me_statp = &pmap_stats.ps_npmeg_locked; 1678 } else { 1679 me->me_statp = &pmap_stats.ps_npmeg_lru; 1680 } 1681 #endif 1682 1683 rp = &pm->pm_regmap[me->me_vreg]; 1684 sp = &rp->rg_segmap[me->me_vseg]; 1685 ptep = sp->sg_pte; 1686 1687 #ifdef DEBUG 1688 if (sp->sg_pmeg != me->me_cookie) 1689 panic("me_alloc: wrong sg_pmeg (%d != %d)", 1690 sp->sg_pmeg, me->me_cookie); 1691 #endif 1692 1693 /* 1694 * The PMEG must be mapped into some context so that we can 1695 * read its PTEs. Use its current context if it has one; 1696 * if not, and since context 0 is reserved for the kernel, 1697 * the simplest method is to switch to 0 and map the PMEG 1698 * to virtual address 0---which, being a user space address, 1699 * is by definition not in use. 1700 * 1701 * XXX do not have to flush cache immediately 1702 */ 1703 ctx = getcontext4(); 1704 1705 /* 1706 * Even if we're stealing a PMEG from ourselves (i.e. if pm==newpm), 1707 * we must make sure there are no user register windows in the CPU 1708 * for the following reasons: 1709 * (1) if we have a write-allocate cache and the segment we are 1710 * stealing contains stack pages, an interrupt during the 1711 * interval that starts at cache_flush_segment() below and ends 1712 * when the segment is finally removed from the MMU, may cause 1713 * dirty cache lines to reappear. 1714 * (2) when re-wiring this PMEG for use by another segment (e.g. 1715 * in mmu_pagein()) a window exists where the PTEs in this PMEG 1716 * point at arbitrary pages allocated to this address space. 1717 * Again, a register window flush at this point is likely to 1718 * cause data corruption in case the segment being rewired 1719 * contains stack virtual addresses. 1720 */ 1721 write_user_windows(); 1722 if (CTX_USABLE(pm,rp)) { 1723 setcontext4(pm->pm_ctxnum); 1724 va = VSTOVA(me->me_vreg, me->me_vseg); 1725 #ifdef DEBUG 1726 if (getsegmap(va) != me->me_cookie) 1727 panic("me_alloc: wrong pmeg in MMU (%d != %d)", 1728 getsegmap(va), me->me_cookie); 1729 #endif 1730 cache_flush_segment(me->me_vreg, me->me_vseg, pm->pm_ctxnum); 1731 } else { 1732 va = 0; 1733 setcontext4(0); 1734 if (HASSUN4_MMU3L) 1735 setregmap(va, tregion); 1736 setsegmap(va, me->me_cookie); 1737 /* 1738 * No cache flush needed: it happened earlier when 1739 * the old context was taken. 1740 */ 1741 } 1742 1743 /* 1744 * Record reference and modify bits for each page, 1745 * and copy PTEs into kernel memory so that they can 1746 * be reloaded later. 1747 */ 1748 i = NPTESG; 1749 do { 1750 int swbits = *ptep & PG_MBZ; 1751 pte = getpte4(va); 1752 if ((pte & (PG_V | PG_TYPE)) == (PG_V | PG_OBMEM)) { 1753 struct vm_page *pg; 1754 if ((pg = pvhead4_4c(pte)) != NULL) 1755 VM_MDPAGE_PVHEAD(pg)->pv_flags |= MR4_4C(pte); 1756 } 1757 *ptep++ = swbits | (pte & ~(PG_U|PG_M)); 1758 va += NBPG; 1759 } while (--i > 0); 1760 1761 /* update segment tables */ 1762 if (CTX_USABLE(pm,rp)) { 1763 va = VSTOVA(me->me_vreg,me->me_vseg); 1764 if (pm != pmap_kernel() || HASSUN4_MMU3L) 1765 setsegmap(va, seginval); 1766 else { 1767 /* Unmap segment from all contexts */ 1768 for (i = ncontext; --i >= 0;) { 1769 setcontext4(i); 1770 setsegmap(va, seginval); 1771 } 1772 } 1773 } 1774 sp->sg_pmeg = seginval; 1775 1776 /* off old pmap chain */ 1777 TAILQ_REMOVE(&pm->pm_seglist, me, me_pmchain); 1778 setcontext4(ctx); 1779 1780 /* onto new pmap chain; new pmap is already locked, if needed */ 1781 TAILQ_INSERT_TAIL(&newpm->pm_seglist, me, me_pmchain); 1782 1783 /* into new segment table, with backpointers */ 1784 me->me_pmap = newpm; 1785 me->me_vseg = newvseg; 1786 me->me_vreg = newvreg; 1787 1788 return (me->me_cookie); 1789 } 1790 1791 /* 1792 * Free an MMU entry. 1793 * 1794 * Assumes the corresponding pmap is already locked. 1795 * Caller must update hardware. 1796 */ 1797 static inline void 1798 me_free(struct pmap *pm, u_int pmeg) 1799 { 1800 struct mmuentry *me = &mmusegments[pmeg]; 1801 #ifdef DEBUG 1802 struct regmap *rp; 1803 int i, va, tpte, ctx; 1804 #endif 1805 1806 #ifdef DEBUG 1807 rp = &pm->pm_regmap[me->me_vreg]; 1808 DPRINTF(PDB_MMU_ALLOC, 1809 "me_free: freeing pmeg %d from pmap %p", me->me_cookie, pm); 1810 if (me->me_cookie != pmeg) 1811 panic("me_free: wrong mmuentry"); 1812 if (pm != me->me_pmap) 1813 panic("me_free: pm != me_pmap"); 1814 if (rp->rg_segmap[me->me_vseg].sg_pmeg != pmeg && 1815 rp->rg_segmap[me->me_vseg].sg_pmeg != seginval) 1816 panic("me_free: wrong sg_pmeg (%d != %d)", 1817 rp->rg_segmap[me->me_vseg].sg_pmeg, pmeg); 1818 1819 /* check for spurious mappings (using temp. mapping in context 0) */ 1820 ctx = getcontext4(); 1821 setcontext4(0); 1822 if (HASSUN4_MMU3L) 1823 setregmap(0, tregion); 1824 setsegmap(0, me->me_cookie); 1825 va = 0; 1826 i = NPTESG; 1827 do { 1828 tpte = getpte4(va); 1829 if ((tpte & PG_V) == PG_V) 1830 panic("me_free: segment not clean (pte=%x)", tpte); 1831 va += NBPG; 1832 } while (--i > 0); 1833 setcontext4(ctx); 1834 #endif /* DEBUG */ 1835 1836 /* take mmu entry off pmap chain */ 1837 TAILQ_REMOVE(&pm->pm_seglist, me, me_pmchain); 1838 1839 /* off LRU or lock chain */ 1840 mmuq_remove(me); 1841 #ifdef DIAGNOSTIC 1842 if (me->me_statp == NULL) 1843 panic("me_statp"); 1844 (*me->me_statp)--; 1845 me->me_statp = NULL; 1846 #endif 1847 1848 /* no associated pmap; on free list */ 1849 me->me_pmap = NULL; 1850 mmuq_insert_tail(&segm_freelist, me); 1851 #ifdef DIAGNOSTIC 1852 pmap_stats.ps_npmeg_free++; 1853 #endif 1854 } 1855 1856 #if defined(SUN4_MMU3L) 1857 1858 /* XXX - Merge with segm_alloc/segm_free ? */ 1859 1860 int 1861 region_alloc(struct mmuentry *mh, struct pmap *newpm, int newvr) 1862 { 1863 struct mmuentry *me; 1864 struct pmap *pm; 1865 int ctx; 1866 struct regmap *rp; 1867 1868 /* try free list first */ 1869 if (!mmuq_empty(®ion_freelist)) { 1870 me = mmuq_first(®ion_freelist); 1871 mmuq_remove(me); 1872 #ifdef DEBUG 1873 if (me->me_pmap != NULL) 1874 panic("region_alloc: freelist entry has pmap"); 1875 DPRINTF(PDB_MMUREG_ALLOC, 1876 "region_alloc: got smeg 0x%x", me->me_cookie); 1877 #endif 1878 mmuq_insert_tail(mh, me); 1879 1880 /* onto on pmap chain; pmap is already locked, if needed */ 1881 TAILQ_INSERT_TAIL(&newpm->pm_reglist, me, me_pmchain); 1882 1883 /* into pmap segment table, with backpointers */ 1884 me->me_pmap = newpm; 1885 me->me_vreg = newvr; 1886 1887 return (me->me_cookie); 1888 } 1889 1890 /* no luck, take head of LRU list */ 1891 if (mmuq_empty(®ion_lru)) 1892 panic("region_alloc: all smegs gone"); 1893 1894 me = mmuq_first(®ion_lru); 1895 1896 pm = me->me_pmap; 1897 if (pm == NULL) 1898 panic("region_alloc: LRU entry has no pmap"); 1899 if (pm == pmap_kernel()) 1900 panic("region_alloc: stealing from kernel"); 1901 DPRINTF(PDB_MMUREG_ALLOC | PDB_MMUREG_STEAL, 1902 "region_alloc: stealing smeg 0x%x from pmap %p", 1903 me->me_cookie, pm); 1904 1905 /* 1906 * Remove from LRU list, and insert at end of new list 1907 * (probably the LRU list again, but so what?). 1908 */ 1909 mmuq_remove(me); 1910 mmuq_insert_tail(mh, me); 1911 1912 rp = &pm->pm_regmap[me->me_vreg]; 1913 ctx = getcontext4(); 1914 1915 /* Flush register windows; see comment in me_alloc() */ 1916 write_user_windows(); 1917 if (pm->pm_ctx) { 1918 setcontext4(pm->pm_ctxnum); 1919 cache_flush_region(me->me_vreg, pm->pm_ctxnum); 1920 } 1921 1922 /* update region tables */ 1923 if (pm->pm_ctx) 1924 setregmap(VRTOVA(me->me_vreg), reginval); 1925 rp->rg_smeg = reginval; 1926 1927 /* off old pmap chain */ 1928 TAILQ_REMOVE(&pm->pm_reglist, me, me_pmchain); 1929 setcontext4(ctx); /* done with old context */ 1930 1931 /* onto new pmap chain; new pmap is already locked, if needed */ 1932 TAILQ_INSERT_TAIL(&newpm->pm_reglist, me, me_pmchain); 1933 1934 /* into new segment table, with backpointers */ 1935 me->me_pmap = newpm; 1936 me->me_vreg = newvr; 1937 1938 return (me->me_cookie); 1939 } 1940 1941 /* 1942 * Free an MMU entry. 1943 * Assumes the corresponding pmap is already locked. 1944 * Caller must update hardware. 1945 */ 1946 void 1947 region_free(struct pmap *pm, u_int smeg) 1948 { 1949 struct mmuentry *me = &mmuregions[smeg]; 1950 1951 DPRINTF(PDB_MMUREG_ALLOC, 1952 "region_free: freeing smeg 0x%x from pmap %p", me->me_cookie, pm); 1953 #ifdef DEBUG 1954 if (me->me_cookie != smeg) 1955 panic("region_free: wrong mmuentry"); 1956 if (pm != me->me_pmap) 1957 panic("region_free: pm != me_pmap"); 1958 #endif 1959 1960 /* take mmu entry off pmap chain */ 1961 TAILQ_REMOVE(&pm->pm_reglist, me, me_pmchain); 1962 1963 /* off LRU or lock chain */ 1964 mmuq_remove(me); 1965 1966 /* no associated pmap; on free list */ 1967 me->me_pmap = NULL; 1968 mmuq_insert_tail(®ion_freelist, me); 1969 } 1970 1971 static void 1972 mmu_pagein_reg(struct pmap *pm, struct regmap *rp, vaddr_t va, 1973 int vr, struct mmuentry *mh) 1974 { 1975 int i, s, smeg; 1976 1977 va = VA_ROUNDDOWNTOREG(va); 1978 rp->rg_smeg = smeg = region_alloc(mh, pm, vr); 1979 1980 s = splvm(); 1981 if (pm == pmap_kernel()) { 1982 /* Map region into all contexts */ 1983 int ctx = getcontext4(); 1984 i = ncontext - 1; 1985 do { 1986 setcontext4(i); 1987 setregmap(va, smeg); 1988 } while (--i >= 0); 1989 setcontext4(ctx); 1990 } else 1991 setregmap(va, smeg); 1992 1993 /* Load PMEGs into this region */ 1994 for (i = 0; i < NSEGRG; i++) { 1995 setsegmap(va, rp->rg_segmap[i].sg_pmeg); 1996 va += NBPSG; 1997 } 1998 splx(s); 1999 } 2000 #endif /* SUN4_MMU3L */ 2001 2002 static void 2003 mmu_pmeg_lock(int pmeg) 2004 { 2005 struct mmuentry *me = &mmusegments[pmeg]; 2006 2007 mmuq_remove(me); 2008 mmuq_insert_tail(&segm_locked, me); 2009 #ifdef DIAGNOSTIC 2010 (*me->me_statp)--; 2011 pmap_stats.ps_npmeg_locked++; 2012 me->me_statp = &pmap_stats.ps_npmeg_locked; 2013 #endif 2014 } 2015 2016 static void 2017 mmu_pmeg_unlock(int pmeg) 2018 { 2019 struct mmuentry *me = &mmusegments[pmeg]; 2020 2021 mmuq_remove(me); 2022 mmuq_insert_tail(&segm_lru, me); 2023 #ifdef DIAGNOSTIC 2024 (*me->me_statp)--; 2025 pmap_stats.ps_npmeg_lru++; 2026 me->me_statp = &pmap_stats.ps_npmeg_lru; 2027 #endif 2028 } 2029 2030 static void 2031 mmu_pagein_seg(struct pmap *pm, struct segmap *sp, vaddr_t va, 2032 int vr, int vs, struct mmuentry *mh) 2033 { 2034 int s, i, pmeg, *pte; 2035 2036 mmu_pagein_evcnt.ev_count++; 2037 2038 va = VA_ROUNDDOWNTOSEG(va); 2039 s = splvm(); /* paranoid */ 2040 sp->sg_pmeg = pmeg = me_alloc(mh, pm, vr, vs); 2041 if (pm != pmap_kernel() || HASSUN4_MMU3L) 2042 setsegmap(va, pmeg); 2043 else { 2044 /* Map kernel address into all contexts */ 2045 int ctx = getcontext4(); 2046 i = ncontext - 1; 2047 do { 2048 setcontext4(i); 2049 setsegmap(va, pmeg); 2050 } while (--i >= 0); 2051 setcontext4(ctx); 2052 } 2053 2054 /* reload segment: write PTEs into a the MMU */ 2055 pte = sp->sg_pte; 2056 i = NPTESG; 2057 do { 2058 setpte4(va, *pte++ & ~PG_MBZ); 2059 va += NBPG; 2060 } while (--i > 0); 2061 splx(s); 2062 } 2063 2064 /* 2065 * `Page in' (load or inspect) an MMU entry; called on page faults. 2066 * Returns 1 if we reloaded the segment, -1 if the segment was 2067 * already loaded and the page was marked valid (in which case the 2068 * fault must be a bus error or something), or 0 (segment loaded but 2069 * PTE not valid, or segment not loaded at all). 2070 */ 2071 int 2072 mmu_pagein(struct pmap *pm, vaddr_t va, int prot) 2073 { 2074 int vr, vs, bits; 2075 struct regmap *rp; 2076 struct segmap *sp; 2077 2078 PMAP_LOCK(); 2079 2080 if (prot != VM_PROT_NONE) 2081 bits = PG_V | ((prot & VM_PROT_WRITE) ? PG_W : 0); 2082 else 2083 bits = 0; 2084 2085 vr = VA_VREG(va); 2086 vs = VA_VSEG(va); 2087 rp = &pm->pm_regmap[vr]; 2088 2089 /* return 0 if we have no PMEGs to load */ 2090 if (rp->rg_nsegmap == 0) { 2091 PMAP_UNLOCK(); 2092 return (0); 2093 } 2094 2095 #ifdef DIAGNOSTIC 2096 if (rp->rg_segmap == NULL) 2097 panic("pagein: no segmap"); 2098 #endif 2099 2100 #if defined(SUN4_MMU3L) 2101 if (HASSUN4_MMU3L && rp->rg_smeg == reginval) 2102 mmu_pagein_reg(pm, rp, va, vr, ®ion_lru); 2103 #endif 2104 sp = &rp->rg_segmap[vs]; 2105 2106 /* return 0 if we have no PTEs to load */ 2107 if (sp->sg_npte == 0) { 2108 PMAP_UNLOCK(); 2109 return (0); 2110 } 2111 2112 /* return -1 if the fault is `hard', 0 if not */ 2113 if (sp->sg_pmeg != seginval) { 2114 PMAP_UNLOCK(); 2115 return (bits && (getpte4(va) & bits) == bits ? -1 : 0); 2116 } 2117 2118 mmu_pagein_seg(pm, sp, va, vr, vs, &segm_lru); 2119 PMAP_UNLOCK(); 2120 return (1); 2121 } 2122 #endif /* SUN4 or SUN4C */ 2123 2124 /* 2125 * Allocate a context. If necessary, steal one from someone else. 2126 * Changes hardware context number and loads segment map. 2127 * 2128 * This routine is only ever called from locore.s just after it has 2129 * saved away the previous process, so there are no active user windows. 2130 */ 2131 static void 2132 ctx_alloc(struct pmap *pm) 2133 { 2134 union ctxinfo *c; 2135 int cnum, i = 0, doflush; 2136 struct regmap *rp; 2137 int gap_start, gap_end; 2138 vaddr_t va; 2139 #if defined(SUN4M) || defined(SUN4D) 2140 struct cpu_info *cpi; 2141 #endif 2142 2143 KASSERT(mutex_owned(&ctx_lock)); 2144 2145 /*XXX-GCC!*/gap_start=gap_end=0; 2146 #ifdef DEBUG 2147 if (pm->pm_ctx) 2148 panic("ctx_alloc pm_ctx"); 2149 #endif 2150 DPRINTF(PDB_CTX_ALLOC, 2151 "ctx_alloc[%d](%p)", cpu_number(), pm); 2152 2153 if (CPU_HAS_SUNMMU) { 2154 gap_start = pm->pm_gap_start; 2155 gap_end = pm->pm_gap_end; 2156 } 2157 2158 if ((c = ctx_freelist) != NULL) { 2159 ctx_freelist = c->c_nextfree; 2160 cnum = c - ctxinfo; 2161 doflush = 0; 2162 } else { 2163 if ((ctx_kick += ctx_kickdir) >= ncontext) { 2164 ctx_kick = ncontext - 1; 2165 ctx_kickdir = -1; 2166 } else if (ctx_kick < 1) { 2167 ctx_kick = 1; 2168 ctx_kickdir = 1; 2169 } 2170 c = &ctxinfo[cnum = ctx_kick]; 2171 #ifdef DEBUG 2172 if (c->c_pmap == NULL) 2173 panic("ctx_alloc cu_pmap"); 2174 #endif 2175 DPRINTF(PDB_CTX_ALLOC | PDB_CTX_STEAL, 2176 "ctx_alloc[%d]: steal context %d from %p", 2177 cpu_number(), cnum, c->c_pmap); 2178 2179 c->c_pmap->pm_ctx = NULL; 2180 c->c_pmap->pm_ctxnum = 0; 2181 doflush = (CACHEINFO.c_vactype != VAC_NONE); 2182 if (CPU_HAS_SUNMMU) { 2183 if (gap_start < c->c_pmap->pm_gap_start) 2184 gap_start = c->c_pmap->pm_gap_start; 2185 if (gap_end > c->c_pmap->pm_gap_end) 2186 gap_end = c->c_pmap->pm_gap_end; 2187 } 2188 } 2189 2190 c->c_pmap = pm; 2191 pm->pm_ctx = c; 2192 pm->pm_ctxnum = cnum; 2193 2194 if (CPU_HAS_SUNMMU) { 2195 2196 /* 2197 * Write pmap's region (3-level MMU) or segment table into 2198 * the MMU. 2199 * 2200 * Only write those entries that actually map something in 2201 * this context by maintaining a pair of region numbers in 2202 * between which the pmap has no valid mappings. 2203 * 2204 * If a context was just allocated from the free list, trust 2205 * that all its pmeg numbers are `seginval'. We make sure this 2206 * is the case initially in pmap_bootstrap(). Otherwise, the 2207 * context was freed by calling ctx_free() in pmap_release(), 2208 * which in turn is supposedly called only when all mappings 2209 * have been removed. 2210 * 2211 * On the other hand, if the context had to be stolen from 2212 * another pmap, we possibly shrink the gap to be the 2213 * disjuction of the new and the previous map. 2214 */ 2215 2216 setcontext4(cnum); 2217 if (doflush) 2218 cache_flush_context(cnum); 2219 2220 rp = pm->pm_regmap; 2221 for (va = 0, i = NUREG; --i >= 0; ) { 2222 if (VA_VREG(va) >= gap_start) { 2223 va = VRTOVA(gap_end); 2224 i -= gap_end - gap_start; 2225 rp += gap_end - gap_start; 2226 if (i < 0) 2227 break; 2228 /* mustn't re-enter this branch */ 2229 gap_start = NUREG; 2230 } 2231 if (HASSUN4_MMU3L) { 2232 setregmap(va, rp++->rg_smeg); 2233 va += NBPRG; 2234 } else { 2235 int j; 2236 struct segmap *sp = rp->rg_segmap; 2237 for (j = NSEGRG; --j >= 0; va += NBPSG) 2238 setsegmap(va, 2239 sp?sp++->sg_pmeg:seginval); 2240 rp++; 2241 } 2242 } 2243 2244 } else if (CPU_HAS_SRMMU) { 2245 2246 #if defined(SUN4M) || defined(SUN4D) 2247 /* 2248 * Reload page and context tables to activate the page tables 2249 * for this context. 2250 * 2251 * The gap stuff isn't really needed in the sun4m architecture, 2252 * since we don't have to worry about excessive mappings (all 2253 * mappings exist since the page tables must be complete for 2254 * the mmu to be happy). 2255 * 2256 * If a context was just allocated from the free list, trust 2257 * that all of its mmu-edible page tables are zeroed out 2258 * (except for those associated with the kernel). We make 2259 * sure this is the case initially in pmap_bootstrap() and 2260 * pmap_init() (?). 2261 * Otherwise, the context was freed by calling ctx_free() in 2262 * pmap_release(), which in turn is supposedly called only 2263 * when all mappings have been removed. 2264 * 2265 * XXX: Do we have to flush cache after reloading ctx tbl? 2266 */ 2267 2268 /* 2269 * We need to flush the cache only when stealing a context 2270 * from another pmap. In that case it's Ok to switch the 2271 * context and leave it set, since the context table 2272 * will have a valid region table entry for this context 2273 * number. 2274 * 2275 * Otherwise, we switch to the new context after loading 2276 * the context table entry with the new pmap's region. 2277 */ 2278 if (doflush) { 2279 cache_flush_context(cnum); 2280 } 2281 2282 /* 2283 * The context allocated to a process is the same on all CPUs. 2284 * Here we install the per-CPU region table in each CPU's 2285 * context table slot. 2286 * 2287 * Note on multi-threaded processes: a context must remain 2288 * valid as long as any thread is still running on a CPU. 2289 */ 2290 for (CPU_INFO_FOREACH(i, cpi)) { 2291 setpgt4m(&cpi->ctx_tbl[cnum], 2292 (pm->pm_reg_ptps_pa[i] >> SRMMU_PPNPASHIFT) | 2293 SRMMU_TEPTD); 2294 } 2295 2296 /* And finally switch to the new context */ 2297 (*cpuinfo.pure_vcache_flush)(); 2298 setcontext4m(cnum); 2299 #endif /* SUN4M || SUN4D */ 2300 } 2301 } 2302 2303 /* 2304 * Give away a context. 2305 */ 2306 static void 2307 ctx_free(struct pmap *pm) 2308 { 2309 union ctxinfo *c; 2310 int ctx; 2311 #if defined(SUN4M) || defined(SUN4D) 2312 struct cpu_info *cpi; 2313 #endif 2314 2315 KASSERT(mutex_owned(&ctx_lock)); 2316 2317 c = pm->pm_ctx; 2318 ctx = pm->pm_ctxnum; 2319 pm->pm_ctx = NULL; 2320 pm->pm_ctxnum = 0; 2321 #if defined(SUN4) || defined(SUN4C) 2322 if (CPU_HAS_SUNMMU) { 2323 int octx = getcontext4(); 2324 setcontext4(ctx); 2325 cache_flush_context(ctx); 2326 setcontext4(octx); 2327 } 2328 #endif /* SUN4 || SUN4C */ 2329 2330 #if defined(SUN4M) || defined(SUN4D) 2331 if (CPU_HAS_SRMMU) { 2332 CPU_INFO_ITERATOR i; 2333 2334 __USE(i); 2335 2336 cache_flush_context(ctx); 2337 tlb_flush_context(ctx, PMAP_CPUSET(pm)); 2338 for (CPU_INFO_FOREACH(i, cpi)) { 2339 setpgt4m(&cpi->ctx_tbl[ctx], SRMMU_TEINVALID); 2340 } 2341 } 2342 #endif 2343 2344 c->c_nextfree = ctx_freelist; 2345 ctx_freelist = c; 2346 } 2347 2348 2349 /*----------------------------------------------------------------*/ 2350 2351 /* 2352 * pvlist functions. 2353 */ 2354 2355 /* 2356 * Walk the given pv list, and for each PTE, set or clear some bits 2357 * (e.g., PG_W or PG_NC). 2358 * 2359 * This routine flushes the cache for any page whose PTE changes, 2360 * as long as the process has a context; this is overly conservative. 2361 * It also copies ref and mod bits to the pvlist, on the theory that 2362 * this might save work later. (XXX should test this theory) 2363 */ 2364 2365 #if defined(SUN4) || defined(SUN4C) 2366 2367 void 2368 pv_changepte4_4c(struct vm_page *pg, int bis, int bic) 2369 { 2370 int pte, *ptep; 2371 struct pvlist *pv; 2372 struct pmap *pm; 2373 int va, vr, vs; 2374 int ctx, s; 2375 struct regmap *rp; 2376 struct segmap *sp; 2377 2378 pv = VM_MDPAGE_PVHEAD(pg); 2379 2380 write_user_windows(); /* paranoid? */ 2381 s = splvm(); /* paranoid? */ 2382 if (pv->pv_pmap == NULL) { 2383 splx(s); 2384 return; 2385 } 2386 ctx = getcontext4(); 2387 for (; pv != NULL; pv = pv->pv_next) { 2388 pm = pv->pv_pmap; 2389 va = pv->pv_va; 2390 vr = VA_VREG(va); 2391 vs = VA_VSEG(va); 2392 rp = &pm->pm_regmap[vr]; 2393 sp = &rp->rg_segmap[vs]; 2394 ptep = &sp->sg_pte[VA_VPG(va)]; 2395 2396 if (sp->sg_pmeg == seginval) { 2397 /* not in hardware: just fix software copy */ 2398 *ptep = (*ptep | bis) & ~bic; 2399 } else { 2400 /* in hardware: fix hardware copy */ 2401 if (CTX_USABLE(pm,rp)) { 2402 setcontext4(pm->pm_ctxnum); 2403 /* XXX should flush only when necessary */ 2404 pte = getpte4(va); 2405 /* 2406 * XXX: always flush cache; conservative, but 2407 * needed to invalidate cache tag protection 2408 * bits and when disabling caching. 2409 */ 2410 cache_flush_page(va, pm->pm_ctxnum); 2411 } else { 2412 /* Make temp map in ctx 0 to access the PTE */ 2413 setcontext4(0); 2414 if (HASSUN4_MMU3L) 2415 setregmap(0, tregion); 2416 setsegmap(0, sp->sg_pmeg); 2417 va = VA_VPG(va) << PGSHIFT; 2418 pte = getpte4(va); 2419 } 2420 if (pte & PG_V) 2421 VM_MDPAGE_PVHEAD(pg)->pv_flags |= MR4_4C(pte); 2422 pte = (pte | bis) & ~bic; 2423 setpte4(va, pte); 2424 *ptep = (*ptep & PG_MBZ) | pte; 2425 } 2426 } 2427 setcontext4(ctx); 2428 splx(s); 2429 } 2430 2431 /* 2432 * Sync ref and mod bits in pvlist (turns off same in hardware PTEs). 2433 * Returns the new flags. 2434 * 2435 * This is just like pv_changepte, but we never add or remove bits, 2436 * hence never need to adjust software copies. 2437 */ 2438 int 2439 pv_syncflags4_4c(struct vm_page *pg) 2440 { 2441 struct pvlist *pv; 2442 struct pmap *pm; 2443 int pte, va, vr, vs, pmeg, flags; 2444 int ctx, s; 2445 struct regmap *rp; 2446 struct segmap *sp; 2447 2448 pv = VM_MDPAGE_PVHEAD(pg); 2449 2450 s = splvm(); /* paranoid? */ 2451 if (pv->pv_pmap == NULL) { 2452 /* Page not mapped; pv_flags is already up to date */ 2453 splx(s); 2454 return (0); 2455 } 2456 ctx = getcontext4(); 2457 flags = pv->pv_flags; 2458 for (; pv != NULL; pv = pv->pv_next) { 2459 pm = pv->pv_pmap; 2460 va = pv->pv_va; 2461 vr = VA_VREG(va); 2462 vs = VA_VSEG(va); 2463 rp = &pm->pm_regmap[vr]; 2464 sp = &rp->rg_segmap[vs]; 2465 if ((pmeg = sp->sg_pmeg) == seginval) 2466 continue; 2467 if (CTX_USABLE(pm,rp)) { 2468 setcontext4(pm->pm_ctxnum); 2469 /* XXX should flush only when necessary */ 2470 pte = getpte4(va); 2471 if (pte & PG_M) 2472 cache_flush_page(va, pm->pm_ctxnum); 2473 } else { 2474 /* Make temp map in ctx 0 to access the PTE */ 2475 setcontext4(0); 2476 if (HASSUN4_MMU3L) 2477 setregmap(0, tregion); 2478 setsegmap(0, pmeg); 2479 va = VA_VPG(va) << PGSHIFT; 2480 pte = getpte4(va); 2481 } 2482 if (pte & (PG_M|PG_U) && pte & PG_V) { 2483 flags |= MR4_4C(pte); 2484 pte &= ~(PG_M|PG_U); 2485 setpte4(va, pte); 2486 } 2487 } 2488 2489 VM_MDPAGE_PVHEAD(pg)->pv_flags = flags; 2490 setcontext4(ctx); 2491 splx(s); 2492 return (flags); 2493 } 2494 2495 /* 2496 * pv_unlink is a helper function for pmap_remove. 2497 * It takes a pointer to the pv_table head for some physical address 2498 * and removes the appropriate (pmap, va) entry. 2499 * 2500 * Once the entry is removed, if the pv_table head has the cache 2501 * inhibit bit set, see if we can turn that off; if so, walk the 2502 * pvlist and turn off PG_NC in each PTE. (The pvlist is by 2503 * definition nonempty, since it must have at least two elements 2504 * in it to have PV_NC set, and we only remove one here.) 2505 */ 2506 /*static*/ void 2507 pv_unlink4_4c(struct vm_page *pg, struct pmap *pm, vaddr_t va) 2508 { 2509 struct pvlist *pv0, *npv; 2510 2511 pv0 = VM_MDPAGE_PVHEAD(pg); 2512 npv = pv0->pv_next; 2513 2514 /* 2515 * First entry is special (sigh). 2516 */ 2517 if (pv0->pv_pmap == pm && pv0->pv_va == va) { 2518 pmap_stats.ps_unlink_pvfirst++; 2519 if (npv != NULL) { 2520 /* 2521 * Shift next entry into the head. 2522 * Make sure to retain the REF, MOD and ANC flags. 2523 */ 2524 pv0->pv_next = npv->pv_next; 2525 pv0->pv_pmap = npv->pv_pmap; 2526 pv0->pv_va = npv->pv_va; 2527 pv0->pv_flags &= ~PV_NC; 2528 pv0->pv_flags |= (npv->pv_flags & PV_NC); 2529 pool_put(&pv_pool, npv); 2530 } else { 2531 /* 2532 * No mappings left; we still need to maintain 2533 * the REF and MOD flags. since pmap_is_modified() 2534 * can still be called for this page. 2535 */ 2536 pv0->pv_pmap = NULL; 2537 pv0->pv_flags &= ~(PV_NC|PV_ANC); 2538 return; 2539 } 2540 } else { 2541 struct pvlist *prev; 2542 2543 pmap_stats.ps_unlink_pvsearch++; 2544 for (prev = pv0;; prev = npv, npv = npv->pv_next) { 2545 if (npv == NULL) { 2546 panic("pv_unlink: pm %p is missing on pg %p", 2547 pm, pg); 2548 } 2549 if (npv->pv_pmap == pm && npv->pv_va == va) 2550 break; 2551 } 2552 prev->pv_next = npv->pv_next; 2553 pool_put(&pv_pool, npv); 2554 } 2555 if ((pv0->pv_flags & (PV_NC|PV_ANC)) == PV_ANC) { 2556 /* 2557 * Not cached: check whether we can fix that now. 2558 */ 2559 va = pv0->pv_va; 2560 for (npv = pv0->pv_next; npv != NULL; npv = npv->pv_next) 2561 if (BADALIAS(va, npv->pv_va) || 2562 (npv->pv_flags & PV_NC) != 0) 2563 return; 2564 pv0->pv_flags &= ~PV_ANC; 2565 pv_changepte4_4c(pg, 0, PG_NC); 2566 } 2567 } 2568 2569 /* 2570 * pv_link is the inverse of pv_unlink, and is used in pmap_enter. 2571 * It returns PG_NC if the (new) pvlist says that the address cannot 2572 * be cached. 2573 */ 2574 /*static*/ int 2575 pv_link4_4c(struct vm_page *pg, struct pmap *pm, vaddr_t va, 2576 unsigned int *pteprotop) 2577 { 2578 struct pvlist *pv0, *pv, *npv; 2579 int nc = (*pteprotop & PG_NC) != 0 ? PV_NC : 0; 2580 2581 pv0 = VM_MDPAGE_PVHEAD(pg); 2582 2583 if (pv0->pv_pmap == NULL) { 2584 /* no pvlist entries yet */ 2585 pmap_stats.ps_enter_firstpv++; 2586 pv0->pv_next = NULL; 2587 pv0->pv_pmap = pm; 2588 pv0->pv_va = va; 2589 pv0->pv_flags |= nc; 2590 return (0); 2591 } 2592 2593 /* 2594 * Allocate the new PV entry now, and, if that fails, bail out 2595 * before changing the cacheable state of the existing mappings. 2596 */ 2597 npv = pool_get(&pv_pool, PR_NOWAIT); 2598 if (npv == NULL) 2599 return (ENOMEM); 2600 2601 pmap_stats.ps_enter_secondpv++; 2602 2603 /* 2604 * Before entering the new mapping, see if 2605 * it will cause old mappings to become aliased 2606 * and thus need to be `discached'. 2607 */ 2608 if (pv0->pv_flags & PV_ANC) { 2609 /* already uncached, just stay that way */ 2610 *pteprotop |= PG_NC; 2611 goto link_npv; 2612 } 2613 2614 for (pv = pv0; pv != NULL; pv = pv->pv_next) { 2615 if ((pv->pv_flags & PV_NC) != 0) { 2616 *pteprotop |= PG_NC; 2617 #ifdef DEBUG 2618 /* Check currently illegal condition */ 2619 if (nc == 0) 2620 printf("pv_link: proc %s, va=0x%lx: " 2621 "unexpected uncached mapping at 0x%lx\n", 2622 curproc ? curproc->p_comm : "--", 2623 va, pv->pv_va); 2624 #endif 2625 } 2626 if (BADALIAS(va, pv->pv_va)) { 2627 DPRINTF(PDB_CACHESTUFF, 2628 "pv_link: badalias: proc %s, 0x%lx<=>0x%lx, pg %p", 2629 curproc ? curproc->p_comm : "--", 2630 va, pv->pv_va, pg); 2631 /* Mark list head `uncached due to aliases' */ 2632 pv0->pv_flags |= PV_ANC; 2633 pv_changepte4_4c(pg, PG_NC, 0); 2634 *pteprotop |= PG_NC; 2635 break; 2636 } 2637 } 2638 2639 link_npv: 2640 npv->pv_next = pv0->pv_next; 2641 npv->pv_pmap = pm; 2642 npv->pv_va = va; 2643 npv->pv_flags = nc; 2644 pv0->pv_next = npv; 2645 return (0); 2646 } 2647 2648 #endif /* SUN4 || SUN4C */ 2649 2650 #if defined(SUN4M) || defined(SUN4D) /* SRMMU versions of above */ 2651 /* 2652 * Walk the given pv list, and for each PTE, set or clear some bits 2653 * (e.g., PG_W or PG_NC). 2654 * 2655 * This routine flushes the cache for any page whose PTE changes, 2656 * as long as the process has a context; this is overly conservative. 2657 * It also copies ref and mod bits to the pvlist, on the theory that 2658 * this might save work later. (XXX should test this theory) 2659 * 2660 * Called with PV lock and pmap main lock held. 2661 */ 2662 void 2663 pv_changepte4m(struct vm_page *pg, int bis, int bic) 2664 { 2665 struct pvlist *pv; 2666 struct pmap *pm; 2667 vaddr_t va; 2668 struct regmap *rp; 2669 struct segmap *sp; 2670 2671 pv = VM_MDPAGE_PVHEAD(pg); 2672 if (pv->pv_pmap == NULL) 2673 return; 2674 2675 for (; pv != NULL; pv = pv->pv_next) { 2676 pm = pv->pv_pmap; 2677 /* XXXSMP: should lock pm */ 2678 va = pv->pv_va; 2679 rp = &pm->pm_regmap[VA_VREG(va)]; 2680 sp = &rp->rg_segmap[VA_VSEG(va)]; 2681 2682 if (pm->pm_ctx) { 2683 /* 2684 * XXX: always flush cache; conservative, but 2685 * needed to invalidate cache tag protection 2686 * bits and when disabling caching. 2687 */ 2688 cache_flush_page(va, pm->pm_ctxnum); 2689 } 2690 2691 KASSERT((sp->sg_pte[VA_SUN4M_VPG(va)] & SRMMU_TETYPE) == 2692 SRMMU_TEPTE); 2693 VM_MDPAGE_PVHEAD(pg)->pv_flags |= MR4M(updatepte4m(va, 2694 &sp->sg_pte[VA_SUN4M_VPG(va)], bic, bis, pm->pm_ctxnum, 2695 PMAP_CPUSET(pm))); 2696 } 2697 } 2698 2699 /* 2700 * Sync ref and mod bits in pvlist. If page has been ref'd or modified, 2701 * update ref/mod bits in pvlist, and clear the hardware bits. 2702 * 2703 * Return the new flags. 2704 */ 2705 int 2706 pv_syncflags4m(struct vm_page *pg) 2707 { 2708 struct pvlist *pv; 2709 struct pmap *pm; 2710 int va, flags; 2711 int s; 2712 struct regmap *rp; 2713 struct segmap *sp; 2714 int tpte; 2715 2716 s = splvm(); 2717 PMAP_LOCK(); 2718 pv = VM_MDPAGE_PVHEAD(pg); 2719 if (pv->pv_pmap == NULL) { 2720 /* Page not mapped; pv_flags is already up to date */ 2721 flags = 0; 2722 goto out; 2723 } 2724 2725 flags = pv->pv_flags; 2726 for (; pv != NULL; pv = pv->pv_next) { 2727 pm = pv->pv_pmap; 2728 va = pv->pv_va; 2729 rp = &pm->pm_regmap[VA_VREG(va)]; 2730 sp = &rp->rg_segmap[VA_VSEG(va)]; 2731 2732 tpte = sp->sg_pte[VA_SUN4M_VPG(va)]; 2733 if ((tpte & SRMMU_TETYPE) == SRMMU_TEPTE && 2734 (tpte & (SRMMU_PG_R|SRMMU_PG_M)) != 0) { 2735 /* 2736 * Flush cache if modified to make sure the PTE 2737 * M bit will be set again on the next write access. 2738 */ 2739 if (pm->pm_ctx && (tpte & SRMMU_PG_M) == SRMMU_PG_M) 2740 cache_flush_page(va, pm->pm_ctxnum); 2741 2742 flags |= MR4M(updatepte4m(va, 2743 &sp->sg_pte[VA_SUN4M_VPG(va)], 2744 SRMMU_PG_M | SRMMU_PG_R, 2745 0, pm->pm_ctxnum, PMAP_CPUSET(pm))); 2746 } 2747 } 2748 2749 VM_MDPAGE_PVHEAD(pg)->pv_flags = flags; 2750 out: 2751 PMAP_UNLOCK(); 2752 splx(s); 2753 return (flags); 2754 } 2755 2756 /* 2757 * Should be called with pmap already locked. 2758 */ 2759 void 2760 pv_unlink4m(struct vm_page *pg, struct pmap *pm, vaddr_t va) 2761 { 2762 struct pvlist *pv0, *npv; 2763 2764 pv0 = VM_MDPAGE_PVHEAD(pg); 2765 2766 npv = pv0->pv_next; 2767 /* 2768 * First entry is special (sigh). 2769 */ 2770 if (pv0->pv_pmap == pm && pv0->pv_va == va) { 2771 pmap_stats.ps_unlink_pvfirst++; 2772 if (npv != NULL) { 2773 /* 2774 * Shift next entry into the head. 2775 * Make sure to retain the REF, MOD and ANC flags 2776 * on the list head. 2777 */ 2778 pv0->pv_next = npv->pv_next; 2779 pv0->pv_pmap = npv->pv_pmap; 2780 pv0->pv_va = npv->pv_va; 2781 pv0->pv_flags &= ~PV_NC; 2782 pv0->pv_flags |= (npv->pv_flags & PV_NC); 2783 pool_put(&pv_pool, npv); 2784 } else { 2785 /* 2786 * No mappings left; we need to maintain 2787 * the REF and MOD flags, since pmap_is_modified() 2788 * can still be called for this page. 2789 */ 2790 pv0->pv_pmap = NULL; 2791 pv0->pv_flags &= ~(PV_NC|PV_ANC); 2792 return; 2793 } 2794 } else { 2795 struct pvlist *prev; 2796 2797 pmap_stats.ps_unlink_pvsearch++; 2798 for (prev = pv0;; prev = npv, npv = npv->pv_next) { 2799 if (npv == NULL) { 2800 panic("pv_unlink: pm %p is missing on pg %p", 2801 pm, pg); 2802 return; 2803 } 2804 if (npv->pv_pmap == pm && npv->pv_va == va) 2805 break; 2806 } 2807 prev->pv_next = npv->pv_next; 2808 pool_put(&pv_pool, npv); 2809 } 2810 2811 if ((pv0->pv_flags & (PV_NC|PV_ANC)) == PV_ANC) { 2812 2813 /* 2814 * Not cached: check whether we can fix that now. 2815 */ 2816 va = pv0->pv_va; 2817 for (npv = pv0->pv_next; npv != NULL; npv = npv->pv_next) 2818 if (BADALIAS(va, npv->pv_va) || 2819 (npv->pv_flags & PV_NC) != 0) 2820 return; 2821 DPRINTF(PDB_CACHESTUFF, 2822 "pv_unlink: alias ok: proc %s, va 0x%lx, pg %p", 2823 curproc ? curproc->p_comm : "--", va, pg); 2824 pv0->pv_flags &= ~PV_ANC; 2825 pv_changepte4m(pg, SRMMU_PG_C, 0); 2826 } 2827 } 2828 2829 /* 2830 * pv_link is the inverse of pv_unlink, and is used in pmap_enter. 2831 * May turn off the cacheable bit in the pte prototype for the new mapping. 2832 * Called with pm locked. 2833 */ 2834 /*static*/ int 2835 pv_link4m(struct vm_page *pg, struct pmap *pm, vaddr_t va, 2836 unsigned int *pteprotop) 2837 { 2838 struct pvlist *pv0, *pv, *npv; 2839 int nc = (*pteprotop & SRMMU_PG_C) == 0 ? PV_NC : 0; 2840 int error = 0; 2841 2842 pv0 = VM_MDPAGE_PVHEAD(pg); 2843 2844 if (pv0->pv_pmap == NULL) { 2845 /* no pvlist entries yet */ 2846 pmap_stats.ps_enter_firstpv++; 2847 pv0->pv_next = NULL; 2848 pv0->pv_pmap = pm; 2849 pv0->pv_va = va; 2850 pv0->pv_flags |= nc; 2851 goto out; 2852 } 2853 2854 /* 2855 * Allocate the new PV entry now, and, if that fails, bail out 2856 * before changing the cacheable state of the existing mappings. 2857 */ 2858 npv = pool_get(&pv_pool, PR_NOWAIT); 2859 if (npv == NULL) { 2860 error = ENOMEM; 2861 goto out; 2862 } 2863 2864 pmap_stats.ps_enter_secondpv++; 2865 2866 /* 2867 * See if the new mapping will cause old mappings to 2868 * become aliased and thus need to be `discached'. 2869 */ 2870 if ((pv0->pv_flags & PV_ANC) != 0) { 2871 /* already uncached, just stay that way */ 2872 *pteprotop &= ~SRMMU_PG_C; 2873 goto link_npv; 2874 } 2875 2876 for (pv = pv0; pv != NULL; pv = pv->pv_next) { 2877 if ((pv->pv_flags & PV_NC) != 0) { 2878 *pteprotop &= ~SRMMU_PG_C; 2879 #ifdef DEBUG 2880 /* Check currently illegal condition */ 2881 if (nc == 0) 2882 printf("pv_link: proc %s, va=0x%lx: " 2883 "unexpected uncached mapping at 0x%lx\n", 2884 curproc ? curproc->p_comm : "--", 2885 va, pv->pv_va); 2886 #endif 2887 } 2888 if (BADALIAS(va, pv->pv_va)) { 2889 DPRINTF(PDB_CACHESTUFF, 2890 "pv_link: badalias: proc %s, 0x%lx<=>0x%lx, pg %p", 2891 curproc ? curproc->p_comm : "--", 2892 va, pv->pv_va, pg); 2893 /* Mark list head `uncached due to aliases' */ 2894 pv0->pv_flags |= PV_ANC; 2895 pv_changepte4m(pg, 0, SRMMU_PG_C); 2896 *pteprotop &= ~SRMMU_PG_C; 2897 break; 2898 } 2899 } 2900 2901 link_npv: 2902 /* Now link in the new PV entry */ 2903 npv->pv_next = pv0->pv_next; 2904 npv->pv_pmap = pm; 2905 npv->pv_va = va; 2906 npv->pv_flags = nc; 2907 pv0->pv_next = npv; 2908 2909 out: 2910 return (error); 2911 } 2912 #endif 2913 2914 /* 2915 * Uncache all entries on behalf of kvm_uncache(). In addition to 2916 * removing the cache bit from the PTE, we are also setting PV_NC 2917 * in each entry to stop pv_unlink() from re-caching (i.e. when a 2918 * a bad alias is going away). 2919 */ 2920 static void 2921 pv_uncache(struct vm_page *pg) 2922 { 2923 struct pvlist *pv; 2924 int s; 2925 2926 s = splvm(); 2927 PMAP_LOCK(); 2928 2929 for (pv = VM_MDPAGE_PVHEAD(pg); pv != NULL; pv = pv->pv_next) 2930 pv->pv_flags |= PV_NC; 2931 2932 #if defined(SUN4M) || defined(SUN4D) 2933 if (CPU_HAS_SRMMU) 2934 pv_changepte4m(pg, 0, SRMMU_PG_C); 2935 #endif 2936 #if defined(SUN4) || defined(SUN4C) 2937 if (CPU_HAS_SUNMMU) 2938 pv_changepte4_4c(pg, PG_NC, 0); 2939 #endif 2940 PMAP_UNLOCK(); 2941 splx(s); 2942 } 2943 2944 /* 2945 * Walk the given list and flush the cache for each (MI) page that is 2946 * potentially in the cache. Called only if vactype != VAC_NONE. 2947 */ 2948 #if defined(SUN4) || defined(SUN4C) 2949 static void 2950 pv_flushcache4_4c(struct vm_page *pg) 2951 { 2952 struct pvlist *pv; 2953 struct pmap *pm; 2954 int s, ctx; 2955 2956 pv = VM_MDPAGE_PVHEAD(pg); 2957 2958 write_user_windows(); /* paranoia? */ 2959 s = splvm(); /* XXX extreme paranoia */ 2960 if ((pm = pv->pv_pmap) != NULL) { 2961 ctx = getcontext4(); 2962 for (;;) { 2963 if (pm->pm_ctx) { 2964 setcontext4(pm->pm_ctxnum); 2965 cache_flush_page(pv->pv_va, pm->pm_ctxnum); 2966 } 2967 pv = pv->pv_next; 2968 if (pv == NULL) 2969 break; 2970 pm = pv->pv_pmap; 2971 } 2972 setcontext4(ctx); 2973 } 2974 splx(s); 2975 } 2976 #endif /* SUN4 || SUN4C */ 2977 2978 #if defined(SUN4M) || defined(SUN4D) 2979 static void 2980 pv_flushcache4m(struct vm_page *pg) 2981 { 2982 struct pvlist *pv; 2983 struct pmap *pm; 2984 int s; 2985 2986 pv = VM_MDPAGE_PVHEAD(pg); 2987 2988 s = splvm(); /* XXX extreme paranoia */ 2989 if ((pm = pv->pv_pmap) != NULL) { 2990 for (;;) { 2991 if (pm->pm_ctx) { 2992 cache_flush_page(pv->pv_va, pm->pm_ctxnum); 2993 } 2994 pv = pv->pv_next; 2995 if (pv == NULL) 2996 break; 2997 pm = pv->pv_pmap; 2998 } 2999 } 3000 splx(s); 3001 } 3002 #endif /* SUN4M || SUN4D */ 3003 3004 /*----------------------------------------------------------------*/ 3005 3006 /* 3007 * At last, pmap code. 3008 */ 3009 3010 #if defined(SUN4) && (defined(SUN4C) || defined(SUN4M) || defined(SUN4D)) 3011 int nptesg; 3012 #endif 3013 3014 #if defined(SUN4M) || defined(SUN4D) 3015 static void pmap_bootstrap4m(void *); 3016 #endif 3017 #if defined(SUN4) || defined(SUN4C) 3018 static void pmap_bootstrap4_4c(void *, int, int, int); 3019 #endif 3020 3021 /* 3022 * Bootstrap the system enough to run with VM enabled. 3023 * 3024 * nsegment is the number of mmu segment entries (``PMEGs''); 3025 * nregion is the number of mmu region entries (``SMEGs''); 3026 * nctx is the number of contexts. 3027 */ 3028 void 3029 pmap_bootstrap(int nctx, int nregion, int nsegment) 3030 { 3031 void *p; 3032 3033 uvmexp.pagesize = NBPG; 3034 uvm_md_init(); 3035 3036 #if defined(SUN4) && (defined(SUN4C) || defined(SUN4M) || defined(SUN4D)) 3037 /* In this case NPTESG is a variable */ 3038 nptesg = (NBPSG >> pgshift); 3039 #endif 3040 3041 /* 3042 * Grab physical memory list. 3043 */ 3044 p = kernel_top; 3045 get_phys_mem(&p); 3046 3047 /* 3048 * The data segment in sparc ELF images is aligned to a 64KB 3049 * (the maximum page size defined by the ELF/sparc ABI) boundary. 3050 * This results in a unused portion of physical memory in between 3051 * the text/rodata and the data segment. We pick up that gap 3052 * here to remove it from the kernel map and give it to the 3053 * VM manager later. 3054 */ 3055 etext_gap_start = (vaddr_t)(etext + NBPG - 1) & ~PGOFSET; 3056 etext_gap_end = (vaddr_t)kernel_data_start & ~PGOFSET; 3057 3058 if (CPU_HAS_SRMMU) { 3059 #if defined(SUN4M) || defined(SUN4D) 3060 pmap_bootstrap4m(p); 3061 #endif 3062 } else if (CPU_HAS_SUNMMU) { 3063 #if defined(SUN4) || defined(SUN4C) 3064 pmap_bootstrap4_4c(p, nctx, nregion, nsegment); 3065 #endif 3066 } 3067 3068 pmap_page_upload(); 3069 mutex_init(&pmap_lock, MUTEX_DEFAULT, IPL_NONE); 3070 mutex_init(&demap_lock, MUTEX_DEFAULT, IPL_VM); 3071 mutex_init(&ctx_lock, MUTEX_DEFAULT, IPL_SCHED); 3072 lock_available = true; 3073 } 3074 3075 #if defined(SUN4) || defined(SUN4C) 3076 void 3077 pmap_bootstrap4_4c(void *top, int nctx, int nregion, int nsegment) 3078 { 3079 union ctxinfo *ci; 3080 struct mmuentry *mmuseg; 3081 #if defined(SUN4_MMU3L) 3082 struct mmuentry *mmureg; 3083 #endif 3084 struct regmap *rp; 3085 struct segmap *sp; 3086 int i, j; 3087 int npte, zseg, vr, vs; 3088 int startscookie, scookie; 3089 #if defined(SUN4_MMU3L) 3090 int startrcookie = 0, rcookie = 0; 3091 #endif 3092 int *kptes; 3093 int lastpage; 3094 vaddr_t va; 3095 vaddr_t p; 3096 3097 /* 3098 * Compute `va2pa_offset'. 3099 * Use `kernel_text' to probe the MMU translation since 3100 * the pages at KERNBASE might not be mapped. 3101 */ 3102 va2pa_offset = (vaddr_t)kernel_text - 3103 ((getpte4(kernel_text) & PG_PFNUM) << PGSHIFT); 3104 3105 ncontext = nctx; 3106 3107 switch (cputyp) { 3108 case CPU_SUN4C: 3109 mmu_has_hole = 1; 3110 break; 3111 case CPU_SUN4: 3112 if (cpuinfo.cpu_type != CPUTYP_4_400) { 3113 mmu_has_hole = 1; 3114 break; 3115 } 3116 } 3117 3118 #if defined(SUN4) 3119 /* 3120 * set up the segfixmask to mask off invalid bits 3121 */ 3122 segfixmask = nsegment - 1; /* assume nsegment is a power of 2 */ 3123 #ifdef DIAGNOSTIC 3124 if (((nsegment & segfixmask) | (nsegment & ~segfixmask)) != nsegment) { 3125 printf("pmap_bootstrap: unsuitable number of segments (%d)\n", 3126 nsegment); 3127 callrom(); 3128 } 3129 #endif 3130 #endif 3131 3132 #if defined(SUN4M) || defined(SUN4D) /* We're in a dual-arch kernel. 3133 Setup 4/4c fn. ptrs */ 3134 pmap_clear_modify_p = pmap_clear_modify4_4c; 3135 pmap_clear_reference_p = pmap_clear_reference4_4c; 3136 pmap_enter_p = pmap_enter4_4c; 3137 pmap_extract_p = pmap_extract4_4c; 3138 pmap_is_modified_p = pmap_is_modified4_4c; 3139 pmap_is_referenced_p = pmap_is_referenced4_4c; 3140 pmap_kenter_pa_p = pmap_kenter_pa4_4c; 3141 pmap_kremove_p = pmap_kremove4_4c; 3142 pmap_kprotect_p = pmap_kprotect4_4c; 3143 pmap_page_protect_p = pmap_page_protect4_4c; 3144 pmap_protect_p = pmap_protect4_4c; 3145 pmap_rmk_p = pmap_rmk4_4c; 3146 pmap_rmu_p = pmap_rmu4_4c; 3147 #endif /* defined SUN4M || defined SUN4D */ 3148 3149 p = (vaddr_t)top; 3150 3151 /* 3152 * Last segment is the `invalid' one (one PMEG of pte's with !pg_v). 3153 * It will never be used for anything else. 3154 */ 3155 seginval = --nsegment; 3156 3157 #if defined(SUN4_MMU3L) 3158 if (HASSUN4_MMU3L) 3159 reginval = --nregion; 3160 #endif 3161 3162 /* 3163 * Allocate and initialise mmu entries and context structures. 3164 */ 3165 #if defined(SUN4_MMU3L) 3166 mmuregions = mmureg = (struct mmuentry *)p; 3167 p += nregion * sizeof(struct mmuentry); 3168 memset(mmuregions, 0, nregion * sizeof(struct mmuentry)); 3169 #endif 3170 mmusegments = mmuseg = (struct mmuentry *)p; 3171 p += nsegment * sizeof(struct mmuentry); 3172 memset(mmusegments, 0, nsegment * sizeof(struct mmuentry)); 3173 3174 pmap_kernel()->pm_ctx = ctxinfo = ci = (union ctxinfo *)p; 3175 p += nctx * sizeof *ci; 3176 3177 /* Initialize MMU resource queues */ 3178 #if defined(SUN4_MMU3L) 3179 mmuq_init(®ion_freelist); 3180 mmuq_init(®ion_lru); 3181 mmuq_init(®ion_locked); 3182 #endif 3183 mmuq_init(&segm_freelist); 3184 mmuq_init(&segm_lru); 3185 mmuq_init(&segm_locked); 3186 3187 3188 /* 3189 * Initialize the kernel pmap. 3190 */ 3191 /* kernel_pmap_store.pm_ctxnum = 0; */ 3192 kernel_pmap_store.pm_refcount = 1; 3193 #if defined(SUN4_MMU3L) 3194 TAILQ_INIT(&kernel_pmap_store.pm_reglist); 3195 #endif 3196 TAILQ_INIT(&kernel_pmap_store.pm_seglist); 3197 3198 /* 3199 * Allocate memory for kernel PTEs 3200 * XXX Consider allocating memory for only a few regions 3201 * and use growkernel() to allocate more as needed. 3202 */ 3203 kptes = (int *)p; 3204 p += NKREG * NSEGRG * NPTESG * sizeof(int); 3205 memset(kptes, 0, NKREG * NSEGRG * NPTESG * sizeof(int)); 3206 3207 /* 3208 * Set up pm_regmap for kernel to point NUREG *below* the beginning 3209 * of kernel regmap storage. Since the kernel only uses regions 3210 * above NUREG, we save storage space and can index kernel and 3211 * user regions in the same way. 3212 */ 3213 #pragma GCC diagnostic push 3214 #pragma GCC diagnostic ignored "-Warray-bounds" 3215 kernel_pmap_store.pm_regmap = kernel_regmap_store - NUREG; 3216 #pragma GCC diagnostic pop 3217 for (i = NKREG; --i >= 0;) { 3218 #if defined(SUN4_MMU3L) 3219 kernel_regmap_store[i].rg_smeg = reginval; 3220 #endif 3221 kernel_regmap_store[i].rg_segmap = 3222 &kernel_segmap_store[i * NSEGRG]; 3223 for (j = NSEGRG; --j >= 0;) { 3224 sp = &kernel_segmap_store[i * NSEGRG + j]; 3225 sp->sg_pmeg = seginval; 3226 sp->sg_pte = &kptes[(i * NSEGRG + j) * NPTESG]; 3227 } 3228 } 3229 3230 /* 3231 * Preserve the monitor ROM's reserved VM region, so that 3232 * we can use L1-A or the monitor's debugger. As a side 3233 * effect we map the ROM's reserved VM into all contexts 3234 * (otherwise L1-A crashes the machine!). 3235 */ 3236 3237 mmu_reservemon4_4c(&nregion, &nsegment); 3238 3239 #if defined(SUN4_MMU3L) 3240 /* Reserve one region for temporary mappings */ 3241 if (HASSUN4_MMU3L) 3242 tregion = --nregion; 3243 #endif 3244 3245 /* 3246 * Set up the `constants' for the call to vm_init() 3247 * in main(). All pages beginning at p (rounded up to 3248 * the next whole page) and continuing through the number 3249 * of available pages are free, but they start at a higher 3250 * virtual address. This gives us two mappable MD pages 3251 * for pmap_zero_page and pmap_copy_page, and one MI page 3252 * for /dev/mem, all with no associated physical memory. 3253 */ 3254 p = (p + NBPG - 1) & ~PGOFSET; 3255 3256 avail_start = PMAP_BOOTSTRAP_VA2PA(p); 3257 3258 i = p; 3259 cpuinfo.vpage[0] = (void *)p, p += NBPG; 3260 cpuinfo.vpage[1] = (void *)p, p += NBPG; 3261 p = (vaddr_t)reserve_dumppages((void *)p); 3262 3263 virtual_avail = p; 3264 virtual_end = VM_MAX_KERNEL_ADDRESS; 3265 3266 p = i; /* retract to first free phys */ 3267 3268 3269 /* 3270 * All contexts are free except the kernel's. 3271 * 3272 * XXX sun4c could use context 0 for users? 3273 */ 3274 ci->c_pmap = pmap_kernel(); 3275 ctx_freelist = ci + 1; 3276 for (i = 1; i < ncontext; i++) { 3277 ci++; 3278 ci->c_nextfree = ci + 1; 3279 } 3280 ci->c_nextfree = NULL; 3281 ctx_kick = 0; 3282 ctx_kickdir = -1; 3283 3284 /* 3285 * Init mmu entries that map the kernel physical addresses. 3286 * 3287 * All the other MMU entries are free. 3288 * 3289 * THIS ASSUMES THE KERNEL IS MAPPED BY A CONTIGUOUS RANGE OF 3290 * MMU SEGMENTS/REGIONS DURING THE BOOT PROCESS 3291 */ 3292 3293 /* Compute the number of segments used by the kernel */ 3294 zseg = (((p + NBPSG - 1) & ~SGOFSET) - KERNBASE) >> SGSHIFT; 3295 lastpage = VA_VPG(p); 3296 if (lastpage == 0) 3297 /* 3298 * If the page bits in p are 0, we filled the last segment 3299 * exactly; if not, it is the last page filled in the 3300 * last segment. 3301 */ 3302 lastpage = NPTESG; 3303 3304 p = KERNBASE; /* first va */ 3305 vs = VA_VSEG(KERNBASE); /* first virtual segment */ 3306 vr = VA_VREG(KERNBASE); /* first virtual region */ 3307 rp = &pmap_kernel()->pm_regmap[vr]; 3308 3309 /* Get region/segment where kernel addresses start */ 3310 #if defined(SUN4_MMU3L) 3311 if (HASSUN4_MMU3L) 3312 startrcookie = rcookie = getregmap(p); 3313 mmureg = &mmuregions[rcookie]; 3314 #endif 3315 3316 startscookie = scookie = getsegmap(p); 3317 mmuseg = &mmusegments[scookie]; 3318 zseg += scookie; /* First free segment */ 3319 3320 for (;;) { 3321 3322 /* 3323 * Distribute each kernel region/segment into all contexts. 3324 * This is done through the monitor ROM, rather than 3325 * directly here: if we do a setcontext we will fault, 3326 * as we are not (yet) mapped in any other context. 3327 */ 3328 3329 if ((vs % NSEGRG) == 0) { 3330 /* Entering a new region */ 3331 if (VA_VREG(p) > vr) { 3332 #ifdef DEBUG 3333 printf("note: giant kernel!\n"); 3334 #endif 3335 vr++, rp++; 3336 } 3337 #if defined(SUN4_MMU3L) 3338 if (HASSUN4_MMU3L) { 3339 for (i = 1; i < nctx; i++) 3340 prom_setcontext(i, (void *)p, rcookie); 3341 3342 mmuq_insert_tail(®ion_locked, 3343 mmureg); 3344 TAILQ_INSERT_TAIL(&pmap_kernel()->pm_reglist, 3345 mmureg, me_pmchain); 3346 #ifdef DIAGNOSTIC 3347 mmuseg->me_statp = NULL; 3348 #endif 3349 mmureg->me_cookie = rcookie; 3350 mmureg->me_pmap = pmap_kernel(); 3351 mmureg->me_vreg = vr; 3352 rp->rg_smeg = rcookie; 3353 mmureg++; 3354 rcookie++; 3355 } 3356 #endif /* SUN4_MMU3L */ 3357 } 3358 3359 #if defined(SUN4_MMU3L) 3360 if (!HASSUN4_MMU3L) 3361 #endif 3362 for (i = 1; i < nctx; i++) 3363 prom_setcontext(i, (void *)p, scookie); 3364 3365 /* set up the mmu entry */ 3366 mmuq_insert_tail(&segm_locked, mmuseg); 3367 #ifdef DIAGNOSTIC 3368 mmuseg->me_statp = &pmap_stats.ps_npmeg_locked; 3369 #endif 3370 TAILQ_INSERT_TAIL(&pmap_kernel()->pm_seglist, mmuseg, me_pmchain); 3371 pmap_stats.ps_npmeg_locked++; 3372 mmuseg->me_cookie = scookie; 3373 mmuseg->me_pmap = pmap_kernel(); 3374 mmuseg->me_vreg = vr; 3375 mmuseg->me_vseg = vs % NSEGRG; 3376 sp = &rp->rg_segmap[vs % NSEGRG]; 3377 sp->sg_pmeg = scookie; 3378 npte = ++scookie < zseg ? NPTESG : lastpage; 3379 sp->sg_npte = npte; 3380 sp->sg_nwired = npte; 3381 pmap_kernel()->pm_stats.resident_count += npte; 3382 rp->rg_nsegmap += 1; 3383 for (i = 0; i < npte; i++) 3384 sp->sg_pte[i] = getpte4(p + i * NBPG) | PG_WIRED; 3385 mmuseg++; 3386 vs++; 3387 if (scookie < zseg) { 3388 p += NBPSG; 3389 continue; 3390 } 3391 3392 /* 3393 * Unmap the pages, if any, that are not part of 3394 * the final segment. 3395 */ 3396 for (p += npte << PGSHIFT; npte < NPTESG; npte++, p += NBPG) 3397 setpte4(p, 0); 3398 3399 #if defined(SUN4_MMU3L) 3400 if (HASSUN4_MMU3L) { 3401 /* 3402 * Unmap the segments, if any, that are not part of 3403 * the final region. 3404 */ 3405 for (i = rp->rg_nsegmap; i < NSEGRG; i++, p += NBPSG) 3406 setsegmap(p, seginval); 3407 3408 /* 3409 * Unmap any kernel regions that we aren't using. 3410 */ 3411 for (i = 0; i < nctx; i++) { 3412 setcontext4(i); 3413 for (va = p; 3414 va < (OPENPROM_STARTVADDR & ~(NBPRG - 1)); 3415 va += NBPRG) 3416 setregmap(va, reginval); 3417 } 3418 3419 } else 3420 #endif 3421 { 3422 /* 3423 * Unmap any kernel segments that we aren't using. 3424 */ 3425 for (i = 0; i < nctx; i++) { 3426 setcontext4(i); 3427 for (va = p; 3428 va < (OPENPROM_STARTVADDR & ~(NBPSG - 1)); 3429 va += NBPSG) 3430 setsegmap(va, seginval); 3431 } 3432 } 3433 break; 3434 } 3435 3436 #if defined(SUN4_MMU3L) 3437 if (HASSUN4_MMU3L) 3438 for (rcookie = 0; rcookie < nregion; rcookie++) { 3439 if (rcookie == startrcookie) 3440 /* Kernel must fit in one region! */ 3441 rcookie++; 3442 mmureg = &mmuregions[rcookie]; 3443 mmureg->me_cookie = rcookie; 3444 mmuq_insert_tail(®ion_freelist, mmureg); 3445 #ifdef DIAGNOSTIC 3446 mmuseg->me_statp = NULL; 3447 #endif 3448 } 3449 #endif /* SUN4_MMU3L */ 3450 3451 for (scookie = 0; scookie < nsegment; scookie++) { 3452 if (scookie == startscookie) 3453 /* Skip static kernel image */ 3454 scookie = zseg; 3455 mmuseg = &mmusegments[scookie]; 3456 mmuseg->me_cookie = scookie; 3457 mmuq_insert_tail(&segm_freelist, mmuseg); 3458 pmap_stats.ps_npmeg_free++; 3459 #ifdef DIAGNOSTIC 3460 mmuseg->me_statp = NULL; 3461 #endif 3462 } 3463 3464 /* Erase all spurious user-space segmaps */ 3465 for (i = 1; i < ncontext; i++) { 3466 setcontext4(i); 3467 if (HASSUN4_MMU3L) 3468 for (p = 0, j = NUREG; --j >= 0; p += NBPRG) 3469 setregmap(p, reginval); 3470 else 3471 for (p = 0, vr = 0; vr < NUREG; vr++) { 3472 if (VA_INHOLE(p)) { 3473 p = MMU_HOLE_END; 3474 vr = VA_VREG(p); 3475 } 3476 for (j = NSEGRG; --j >= 0; p += NBPSG) 3477 setsegmap(p, seginval); 3478 } 3479 } 3480 setcontext4(0); 3481 3482 /* 3483 * write protect & encache kernel text; 3484 * set red zone at kernel base; 3485 * enable cache on message buffer and cpuinfo. 3486 */ 3487 3488 /* Enable cache on message buffer and cpuinfo */ 3489 for (p = KERNBASE; p < (vaddr_t)trapbase; p += NBPG) 3490 setpte4(p, getpte4(p) & ~PG_NC); 3491 3492 /* Enable cache and write protect kernel text */ 3493 for (p = (vaddr_t)trapbase; p < (vaddr_t)etext; p += NBPG) 3494 setpte4(p, getpte4(p) & ~(PG_NC|PG_W)); 3495 3496 /* 3497 * Unmap the `etext gap'; it'll be made available 3498 * to the VM manager. 3499 */ 3500 for (p = etext_gap_start; p < etext_gap_end; p += NBPG) { 3501 rp = &pmap_kernel()->pm_regmap[VA_VREG(p)]; 3502 sp = &rp->rg_segmap[VA_VSEG(p)]; 3503 sp->sg_nwired--; 3504 sp->sg_npte--; 3505 pmap_kernel()->pm_stats.resident_count--; 3506 sp->sg_pte[VA_VPG(p)] = 0; 3507 setpte4(p, 0); 3508 } 3509 3510 /* Enable cache on data & bss */ 3511 for (p = etext_gap_end; p < virtual_avail; p += NBPG) 3512 setpte4(p, getpte4(p) & ~PG_NC); 3513 3514 cpus[0] = (struct cpu_info *)CPUINFO_VA; 3515 } 3516 #endif 3517 3518 #if defined(SUN4M) || defined(SUN4D) /* SRMMU version of pmap_bootstrap */ 3519 /* 3520 * Bootstrap the system enough to run with VM enabled on a sun4m machine. 3521 * 3522 * Switches from ROM to kernel page tables, and sets up initial mappings. 3523 */ 3524 static void 3525 pmap_bootstrap4m(void *top) 3526 { 3527 int i, j; 3528 vaddr_t p, q; 3529 union ctxinfo *ci; 3530 int reg, seg; 3531 unsigned int ctxtblsize; 3532 vaddr_t pagetables_start, pagetables_end; 3533 paddr_t pagetables_start_pa; 3534 vaddr_t va; 3535 #if defined(MULTIPROCESSOR) 3536 vsize_t off; 3537 size_t cpuinfo_len = sizeof(struct cpu_info); 3538 uint8_t *cpuinfo_data; 3539 int align = PAGE_SIZE; 3540 vaddr_t sva, cpuinfo_va; 3541 vsize_t sz; 3542 #endif 3543 3544 /* 3545 * Compute `va2pa_offset'. 3546 * Use `kernel_text' to probe the MMU translation since 3547 * the pages at KERNBASE might not be mapped. 3548 */ 3549 va2pa_offset = (vaddr_t)kernel_text - VA2PA(kernel_text); 3550 3551 ncontext = cpuinfo.mmu_ncontext; 3552 3553 #if defined(SUN4) || defined(SUN4C) /* setup SRMMU fn. ptrs for dual-arch 3554 kernel */ 3555 pmap_clear_modify_p = pmap_clear_modify4m; 3556 pmap_clear_reference_p = pmap_clear_reference4m; 3557 pmap_enter_p = pmap_enter4m; 3558 pmap_extract_p = pmap_extract4m; 3559 pmap_is_modified_p = pmap_is_modified4m; 3560 pmap_is_referenced_p = pmap_is_referenced4m; 3561 pmap_kenter_pa_p = pmap_kenter_pa4m; 3562 pmap_kremove_p = pmap_kremove4m; 3563 pmap_kprotect_p = pmap_kprotect4m; 3564 pmap_page_protect_p = pmap_page_protect4m; 3565 pmap_protect_p = pmap_protect4m; 3566 pmap_rmk_p = pmap_rmk4m; 3567 pmap_rmu_p = pmap_rmu4m; 3568 #endif /* defined SUN4/SUN4C */ 3569 3570 /* 3571 * p points to top of kernel mem 3572 */ 3573 p = (vaddr_t)top; 3574 3575 p = (p + NBPG - 1) & ~PGOFSET; 3576 DPRINTF(PDB_INITLOUD, "initial p=%lx", p); 3577 3578 /* 3579 * Initialize the kernel pmap. 3580 */ 3581 /* kernel_pmap_store.pm_ctxnum = 0; */ 3582 kernel_pmap_store.pm_refcount = 1; 3583 3584 /* 3585 * Set up pm_regmap for kernel to point NUREG *below* the beginning 3586 * of kernel regmap storage. Since the kernel only uses regions 3587 * above NUREG, we save storage space and can index kernel and 3588 * user regions in the same way. 3589 */ 3590 #pragma GCC diagnostic push 3591 #pragma GCC diagnostic ignored "-Warray-bounds" 3592 kernel_pmap_store.pm_regmap = kernel_regmap_store - NUREG; 3593 #pragma GCC diagnostic pop 3594 memset(kernel_regmap_store, 0, sizeof kernel_regmap_store); 3595 memset(kernel_segmap_store, 0, sizeof kernel_segmap_store); 3596 for (i = NKREG; --i >= 0;) { 3597 kernel_regmap_store[i].rg_segmap = 3598 &kernel_segmap_store[i * NSEGRG]; 3599 kernel_regmap_store[i].rg_seg_ptps = NULL; 3600 for (j = NSEGRG; --j >= 0;) 3601 kernel_segmap_store[i * NSEGRG + j].sg_pte = NULL; 3602 } 3603 3604 /* Allocate kernel region pointer tables */ 3605 pmap_kernel()->pm_reg_ptps = (int **)(q = p); 3606 DPRINTF(PDB_INITLOUD, "kernel region pointer tables p=%lx", p); 3607 p += sparc_ncpus * sizeof(int **); 3608 memset((void *)q, 0, (u_int)p - (u_int)q); 3609 3610 pmap_kernel()->pm_reg_ptps_pa = (int *)(q = p); 3611 DPRINTF(PDB_INITLOUD, "kernel region pointer tables pa p=%lx", p); 3612 p += sparc_ncpus * sizeof(int *); 3613 memset((void *)q, 0, (u_int)p - (u_int)q); 3614 3615 /* Allocate context administration */ 3616 pmap_kernel()->pm_ctx = ctxinfo = ci = (union ctxinfo *)p; 3617 DPRINTF(PDB_INITLOUD, "context administration p=%lx", p); 3618 p += ncontext * sizeof *ci; 3619 memset((void *)ci, 0, (u_int)p - (u_int)ci); 3620 3621 /* 3622 * Set up the `constants' for the call to vm_init() 3623 * in main(). All pages beginning at p (rounded up to 3624 * the next whole page) and continuing through the number 3625 * of available pages are free. 3626 */ 3627 p = (p + NBPG - 1) & ~PGOFSET; 3628 DPRINTF(PDB_INITLOUD, "align p=%lx", p); 3629 3630 /* 3631 * Reserve memory for MMU pagetables. Some of these have severe 3632 * alignment restrictions. We allocate in a sequence that 3633 * minimizes alignment gaps. 3634 */ 3635 3636 pagetables_start = p; 3637 pagetables_start_pa = PMAP_BOOTSTRAP_VA2PA(p); 3638 3639 /* 3640 * Allocate context table. 3641 * To keep supersparc happy, minimum alignment is on a 4K boundary. 3642 */ 3643 ctxtblsize = uimax(ncontext,1024) * sizeof(int); 3644 cpuinfo.ctx_tbl = (int *)roundup((u_int)p, ctxtblsize); 3645 cpuinfo.ctx_tbl_pa = PMAP_BOOTSTRAP_VA2PA(cpuinfo.ctx_tbl); 3646 p = (u_int)cpuinfo.ctx_tbl + ctxtblsize; 3647 DPRINTF(PDB_INITLOUD, "post ctx table p=%lx", p); 3648 3649 #if defined(MULTIPROCESSOR) 3650 /* 3651 * Make sure all smp_tlb_flush*() routines for kernel pmap are 3652 * broadcast to all CPU's. 3653 */ 3654 pmap_kernel()->pm_cpuset = CPUSET_ALL; 3655 #endif 3656 3657 /* 3658 * Reserve memory for segment and page tables needed to map the entire 3659 * kernel. This takes (2K + NKREG * 16K) of space, but unfortunately 3660 * is necessary since pmap_enter() *must* be able to enter a kernel 3661 * mapping without delay. 3662 */ 3663 p = (vaddr_t) roundup(p, SRMMU_L1SIZE * sizeof(u_int)); 3664 DPRINTF(PDB_INITLOUD, "roundup kernel_regtable_store p=%lx", p); 3665 qzero((void *)p, SRMMU_L1SIZE * sizeof(u_int)); 3666 kernel_regtable_store = (u_int *)p; 3667 p += SRMMU_L1SIZE * sizeof(u_int); 3668 DPRINTF(PDB_INITLOUD, "L1 pages p=%lx", p); 3669 3670 p = (vaddr_t) roundup(p, SRMMU_L2SIZE * sizeof(u_int)); 3671 DPRINTF(PDB_INITLOUD, "roundup kernel_segtable_store p=%lx", p); 3672 qzero((void *)p, (SRMMU_L2SIZE * sizeof(u_int)) * NKREG); 3673 kernel_segtable_store = (u_int *)p; 3674 p += (SRMMU_L2SIZE * sizeof(u_int)) * NKREG; 3675 DPRINTF(PDB_INITLOUD, "L2 pages p=%lx", p); 3676 3677 p = (vaddr_t) roundup(p, SRMMU_L3SIZE * sizeof(u_int)); 3678 DPRINTF(PDB_INITLOUD, "roundup kernel_pagtable_store p=%lx", p); 3679 /* zero it: all will be SRMMU_TEINVALID */ 3680 qzero((void *)p, ((SRMMU_L3SIZE * sizeof(u_int)) * NSEGRG) * NKREG); 3681 kernel_pagtable_store = (u_int *)p; 3682 p += ((SRMMU_L3SIZE * sizeof(u_int)) * NSEGRG) * NKREG; 3683 DPRINTF(PDB_INITLOUD, "L3 pages p=%lx", p); 3684 3685 /* Round to next page and mark end of pre-wired kernel space */ 3686 p = (p + NBPG - 1) & ~PGOFSET; 3687 DPRINTF(PDB_INITLOUD, "align p=%lx", p); 3688 pagetables_end = p; 3689 3690 #if defined(MULTIPROCESSOR) 3691 /* 3692 * Allocate aligned KVA. `cpuinfo' resides at a fixed virtual 3693 * address. Since we need to access an other CPU's cpuinfo 3694 * structure occasionally, this must be done at a virtual address 3695 * that's cache congruent to the fixed address CPUINFO_VA. 3696 * 3697 * NOTE: we're using the cache properties of the boot CPU to 3698 * determine the alignment (XXX). 3699 */ 3700 sz = sizeof(struct cpu_info); 3701 if (sparc_ncpus > 1) { 3702 if (CACHEINFO.c_totalsize > align) { 3703 /* Need a power of two */ 3704 while (align <= CACHEINFO.c_totalsize) 3705 align <<= 1; 3706 align >>= 1; 3707 } 3708 3709 sz = (sz + PAGE_SIZE - 1) & -PAGE_SIZE; 3710 cpuinfo_len = sz + align - PAGE_SIZE; 3711 3712 /* Grab as much space as we need */ 3713 DPRINTF(PDB_INITLOUD, "cpuinfo=%lx", p); 3714 cpuinfo_data = (uint8_t *)p; 3715 p += (cpuinfo_len * sparc_ncpus); 3716 } else 3717 cpuinfo_data = (uint8_t *)CPUINFO_VA; 3718 #endif 3719 3720 DPRINTF(PDB_INITLOUD, "avail_start=%lx", p); 3721 avail_start = PMAP_BOOTSTRAP_VA2PA(p); 3722 3723 /* 3724 * Now wire the region and segment tables of the kernel map. 3725 */ 3726 pmap_kernel()->pm_reg_ptps[0] = (int *) kernel_regtable_store; 3727 pmap_kernel()->pm_reg_ptps_pa[0] = 3728 PMAP_BOOTSTRAP_VA2PA(kernel_regtable_store); 3729 3730 /* Install L1 table in context 0 */ 3731 setpgt4m(&cpuinfo.ctx_tbl[0], 3732 (pmap_kernel()->pm_reg_ptps_pa[0] >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD); 3733 3734 for (reg = 0; reg < NKREG; reg++) { 3735 struct regmap *rp; 3736 void *kphyssegtbl; 3737 3738 /* 3739 * Entering new region; install & build segtbl 3740 */ 3741 3742 rp = &pmap_kernel()->pm_regmap[reg + VA_VREG(KERNBASE)]; 3743 3744 kphyssegtbl = (void *) 3745 &kernel_segtable_store[reg * SRMMU_L2SIZE]; 3746 3747 setpgt4m(&pmap_kernel()->pm_reg_ptps[0][reg + VA_VREG(KERNBASE)], 3748 (PMAP_BOOTSTRAP_VA2PA(kphyssegtbl) >> SRMMU_PPNPASHIFT) | 3749 SRMMU_TEPTD); 3750 3751 rp->rg_seg_ptps = (int *)kphyssegtbl; 3752 3753 for (seg = 0; seg < NSEGRG; seg++) { 3754 struct segmap *sp; 3755 void *kphyspagtbl; 3756 3757 rp->rg_nsegmap++; 3758 3759 sp = &rp->rg_segmap[seg]; 3760 kphyspagtbl = (void *) 3761 &kernel_pagtable_store 3762 [((reg * NSEGRG) + seg) * SRMMU_L3SIZE]; 3763 3764 setpgt4m(&rp->rg_seg_ptps[seg], 3765 (PMAP_BOOTSTRAP_VA2PA(kphyspagtbl) >> SRMMU_PPNPASHIFT) | 3766 SRMMU_TEPTD); 3767 sp->sg_pte = (int *) kphyspagtbl; 3768 } 3769 } 3770 3771 /* 3772 * Preserve the monitor ROM's reserved VM region, so that 3773 * we can use L1-A or the monitor's debugger. 3774 */ 3775 mmu_reservemon4m(&kernel_pmap_store); 3776 3777 /* 3778 * Reserve virtual address space for two mappable MD pages 3779 * for pmap_zero_page and pmap_copy_page, one MI page 3780 * for /dev/mem, and some more for dumpsys(). 3781 */ 3782 q = p; 3783 cpuinfo.vpage[0] = (void *)p, p += NBPG; 3784 cpuinfo.vpage[1] = (void *)p, p += NBPG; 3785 p = (vaddr_t)reserve_dumppages((void *)p); 3786 3787 /* Find PTE locations of vpage[] to optimize zero_fill() et.al. */ 3788 for (i = 0; i < 2; i++) { 3789 struct regmap *rp; 3790 struct segmap *sp; 3791 rp = &pmap_kernel()->pm_regmap[VA_VREG(cpuinfo.vpage[i])]; 3792 sp = &rp->rg_segmap[VA_VSEG(cpuinfo.vpage[i])]; 3793 cpuinfo.vpage_pte[i] = 3794 &sp->sg_pte[VA_SUN4M_VPG(cpuinfo.vpage[i])]; 3795 } 3796 3797 #if !(defined(PROM_AT_F0) || defined(MSIIEP)) 3798 virtual_avail = p; 3799 #elif defined(MSIIEP) 3800 virtual_avail = (vaddr_t)0xf0800000; /* Krups */ 3801 #else 3802 virtual_avail = (vaddr_t)0xf0080000; /* Mr.Coffee/OFW */ 3803 #endif 3804 virtual_end = VM_MAX_KERNEL_ADDRESS; 3805 3806 p = q; /* retract to first free phys */ 3807 3808 /* 3809 * Set up the ctxinfo structures (freelist of contexts) 3810 */ 3811 ci->c_pmap = pmap_kernel(); 3812 ctx_freelist = ci + 1; 3813 for (i = 1; i < ncontext; i++) { 3814 ci++; 3815 ci->c_nextfree = ci + 1; 3816 } 3817 ci->c_nextfree = NULL; 3818 ctx_kick = 0; 3819 ctx_kickdir = -1; 3820 3821 /* 3822 * Now map the kernel into our new set of page tables, then 3823 * (finally) switch over to our running page tables. 3824 * We map from KERNBASE to p into context 0's page tables (and 3825 * the kernel pmap). 3826 */ 3827 #ifdef DEBUG /* Sanity checks */ 3828 if (p % NBPG != 0) 3829 panic("pmap_bootstrap4m: p misaligned?!?"); 3830 if (KERNBASE % NBPRG != 0) 3831 panic("pmap_bootstrap4m: KERNBASE not region-aligned"); 3832 #endif 3833 3834 for (q = KERNBASE; q < p; q += NBPG) { 3835 struct regmap *rp; 3836 struct segmap *sp; 3837 int pte, *ptep; 3838 3839 /* 3840 * Now install entry for current page. 3841 */ 3842 rp = &pmap_kernel()->pm_regmap[VA_VREG(q)]; 3843 sp = &rp->rg_segmap[VA_VSEG(q)]; 3844 ptep = &sp->sg_pte[VA_VPG(q)]; 3845 3846 /* 3847 * Unmap the `etext gap'; it'll be made available 3848 * to the VM manager. 3849 */ 3850 if (q >= etext_gap_start && q < etext_gap_end) { 3851 setpgt4m(ptep, 0); 3852 continue; 3853 } 3854 3855 pte = PMAP_BOOTSTRAP_VA2PA(q) >> SRMMU_PPNPASHIFT; 3856 pte |= PPROT_N_RX | SRMMU_TEPTE; 3857 3858 /* Deal with the cacheable bit for pagetable memory */ 3859 if ((CACHEINFO.c_flags & CACHE_PAGETABLES) != 0 || 3860 q < pagetables_start || q >= pagetables_end) 3861 pte |= SRMMU_PG_C; 3862 3863 /* write-protect kernel text */ 3864 if (q < (vaddr_t)trapbase || q >= (vaddr_t)etext) 3865 pte |= PPROT_WRITE; 3866 3867 setpgt4m(ptep, pte); 3868 pmap_kernel()->pm_stats.resident_count++; 3869 } 3870 3871 if ((CACHEINFO.c_flags & CACHE_PAGETABLES) == 0) { 3872 /* 3873 * The page tables have been setup. Since we're still 3874 * running on the PROM's memory map, the memory we 3875 * allocated for our page tables might still be cached. 3876 * Flush it now, and don't touch it again until we 3877 * switch to our own tables (will be done immediately below). 3878 */ 3879 int size = pagetables_end - pagetables_start; 3880 if (CACHEINFO.c_vactype != VAC_NONE) { 3881 va = (vaddr_t)pagetables_start; 3882 while (size > 0) { 3883 cache_flush_page(va, 0); 3884 va += NBPG; 3885 size -= NBPG; 3886 } 3887 } else if (cpuinfo.pcache_flush_page != NULL) { 3888 paddr_t pa = pagetables_start_pa; 3889 while (size > 0) { 3890 pcache_flush_page(pa, 0); 3891 pa += NBPG; 3892 size -= NBPG; 3893 } 3894 } 3895 } 3896 3897 /* 3898 * Now switch to kernel pagetables (finally!) 3899 */ 3900 mmu_install_tables(&cpuinfo); 3901 3902 #if defined(MULTIPROCESSOR) 3903 /* 3904 * Initialise any cpu-specific data now. 3905 */ 3906 cpu_init_system(); 3907 3908 /* 3909 * Setup the cpus[] array and the ci_self links. 3910 */ 3911 for (i = 0; i < sparc_ncpus; i++) { 3912 sva = (vaddr_t) (cpuinfo_data + (cpuinfo_len * i)); 3913 cpuinfo_va = sva + 3914 (((CPUINFO_VA & (align - 1)) + align - sva) & (align - 1)); 3915 3916 /* 3917 * Either remap from CPUINFO_VA to the new correct value 3918 * or clear out this cpuinfo. 3919 */ 3920 if (i == 0) { 3921 for (off = 0, va = cpuinfo_va; 3922 sparc_ncpus > 1 && off < sizeof(struct cpu_info); 3923 va += NBPG, off += NBPG) { 3924 paddr_t pa = 3925 PMAP_BOOTSTRAP_VA2PA(CPUINFO_VA + off); 3926 3927 pmap_kremove(va, NBPG); 3928 pmap_kenter_pa(va, pa, 3929 VM_PROT_READ | VM_PROT_WRITE, 0); 3930 } 3931 3932 } else 3933 memset((void *)cpuinfo_va, 0, sizeof(struct cpu_info)); 3934 3935 cpus[i] = (struct cpu_info *)cpuinfo_va; 3936 cpus[i]->ci_self = cpus[i]; 3937 3938 /* Unmap and prepare to return unused pages */ 3939 if (cpuinfo_va != sva) { 3940 cpus[i]->ci_free_sva1 = sva; 3941 cpus[i]->ci_free_eva1 = cpuinfo_va; 3942 for (va = cpus[i]->ci_free_sva1; 3943 va < cpus[i]->ci_free_eva1; 3944 va += NBPG) 3945 setpte4m(va, 0); 3946 } 3947 if (cpuinfo_va + sz != sva + cpuinfo_len) { 3948 cpus[i]->ci_free_sva2 = cpuinfo_va + sz; 3949 cpus[i]->ci_free_eva2 = sva + cpuinfo_len; 3950 for (va = cpus[i]->ci_free_sva2; 3951 va < cpus[i]->ci_free_eva2; 3952 va += NBPG) 3953 setpte4m(va, 0); 3954 } 3955 } 3956 #else 3957 cpus[0] = (struct cpu_info *)CPUINFO_VA; 3958 #endif 3959 3960 pmap_update(pmap_kernel()); 3961 3962 #ifdef DIAGNOSTIC 3963 if (curcpu()->ci_self != cpus[0]) { 3964 prom_printf("curcpu()->ci_self %p != cpus[0] %p\n", curcpu()->ci_self, cpus[0]); 3965 panic("cpuinfo inconsistent"); 3966 } 3967 #endif 3968 } 3969 3970 static u_long prom_ctxreg; 3971 3972 void 3973 mmu_install_tables(struct cpu_info *sc) 3974 { 3975 3976 #ifdef DEBUG 3977 prom_printf("pmap_bootstrap: installing kernel page tables..."); 3978 #endif 3979 setcontext4m(0); /* paranoia? %%%: Make 0x3 a define! below */ 3980 3981 /* Enable MMU tablewalk caching, flush TLB */ 3982 if (sc->mmu_enable != 0) 3983 sc->mmu_enable(); 3984 3985 tlb_flush_all_real(); 3986 prom_ctxreg = lda(SRMMU_CXTPTR, ASI_SRMMU); 3987 3988 sta(SRMMU_CXTPTR, ASI_SRMMU, 3989 (sc->ctx_tbl_pa >> SRMMU_PPNPASHIFT) & ~0x3); 3990 3991 tlb_flush_all_real(); 3992 3993 #ifdef DEBUG 3994 prom_printf("done.\n"); 3995 #endif 3996 } 3997 3998 void srmmu_restore_prom_ctx(void); 3999 4000 void 4001 srmmu_restore_prom_ctx(void) 4002 { 4003 4004 tlb_flush_all(); 4005 sta(SRMMU_CXTPTR, ASI_SRMMU, prom_ctxreg); 4006 tlb_flush_all(); 4007 } 4008 #endif /* SUN4M || SUN4D */ 4009 4010 #if defined(MULTIPROCESSOR) 4011 /* 4012 * Allocate per-CPU page tables. One region, segment and page table 4013 * is needed to map CPUINFO_VA to different physical addresses on 4014 * each CPU. Since the kernel region and segment tables are all 4015 * pre-wired (in bootstrap() above) and we also assume that the 4016 * first segment (256K) of kernel space is fully populated with 4017 * pages from the start, these per-CPU tables will never need 4018 * to be updated when mapping kernel virtual memory. 4019 * 4020 * Note: this routine is called in the context of the boot CPU 4021 * during autoconfig. 4022 */ 4023 void 4024 pmap_alloc_cpu(struct cpu_info *sc) 4025 { 4026 #if defined(SUN4M) || defined(SUN4D) /* Only implemented for SUN4M/D */ 4027 vaddr_t va; 4028 paddr_t pa; 4029 paddr_t alignment; 4030 u_int *ctxtable, *regtable, *segtable, *pagtable; 4031 u_int *ctxtable_pa, *regtable_pa, *segtable_pa, *pagtable_pa; 4032 psize_t ctxsize, size; 4033 int vr, vs, vpg; 4034 struct regmap *rp; 4035 struct segmap *sp; 4036 struct pglist mlist; 4037 int cachebit; 4038 int pagesz = NBPG; 4039 int i; 4040 4041 cachebit = (CACHEINFO.c_flags & CACHE_PAGETABLES) != 0; 4042 4043 /* 4044 * Allocate properly aligned and contiguous physically memory 4045 * for the PTE tables. 4046 */ 4047 ctxsize = (sc->mmu_ncontext * sizeof(int) + pagesz - 1) & -pagesz; 4048 alignment = ctxsize; 4049 4050 /* The region, segment and page table we need fit in one page */ 4051 size = ctxsize + pagesz; 4052 4053 if (uvm_pglistalloc(size, vm_first_phys, vm_first_phys+vm_num_phys, 4054 alignment, 0, &mlist, 1, 0) != 0) 4055 panic("pmap_alloc_cpu: no memory"); 4056 4057 pa = VM_PAGE_TO_PHYS(TAILQ_FIRST(&mlist)); 4058 4059 /* Allocate virtual memory */ 4060 va = uvm_km_alloc(kernel_map, size, 0, UVM_KMF_VAONLY); 4061 if (va == 0) 4062 panic("pmap_alloc_cpu: no memory"); 4063 4064 /* 4065 * Layout the page tables in our chunk of memory 4066 */ 4067 ctxtable = (u_int *)va; 4068 regtable = (u_int *)(va + ctxsize); 4069 segtable = regtable + SRMMU_L1SIZE; 4070 pagtable = segtable + SRMMU_L2SIZE; 4071 4072 ctxtable_pa = (u_int *)pa; 4073 regtable_pa = (u_int *)(pa + ctxsize); 4074 segtable_pa = regtable_pa + SRMMU_L1SIZE; 4075 pagtable_pa = segtable_pa + SRMMU_L2SIZE; 4076 4077 /* Map the pages */ 4078 while (size != 0) { 4079 pmap_kenter_pa(va, pa | (cachebit ? 0 : PMAP_NC), 4080 VM_PROT_READ | VM_PROT_WRITE, 0); 4081 va += pagesz; 4082 pa += pagesz; 4083 size -= pagesz; 4084 } 4085 pmap_update(pmap_kernel()); 4086 4087 /* 4088 * Store the region table pointer (and its corresponding physical 4089 * address) in the CPU's slot in the kernel pmap region table 4090 * pointer table. 4091 */ 4092 pmap_kernel()->pm_reg_ptps[sc->ci_cpuid] = regtable; 4093 pmap_kernel()->pm_reg_ptps_pa[sc->ci_cpuid] = (paddr_t)regtable_pa; 4094 4095 vr = VA_VREG(CPUINFO_VA); 4096 vs = VA_VSEG(CPUINFO_VA); 4097 vpg = VA_VPG(CPUINFO_VA); 4098 rp = &pmap_kernel()->pm_regmap[vr]; 4099 sp = &rp->rg_segmap[vs]; 4100 4101 /* 4102 * Copy page tables from CPU #0, then modify entry for CPUINFO_VA 4103 * so that it points at the per-CPU pages. 4104 */ 4105 qcopy(pmap_kernel()->pm_reg_ptps[0], regtable, 4106 SRMMU_L1SIZE * sizeof(int)); 4107 qcopy(rp->rg_seg_ptps, segtable, SRMMU_L2SIZE * sizeof(int)); 4108 qcopy(sp->sg_pte, pagtable, SRMMU_L3SIZE * sizeof(int)); 4109 4110 setpgt4m(&ctxtable[0], 4111 ((u_long)regtable_pa >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD); 4112 setpgt4m(®table[vr], 4113 ((u_long)segtable_pa >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD); 4114 setpgt4m(&segtable[vs], 4115 ((u_long)pagtable_pa >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD); 4116 setpgt4m(&pagtable[vpg], 4117 (VA2PA((void *)sc) >> SRMMU_PPNPASHIFT) | 4118 (SRMMU_TEPTE | PPROT_N_RWX | SRMMU_PG_C)); 4119 4120 /* Install this CPU's context table */ 4121 sc->ctx_tbl = ctxtable; 4122 sc->ctx_tbl_pa = (paddr_t)ctxtable_pa; 4123 4124 /* Pre-compute this CPU's vpage[] PTEs */ 4125 for (i = 0; i < 2; i++) { 4126 rp = &pmap_kernel()->pm_regmap[VA_VREG(sc->vpage[i])]; 4127 sp = &rp->rg_segmap[VA_VSEG(sc->vpage[i])]; 4128 sc->vpage_pte[i] = &sp->sg_pte[VA_SUN4M_VPG(sc->vpage[i])]; 4129 } 4130 #endif /* SUN4M || SUN4D */ 4131 } 4132 #endif /* MULTIPROCESSOR */ 4133 4134 4135 void 4136 pmap_init(void) 4137 { 4138 u_int sz; 4139 4140 if (PAGE_SIZE != NBPG) 4141 panic("pmap_init: PAGE_SIZE!=NBPG"); 4142 4143 vm_num_phys = vm_last_phys - vm_first_phys; 4144 4145 /* Setup a pool for additional pvlist structures */ 4146 pool_init(&pv_pool, sizeof(struct pvlist), 0, 0, 0, "pvtable", NULL, 4147 IPL_NONE); 4148 4149 /* 4150 * Setup a pool for pmap structures. 4151 * The pool size includes space for an array of per-CPU 4152 * region table pointers & physical addresses 4153 */ 4154 sz = ALIGN(sizeof(struct pmap)) + 4155 ALIGN(NUREG * sizeof(struct regmap)) + 4156 sparc_ncpus * sizeof(int *) + /* pm_reg_ptps */ 4157 sparc_ncpus * sizeof(int); /* pm_reg_ptps_pa */ 4158 pool_cache_bootstrap(&pmap_cache, sz, 0, 0, 0, "pmappl", NULL, 4159 IPL_NONE, pmap_pmap_pool_ctor, pmap_pmap_pool_dtor, NULL); 4160 4161 sz = NSEGRG * sizeof (struct segmap); 4162 pool_init(&segmap_pool, sz, 0, 0, 0, "segmap", NULL, IPL_NONE); 4163 4164 #if defined(SUN4M) || defined(SUN4D) 4165 if (CPU_HAS_SRMMU) { 4166 /* 4167 * The SRMMU only ever needs chunks in one of two sizes: 4168 * 1024 (for region level tables) and 256 (for segment 4169 * and page level tables). 4170 */ 4171 sz = SRMMU_L1SIZE * sizeof(int); 4172 pool_init(&L1_pool, sz, sz, 0, 0, "L1 pagetable", 4173 &pgt_page_allocator, IPL_NONE); 4174 4175 sz = SRMMU_L2SIZE * sizeof(int); 4176 pool_init(&L23_pool, sz, sz, 0, 0, "L2/L3 pagetable", 4177 &pgt_page_allocator, IPL_NONE); 4178 } 4179 #endif /* SUN4M || SUN4D */ 4180 #if defined(SUN4) || defined(SUN4C) 4181 if (CPU_HAS_SUNMMU) { 4182 sz = NPTESG * sizeof(int); 4183 pool_init(&pte_pool, sz, 0, 0, 0, "ptemap", NULL, 4184 IPL_NONE); 4185 } 4186 #endif /* SUN4 || SUN4C */ 4187 } 4188 4189 4190 /* 4191 * Map physical addresses into kernel VM. 4192 */ 4193 vaddr_t 4194 pmap_map(vaddr_t va, paddr_t pa, paddr_t endpa, int prot) 4195 { 4196 int pgsize = PAGE_SIZE; 4197 4198 while (pa < endpa) { 4199 pmap_kenter_pa(va, pa, prot, 0); 4200 va += pgsize; 4201 pa += pgsize; 4202 } 4203 pmap_update(pmap_kernel()); 4204 return (va); 4205 } 4206 4207 /* 4208 * Check a pmap for spuriously lingering mappings 4209 */ 4210 static inline void 4211 pmap_quiet_check(struct pmap *pm) 4212 { 4213 #ifdef DEBUG 4214 int vs, vr; 4215 4216 if (CPU_HAS_SUNMMU) { 4217 #if defined(SUN4_MMU3L) 4218 if (TAILQ_FIRST(&pm->pm_reglist)) 4219 panic("pmap_destroy: region list not empty"); 4220 #endif 4221 if (TAILQ_FIRST(&pm->pm_seglist)) 4222 panic("pmap_destroy: segment list not empty"); 4223 } 4224 4225 for (vr = 0; vr < NUREG; vr++) { 4226 struct regmap *rp = &pm->pm_regmap[vr]; 4227 4228 if (HASSUN4_MMU3L) { 4229 if (rp->rg_smeg != reginval) 4230 printf("pmap_chk: spurious smeg in " 4231 "user region %d\n", vr); 4232 } 4233 if (CPU_HAS_SRMMU) { 4234 int n; 4235 #if defined(MULTIPROCESSOR) 4236 for (n = 0; n < sparc_ncpus; n++) 4237 #else 4238 n = 0; 4239 #endif 4240 { 4241 /* Did this cpu attach? */ 4242 if (pmap_kernel()->pm_reg_ptps[n] == 0) 4243 continue; 4244 4245 if (pm->pm_reg_ptps[n][vr] != SRMMU_TEINVALID) 4246 printf("pmap_chk: spurious PTP in user " 4247 "region %d on CPU %d\n", vr, n); 4248 } 4249 } 4250 if (rp->rg_nsegmap != 0) 4251 printf("pmap_chk: %d segments remain in " 4252 "region %d\n", rp->rg_nsegmap, vr); 4253 if (rp->rg_segmap != NULL) { 4254 printf("pmap_chk: segments still " 4255 "allocated in region %d\n", vr); 4256 for (vs = 0; vs < NSEGRG; vs++) { 4257 struct segmap *sp = &rp->rg_segmap[vs]; 4258 if (sp->sg_npte != 0) 4259 printf("pmap_chk: %d ptes " 4260 "remain in segment %d\n", 4261 sp->sg_npte, vs); 4262 if (sp->sg_pte != NULL) { 4263 printf("pmap_chk: ptes still " 4264 "allocated in segment %d\n", vs); 4265 } 4266 if (CPU_HAS_SUNMMU) { 4267 if (sp->sg_pmeg != seginval) 4268 printf("pmap_chk: pm %p(%d,%d) " 4269 "spurious soft pmeg %d\n", 4270 pm, vr, vs, sp->sg_pmeg); 4271 } 4272 } 4273 } 4274 4275 /* Check for spurious pmeg entries in the MMU */ 4276 if (pm->pm_ctx == NULL) 4277 continue; 4278 if (CPU_HAS_SUNMMU) { 4279 int ctx; 4280 if (mmu_has_hole && (vr >= 32 && vr < (256 - 32))) 4281 continue; 4282 ctx = getcontext4(); 4283 setcontext4(pm->pm_ctxnum); 4284 for (vs = 0; vs < NSEGRG; vs++) { 4285 vaddr_t va = VSTOVA(vr,vs); 4286 int pmeg = getsegmap(va); 4287 if (pmeg != seginval) 4288 printf("pmap_chk: pm %p(%d,%d:%x): " 4289 "spurious pmeg %d\n", 4290 pm, vr, vs, (u_int)va, pmeg); 4291 } 4292 setcontext4(ctx); 4293 } 4294 } 4295 if (pm->pm_stats.resident_count) { 4296 printf("pmap_chk: res count %ld\n", 4297 pm->pm_stats.resident_count); 4298 } 4299 if (pm->pm_stats.wired_count) { 4300 printf("pmap_chk: wired count %ld\n", 4301 pm->pm_stats.wired_count); 4302 } 4303 #endif /* DEBUG */ 4304 } 4305 4306 int 4307 pmap_pmap_pool_ctor(void *arg, void *object, int flags) 4308 { 4309 struct pmap *pm = object; 4310 u_long addr; 4311 4312 memset(pm, 0, sizeof *pm); 4313 4314 /* 4315 * `pmap_pool' entries include space for the per-CPU 4316 * region table pointer arrays. 4317 */ 4318 addr = (u_long)pm + ALIGN(sizeof(struct pmap)); 4319 pm->pm_regmap = (void *)addr; 4320 addr += ALIGN(NUREG * sizeof(struct regmap)); 4321 pm->pm_reg_ptps = (int **)addr; 4322 addr += sparc_ncpus * sizeof(int *); 4323 pm->pm_reg_ptps_pa = (int *)addr; 4324 4325 qzero((void *)pm->pm_regmap, NUREG * sizeof(struct regmap)); 4326 4327 /* pm->pm_ctx = NULL; // already done */ 4328 4329 if (CPU_HAS_SUNMMU) { 4330 TAILQ_INIT(&pm->pm_seglist); 4331 #if defined(SUN4_MMU3L) 4332 TAILQ_INIT(&pm->pm_reglist); 4333 if (HASSUN4_MMU3L) { 4334 int i; 4335 for (i = NUREG; --i >= 0;) 4336 pm->pm_regmap[i].rg_smeg = reginval; 4337 } 4338 #endif 4339 } 4340 #if defined(SUN4M) || defined(SUN4D) 4341 else { 4342 int i, n; 4343 4344 /* 4345 * We must allocate and initialize hardware-readable (MMU) 4346 * pagetables. We must also map the kernel regions into this 4347 * pmap's pagetables, so that we can access the kernel from 4348 * this user context. 4349 */ 4350 #if defined(MULTIPROCESSOR) 4351 for (n = 0; n < sparc_ncpus; n++) 4352 #else 4353 n = 0; 4354 #endif 4355 { 4356 int *upt, *kpt; 4357 4358 #if defined(MULTIPROCESSOR) 4359 /* Did this cpu attach? */ 4360 if (pmap_kernel()->pm_reg_ptps[n] == 0) 4361 continue; 4362 #endif 4363 4364 upt = pool_get(&L1_pool, flags); 4365 pm->pm_reg_ptps[n] = upt; 4366 pm->pm_reg_ptps_pa[n] = VA2PA((char *)upt); 4367 4368 /* Invalidate user space regions */ 4369 for (i = 0; i < NUREG; i++) 4370 setpgt4m(upt++, SRMMU_TEINVALID); 4371 4372 /* Copy kernel regions */ 4373 kpt = &pmap_kernel()->pm_reg_ptps[n][VA_VREG(KERNBASE)]; 4374 for (i = 0; i < NKREG; i++) 4375 setpgt4m(upt++, kpt[i]); 4376 } 4377 } 4378 #endif /* SUN4M || SUN4D */ 4379 4380 /* XXX - a peculiar place to do this, but we can't do it in pmap_init 4381 * and here at least it's off the beaten code track. 4382 */ 4383 {static int x; if (x == 0) pool_setlowat(&pv_pool, 512), x = 1; } 4384 4385 return (0); 4386 } 4387 4388 void 4389 pmap_pmap_pool_dtor(void *arg, void *object) 4390 { 4391 struct pmap *pm = object; 4392 union ctxinfo *c; 4393 int s = splvm(); /* paranoia */ 4394 4395 DPRINTF(PDB_DESTROY, "pmap_pmap_pool_dtor(%p)", pm); 4396 4397 if ((c = pm->pm_ctx) != NULL) { 4398 mutex_spin_enter(&ctx_lock); 4399 ctx_free(pm); 4400 mutex_spin_exit(&ctx_lock); 4401 } 4402 4403 #if defined(SUN4M) || defined(SUN4D) 4404 if (CPU_HAS_SRMMU) { 4405 int n; 4406 4407 #if defined(MULTIPROCESSOR) 4408 for (n = 0; n < sparc_ncpus; n++) 4409 #else 4410 n = 0; 4411 #endif 4412 { 4413 int *pt; 4414 4415 #if defined(MULTIPROCESSOR) 4416 /* Did this cpu attach? */ 4417 if (pmap_kernel()->pm_reg_ptps[n] == 0) 4418 continue; 4419 #endif 4420 4421 pt = pm->pm_reg_ptps[n]; 4422 pm->pm_reg_ptps[n] = NULL; 4423 pm->pm_reg_ptps_pa[n] = 0; 4424 pool_put(&L1_pool, pt); 4425 } 4426 } 4427 #endif /* SUN4M || SUN4D */ 4428 splx(s); 4429 } 4430 4431 /* 4432 * Create and return a physical map. 4433 */ 4434 struct pmap * 4435 pmap_create(void) 4436 { 4437 struct pmap *pm; 4438 4439 pm = pool_cache_get(&pmap_cache, PR_WAITOK); 4440 4441 /* 4442 * Reset fields that are not preserved in the pmap cache pool. 4443 */ 4444 pm->pm_refcount = 1; 4445 #if defined(MULTIPROCESSOR) 4446 /* reset active CPU set */ 4447 pm->pm_cpuset = 0; 4448 #endif 4449 if (CPU_HAS_SUNMMU) { 4450 /* reset the region gap */ 4451 pm->pm_gap_start = 0; 4452 pm->pm_gap_end = VA_VREG(VM_MAXUSER_ADDRESS); 4453 } 4454 4455 DPRINTF(PDB_CREATE, "pmap_create[%d]: created %p", cpu_number(), pm); 4456 pmap_quiet_check(pm); 4457 4458 return (pm); 4459 } 4460 4461 /* 4462 * Retire the given pmap from service. 4463 * Should only be called if the map contains no valid mappings. 4464 */ 4465 void 4466 pmap_destroy(struct pmap *pm) 4467 { 4468 4469 DPRINTF(PDB_DESTROY, "pmap_destroy[%d](%p)", cpu_number(), pm); 4470 membar_release(); 4471 if (atomic_dec_uint_nv(&pm->pm_refcount) == 0) { 4472 membar_acquire(); 4473 pmap_quiet_check(pm); 4474 pool_cache_put(&pmap_cache, pm); 4475 } 4476 } 4477 4478 /* 4479 * Add a reference to the given pmap. 4480 */ 4481 void 4482 pmap_reference(struct pmap *pm) 4483 { 4484 4485 atomic_inc_uint(&pm->pm_refcount); 4486 } 4487 4488 #if defined(SUN4) || defined(SUN4C) 4489 /* 4490 * helper to deallocate level 2 & 3 page tables. 4491 */ 4492 static void 4493 pgt_lvl23_remove4_4c(struct pmap *pm, struct regmap *rp, struct segmap *sp, 4494 int vr, int vs) 4495 { 4496 vaddr_t va, tva; 4497 int i, pmeg; 4498 4499 va = VSTOVA(vr,vs); 4500 if ((pmeg = sp->sg_pmeg) != seginval) { 4501 if (CTX_USABLE(pm,rp)) { 4502 setcontext4(pm->pm_ctxnum); 4503 setsegmap(va, seginval); 4504 } else { 4505 /* no context, use context 0 */ 4506 setcontext4(0); 4507 if (HASSUN4_MMU3L && rp->rg_smeg != reginval) { 4508 setregmap(0, rp->rg_smeg); 4509 tva = vs << SGSHIFT; 4510 setsegmap(tva, seginval); 4511 } 4512 } 4513 if (!HASSUN4_MMU3L) { 4514 if (pm == pmap_kernel()) { 4515 /* Unmap segment from all contexts */ 4516 for (i = ncontext; --i >= 0;) { 4517 setcontext4(i); 4518 setsegmap(va, seginval); 4519 } 4520 } 4521 } 4522 me_free(pm, pmeg); 4523 sp->sg_pmeg = seginval; 4524 } 4525 /* Free software tables for non-kernel maps */ 4526 if (pm != pmap_kernel()) { 4527 pool_put(&pte_pool, sp->sg_pte); 4528 sp->sg_pte = NULL; 4529 } 4530 4531 if (rp->rg_nsegmap <= 0) 4532 panic("pgt_rm: pm %p: nsegmap = %d\n", pm, rp->rg_nsegmap); 4533 4534 if (--rp->rg_nsegmap == 0) { 4535 #if defined(SUN4_MMU3L) 4536 if (HASSUN4_MMU3L) { 4537 if (rp->rg_smeg != reginval) { 4538 if (pm == pmap_kernel()) { 4539 /* Unmap from all contexts */ 4540 for (i = ncontext; --i >= 0;) { 4541 setcontext4(i); 4542 setregmap(va, reginval); 4543 } 4544 } else if (pm->pm_ctx) { 4545 setcontext4(pm->pm_ctxnum); 4546 setregmap(va, reginval); 4547 } 4548 4549 /* Release MMU resource */ 4550 region_free(pm, rp->rg_smeg); 4551 rp->rg_smeg = reginval; 4552 } 4553 } 4554 #endif /* SUN4_MMU3L */ 4555 /* Free software tables for non-kernel maps */ 4556 if (pm != pmap_kernel()) { 4557 GAP_WIDEN(pm,vr); 4558 pool_put(&segmap_pool, rp->rg_segmap); 4559 rp->rg_segmap = NULL; 4560 } 4561 } 4562 } 4563 #endif /* SUN4 || SUN4C */ 4564 4565 #if defined(SUN4M) || defined(SUN4D) 4566 /* 4567 * SRMMU helper to deallocate level 2 & 3 page tables. 4568 */ 4569 static void 4570 pgt_lvl23_remove4m(struct pmap *pm, struct regmap *rp, struct segmap *sp, 4571 int vr, int vs) 4572 { 4573 4574 /* Invalidate level 2 PTP entry */ 4575 if (pm->pm_ctx) 4576 tlb_flush_segment(VSTOVA(vr,vs), pm->pm_ctxnum, 4577 PMAP_CPUSET(pm)); 4578 setpgt4m(&rp->rg_seg_ptps[vs], SRMMU_TEINVALID); 4579 pool_put(&L23_pool, sp->sg_pte); 4580 sp->sg_pte = NULL; 4581 4582 /* If region is now empty, remove level 2 pagetable as well */ 4583 if (--rp->rg_nsegmap == 0) { 4584 int n = 0; 4585 if (pm->pm_ctx) 4586 tlb_flush_region(VRTOVA(vr), pm->pm_ctxnum, 4587 PMAP_CPUSET(pm)); 4588 #if defined(MULTIPROCESSOR) 4589 /* Invalidate level 1 PTP entries on all CPUs */ 4590 for (; n < sparc_ncpus; n++) { 4591 if ((cpus[n]->flags & CPUFLG_HATCHED) == 0) 4592 continue; 4593 #endif 4594 setpgt4m(&pm->pm_reg_ptps[n][vr], SRMMU_TEINVALID); 4595 #if defined(MULTIPROCESSOR) 4596 } 4597 #endif 4598 4599 pool_put(&segmap_pool, rp->rg_segmap); 4600 rp->rg_segmap = NULL; 4601 pool_put(&L23_pool, rp->rg_seg_ptps); 4602 } 4603 } 4604 #endif /* SUN4M || SUN4D */ 4605 4606 bool 4607 pmap_remove_all(struct pmap *pm) 4608 { 4609 if (pm->pm_ctx == NULL) 4610 return false; 4611 4612 #if defined(SUN4) || defined(SUN4C) 4613 if (CPU_HAS_SUNMMU) { 4614 int ctx = getcontext4(); 4615 setcontext4(pm->pm_ctxnum); 4616 cache_flush_context(pm->pm_ctxnum); 4617 setcontext4(ctx); 4618 } 4619 #endif 4620 4621 #if defined(SUN4M) || defined(SUN4D) 4622 if (CPU_HAS_SRMMU) { 4623 cache_flush_context(pm->pm_ctxnum); 4624 } 4625 #endif 4626 4627 pm->pm_flags |= PMAP_USERCACHECLEAN; 4628 return false; 4629 } 4630 4631 /* 4632 * Remove the given range of mapping entries. 4633 * The starting and ending addresses are already rounded to pages. 4634 * Sheer lunacy: pmap_remove is often asked to remove nonexistent 4635 * mappings. 4636 */ 4637 void 4638 pmap_remove(struct pmap *pm, vaddr_t va, vaddr_t endva) 4639 { 4640 vaddr_t nva; 4641 int vr, vs, s, ctx; 4642 void (*rm)(struct pmap *, vaddr_t, vaddr_t, int, int); 4643 4644 DPRINTF(PDB_REMOVE, "pmap_remove[%d](%p, 0x%lx, 0x%lx)", 4645 cpu_number(), pm, va, endva); 4646 4647 if (!CPU_HAS_SRMMU) 4648 write_user_windows(); 4649 4650 if (pm == pmap_kernel()) { 4651 /* 4652 * Removing from kernel address space. 4653 */ 4654 rm = pmap_rmk; 4655 } else { 4656 /* 4657 * Removing from user address space. 4658 */ 4659 rm = pmap_rmu; 4660 } 4661 4662 ctx = getcontext(); 4663 s = splvm(); 4664 PMAP_LOCK(); 4665 for (; va < endva; va = nva) { 4666 /* do one virtual segment at a time */ 4667 vr = VA_VREG(va); 4668 vs = VA_VSEG(va); 4669 nva = VSTOVA(vr, vs + 1); 4670 if (nva == 0 || nva > endva) 4671 nva = endva; 4672 if (pm->pm_regmap[vr].rg_nsegmap != 0) 4673 (*rm)(pm, va, nva, vr, vs); 4674 } 4675 PMAP_UNLOCK(); 4676 splx(s); 4677 setcontext(ctx); 4678 } 4679 4680 /* 4681 * It is the same amount of work to cache_flush_page 16 pages 4682 * as to cache_flush_segment 1 segment, assuming a 64K cache size 4683 * and a 4K page size or a 128K cache size and 8K page size. 4684 */ 4685 #define PMAP_SFL_THRESHOLD 16 /* if > magic, use cache_flush_segment */ 4686 4687 /* 4688 * Remove a range contained within a single segment. 4689 * These are egregiously complicated routines. 4690 */ 4691 4692 #if defined(SUN4) || defined(SUN4C) 4693 4694 /* remove from kernel */ 4695 /*static*/ void 4696 pmap_rmk4_4c(struct pmap *pm, vaddr_t va, vaddr_t endva, int vr, int vs) 4697 { 4698 int pte, mmupte, *ptep, perpage, npg; 4699 struct vm_page *pg; 4700 int nleft, pmeg, inmmu; 4701 struct regmap *rp; 4702 struct segmap *sp; 4703 4704 rp = &pm->pm_regmap[vr]; 4705 sp = &rp->rg_segmap[vs]; 4706 4707 if (rp->rg_nsegmap == 0) 4708 return; 4709 if ((nleft = sp->sg_npte) == 0) 4710 return; 4711 pmeg = sp->sg_pmeg; 4712 inmmu = pmeg != seginval; 4713 ptep = &sp->sg_pte[VA_VPG(va)]; 4714 4715 /* decide how to flush cache */ 4716 npg = (endva - va) >> PGSHIFT; 4717 if (!inmmu) { 4718 perpage = 0; 4719 } else if (npg > PMAP_SFL_THRESHOLD) { 4720 /* flush the whole segment */ 4721 perpage = 0; 4722 cache_flush_segment(vr, vs, 0); 4723 } else { 4724 /* flush each page individually; some never need flushing */ 4725 perpage = (CACHEINFO.c_vactype != VAC_NONE); 4726 } 4727 4728 for (; va < endva; va += NBPG, ptep++) { 4729 pte = *ptep; 4730 mmupte = inmmu ? getpte4(va) : 0; 4731 if ((pte & PG_V) == 0) { 4732 #ifdef DIAGNOSTIC 4733 if (inmmu && (mmupte & PG_V) != 0) 4734 printf("rmk: inconsistent ptes va=%lx\n", va); 4735 #endif 4736 continue; 4737 } 4738 if ((pte & PG_TYPE) == PG_OBMEM) { 4739 /* if cacheable, flush page as needed */ 4740 if (perpage && (mmupte & PG_NC) == 0) 4741 cache_flush_page(va, 0); 4742 if ((pg = pvhead4_4c(pte)) != NULL) { 4743 if (inmmu) 4744 VM_MDPAGE_PVHEAD(pg)->pv_flags |= MR4_4C(mmupte); 4745 pv_unlink4_4c(pg, pm, va); 4746 } 4747 } 4748 nleft--; 4749 #ifdef DIAGNOSTIC 4750 if (nleft < 0) 4751 panic("pmap_rmk: too many PTEs in segment; " 4752 "va 0x%lx; endva 0x%lx", va, endva); 4753 #endif 4754 if (pte & PG_WIRED) { 4755 sp->sg_nwired--; 4756 pm->pm_stats.wired_count--; 4757 } 4758 4759 if (inmmu) 4760 setpte4(va, 0); 4761 *ptep = 0; 4762 pm->pm_stats.resident_count--; 4763 } 4764 4765 #ifdef DIAGNOSTIC 4766 if (sp->sg_nwired > nleft || sp->sg_nwired < 0) 4767 panic("pmap_rmk: pm %p, va %lx: nleft=%d, nwired=%d", 4768 pm, va, nleft, sp->sg_nwired); 4769 #endif 4770 if ((sp->sg_npte = nleft) == 0) 4771 pgt_lvl23_remove4_4c(pm, rp, sp, vr, vs); 4772 else if (sp->sg_nwired == 0) { 4773 if (sp->sg_pmeg != seginval) 4774 mmu_pmeg_unlock(sp->sg_pmeg); 4775 } 4776 } 4777 4778 #endif /* SUN4 || SUN4C */ 4779 4780 #if defined(SUN4M) || defined(SUN4D) /* SRMMU version of pmap_rmk */ 4781 4782 /* remove from kernel (4m)*/ 4783 /* pm is already locked */ 4784 /*static*/ void 4785 pmap_rmk4m(struct pmap *pm, vaddr_t va, vaddr_t endva, int vr, int vs) 4786 { 4787 int tpte, perpage, npg; 4788 struct vm_page *pg; 4789 struct regmap *rp; 4790 struct segmap *sp; 4791 4792 rp = &pm->pm_regmap[vr]; 4793 sp = &rp->rg_segmap[vs]; 4794 if (rp->rg_nsegmap == 0) 4795 return; 4796 4797 /* decide how to flush cache */ 4798 npg = (endva - va) >> PGSHIFT; 4799 if (npg > PMAP_SFL_THRESHOLD) { 4800 /* flush the whole segment */ 4801 perpage = 0; 4802 if (CACHEINFO.c_vactype != VAC_NONE) 4803 cache_flush_segment(vr, vs, 0); 4804 } else { 4805 /* flush each page individually; some never need flushing */ 4806 perpage = (CACHEINFO.c_vactype != VAC_NONE); 4807 } 4808 while (va < endva) { 4809 tpte = sp->sg_pte[VA_SUN4M_VPG(va)]; 4810 if ((tpte & SRMMU_TETYPE) != SRMMU_TEPTE) { 4811 #ifdef DEBUG 4812 if ((pmapdebug & PDB_SANITYCHK) && 4813 (getpte4m(va) & SRMMU_TETYPE) == SRMMU_TEPTE) 4814 panic("pmap_rmk: Spurious kTLB entry for 0x%lx", 4815 va); 4816 #endif 4817 va += NBPG; 4818 continue; 4819 } 4820 if ((tpte & SRMMU_PGTYPE) == PG_SUN4M_OBMEM) { 4821 /* if cacheable, flush page as needed */ 4822 if (perpage && (tpte & SRMMU_PG_C)) 4823 cache_flush_page(va, 0); 4824 if ((pg = pvhead4m(tpte)) != NULL) { 4825 VM_MDPAGE_PVHEAD(pg)->pv_flags |= MR4M(tpte); 4826 pv_unlink4m(pg, pm, va); 4827 } 4828 } 4829 setpgt4m_va(va, &sp->sg_pte[VA_SUN4M_VPG(va)], 4830 SRMMU_TEINVALID, 1, 0, CPUSET_ALL); 4831 pm->pm_stats.resident_count--; 4832 va += NBPG; 4833 } 4834 } 4835 #endif /* SUN4M || SUN4D */ 4836 4837 #if defined(SUN4) || defined(SUN4C) 4838 4839 /* remove from user */ 4840 /*static*/ void 4841 pmap_rmu4_4c(struct pmap *pm, vaddr_t va, vaddr_t endva, int vr, int vs) 4842 { 4843 int *ptep, pteva, pte, perpage, npg; 4844 struct vm_page *pg; 4845 int nleft, pmeg, inmmu; 4846 struct regmap *rp; 4847 struct segmap *sp; 4848 4849 rp = &pm->pm_regmap[vr]; 4850 if (rp->rg_nsegmap == 0) 4851 return; 4852 sp = &rp->rg_segmap[vs]; 4853 if ((nleft = sp->sg_npte) == 0) 4854 return; 4855 pmeg = sp->sg_pmeg; 4856 inmmu = pmeg != seginval; 4857 4858 /* 4859 * PTEs are in MMU. Invalidate in hardware, update ref & 4860 * mod bits, and flush cache if required. 4861 */ 4862 if (!inmmu) { 4863 perpage = 0; 4864 pteva = 0; 4865 } else if (CTX_USABLE(pm,rp)) { 4866 /* process has a context, must flush cache */ 4867 npg = (endva - va) >> PGSHIFT; 4868 setcontext4(pm->pm_ctxnum); 4869 if ((pm->pm_flags & PMAP_USERCACHECLEAN) != 0) 4870 perpage = 0; 4871 else if (npg > PMAP_SFL_THRESHOLD) { 4872 perpage = 0; /* flush the whole segment */ 4873 cache_flush_segment(vr, vs, pm->pm_ctxnum); 4874 } else 4875 perpage = (CACHEINFO.c_vactype != VAC_NONE); 4876 pteva = va; 4877 } else { 4878 /* no context, use context 0; cache flush unnecessary */ 4879 setcontext4(0); 4880 if (HASSUN4_MMU3L) 4881 setregmap(0, tregion); 4882 /* XXX use per-CPU pteva? */ 4883 setsegmap(0, pmeg); 4884 pteva = VA_VPG(va) << PGSHIFT; 4885 perpage = 0; 4886 } 4887 4888 ptep = sp->sg_pte + VA_VPG(va); 4889 for (; va < endva; ptep++, pteva += NBPG, va += NBPG) { 4890 int mmupte; 4891 pte = *ptep; 4892 mmupte = inmmu ? getpte4(pteva) : 0; 4893 4894 if ((pte & PG_V) == 0) { 4895 #ifdef DIAGNOSTIC 4896 if (inmmu && (mmupte & PG_V) != 0) 4897 printf("pmap_rmu: pte=%x, mmupte=%x\n", 4898 pte, getpte4(pteva)); 4899 #endif 4900 continue; 4901 } 4902 if ((pte & PG_TYPE) == PG_OBMEM) { 4903 /* if cacheable, flush page as needed */ 4904 if (perpage && (mmupte & PG_NC) == 0) 4905 cache_flush_page(va, pm->pm_ctxnum); 4906 if ((pg = pvhead4_4c(pte)) != NULL) { 4907 if (inmmu) 4908 VM_MDPAGE_PVHEAD(pg)->pv_flags |= MR4_4C(mmupte); 4909 pv_unlink4_4c(pg, pm, va); 4910 } 4911 } 4912 nleft--; 4913 #ifdef DIAGNOSTIC 4914 if (nleft < 0) 4915 panic("pmap_rmu: too many PTEs in segment; " 4916 "va 0x%lx; endva 0x%lx", va, endva); 4917 #endif 4918 if (inmmu) 4919 setpte4(pteva, 0); 4920 4921 if (pte & PG_WIRED) { 4922 sp->sg_nwired--; 4923 pm->pm_stats.wired_count--; 4924 } 4925 *ptep = 0; 4926 pm->pm_stats.resident_count--; 4927 } 4928 4929 #ifdef DIAGNOSTIC 4930 if (sp->sg_nwired > nleft || sp->sg_nwired < 0) 4931 panic("pmap_rmu: pm %p, va %lx: nleft=%d, nwired=%d", 4932 pm, va, nleft, sp->sg_nwired); 4933 #endif 4934 if ((sp->sg_npte = nleft) == 0) 4935 pgt_lvl23_remove4_4c(pm, rp, sp, vr, vs); 4936 else if (sp->sg_nwired == 0) { 4937 if (sp->sg_pmeg != seginval) 4938 mmu_pmeg_unlock(sp->sg_pmeg); 4939 } 4940 } 4941 4942 #endif /* SUN4 || SUN4C */ 4943 4944 #if defined(SUN4M) || defined(SUN4D) /* SRMMU version of pmap_rmu */ 4945 /* remove from user */ 4946 /* Note: pm is already locked */ 4947 /*static*/ void 4948 pmap_rmu4m(struct pmap *pm, vaddr_t va, vaddr_t endva, int vr, int vs) 4949 { 4950 int *pte0, perpage, npg; 4951 struct vm_page *pg; 4952 int nleft; 4953 struct regmap *rp; 4954 struct segmap *sp; 4955 4956 rp = &pm->pm_regmap[vr]; 4957 if (rp->rg_nsegmap == 0) 4958 return; 4959 sp = &rp->rg_segmap[vs]; 4960 if ((nleft = sp->sg_npte) == 0) 4961 return; 4962 pte0 = sp->sg_pte; 4963 4964 /* 4965 * Invalidate PTE in MMU pagetables. Flush cache if necessary. 4966 */ 4967 if (pm->pm_ctx && (pm->pm_flags & PMAP_USERCACHECLEAN) == 0) { 4968 /* process has a context, must flush cache */ 4969 if (CACHEINFO.c_vactype != VAC_NONE) { 4970 npg = (endva - va) >> PGSHIFT; 4971 if (npg > PMAP_SFL_THRESHOLD) { 4972 perpage = 0; /* flush the whole segment */ 4973 cache_flush_segment(vr, vs, pm->pm_ctxnum); 4974 } else 4975 perpage = 1; 4976 } else 4977 perpage = 0; 4978 } else { 4979 /* no context; cache flush unnecessary */ 4980 perpage = 0; 4981 } 4982 for (; va < endva; va += NBPG) { 4983 int tpte; 4984 4985 tpte = pte0[VA_SUN4M_VPG(va)]; 4986 4987 if ((tpte & SRMMU_TETYPE) != SRMMU_TEPTE) { 4988 #ifdef DEBUG 4989 if ((pmapdebug & PDB_SANITYCHK) && 4990 pm->pm_ctx && 4991 (getpte4m(va) & SRMMU_TEPTE) == SRMMU_TEPTE) 4992 panic("pmap_rmu: Spurious uTLB entry for 0x%lx", 4993 va); 4994 #endif 4995 continue; 4996 } 4997 4998 if ((tpte & SRMMU_PGTYPE) == PG_SUN4M_OBMEM) { 4999 /* if cacheable, flush page as needed */ 5000 if (perpage && (tpte & SRMMU_PG_C)) 5001 cache_flush_page(va, pm->pm_ctxnum); 5002 if ((pg = pvhead4m(tpte)) != NULL) { 5003 VM_MDPAGE_PVHEAD(pg)->pv_flags |= MR4M(tpte); 5004 pv_unlink4m(pg, pm, va); 5005 } 5006 } 5007 nleft--; 5008 #ifdef DIAGNOSTIC 5009 if (nleft < 0) 5010 panic("pmap_rmu: too many PTEs in segment; " 5011 "va 0x%lx; endva 0x%lx", va, endva); 5012 #endif 5013 setpgt4m_va(va, &pte0[VA_SUN4M_VPG(va)], SRMMU_TEINVALID, 5014 pm->pm_ctx != NULL, pm->pm_ctxnum, PMAP_CPUSET(pm)); 5015 pm->pm_stats.resident_count--; 5016 if (sp->sg_wiremap & (1 << VA_SUN4M_VPG(va))) { 5017 sp->sg_wiremap &= ~(1 << VA_SUN4M_VPG(va)); 5018 pm->pm_stats.wired_count--; 5019 } 5020 } 5021 5022 /* 5023 * If the segment is all gone, and the context is loaded, give 5024 * the segment back. 5025 */ 5026 if ((sp->sg_npte = nleft) == 0) 5027 pgt_lvl23_remove4m(pm, rp, sp, vr, vs); 5028 } 5029 #endif /* SUN4M || SUN4D */ 5030 5031 /* 5032 * Lower (make more strict) the protection on the specified 5033 * physical page. 5034 * 5035 * There are only two cases: either the protection is going to 0 5036 * (in which case we do the dirty work here), or it is going from 5037 * to read-only (in which case pv_changepte does the trick). 5038 */ 5039 5040 #if defined(SUN4) || defined(SUN4C) 5041 void 5042 pmap_page_protect4_4c(struct vm_page *pg, vm_prot_t prot) 5043 { 5044 struct pvlist *pv, *npv; 5045 struct pmap *pm; 5046 vaddr_t va; 5047 int vr, vs, pteva, pte, *ptep; 5048 int flags, nleft, s, ctx; 5049 struct regmap *rp; 5050 struct segmap *sp; 5051 5052 #ifdef DEBUG 5053 if ((pmapdebug & PDB_CHANGEPROT) || 5054 (pmapdebug & PDB_REMOVE && prot == VM_PROT_NONE)) 5055 printf("pmap_page_protect(0x%lx, 0x%x)\n", 5056 VM_PAGE_TO_PHYS(pg), prot); 5057 #endif 5058 5059 /* 5060 * Skip unmanaged pages, or operations that do not take 5061 * away write permission. 5062 */ 5063 if (prot & VM_PROT_WRITE) 5064 return; 5065 5066 write_user_windows(); /* paranoia */ 5067 if (prot & VM_PROT_READ) { 5068 pv_changepte4_4c(pg, 0, PG_W); 5069 return; 5070 } 5071 5072 /* 5073 * Remove all access to all people talking to this page. 5074 * Walk down PV list, removing all mappings. 5075 * The logic is much like that for pmap_remove, 5076 * but we know we are removing exactly one page. 5077 */ 5078 s = splvm(); 5079 pv = VM_MDPAGE_PVHEAD(pg); 5080 if (pv->pv_pmap == NULL) { 5081 splx(s); 5082 return; 5083 } 5084 ctx = getcontext4(); 5085 5086 /* This pv head will become empty, so clear caching state flags */ 5087 flags = pv->pv_flags & ~(PV_NC|PV_ANC); 5088 5089 while (pv != NULL) { 5090 pm = pv->pv_pmap; 5091 va = pv->pv_va; 5092 vr = VA_VREG(va); 5093 vs = VA_VSEG(va); 5094 rp = &pm->pm_regmap[vr]; 5095 sp = &rp->rg_segmap[vs]; 5096 if ((nleft = sp->sg_npte) <= 0) 5097 panic("pmap_page_protect: empty vseg"); 5098 sp->sg_npte = --nleft; 5099 ptep = &sp->sg_pte[VA_VPG(va)]; 5100 5101 if (*ptep & PG_WIRED) { 5102 sp->sg_nwired--; 5103 pm->pm_stats.wired_count--; 5104 } 5105 5106 if (sp->sg_pmeg != seginval) { 5107 /* Update PV flags */ 5108 if (CTX_USABLE(pm,rp)) { 5109 setcontext4(pm->pm_ctxnum); 5110 pteva = va; 5111 cache_flush_page(va, pm->pm_ctxnum); 5112 } else { 5113 setcontext4(0); 5114 /* XXX use per-CPU pteva? */ 5115 if (HASSUN4_MMU3L) 5116 setregmap(0, tregion); 5117 setsegmap(0, sp->sg_pmeg); 5118 pteva = VA_VPG(va) << PGSHIFT; 5119 } 5120 5121 pte = getpte4(pteva); 5122 #ifdef DIAGNOSTIC 5123 if ((pte & PG_V) == 0) 5124 panic("pmap_page_protect !PG_V: pg %p " 5125 "ctx %d, va 0x%lx, pte 0x%x", 5126 pg, pm->pm_ctxnum, va, pte); 5127 #endif 5128 flags |= MR4_4C(pte); 5129 5130 setpte4(pteva, 0); 5131 #ifdef DIAGNOSTIC 5132 if (sp->sg_nwired > nleft || sp->sg_nwired < 0) 5133 panic("pmap_page_protect: pm %p, va %lx: nleft=%d, nwired=%d", 5134 pm, va, nleft, sp->sg_nwired); 5135 #endif 5136 if (sp->sg_nwired == 0) 5137 mmu_pmeg_unlock(sp->sg_pmeg); 5138 } 5139 5140 *ptep = 0; 5141 pm->pm_stats.resident_count--; 5142 if (nleft == 0) 5143 pgt_lvl23_remove4_4c(pm, rp, sp, vr, vs); 5144 npv = pv->pv_next; 5145 if (pv != VM_MDPAGE_PVHEAD(pg)) 5146 pool_put(&pv_pool, pv); 5147 pv = npv; 5148 } 5149 5150 /* Finally, update pv head */ 5151 VM_MDPAGE_PVHEAD(pg)->pv_pmap = NULL; 5152 VM_MDPAGE_PVHEAD(pg)->pv_next = NULL; 5153 VM_MDPAGE_PVHEAD(pg)->pv_flags = flags; 5154 setcontext4(ctx); 5155 splx(s); 5156 } 5157 5158 /* 5159 * Lower (make more strict) the protection on the specified 5160 * range of this pmap. 5161 * 5162 * There are only two cases: either the protection is going to 0 5163 * (in which case we call pmap_remove to do the dirty work), or 5164 * it is going from read/write to read-only. The latter is 5165 * fairly easy. 5166 */ 5167 void 5168 pmap_protect4_4c(struct pmap *pm, vaddr_t sva, vaddr_t eva, vm_prot_t prot) 5169 { 5170 int va, nva, vr, vs; 5171 int s, ctx; 5172 struct regmap *rp; 5173 struct segmap *sp; 5174 5175 if ((prot & VM_PROT_READ) == 0) { 5176 pmap_remove(pm, sva, eva); 5177 return; 5178 } 5179 5180 write_user_windows(); 5181 ctx = getcontext4(); 5182 s = splvm(); 5183 PMAP_LOCK(); 5184 for (va = sva; va < eva;) { 5185 vr = VA_VREG(va); 5186 vs = VA_VSEG(va); 5187 rp = &pm->pm_regmap[vr]; 5188 nva = VSTOVA(vr,vs + 1); 5189 if (nva > eva) 5190 nva = eva; 5191 if (rp->rg_nsegmap == 0) { 5192 va = nva; 5193 continue; 5194 } 5195 #ifdef DEBUG 5196 if (rp->rg_segmap == NULL) 5197 panic("pmap_protect: no segments"); 5198 #endif 5199 sp = &rp->rg_segmap[vs]; 5200 if (sp->sg_npte == 0) { 5201 va = nva; 5202 continue; 5203 } 5204 #ifdef DEBUG 5205 if (sp->sg_pte == NULL) 5206 panic("pmap_protect: no pages"); 5207 #endif 5208 if (sp->sg_pmeg == seginval) { 5209 int *ptep = &sp->sg_pte[VA_VPG(va)]; 5210 5211 /* not in MMU; just clear PG_W from core copies */ 5212 for (; va < nva; va += NBPG) 5213 *ptep++ &= ~PG_W; 5214 } else { 5215 /* in MMU: take away write bits from MMU PTEs */ 5216 if (CTX_USABLE(pm,rp)) { 5217 int pte; 5218 5219 /* 5220 * Flush cache so that any existing cache 5221 * tags are updated. This is really only 5222 * needed for PTEs that lose PG_W. 5223 */ 5224 pmap_stats.ps_npg_prot_all += 5225 (nva - va) >> PGSHIFT; 5226 setcontext4(pm->pm_ctxnum); 5227 for (; va < nva; va += NBPG) { 5228 pte = getpte4(va); 5229 if ((pte & (PG_W|PG_TYPE)) == 5230 (PG_W|PG_OBMEM)) { 5231 pmap_stats.ps_npg_prot_actual++; 5232 cache_flush_page(va, pm->pm_ctxnum); 5233 setpte4(va, pte & ~PG_W); 5234 } 5235 } 5236 } else { 5237 int pteva; 5238 5239 /* 5240 * No context, hence not cached; 5241 * just update PTEs. 5242 */ 5243 setcontext4(0); 5244 /* XXX use per-CPU pteva? */ 5245 if (HASSUN4_MMU3L) 5246 setregmap(0, tregion); 5247 setsegmap(0, sp->sg_pmeg); 5248 pteva = VA_VPG(va) << PGSHIFT; 5249 for (; va < nva; pteva += NBPG, va += NBPG) 5250 setpte4(pteva, getpte4(pteva) & ~PG_W); 5251 } 5252 } 5253 } 5254 PMAP_UNLOCK(); 5255 splx(s); 5256 setcontext4(ctx); 5257 } 5258 5259 /* 5260 * Change the protection and/or wired status of the given (MI) virtual page. 5261 * XXX: should have separate function (or flag) telling whether only wiring 5262 * is changing. 5263 */ 5264 void 5265 pmap_changeprot4_4c(struct pmap *pm, vaddr_t va, vm_prot_t prot, int flags) 5266 { 5267 int vr, vs, newprot, ctx, pte, *ptep; 5268 int pmeg; 5269 struct regmap *rp; 5270 struct segmap *sp; 5271 5272 DPRINTF(PDB_CHANGEPROT, "pmap_changeprot(%p, 0x%lx, 0x%x, 0x%x)", 5273 pm, va, prot, flags); 5274 5275 if (pm == pmap_kernel()) 5276 newprot = prot & VM_PROT_WRITE ? PG_S|PG_W : PG_S; 5277 else 5278 newprot = prot & VM_PROT_WRITE ? PG_W : 0; 5279 vr = VA_VREG(va); 5280 vs = VA_VSEG(va); 5281 rp = &pm->pm_regmap[vr]; 5282 sp = &rp->rg_segmap[vs]; 5283 ptep = &sp->sg_pte[VA_VPG(va)]; 5284 5285 pmap_stats.ps_changeprots++; 5286 5287 pte = *ptep; 5288 if (pte & PG_WIRED && (flags & PMAP_WIRED) == 0) { 5289 pte &= ~PG_WIRED; 5290 sp->sg_nwired--; 5291 pm->pm_stats.wired_count--; 5292 } else if ((pte & PG_WIRED) == 0 && flags & PMAP_WIRED) { 5293 pte |= PG_WIRED; 5294 sp->sg_nwired++; 5295 pm->pm_stats.wired_count++; 5296 } 5297 pte = (pte & ~PG_PROT) | newprot; 5298 /* Update S/W pte entry */ 5299 *ptep = pte; 5300 5301 /* update PTEs in software or hardware */ 5302 if ((pmeg = sp->sg_pmeg) != seginval) { 5303 /* update in hardware */ 5304 ctx = getcontext4(); 5305 if (CTX_USABLE(pm,rp)) { 5306 /* 5307 * Use current context. 5308 * Flush cache if page has been referenced to 5309 * avoid stale protection bits in the cache tags. 5310 */ 5311 setcontext4(pm->pm_ctxnum); 5312 pte = getpte4(va); 5313 if ((pte & (PG_U|PG_NC|PG_TYPE)) == (PG_U|PG_OBMEM)) 5314 cache_flush_page(va, pm->pm_ctxnum); 5315 } else { 5316 setcontext4(0); 5317 /* XXX use per-CPU va? */ 5318 if (HASSUN4_MMU3L) 5319 setregmap(0, tregion); 5320 setsegmap(0, pmeg); 5321 va = VA_VPG(va) << PGSHIFT; 5322 pte = getpte4(va); 5323 } 5324 pte = (pte & ~PG_PROT) | newprot; 5325 setpte4(va, pte); 5326 setcontext4(ctx); 5327 #ifdef DIAGNOSTIC 5328 if (sp->sg_nwired > sp->sg_npte || sp->sg_nwired < 0) 5329 panic("pmap_protect: pm %p, va %lx: nleft=%d, nwired=%d", 5330 pm, va, sp->sg_npte, sp->sg_nwired); 5331 #endif 5332 if (sp->sg_nwired == 0) 5333 mmu_pmeg_unlock(pmeg); 5334 else 5335 mmu_pmeg_lock(pmeg); 5336 } 5337 } 5338 5339 #endif /* SUN4 || SUN4C */ 5340 5341 #if defined(SUN4M) || defined(SUN4D) 5342 /* 5343 * Lower (make more strict) the protection on the specified 5344 * physical page. 5345 * 5346 * There are only two cases: either the protection is going to 0 5347 * (in which case we do the dirty work here), or it is going 5348 * to read-only (in which case pv_changepte does the trick). 5349 */ 5350 void 5351 pmap_page_protect4m(struct vm_page *pg, vm_prot_t prot) 5352 { 5353 struct pvlist *pv, *npv; 5354 struct pmap *pm; 5355 vaddr_t va; 5356 int vr, vs, tpte; 5357 int flags, nleft, s; 5358 struct regmap *rp; 5359 struct segmap *sp; 5360 5361 #ifdef DEBUG 5362 if ((pmapdebug & PDB_CHANGEPROT) || 5363 (pmapdebug & PDB_REMOVE && prot == VM_PROT_NONE)) 5364 printf("pmap_page_protect[%d](0x%lx, 0x%x)\n", 5365 cpu_number(), VM_PAGE_TO_PHYS(pg), prot); 5366 #endif 5367 s = splvm(); 5368 PMAP_LOCK(); 5369 5370 if (prot & VM_PROT_READ) { 5371 pv_changepte4m(pg, 0, PPROT_WRITE); 5372 goto out; 5373 } 5374 5375 /* 5376 * Remove all access to all people talking to this page. 5377 * Walk down PV list, removing all mappings. The logic is much 5378 * like that for pmap_remove, but we know we are removing exactly 5379 * one page. 5380 */ 5381 pv = VM_MDPAGE_PVHEAD(pg); 5382 if (pv->pv_pmap == NULL) 5383 goto out; 5384 5385 /* This pv head will become empty, so clear caching state flags */ 5386 flags = pv->pv_flags & ~(PV_NC|PV_ANC); 5387 while (pv != NULL) { 5388 pm = pv->pv_pmap; 5389 va = pv->pv_va; 5390 vr = VA_VREG(va); 5391 vs = VA_VSEG(va); 5392 rp = &pm->pm_regmap[vr]; 5393 if (rp->rg_nsegmap == 0) 5394 panic("pmap_remove_all: empty vreg"); 5395 sp = &rp->rg_segmap[vs]; 5396 nleft = sp->sg_npte; 5397 if (pm != pmap_kernel()) { 5398 if (nleft <= 0) 5399 panic("pmap_page_protect: empty vseg"); 5400 sp->sg_npte = --nleft; 5401 } 5402 5403 /* 5404 * Invalidate PTE in MMU pagetables. 5405 * Flush cache if necessary. 5406 */ 5407 if (pm->pm_ctx) { 5408 cache_flush_page(va, pm->pm_ctxnum); 5409 } 5410 5411 tpte = sp->sg_pte[VA_SUN4M_VPG(va)]; 5412 setpgt4m_va(va, &sp->sg_pte[VA_SUN4M_VPG(va)], SRMMU_TEINVALID, 5413 pm->pm_ctx != NULL, pm->pm_ctxnum, PMAP_CPUSET(pm)); 5414 5415 pm->pm_stats.resident_count--; 5416 if (sp->sg_wiremap & (1 << VA_SUN4M_VPG(va))) { 5417 sp->sg_wiremap &= ~(1 << VA_SUN4M_VPG(va)); 5418 pm->pm_stats.wired_count--; 5419 } 5420 5421 if ((tpte & SRMMU_TETYPE) != SRMMU_TEPTE) 5422 panic("pmap_page_protect !PG_V: pg %p va %lx", pg, va); 5423 5424 flags |= MR4M(tpte); 5425 5426 if (pm != pmap_kernel() && nleft == 0) 5427 /* 5428 * Entire user mode segment is gone 5429 */ 5430 pgt_lvl23_remove4m(pm, rp, sp, vr, vs); 5431 5432 npv = pv->pv_next; 5433 if (pv != VM_MDPAGE_PVHEAD(pg)) 5434 pool_put(&pv_pool, pv); 5435 pv = npv; 5436 } 5437 5438 /* Finally, update pv head */ 5439 VM_MDPAGE_PVHEAD(pg)->pv_pmap = NULL; 5440 VM_MDPAGE_PVHEAD(pg)->pv_next = NULL; 5441 VM_MDPAGE_PVHEAD(pg)->pv_flags = flags; 5442 5443 out: 5444 PMAP_UNLOCK(); 5445 splx(s); 5446 } 5447 5448 /* 5449 * Lower (make more strict) the protection on the specified 5450 * range of this pmap. 5451 */ 5452 void 5453 pmap_protect4m(struct pmap *pm, vaddr_t sva, vaddr_t eva, vm_prot_t prot) 5454 { 5455 vaddr_t va, nva; 5456 int s, vr, vs; 5457 struct regmap *rp; 5458 struct segmap *sp; 5459 int newprot; 5460 5461 if ((prot & VM_PROT_READ) == 0) { 5462 pmap_remove(pm, sva, eva); 5463 return; 5464 } 5465 5466 DPRINTF(PDB_CHANGEPROT, 5467 "pmap_protect[%d][curpid %d, ctx %d,%d](%lx, %lx, %x)", 5468 cpu_number(), curproc->p_pid, getcontext4m(), 5469 pm->pm_ctx ? pm->pm_ctxnum : -1, sva, eva, prot); 5470 5471 newprot = pte_prot4m(pm, prot); 5472 5473 write_user_windows(); 5474 s = splvm(); 5475 PMAP_LOCK(); 5476 5477 for (va = sva; va < eva;) { 5478 vr = VA_VREG(va); 5479 vs = VA_VSEG(va); 5480 rp = &pm->pm_regmap[vr]; 5481 nva = VSTOVA(vr,vs + 1); 5482 if (nva > eva) 5483 nva = eva; 5484 if (rp->rg_nsegmap == 0) { 5485 va = nva; 5486 continue; 5487 } 5488 sp = &rp->rg_segmap[vs]; 5489 if (pm != pmap_kernel() && sp->sg_npte == 0) { 5490 va = nva; 5491 continue; 5492 } 5493 5494 /* 5495 * pages loaded: take away write bits from MMU PTEs 5496 */ 5497 pmap_stats.ps_npg_prot_all += (nva - va) >> PGSHIFT; 5498 for (; va < nva; va += NBPG) { 5499 int tpte, npte; 5500 5501 tpte = sp->sg_pte[VA_SUN4M_VPG(va)]; 5502 if ((tpte & SRMMU_PGTYPE) != PG_SUN4M_OBMEM) 5503 continue; 5504 if ((tpte & SRMMU_TETYPE) != SRMMU_TEPTE) 5505 continue; 5506 npte = (tpte & ~SRMMU_PROT_MASK) | newprot; 5507 if (npte == tpte) 5508 continue; 5509 5510 /* 5511 * Flush cache so that any existing cache 5512 * tags are updated. 5513 */ 5514 5515 pmap_stats.ps_npg_prot_actual++; 5516 if (pm->pm_ctx) { 5517 cache_flush_page(va, pm->pm_ctxnum); 5518 } 5519 updatepte4m(va, &sp->sg_pte[VA_SUN4M_VPG(va)], 5520 SRMMU_PROT_MASK, newprot, pm->pm_ctxnum, 5521 PMAP_CPUSET(pm)); 5522 } 5523 } 5524 PMAP_UNLOCK(); 5525 splx(s); 5526 } 5527 5528 /* 5529 * Change the protection and/or wired status of the given (MI) virtual page. 5530 * XXX: should have separate function (or flag) telling whether only wiring 5531 * is changing. 5532 */ 5533 void 5534 pmap_changeprot4m(struct pmap *pm, vaddr_t va, vm_prot_t prot, int flags) 5535 { 5536 int pte, newprot; 5537 struct regmap *rp; 5538 struct segmap *sp; 5539 bool owired; 5540 5541 DPRINTF(PDB_CHANGEPROT, "pmap_changeprot[%d](%p, 0x%lx, 0x%x, 0x%x)", 5542 cpu_number(), pm, va, prot, flags); 5543 5544 newprot = pte_prot4m(pm, prot); 5545 5546 pmap_stats.ps_changeprots++; 5547 5548 rp = &pm->pm_regmap[VA_VREG(va)]; 5549 sp = &rp->rg_segmap[VA_VSEG(va)]; 5550 5551 pte = sp->sg_pte[VA_SUN4M_VPG(va)]; 5552 owired = sp->sg_wiremap & (1 << VA_SUN4M_VPG(va)); 5553 5554 if (owired) { 5555 pm->pm_stats.wired_count--; 5556 sp->sg_wiremap &= ~(1 << VA_SUN4M_VPG(va)); 5557 } 5558 if (flags & PMAP_WIRED) { 5559 pm->pm_stats.wired_count++; 5560 sp->sg_wiremap |= (1 << VA_SUN4M_VPG(va)); 5561 } 5562 5563 if (pm->pm_ctx) { 5564 /* 5565 * Use current context. 5566 * Flush cache if page has been referenced to 5567 * avoid stale protection bits in the cache tags. 5568 */ 5569 5570 if ((pte & (SRMMU_PG_C|SRMMU_PGTYPE)) == 5571 (SRMMU_PG_C|PG_SUN4M_OBMEM)) 5572 cache_flush_page(va, pm->pm_ctxnum); 5573 } 5574 5575 setpgt4m_va(va, &sp->sg_pte[VA_SUN4M_VPG(va)], 5576 (pte & ~SRMMU_PROT_MASK) | newprot, 5577 pm->pm_ctx != NULL, pm->pm_ctxnum, PMAP_CPUSET(pm)); 5578 5579 } 5580 #endif /* SUN4M || SUN4D */ 5581 5582 /* 5583 * Insert (MI) physical page pa at virtual address va in the given pmap. 5584 * NB: the pa parameter includes type bits PMAP_OBIO, PMAP_NC as necessary. 5585 * 5586 * If pa is not in the `managed' range it will not be `bank mapped'. 5587 * This works during bootstrap only because the first 4MB happens to 5588 * map one-to-one. 5589 * 5590 * There may already be something else there, or we might just be 5591 * changing protections and/or wiring on an existing mapping. 5592 * XXX should have different entry points for changing! 5593 */ 5594 5595 #if defined(SUN4) || defined(SUN4C) 5596 5597 int 5598 pmap_enter4_4c(struct pmap *pm, vaddr_t va, paddr_t pa, 5599 vm_prot_t prot, u_int flags) 5600 { 5601 struct vm_page *pg; 5602 int pteproto, ctx; 5603 int error; 5604 5605 if (VA_INHOLE(va)) { 5606 #ifdef DEBUG 5607 printf("pmap_enter: pm %p, va 0x%lx, pa 0x%lx: in MMU hole\n", 5608 pm, va, pa); 5609 #endif 5610 return 0; 5611 } 5612 5613 DPRINTF(PDB_ENTER, "pmap_enter(%p, 0x%lx, 0x%lx, 0x%x, 0x%x)", 5614 pm, va, pa, prot, flags); 5615 5616 pg = PHYS_TO_VM_PAGE(pa); 5617 pteproto = PG_V | PMAP_T2PTE_4(pa); 5618 pa &= ~PMAP_TNC_4; 5619 5620 /* 5621 * Set up prototype for new PTE. Cannot set PG_NC from PV_NC yet 5622 * since the pvlist no-cache bit might change as a result of the 5623 * new mapping. 5624 */ 5625 pteproto |= atop(pa) & PG_PFNUM; 5626 if (prot & VM_PROT_WRITE) 5627 pteproto |= PG_W; 5628 if ((flags & PMAP_WIRED) != 0) 5629 pteproto |= PG_WIRED; 5630 if (flags & VM_PROT_ALL) { 5631 pteproto |= PG_U; 5632 if (flags & VM_PROT_WRITE) { 5633 pteproto |= PG_M; 5634 } 5635 } 5636 5637 write_user_windows(); 5638 ctx = getcontext4(); 5639 if (pm == pmap_kernel()) 5640 error = pmap_enk4_4c(pm, va, prot, flags, pg, pteproto | PG_S); 5641 else 5642 error = pmap_enu4_4c(pm, va, prot, flags, pg, pteproto); 5643 setcontext4(ctx); 5644 return (error); 5645 } 5646 5647 /* enter new (or change existing) kernel mapping */ 5648 int 5649 pmap_enk4_4c(struct pmap *pm, vaddr_t va, vm_prot_t prot, int flags, 5650 struct vm_page *pg, int pteproto) 5651 { 5652 int vr, vs, pte, s, inmmu; 5653 int *ptep; 5654 struct regmap *rp; 5655 struct segmap *sp; 5656 int error = 0; 5657 5658 vr = VA_VREG(va); 5659 vs = VA_VSEG(va); 5660 rp = &pm->pm_regmap[vr]; 5661 sp = &rp->rg_segmap[vs]; 5662 ptep = &sp->sg_pte[VA_VPG(va)]; 5663 s = splvm(); /* XXX way too conservative */ 5664 5665 #if defined(SUN4_MMU3L) 5666 if (HASSUN4_MMU3L && rp->rg_smeg == reginval) 5667 mmu_pagein_reg(pm, rp, va, vr, ®ion_locked); 5668 #endif 5669 5670 inmmu = sp->sg_pmeg != seginval; 5671 if ((pte = *ptep) & PG_V) { 5672 5673 /* old mapping exists, and is of the same pa type */ 5674 if ((pte & (PG_PFNUM|PG_TYPE)) == 5675 (pteproto & (PG_PFNUM|PG_TYPE))) { 5676 /* just changing protection and/or wiring */ 5677 pmap_changeprot4_4c(pm, va, prot, flags); 5678 splx(s); 5679 return (0); 5680 } 5681 5682 if ((pte & PG_TYPE) == PG_OBMEM) { 5683 struct vm_page *opg; 5684 5685 /* 5686 * Switcheroo: changing pa for this va. 5687 * If old pa was managed, remove from pvlist. 5688 * If old page was cached, flush cache. 5689 */ 5690 if ((opg = pvhead4_4c(pte)) != NULL) 5691 pv_unlink4_4c(opg, pm, va); 5692 if (inmmu && (pte & PG_NC) == 0) { 5693 setcontext4(0); /* ??? */ 5694 cache_flush_page(va, 0); 5695 } 5696 } 5697 *ptep = 0; 5698 if (inmmu) 5699 setpte4(va, 0); 5700 if (pte & PG_WIRED) { 5701 sp->sg_nwired--; 5702 pm->pm_stats.wired_count--; 5703 } 5704 pm->pm_stats.resident_count--; 5705 } else { 5706 /* adding new entry */ 5707 if (sp->sg_npte++ == 0) { 5708 #ifdef DIAGNOSTIC 5709 int i; for (i = 0; i < NPTESG; i++) { 5710 if (sp->sg_pte[i] == 0) 5711 continue; 5712 panic("pmap_enk: pm %p, va %lx: pte[%d] not empty\n", 5713 pm, va, i); 5714 } 5715 #endif 5716 rp->rg_nsegmap++; 5717 } 5718 } 5719 5720 /* 5721 * If the new mapping is for a managed PA, enter into pvlist. 5722 */ 5723 if (pg != NULL && (error = pv_link4_4c(pg, pm, va, &pteproto)) != 0) { 5724 if (--sp->sg_npte == 0) 5725 pgt_lvl23_remove4_4c(pm, rp, sp, vr, vs); 5726 if ((flags & PMAP_CANFAIL) != 0) 5727 goto out; 5728 panic("pmap_enter: cannot allocate PV entry"); 5729 } 5730 5731 /* Update S/W page table */ 5732 *ptep = pteproto; 5733 if (pteproto & PG_WIRED) { 5734 sp->sg_nwired++; 5735 pm->pm_stats.wired_count++; 5736 } 5737 pm->pm_stats.resident_count++; 5738 5739 #ifdef DIAGNOSTIC 5740 if (sp->sg_nwired > sp->sg_npte || sp->sg_nwired < 0) 5741 panic("pmap_enk: pm %p, va %lx: nleft=%d, nwired=%d", 5742 pm, va, sp->sg_npte, sp->sg_nwired); 5743 #endif 5744 if (sp->sg_pmeg == seginval) 5745 mmu_pagein_seg(pm, sp, va, vr, vs, 5746 (pteproto & PG_WIRED) != 0 ? &segm_locked : &segm_lru); 5747 else if ((pteproto & PG_WIRED) != 0) 5748 mmu_pmeg_lock(sp->sg_pmeg); 5749 5750 /* Update H/W page table */ 5751 setpte4(va, pteproto & ~PG_MBZ); 5752 out: 5753 splx(s); 5754 return (error); 5755 } 5756 5757 /* enter new (or change existing) user mapping */ 5758 int 5759 pmap_enu4_4c(struct pmap *pm, vaddr_t va, vm_prot_t prot, int flags, 5760 struct vm_page *pg, int pteproto) 5761 { 5762 int vr, vs, *ptep, pte, pmeg, s; 5763 int error = 0; 5764 struct regmap *rp; 5765 struct segmap *sp; 5766 5767 pm->pm_flags &= ~PMAP_USERCACHECLEAN; 5768 5769 vr = VA_VREG(va); 5770 vs = VA_VSEG(va); 5771 rp = &pm->pm_regmap[vr]; 5772 s = splvm(); /* XXX conservative */ 5773 5774 /* 5775 * If there is no space in which the PTEs can be written 5776 * while they are not in the hardware, this must be a new 5777 * virtual segment. Get PTE space and count the segment. 5778 * 5779 * TO SPEED UP CTX ALLOC, PUT SEGMENT BOUNDS STUFF HERE 5780 * AND IN pmap_rmu() 5781 */ 5782 5783 GAP_SHRINK(pm,vr); 5784 5785 #ifdef DEBUG 5786 if (pm->pm_gap_end < pm->pm_gap_start) { 5787 printf("pmap_enu: gap_start 0x%x, gap_end 0x%x", 5788 pm->pm_gap_start, pm->pm_gap_end); 5789 panic("pmap_enu: gap botch"); 5790 } 5791 #endif 5792 5793 if (rp->rg_segmap == NULL) { 5794 /* definitely a new mapping */ 5795 int i; 5796 int mflag = PR_NOWAIT; 5797 5798 rretry: 5799 sp = (struct segmap *)pool_get(&segmap_pool, mflag); 5800 if (sp == NULL) { 5801 if ((flags & PMAP_CANFAIL) != 0) { 5802 error = ENOMEM; 5803 goto out; 5804 } 5805 mflag = PR_WAITOK; 5806 goto rretry; 5807 } 5808 #ifdef DEBUG 5809 if (rp->rg_segmap != NULL) 5810 panic("pmap_enter: segment filled during sleep"); 5811 #endif 5812 qzero((void *)sp, NSEGRG * sizeof (struct segmap)); 5813 rp->rg_segmap = sp; 5814 rp->rg_nsegmap = 0; 5815 for (i = NSEGRG; --i >= 0;) 5816 sp++->sg_pmeg = seginval; 5817 } 5818 5819 sp = &rp->rg_segmap[vs]; 5820 5821 if ((ptep = sp->sg_pte) == NULL) { 5822 /* definitely a new mapping */ 5823 int size = NPTESG * sizeof *ptep; 5824 int mflag = PR_NOWAIT; 5825 5826 sretry: 5827 ptep = (int *)pool_get(&pte_pool, mflag); 5828 if (ptep == NULL) { 5829 if ((flags & PMAP_CANFAIL) != 0) { 5830 error = ENOMEM; 5831 goto out; 5832 } 5833 mflag = PR_WAITOK; 5834 goto sretry; 5835 } 5836 #ifdef DEBUG 5837 if (sp->sg_pte != NULL) 5838 panic("pmap_enter: pte filled during sleep"); 5839 if (sp->sg_pmeg != seginval) 5840 panic("pmap_enter: new ptes, but not seginval"); 5841 #endif 5842 qzero((void *)ptep, size); 5843 sp->sg_pte = ptep; 5844 sp->sg_npte = 1; 5845 rp->rg_nsegmap++; 5846 } else { 5847 /* might be a change: fetch old pte */ 5848 pte = ptep[VA_VPG(va)]; 5849 if (pte & PG_V) { 5850 /* old mapping exists, and is of the same pa type */ 5851 if ((pte & (PG_PFNUM|PG_TYPE)) == 5852 (pteproto & (PG_PFNUM|PG_TYPE))) { 5853 /* just changing prot and/or wiring */ 5854 pmap_changeprot4_4c(pm, va, prot, flags); 5855 splx(s); 5856 return (0); 5857 } 5858 /* 5859 * Switcheroo: changing pa for this va. 5860 * If old pa was managed, remove from pvlist. 5861 * If old page was cached, flush cache. 5862 */ 5863 #if 0 5864 printf("%s[%d]: pmap_enu: changing existing " 5865 "va(0x%lx)=>pa entry\n", 5866 curproc->p_comm, curproc->p_pid, va); 5867 #endif 5868 if ((pte & PG_TYPE) == PG_OBMEM) { 5869 struct vm_page *opg; 5870 if ((opg = pvhead4_4c(pte)) != NULL) 5871 pv_unlink4_4c(opg, pm, va); 5872 if (CACHEINFO.c_vactype != VAC_NONE && 5873 (pmeg = sp->sg_pmeg) != seginval) { 5874 /* hardware pte */ 5875 if (CTX_USABLE(pm,rp)) { 5876 setcontext4(pm->pm_ctxnum); 5877 } else { 5878 setcontext4(0); 5879 /* XXX use per-CPU pteva? */ 5880 if (HASSUN4_MMU3L) 5881 setregmap(0, tregion); 5882 setsegmap(0, pmeg); 5883 } 5884 cache_flush_page(va, pm->pm_ctxnum); 5885 } 5886 } 5887 if (pte & PG_WIRED) { 5888 sp->sg_nwired--; 5889 pm->pm_stats.wired_count--; 5890 } 5891 pm->pm_stats.resident_count--; 5892 ptep[VA_VPG(va)] = 0; 5893 if (sp->sg_pmeg != seginval) 5894 setpte4(va, 0); 5895 } else { 5896 /* adding new entry */ 5897 sp->sg_npte++; 5898 } 5899 } 5900 5901 if (pg != NULL && (error = pv_link4_4c(pg, pm, va, &pteproto)) != 0) { 5902 if (--sp->sg_npte == 0) 5903 /* Sigh, undo pgt allocations */ 5904 pgt_lvl23_remove4_4c(pm, rp, sp, vr, vs); 5905 5906 if ((flags & PMAP_CANFAIL) != 0) 5907 goto out; 5908 panic("pmap_enter: cannot allocate PV entry"); 5909 } 5910 5911 /* Update S/W page table */ 5912 ptep += VA_VPG(va); 5913 *ptep = pteproto; 5914 if (pteproto & PG_WIRED) { 5915 sp->sg_nwired++; 5916 pm->pm_stats.wired_count++; 5917 } 5918 pm->pm_stats.resident_count++; 5919 5920 #ifdef DIAGNOSTIC 5921 if (sp->sg_nwired > sp->sg_npte || sp->sg_nwired < 0) 5922 panic("pmap_enu: pm %p, va %lx: nleft=%d, nwired=%d", 5923 pm, va, sp->sg_npte, sp->sg_nwired); 5924 #endif 5925 5926 if ((pmeg = sp->sg_pmeg) != seginval) { 5927 /* Update H/W page table */ 5928 if (CTX_USABLE(pm,rp)) 5929 setcontext4(pm->pm_ctxnum); 5930 else { 5931 setcontext4(0); 5932 if (HASSUN4_MMU3L) 5933 setregmap(0, tregion); 5934 setsegmap(0, pmeg); 5935 va = VA_VPG(va) << PGSHIFT; 5936 } 5937 setpte4(va, pteproto & ~PG_MBZ); 5938 } 5939 5940 out: 5941 splx(s); 5942 return (error); 5943 } 5944 5945 void 5946 pmap_kenter_pa4_4c(vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags) 5947 { 5948 struct pmap *pm = pmap_kernel(); 5949 struct regmap *rp; 5950 struct segmap *sp; 5951 int vr, vs, s; 5952 int *ptep, pteproto; 5953 int lockit = 1; 5954 5955 pteproto = PG_S | PG_V | PMAP_T2PTE_4(pa); 5956 pa &= ~PMAP_TNC_4; 5957 pteproto |= atop(pa) & PG_PFNUM; 5958 if (prot & VM_PROT_WRITE) 5959 pteproto |= PG_W; 5960 5961 vr = VA_VREG(va); 5962 vs = VA_VSEG(va); 5963 rp = &pm->pm_regmap[vr]; 5964 sp = &rp->rg_segmap[vs]; 5965 ptep = &sp->sg_pte[VA_VPG(va)]; 5966 5967 if (lockit) { 5968 pteproto |= PG_WIRED; 5969 sp->sg_nwired++; 5970 } 5971 5972 KASSERT((*ptep & PG_V) == 0); 5973 5974 s = splvm(); 5975 #if defined(SUN4_MMU3L) 5976 if (HASSUN4_MMU3L && rp->rg_smeg == reginval) 5977 mmu_pagein_reg(pm, rp, va, vr, ®ion_locked); 5978 #endif 5979 5980 if (sp->sg_npte++ == 0) { 5981 #ifdef DIAGNOSTIC 5982 int i; for (i = 0; i < NPTESG; i++) { 5983 if (sp->sg_pte[i] == 0) 5984 continue; 5985 panic("pmap_enk: pm %p, va %lx: pte[%d] not empty\n", 5986 pm, va, i); 5987 } 5988 #endif 5989 rp->rg_nsegmap++; 5990 } 5991 5992 /* Update S/W page table */ 5993 *ptep = pteproto; 5994 5995 #ifdef DIAGNOSTIC 5996 if (sp->sg_nwired > sp->sg_npte || sp->sg_nwired < 0) 5997 panic("pmap_kenter: pm %p, va %lx: nleft=%d, nwired=%d", 5998 pm, va, sp->sg_npte, sp->sg_nwired); 5999 #endif 6000 6001 if (sp->sg_pmeg == seginval) { 6002 mmu_pagein_seg(pm, sp, va, vr, vs, 6003 lockit ? &segm_locked : &segm_lru); 6004 } else if (lockit) 6005 mmu_pmeg_lock(sp->sg_pmeg); 6006 6007 /* Update H/W page table */ 6008 setpte4(va, pteproto & ~PG_MBZ); 6009 splx(s); 6010 } 6011 6012 #if notyet /* XXXMRG delete */ 6013 void pmap_lockmmu(vaddr_t sva, size_t sz); 6014 6015 void 6016 pmap_lockmmu(vaddr_t sva, size_t sz) 6017 { 6018 struct pmap *pm = pmap_kernel(); 6019 vaddr_t va, eva; 6020 struct regmap *rp; 6021 struct segmap *sp; 6022 int vr, vs; 6023 6024 if (CPU_HAS_SRMMU) 6025 return; 6026 6027 eva = sva + sz; 6028 va = VA_ROUNDDOWNTOSEG(sva); 6029 6030 for (; va < eva; va += NBPSG) { 6031 vr = VA_VREG(va); 6032 vs = VA_VSEG(va); 6033 rp = &pm->pm_regmap[vr]; 6034 sp = &rp->rg_segmap[vs]; 6035 6036 KASSERT(sp->sg_npte != 0); 6037 6038 if (sp->sg_pmeg == seginval) 6039 mmu_pagein_seg(pm, sp, va, vr, vs, &segm_locked); 6040 else 6041 mmu_pmeg_lock(sp->sg_pmeg); 6042 } 6043 } 6044 #endif 6045 6046 void 6047 pmap_kremove4_4c(vaddr_t va, vsize_t len) 6048 { 6049 struct pmap *pm = pmap_kernel(); 6050 struct regmap *rp; 6051 struct segmap *sp; 6052 vaddr_t nva, endva; 6053 int pte, mmupte, *ptep, perpage, npg, inmmu; 6054 int nleft, pmeg; 6055 int vr, vs, s, ctx; 6056 6057 endva = va + len; 6058 DPRINTF(PDB_REMOVE, "pmap_kremove(0x%lx, 0x%lx)", va, endva); 6059 6060 write_user_windows(); 6061 6062 s = splvm(); 6063 ctx = getcontext(); 6064 PMAP_LOCK(); 6065 setcontext4(0); 6066 for (; va < endva; va = nva) { 6067 /* do one virtual segment at a time */ 6068 vr = VA_VREG(va); 6069 vs = VA_VSEG(va); 6070 nva = VSTOVA(vr, vs + 1); 6071 if (nva == 0 || nva > endva) 6072 nva = endva; 6073 6074 rp = &pm->pm_regmap[vr]; 6075 sp = &rp->rg_segmap[vs]; 6076 6077 if (rp->rg_nsegmap == 0) 6078 continue; 6079 nleft = sp->sg_npte; 6080 if (nleft == 0) 6081 continue; 6082 pmeg = sp->sg_pmeg; 6083 inmmu = (pmeg != seginval); 6084 ptep = &sp->sg_pte[VA_VPG(va)]; 6085 6086 /* decide how to flush cache */ 6087 npg = (nva - va) >> PGSHIFT; 6088 if (!inmmu) { 6089 perpage = 0; 6090 } else if (npg > PMAP_SFL_THRESHOLD) { 6091 /* flush the whole segment */ 6092 perpage = 0; 6093 cache_flush_segment(vr, vs, 0); 6094 } else { 6095 /* 6096 * flush each page individually; 6097 * some never need flushing 6098 */ 6099 perpage = (CACHEINFO.c_vactype != VAC_NONE); 6100 } 6101 6102 for (; va < nva; va += NBPG, ptep++) { 6103 pte = *ptep; 6104 mmupte = inmmu ? getpte4(va) : 0; 6105 if ((pte & PG_V) == 0) { 6106 #ifdef DIAGNOSTIC 6107 if (inmmu && (mmupte & PG_V) != 0) 6108 printf("rmk: inconsistent ptes va=%lx\n", va); 6109 #endif 6110 continue; 6111 } 6112 if ((pte & PG_TYPE) == PG_OBMEM) { 6113 /* if cacheable, flush page as needed */ 6114 if (perpage && (mmupte & PG_NC) == 0) 6115 cache_flush_page(va, 0); 6116 } 6117 nleft--; 6118 #ifdef DIAGNOSTIC 6119 if (nleft < 0) 6120 panic("pmap_kremove: too many PTEs in segment; " 6121 "va 0x%lx; endva 0x%lx", va, endva); 6122 #endif 6123 if (pte & PG_WIRED) 6124 sp->sg_nwired--; 6125 6126 if (inmmu) 6127 setpte4(va, 0); 6128 *ptep = 0; 6129 } 6130 6131 #ifdef DIAGNOSTIC 6132 if (sp->sg_nwired > nleft || sp->sg_nwired < 0) 6133 panic("pmap_kremove: pm %p, va %lx: nleft=%d, nwired=%d", 6134 pm, va, nleft, sp->sg_nwired); 6135 #endif 6136 6137 if ((sp->sg_npte = nleft) == 0) 6138 pgt_lvl23_remove4_4c(pm, rp, sp, vr, vs); 6139 else if (sp->sg_nwired == 0) { 6140 if (sp->sg_pmeg != seginval) 6141 mmu_pmeg_unlock(sp->sg_pmeg); 6142 } 6143 } 6144 PMAP_UNLOCK(); 6145 setcontext4(ctx); 6146 splx(s); 6147 } 6148 6149 /* 6150 * Change protection on a range of kernel addresses. 6151 */ 6152 void 6153 pmap_kprotect4_4c(vaddr_t va, vsize_t size, vm_prot_t prot) 6154 { 6155 int pte, newprot, ctx; 6156 6157 size = roundup(size,NBPG); 6158 newprot = prot & VM_PROT_WRITE ? PG_S|PG_W : PG_S; 6159 6160 ctx = getcontext4(); 6161 setcontext4(0); 6162 while (size > 0) { 6163 pte = getpte4(va); 6164 6165 /* 6166 * Flush cache if page has been referenced to 6167 * avoid stale protection bits in the cache tags. 6168 */ 6169 if ((pte & (PG_NC|PG_TYPE)) == PG_OBMEM) 6170 cache_flush_page(va, 0); 6171 6172 pte = (pte & ~PG_PROT) | newprot; 6173 setpte4(va, pte); 6174 6175 va += NBPG; 6176 size -= NBPG; 6177 } 6178 setcontext4(ctx); 6179 } 6180 #endif /* SUN4 || SUN4C */ 6181 6182 #if defined(SUN4M) || defined(SUN4D) /* SRMMU versions of enter routines */ 6183 /* 6184 * Insert (MI) physical page pa at virtual address va in the given pmap. 6185 * NB: the pa parameter includes type bits PMAP_OBIO, PMAP_NC as necessary. 6186 * 6187 * If pa is not in the `managed' range it will not be `bank mapped'. 6188 * This works during bootstrap only because the first 4MB happens to 6189 * map one-to-one. 6190 * 6191 * There may already be something else there, or we might just be 6192 * changing protections and/or wiring on an existing mapping. 6193 * XXX should have different entry points for changing! 6194 */ 6195 6196 int 6197 pmap_enter4m(struct pmap *pm, vaddr_t va, paddr_t pa, 6198 vm_prot_t prot, u_int flags) 6199 { 6200 struct vm_page *pg; 6201 int pteproto; 6202 int error; 6203 6204 DPRINTF(PDB_ENTER, "pmap_enter[curcpu %d, curpid %d, ctx %d,%d]" 6205 "(%p, 0x%lx, 0x%lx, 0x%x, 0x%x)", 6206 cpu_number(), curproc == NULL ? -1 : curproc->p_pid, 6207 getcontext4m(), pm->pm_ctx == NULL ? -1 : pm->pm_ctxnum, 6208 pm, va, pa, prot, flags); 6209 6210 pg = PHYS_TO_VM_PAGE(pa); 6211 6212 /* Initialise pteproto with cache bit */ 6213 pteproto = (pa & PMAP_NC) == 0 ? SRMMU_PG_C : 0; 6214 6215 #ifdef DEBUG 6216 if (pa & PMAP_TYPE_SRMMU) { /* this page goes in an iospace */ 6217 if (cpuinfo.cpu_type == CPUTYP_MS1) 6218 panic("pmap_enter4m: attempt to use 36-bit iospace on" 6219 " MicroSPARC"); 6220 } 6221 #endif 6222 pteproto |= SRMMU_TEPTE; 6223 pteproto |= PMAP_T2PTE_SRMMU(pa); 6224 pa &= ~PMAP_TNC_SRMMU; 6225 6226 /* 6227 * Set up prototype for new PTE. Cannot set PG_NC from PV_NC yet 6228 * since the pvlist no-cache bit might change as a result of the 6229 * new mapping. 6230 */ 6231 pteproto |= (atop(pa) << SRMMU_PPNSHIFT); 6232 6233 /* Make sure we get a pte with appropriate perms! */ 6234 pteproto |= pte_prot4m(pm, prot); 6235 if (flags & VM_PROT_ALL) { 6236 pteproto |= SRMMU_PG_R; 6237 if (flags & VM_PROT_WRITE) { 6238 pteproto |= SRMMU_PG_M; 6239 } 6240 } 6241 6242 if (pm == pmap_kernel()) 6243 error = pmap_enk4m(pm, va, prot, flags, pg, pteproto | PPROT_S); 6244 else 6245 error = pmap_enu4m(pm, va, prot, flags, pg, pteproto); 6246 6247 return (error); 6248 } 6249 6250 /* enter new (or change existing) kernel mapping */ 6251 int 6252 pmap_enk4m(struct pmap *pm, vaddr_t va, vm_prot_t prot, int flags, 6253 struct vm_page *pg, int pteproto) 6254 { 6255 int vr, vs, tpte, s; 6256 struct regmap *rp; 6257 struct segmap *sp; 6258 int error = 0; 6259 6260 #ifdef DEBUG 6261 if (va < KERNBASE) 6262 panic("pmap_enk4m: can't enter va 0x%lx below KERNBASE", va); 6263 #endif 6264 vr = VA_VREG(va); 6265 vs = VA_VSEG(va); 6266 rp = &pm->pm_regmap[vr]; 6267 sp = &rp->rg_segmap[vs]; 6268 6269 kpreempt_disable(); 6270 s = splvm(); 6271 PMAP_LOCK(); 6272 6273 if (rp->rg_seg_ptps == NULL) /* enter new region */ 6274 panic("pmap_enk4m: missing kernel region table for va 0x%lx",va); 6275 6276 tpte = sp->sg_pte[VA_SUN4M_VPG(va)]; 6277 if ((tpte & SRMMU_TETYPE) == SRMMU_TEPTE) { 6278 6279 /* old mapping exists, and is of the same pa type */ 6280 6281 if ((tpte & SRMMU_PPNMASK) == (pteproto & SRMMU_PPNMASK)) { 6282 /* just changing protection and/or wiring */ 6283 pmap_changeprot4m(pm, va, prot, flags); 6284 error = 0; 6285 goto out; 6286 } 6287 6288 if ((tpte & SRMMU_PGTYPE) == PG_SUN4M_OBMEM) { 6289 struct vm_page *opg; 6290 #ifdef DEBUG 6291 printf("pmap_enk4m: changing existing va=>pa entry: va 0x%lx, pteproto 0x%x, " 6292 "oldpte 0x%x\n", va, pteproto, tpte); 6293 #endif 6294 /* 6295 * Switcheroo: changing pa for this va. 6296 * If old pa was managed, remove from pvlist. 6297 * If old page was cached, flush cache. 6298 */ 6299 if ((opg = pvhead4m(tpte)) != NULL) 6300 pv_unlink4m(opg, pm, va); 6301 if (tpte & SRMMU_PG_C) { 6302 cache_flush_page(va, 0); 6303 } 6304 } 6305 6306 /* 6307 * Invalidate the mapping now, so we can avoid the 6308 * de-map and update protocol when setting the new 6309 * PTE below. 6310 */ 6311 setpgt4m_va(va, &sp->sg_pte[VA_SUN4M_VPG(va)], 6312 SRMMU_TEINVALID, pm->pm_ctx != NULL, 6313 pm->pm_ctxnum, PMAP_CPUSET(pm)); 6314 pm->pm_stats.resident_count--; 6315 } 6316 6317 /* 6318 * If the new mapping is for a managed PA, enter into pvlist. 6319 */ 6320 if (pg != NULL && (error = pv_link4m(pg, pm, va, &pteproto)) != 0) { 6321 if ((flags & PMAP_CANFAIL) != 0) 6322 goto out; 6323 panic("pmap_enter: cannot allocate PV entry"); 6324 } 6325 6326 setpgt4m(&sp->sg_pte[VA_SUN4M_VPG(va)], pteproto); 6327 pm->pm_stats.resident_count++; 6328 out: 6329 PMAP_UNLOCK(); 6330 splx(s); 6331 kpreempt_enable(); 6332 return (error); 6333 } 6334 6335 /* enter new (or change existing) user mapping */ 6336 int 6337 pmap_enu4m(struct pmap *pm, vaddr_t va, vm_prot_t prot, int flags, 6338 struct vm_page *pg, int pteproto) 6339 { 6340 int vr, vs, *pte, tpte, s; 6341 int error = 0; 6342 struct regmap *rp; 6343 struct segmap *sp; 6344 bool owired; 6345 6346 #ifdef DEBUG 6347 if (KERNBASE < va) 6348 panic("pmap_enu4m: can't enter va 0x%lx above KERNBASE", va); 6349 #endif 6350 6351 pm->pm_flags &= ~PMAP_USERCACHECLEAN; 6352 6353 vr = VA_VREG(va); 6354 vs = VA_VSEG(va); 6355 rp = &pm->pm_regmap[vr]; 6356 s = splvm(); 6357 PMAP_LOCK(); 6358 6359 if (rp->rg_segmap == NULL) { 6360 /* definitely a new mapping */ 6361 int mflag = PR_NOWAIT; 6362 6363 rretry: 6364 sp = (struct segmap *)pool_get(&segmap_pool, mflag); 6365 if (sp == NULL) { 6366 if ((flags & PMAP_CANFAIL) != 0) { 6367 error = ENOMEM; 6368 goto out; 6369 } 6370 mflag = PR_WAITOK; 6371 goto rretry; 6372 } 6373 #ifdef DEBUG 6374 if (rp->rg_segmap != NULL) 6375 panic("pmap_enu4m: segment filled during sleep"); 6376 #endif 6377 qzero((void *)sp, NSEGRG * sizeof (struct segmap)); 6378 rp->rg_segmap = sp; 6379 rp->rg_nsegmap = 0; 6380 rp->rg_seg_ptps = NULL; 6381 } 6382 if (rp->rg_seg_ptps == NULL) { 6383 /* Need a segment table */ 6384 int i, *ptd; 6385 int mflag = PR_NOWAIT; 6386 6387 sretry: 6388 ptd = pool_get(&L23_pool, mflag); 6389 if (ptd == NULL) { 6390 if ((flags & PMAP_CANFAIL) != 0) { 6391 error = ENOMEM; 6392 goto out; 6393 } 6394 mflag = PR_WAITOK; 6395 goto sretry; 6396 } 6397 6398 rp->rg_seg_ptps = ptd; 6399 for (i = 0; i < SRMMU_L2SIZE; i++) 6400 setpgt4m(&ptd[i], SRMMU_TEINVALID); 6401 6402 /* Replicate segment allocation in each CPU's region table */ 6403 #if defined(MULTIPROCESSOR) 6404 for (i = 0; i < sparc_ncpus; i++) 6405 #else 6406 i = 0; 6407 #endif 6408 { 6409 #if defined(MULTIPROCESSOR) 6410 if ((cpus[i]->flags & CPUFLG_HATCHED) == 0) 6411 continue; 6412 #endif 6413 setpgt4m(&pm->pm_reg_ptps[i][vr], 6414 (VA2PA((void *)ptd) >> SRMMU_PPNPASHIFT) | 6415 SRMMU_TEPTD); 6416 } 6417 } 6418 6419 sp = &rp->rg_segmap[vs]; 6420 6421 owired = false; 6422 if ((pte = sp->sg_pte) == NULL) { 6423 /* definitely a new mapping */ 6424 int i; 6425 int mflag = PR_NOWAIT; 6426 6427 pte = pool_get(&L23_pool, mflag); 6428 if (pte == NULL) { 6429 if ((flags & PMAP_CANFAIL) != 0) { 6430 error = ENOMEM; 6431 goto out; 6432 } 6433 panic("pmap_enter: cannot allocate PTE table"); 6434 } 6435 6436 sp->sg_pte = pte; 6437 sp->sg_npte = 1; 6438 rp->rg_nsegmap++; 6439 for (i = 0; i < SRMMU_L3SIZE; i++) 6440 setpgt4m(&pte[i], SRMMU_TEINVALID); 6441 setpgt4m(&rp->rg_seg_ptps[vs], 6442 (VA2PA((void *)pte) >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD); 6443 } else { 6444 #ifdef DIAGNOSTIC 6445 if (sp->sg_npte <= 0) 6446 panic("pm %p: npte %d", pm, sp->sg_npte); 6447 #endif 6448 /* 6449 * Might be a change: fetch old pte 6450 */ 6451 tpte = pte[VA_SUN4M_VPG(va)]; 6452 6453 if ((tpte & SRMMU_TETYPE) == SRMMU_TEPTE) { 6454 6455 /* old mapping exists, and is of the same pa type */ 6456 if ((tpte & SRMMU_PPNMASK) == 6457 (pteproto & SRMMU_PPNMASK)) { 6458 /* just changing prot and/or wiring */ 6459 /* caller should call this directly: */ 6460 pmap_changeprot4m(pm, va, prot, flags); 6461 error = 0; 6462 goto out; 6463 } 6464 /* 6465 * Switcheroo: changing pa for this va. 6466 * If old pa was managed, remove from pvlist. 6467 * If old page was cached, flush cache. 6468 */ 6469 DPRINTF(PDB_SWITCHMAP, 6470 "%s[%d]: pmap_enu: changing existing " 6471 "va 0x%x: pte 0x%x=>0x%x", 6472 curproc->p_comm, curproc->p_pid, 6473 (int)va, tpte, pteproto); 6474 6475 if ((tpte & SRMMU_PGTYPE) == PG_SUN4M_OBMEM) { 6476 struct vm_page *opg; 6477 if ((opg = pvhead4m(tpte)) != NULL) { 6478 VM_MDPAGE_PVHEAD(opg)->pv_flags |= 6479 MR4M(tpte); 6480 pv_unlink4m(opg, pm, va); 6481 } 6482 if (pm->pm_ctx && (tpte & SRMMU_PG_C)) 6483 cache_flush_page(va, pm->pm_ctxnum); 6484 } 6485 /* 6486 * We end up in this `change map' branch relatively 6487 * infrequently. 6488 * Invalidate the mapping now, so we can avoid the 6489 * de-map and update protocol when setting the new 6490 * PTE below. 6491 */ 6492 setpgt4m_va(va, &sp->sg_pte[VA_SUN4M_VPG(va)], 6493 SRMMU_TEINVALID, pm->pm_ctx != NULL, 6494 pm->pm_ctxnum, PMAP_CPUSET(pm)); 6495 pm->pm_stats.resident_count--; 6496 owired = sp->sg_wiremap & (1 << VA_SUN4M_VPG(va)); 6497 } else { 6498 /* adding new entry */ 6499 sp->sg_npte++; 6500 } 6501 } 6502 6503 if (pg != NULL && (error = pv_link4m(pg, pm, va, &pteproto)) != 0) { 6504 if (--sp->sg_npte == 0) 6505 /* Sigh, undo pgt allocations */ 6506 pgt_lvl23_remove4m(pm, rp, sp, vr, vs); 6507 6508 if ((flags & PMAP_CANFAIL) != 0) 6509 goto out; 6510 panic("pmap_enter: cannot allocate PV entry"); 6511 } 6512 6513 /* 6514 * Update PTEs, flush TLB as necessary. 6515 */ 6516 setpgt4m(&sp->sg_pte[VA_SUN4M_VPG(va)], pteproto); 6517 pm->pm_stats.resident_count++; 6518 if (owired) { 6519 pm->pm_stats.wired_count--; 6520 sp->sg_wiremap &= ~(1 << VA_SUN4M_VPG(va)); 6521 } 6522 if (flags & PMAP_WIRED) { 6523 pm->pm_stats.wired_count++; 6524 sp->sg_wiremap |= (1 << VA_SUN4M_VPG(va)); 6525 } 6526 6527 out: 6528 PMAP_UNLOCK(); 6529 splx(s); 6530 return (error); 6531 } 6532 6533 void 6534 pmap_kenter_pa4m(vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags) 6535 { 6536 struct pmap *pm = pmap_kernel(); 6537 struct regmap *rp; 6538 struct segmap *sp; 6539 int pteproto, vr, vs; 6540 6541 /* Initialise pteproto with cache bit */ 6542 pteproto = (pa & PMAP_NC) == 0 ? SRMMU_PG_C : 0; 6543 pteproto |= SRMMU_TEPTE | PPROT_S; 6544 pteproto |= PMAP_T2PTE_SRMMU(pa); 6545 pteproto |= (atop(pa & ~PMAP_TNC_SRMMU) << SRMMU_PPNSHIFT); 6546 pteproto |= pte_kprot4m(prot); 6547 6548 vr = VA_VREG(va); 6549 vs = VA_VSEG(va); 6550 rp = &pm->pm_regmap[vr]; 6551 sp = &rp->rg_segmap[vs]; 6552 6553 KASSERT((sp->sg_pte[VA_SUN4M_VPG(va)] & SRMMU_TETYPE) != SRMMU_TEPTE); 6554 6555 setpgt4m(&sp->sg_pte[VA_SUN4M_VPG(va)], pteproto); 6556 } 6557 6558 void 6559 pmap_kremove4m(vaddr_t va, vsize_t len) 6560 { 6561 struct pmap *pm = pmap_kernel(); 6562 struct regmap *rp; 6563 struct segmap *sp; 6564 vaddr_t endva, nva; 6565 int vr, vs; 6566 int tpte, perpage, npg, s; 6567 6568 /* 6569 * The kernel pmap doesn't need to be locked, but the demap lock 6570 * in updatepte() requires interrupt protection. 6571 */ 6572 kpreempt_disable(); 6573 s = splvm(); 6574 6575 endva = va + len; 6576 for (; va < endva; va = nva) { 6577 /* do one virtual segment at a time */ 6578 vr = VA_VREG(va); 6579 vs = VA_VSEG(va); 6580 nva = VSTOVA(vr, vs + 1); 6581 if (nva == 0 || nva > endva) { 6582 nva = endva; 6583 } 6584 6585 rp = &pm->pm_regmap[vr]; 6586 sp = &rp->rg_segmap[vs]; 6587 6588 /* decide how to flush the cache */ 6589 npg = (nva - va) >> PGSHIFT; 6590 if (npg > PMAP_SFL_THRESHOLD) { 6591 /* flush the whole segment */ 6592 perpage = 0; 6593 if (CACHEINFO.c_vactype != VAC_NONE) { 6594 cache_flush_segment(vr, vs, 0); 6595 } 6596 } else { 6597 /* 6598 * flush each page individually; 6599 * some never need flushing 6600 */ 6601 perpage = (CACHEINFO.c_vactype != VAC_NONE); 6602 } 6603 for (; va < nva; va += NBPG) { 6604 tpte = sp->sg_pte[VA_SUN4M_VPG(va)]; 6605 if ((tpte & SRMMU_TETYPE) != SRMMU_TEPTE) 6606 continue; 6607 6608 if ((tpte & SRMMU_PGTYPE) == PG_SUN4M_OBMEM) { 6609 /* if cacheable, flush page as needed */ 6610 if (perpage && (tpte & SRMMU_PG_C)) 6611 cache_flush_page(va, 0); 6612 } 6613 setpgt4m_va(va, &sp->sg_pte[VA_SUN4M_VPG(va)], 6614 SRMMU_TEINVALID, 1, 0, CPUSET_ALL); 6615 } 6616 } 6617 splx(s); 6618 kpreempt_enable(); 6619 } 6620 6621 /* 6622 * Change protection on a range of kernel addresses. 6623 */ 6624 void 6625 pmap_kprotect4m(vaddr_t va, vsize_t size, vm_prot_t prot) 6626 { 6627 struct pmap *pm = pmap_kernel(); 6628 int pte, newprot, s; 6629 struct regmap *rp; 6630 struct segmap *sp; 6631 6632 size = roundup(size,NBPG); 6633 newprot = pte_kprot4m(prot); 6634 6635 /* 6636 * The kernel pmap doesn't need to be locked, but the demap lock 6637 * in updatepte() requires interrupt protection. 6638 */ 6639 kpreempt_disable(); 6640 s = splvm(); 6641 6642 while (size > 0) { 6643 rp = &pm->pm_regmap[VA_VREG(va)]; 6644 sp = &rp->rg_segmap[VA_VSEG(va)]; 6645 pte = sp->sg_pte[VA_SUN4M_VPG(va)]; 6646 6647 /* 6648 * Flush cache if page has been referenced to 6649 * avoid stale protection bits in the cache tags. 6650 */ 6651 if ((pte & (SRMMU_PG_C|SRMMU_PGTYPE)) == 6652 (SRMMU_PG_C|PG_SUN4M_OBMEM)) 6653 cache_flush_page(va, 0); 6654 6655 setpgt4m_va(va, &sp->sg_pte[VA_SUN4M_VPG(va)], 6656 (pte & ~SRMMU_PROT_MASK) | newprot, 6657 1, pm->pm_ctxnum, PMAP_CPUSET(pm)); 6658 6659 va += NBPG; 6660 size -= NBPG; 6661 } 6662 splx(s); 6663 kpreempt_enable(); 6664 } 6665 #endif /* SUN4M || SUN4D */ 6666 6667 /* 6668 * Clear the wiring attribute for a map/virtual-address pair. 6669 */ 6670 /* ARGSUSED */ 6671 void 6672 pmap_unwire(struct pmap *pm, vaddr_t va) 6673 { 6674 int vr, vs, *ptep; 6675 struct regmap *rp; 6676 struct segmap *sp; 6677 bool owired; 6678 6679 kpreempt_disable(); 6680 vr = VA_VREG(va); 6681 vs = VA_VSEG(va); 6682 rp = &pm->pm_regmap[vr]; 6683 sp = &rp->rg_segmap[vs]; 6684 6685 owired = false; 6686 if (CPU_HAS_SUNMMU) { 6687 ptep = &sp->sg_pte[VA_VPG(va)]; 6688 owired = *ptep & PG_WIRED; 6689 *ptep &= ~PG_WIRED; 6690 } 6691 if (CPU_HAS_SRMMU) { 6692 owired = sp->sg_wiremap & (1 << VA_SUN4M_VPG(va)); 6693 sp->sg_wiremap &= ~(1 << VA_SUN4M_VPG(va)); 6694 } 6695 if (!owired) { 6696 pmap_stats.ps_useless_changewire++; 6697 kpreempt_enable(); 6698 return; 6699 } 6700 6701 pm->pm_stats.wired_count--; 6702 #if defined(SUN4) || defined(SUN4C) 6703 if (CPU_HAS_SUNMMU && --sp->sg_nwired <= 0) { 6704 #ifdef DIAGNOSTIC 6705 if (sp->sg_nwired > sp->sg_npte || sp->sg_nwired < 0) 6706 panic("pmap_unwire: pm %p, va %lx: nleft=%d, nwired=%d", 6707 pm, va, sp->sg_npte, sp->sg_nwired); 6708 #endif 6709 if (sp->sg_pmeg != seginval) 6710 mmu_pmeg_unlock(sp->sg_pmeg); 6711 } 6712 #endif /* SUN4 || SUN4C */ 6713 kpreempt_enable(); 6714 } 6715 6716 /* 6717 * Extract the physical page address associated 6718 * with the given map/virtual_address pair. 6719 * GRR, the vm code knows; we should not have to do this! 6720 */ 6721 6722 #if defined(SUN4) || defined(SUN4C) 6723 bool 6724 pmap_extract4_4c(struct pmap *pm, vaddr_t va, paddr_t *pap) 6725 { 6726 int vr, vs; 6727 struct regmap *rp; 6728 struct segmap *sp; 6729 int pte, *ptep; 6730 6731 vr = VA_VREG(va); 6732 vs = VA_VSEG(va); 6733 rp = &pm->pm_regmap[vr]; 6734 if (rp->rg_segmap == NULL) { 6735 DPRINTF(PDB_FOLLOW, "pmap_extract: invalid segment (%d)", vr); 6736 return (false); 6737 } 6738 sp = &rp->rg_segmap[vs]; 6739 ptep = sp->sg_pte; 6740 if (ptep == NULL) { 6741 DPRINTF(PDB_FOLLOW, "pmap_extract: invalid segment"); 6742 return (false); 6743 } 6744 pte = ptep[VA_VPG(va)]; 6745 6746 if ((pte & PG_V) == 0) { 6747 DPRINTF(PDB_FOLLOW, "pmap_extract: invalid pte"); 6748 return (false); 6749 } 6750 pte &= PG_PFNUM; 6751 if (pap != NULL) 6752 *pap = (pte << PGSHIFT) | (va & PGOFSET); 6753 return (true); 6754 } 6755 #endif /* SUN4 || SUN4C */ 6756 6757 #if defined(SUN4M) || defined(SUN4D) /* SRMMU version of pmap_extract */ 6758 /* 6759 * Extract the physical page address associated 6760 * with the given map/virtual_address pair. 6761 * GRR, the vm code knows; we should not have to do this! 6762 */ 6763 bool 6764 pmap_extract4m(struct pmap *pm, vaddr_t va, paddr_t *pap) 6765 { 6766 struct regmap *rp; 6767 struct segmap *sp; 6768 int pte; 6769 int vr, vs, s, v = false; 6770 bool can_lock = lock_available; 6771 6772 vr = VA_VREG(va); 6773 vs = VA_VSEG(va); 6774 6775 /* 6776 * The kernel pmap doesn't need to be locked, but the demap lock 6777 * requires interrupt protection. 6778 */ 6779 s = splvm(); 6780 if (pm != pmap_kernel()) { 6781 PMAP_LOCK(); 6782 } 6783 6784 rp = &pm->pm_regmap[vr]; 6785 if (rp->rg_segmap == NULL) { 6786 DPRINTF(PDB_FOLLOW, "pmap_extract: no segmap"); 6787 goto out; 6788 } 6789 6790 sp = &rp->rg_segmap[vs]; 6791 if (sp->sg_pte == NULL) { 6792 DPRINTF(PDB_FOLLOW, "pmap_extract: no ptes"); 6793 goto out; 6794 } 6795 6796 pte = sp->sg_pte[VA_SUN4M_VPG(va)]; 6797 if ((pte & SRMMU_TETYPE) != SRMMU_TEPTE) { 6798 DPRINTF(PDB_FOLLOW, "pmap_extract: invalid pte of type %d", 6799 pte & SRMMU_TETYPE); 6800 /* 6801 * We can read a spurious invalid pte if the system is in 6802 * the middle of the PTE update protocol. So, acquire the 6803 * demap lock and retry. 6804 */ 6805 if (__predict_true(can_lock)) 6806 mutex_spin_enter(&demap_lock); 6807 pte = sp->sg_pte[VA_SUN4M_VPG(va)]; 6808 if (__predict_true(can_lock)) 6809 mutex_spin_exit(&demap_lock); 6810 if ((pte & SRMMU_TETYPE) != SRMMU_TEPTE) 6811 goto out; 6812 } 6813 #ifdef DIAGNOSTIC 6814 if (pm != pmap_kernel() && sp->sg_npte <= 0) 6815 panic("pmap_extract: pm %p: npte = %d\n", pm, sp->sg_npte); 6816 #endif 6817 6818 if (pap != NULL) 6819 *pap = ptoa((pte & SRMMU_PPNMASK) >> SRMMU_PPNSHIFT) | 6820 VA_OFF(va); 6821 6822 v = true; 6823 out: 6824 if (pm != pmap_kernel()) { 6825 PMAP_UNLOCK(); 6826 } 6827 splx(s); 6828 return (v); 6829 } 6830 #endif /* sun4m */ 6831 6832 int pmap_copy_disabled=0; 6833 6834 /* 6835 * Copy the range specified by src_addr/len 6836 * from the source map to the range dst_addr/len 6837 * in the destination map. 6838 * 6839 * This routine is only advisory and need not do anything. 6840 */ 6841 /* ARGSUSED */ 6842 void 6843 pmap_copy(struct pmap *dst_pmap, struct pmap *src_pmap, 6844 vaddr_t dst_addr, vsize_t len, vaddr_t src_addr) 6845 { 6846 #if notyet 6847 struct regmap *rp; 6848 struct segmap *sp; 6849 6850 if (pmap_copy_disabled) 6851 return; 6852 #ifdef DIAGNOSTIC 6853 if (VA_OFF(src_addr) != 0) 6854 printf("pmap_copy: addr not page aligned: 0x%lx\n", src_addr); 6855 if ((len & (NBPG-1)) != 0) 6856 printf("pmap_copy: length not page aligned: 0x%lx\n", len); 6857 #endif 6858 6859 if (src_pmap == NULL) 6860 return; 6861 6862 if (CPU_HAS_SRMMU) { 6863 int i, npg, pte; 6864 paddr_t pa; 6865 6866 npg = len >> PGSHIFT; 6867 for (i = 0; i < npg; i++) { 6868 if ((rp = src_pmap->pm_regmap) == NULL) 6869 continue; 6870 rp += VA_VREG(src_addr); 6871 6872 if ((sp = rp->rg_segmap) == NULL) 6873 continue; 6874 sp += VA_VSEG(src_addr); 6875 if (sp->sg_npte == 0) 6876 continue; 6877 6878 pte = sp->sg_pte[VA_SUN4M_VPG(src_addr)]; 6879 if ((pte & SRMMU_TETYPE) != SRMMU_TEPTE) 6880 continue; 6881 6882 pa = ptoa((pte & SRMMU_PPNMASK) >> SRMMU_PPNSHIFT); 6883 pmap_enter(dst_pmap, dst_addr, 6884 pa, 6885 /* XXX - need to copy VM_PROT_EXEC too */ 6886 (pte & PPROT_WRITE) 6887 ? (VM_PROT_WRITE | VM_PROT_READ) 6888 : VM_PROT_READ, 6889 0); 6890 src_addr += NBPG; 6891 dst_addr += NBPG; 6892 } 6893 pmap_update(dst_pmap); 6894 } 6895 #endif 6896 } 6897 6898 #if defined(SUN4) || defined(SUN4C) 6899 /* 6900 * Clear the modify bit for the given physical page. 6901 */ 6902 bool 6903 pmap_clear_modify4_4c(struct vm_page *pg) 6904 { 6905 bool rv; 6906 6907 (void) pv_syncflags4_4c(pg); 6908 rv = VM_MDPAGE_PVHEAD(pg)->pv_flags & PV_MOD; 6909 VM_MDPAGE_PVHEAD(pg)->pv_flags &= ~PV_MOD; 6910 return (rv); 6911 } 6912 6913 /* 6914 * Tell whether the given physical page has been modified. 6915 */ 6916 bool 6917 pmap_is_modified4_4c(struct vm_page *pg) 6918 { 6919 6920 return (VM_MDPAGE_PVHEAD(pg)->pv_flags & PV_MOD || 6921 pv_syncflags4_4c(pg) & PV_MOD); 6922 } 6923 6924 /* 6925 * Clear the reference bit for the given physical page. 6926 */ 6927 bool 6928 pmap_clear_reference4_4c(struct vm_page *pg) 6929 { 6930 bool rv; 6931 6932 (void) pv_syncflags4_4c(pg); 6933 rv = VM_MDPAGE_PVHEAD(pg)->pv_flags & PV_REF; 6934 VM_MDPAGE_PVHEAD(pg)->pv_flags &= ~PV_REF; 6935 return (rv); 6936 } 6937 6938 /* 6939 * Tell whether the given physical page has been referenced. 6940 */ 6941 bool 6942 pmap_is_referenced4_4c(struct vm_page *pg) 6943 { 6944 6945 return (VM_MDPAGE_PVHEAD(pg)->pv_flags & PV_REF || 6946 pv_syncflags4_4c(pg) & PV_REF); 6947 } 6948 #endif /* SUN4 || SUN4C */ 6949 6950 #if defined(SUN4M) || defined(SUN4D) 6951 6952 /* 6953 * SRMMU versions of bit test/set routines 6954 * 6955 * Note that the 4m-specific routines should eventually service these 6956 * requests from their page tables, and the whole pvlist bit mess should 6957 * be dropped for the 4m (unless this causes a performance hit from 6958 * tracing down pagetables/regmap/segmaps). 6959 */ 6960 6961 /* 6962 * Clear the modify bit for the given physical page. 6963 */ 6964 bool 6965 pmap_clear_modify4m(struct vm_page *pg) 6966 { 6967 bool rv; 6968 6969 (void) pv_syncflags4m(pg); 6970 rv = VM_MDPAGE_PVHEAD(pg)->pv_flags & PV_MOD4M; 6971 VM_MDPAGE_PVHEAD(pg)->pv_flags &= ~PV_MOD4M; 6972 return (rv); 6973 } 6974 6975 /* 6976 * Tell whether the given physical page has been modified. 6977 */ 6978 bool 6979 pmap_is_modified4m(struct vm_page *pg) 6980 { 6981 6982 return (VM_MDPAGE_PVHEAD(pg)->pv_flags & PV_MOD4M || 6983 pv_syncflags4m(pg) & PV_MOD4M); 6984 } 6985 6986 /* 6987 * Clear the reference bit for the given physical page. 6988 */ 6989 bool 6990 pmap_clear_reference4m(struct vm_page *pg) 6991 { 6992 bool rv; 6993 6994 (void) pv_syncflags4m(pg); 6995 rv = VM_MDPAGE_PVHEAD(pg)->pv_flags & PV_REF4M; 6996 VM_MDPAGE_PVHEAD(pg)->pv_flags &= ~PV_REF4M; 6997 return (rv); 6998 } 6999 7000 /* 7001 * Tell whether the given physical page has been referenced. 7002 */ 7003 bool 7004 pmap_is_referenced4m(struct vm_page *pg) 7005 { 7006 7007 return (VM_MDPAGE_PVHEAD(pg)->pv_flags & PV_REF4M || 7008 pv_syncflags4m(pg) & PV_REF4M); 7009 } 7010 #endif /* SUN4M || SUN4D */ 7011 7012 /* 7013 * Fill the given MI physical page with zero bytes. 7014 * 7015 * We avoid stomping on the cache. 7016 * XXX might be faster to use destination's context and allow cache to fill? 7017 */ 7018 7019 #if defined(SUN4) || defined(SUN4C) 7020 7021 void 7022 pmap_zero_page4_4c(paddr_t pa) 7023 { 7024 struct vm_page *pg; 7025 void *va; 7026 int pte; 7027 7028 if ((pg = PHYS_TO_VM_PAGE(pa)) != NULL) { 7029 /* 7030 * The following might not be necessary since the page 7031 * is being cleared because it is about to be allocated, 7032 * i.e., is in use by no one. 7033 */ 7034 pv_flushcache4_4c(pg); 7035 } 7036 pte = PG_V | PG_S | PG_W | PG_NC | (atop(pa) & PG_PFNUM); 7037 7038 va = cpuinfo.vpage[0]; 7039 setpte4(va, pte); 7040 qzero(va, NBPG); 7041 setpte4(va, 0); 7042 } 7043 7044 /* 7045 * Copy the given MI physical source page to its destination. 7046 * 7047 * We avoid stomping on the cache as above (with same `XXX' note). 7048 * We must first flush any write-back cache for the source page. 7049 * We go ahead and stomp on the kernel's virtual cache for the 7050 * source page, since the cache can read memory MUCH faster than 7051 * the processor. 7052 */ 7053 void 7054 pmap_copy_page4_4c(paddr_t src, paddr_t dst) 7055 { 7056 struct vm_page *pg; 7057 char *sva, *dva; 7058 int spte, dpte; 7059 7060 if ((pg = PHYS_TO_VM_PAGE(src)) != NULL) { 7061 if (CACHEINFO.c_vactype == VAC_WRITEBACK) 7062 pv_flushcache4_4c(pg); 7063 } 7064 spte = PG_V | PG_S | (atop(src) & PG_PFNUM); 7065 7066 if ((pg = PHYS_TO_VM_PAGE(dst)) != NULL) { 7067 /* similar `might not be necessary' comment applies */ 7068 if (CACHEINFO.c_vactype != VAC_NONE) 7069 pv_flushcache4_4c(pg); 7070 } 7071 dpte = PG_V | PG_S | PG_W | PG_NC | (atop(dst) & PG_PFNUM); 7072 7073 sva = cpuinfo.vpage[0]; 7074 dva = cpuinfo.vpage[1]; 7075 setpte4(sva, spte); 7076 setpte4(dva, dpte); 7077 qcopy(sva, dva, NBPG); /* loads cache, so we must ... */ 7078 cache_flush_page((vaddr_t)sva, getcontext4()); 7079 setpte4(sva, 0); 7080 setpte4(dva, 0); 7081 } 7082 #endif /* SUN4 || SUN4C */ 7083 7084 #if defined(SUN4M) || defined(SUN4D) /* SRMMU version of copy/zero routines */ 7085 /* 7086 * Fill the given MI physical page with zero bytes. 7087 * 7088 * We avoid stomping on the cache. 7089 * XXX might be faster to use destination's context and allow cache to fill? 7090 */ 7091 void 7092 pmap_zero_page4m(paddr_t pa) 7093 { 7094 struct vm_page *pg; 7095 void *va; 7096 int pte; 7097 7098 kpreempt_disable(); 7099 if ((pg = PHYS_TO_VM_PAGE(pa)) != NULL) { 7100 /* 7101 * The following VAC flush might not be necessary since the 7102 * page is being cleared because it is about to be allocated, 7103 * i.e., is in use by no one. 7104 * In the case of a physical cache, a flush (or just an 7105 * invalidate, if possible) is usually necessary when using 7106 * uncached access to clear it. 7107 */ 7108 if (CACHEINFO.c_vactype != VAC_NONE) 7109 pv_flushcache4m(pg); 7110 else 7111 pcache_flush_page(pa, 1); 7112 } 7113 pte = SRMMU_TEPTE | PPROT_N_RWX | (pa >> SRMMU_PPNPASHIFT); 7114 if (CACHEINFO.c_flags & CACHE_MANDATORY) 7115 pte |= SRMMU_PG_C; 7116 7117 va = cpuinfo.vpage[0]; 7118 setpgt4m(cpuinfo.vpage_pte[0], pte); 7119 qzero(va, NBPG); 7120 /* 7121 * Remove temporary mapping (which is kernel-only, so the 7122 * context used for TLB flushing does not matter) 7123 */ 7124 sp_tlb_flush((int)va, 0, ASI_SRMMUFP_L3); 7125 setpgt4m(cpuinfo.vpage_pte[0], SRMMU_TEINVALID); 7126 kpreempt_enable(); 7127 } 7128 7129 /* 7130 * Viking/MXCC specific version of pmap_zero_page 7131 */ 7132 void 7133 pmap_zero_page_viking_mxcc(paddr_t pa) 7134 { 7135 u_int offset; 7136 u_int stream_data_addr = MXCC_STREAM_DATA; 7137 uint64_t v = (uint64_t)pa; 7138 7139 kpreempt_disable(); 7140 /* Load MXCC stream data register with 0 (bottom 32 bytes only) */ 7141 stda(stream_data_addr+0, ASI_CONTROL, 0); 7142 stda(stream_data_addr+8, ASI_CONTROL, 0); 7143 stda(stream_data_addr+16, ASI_CONTROL, 0); 7144 stda(stream_data_addr+24, ASI_CONTROL, 0); 7145 7146 /* Then write the stream data register to each block in the page */ 7147 v |= MXCC_STREAM_C; 7148 for (offset = 0; offset < NBPG; offset += MXCC_STREAM_BLKSZ) { 7149 stda(MXCC_STREAM_DST, ASI_CONTROL, v | offset); 7150 } 7151 kpreempt_enable(); 7152 } 7153 7154 /* 7155 * HyperSPARC/RT625 specific version of pmap_zero_page 7156 */ 7157 void 7158 pmap_zero_page_hypersparc(paddr_t pa) 7159 { 7160 struct vm_page *pg; 7161 void *va; 7162 int pte; 7163 int offset; 7164 7165 kpreempt_disable(); 7166 /* 7167 * We still have to map the page, since ASI_BLOCKFILL 7168 * takes virtual addresses. This also means we have to 7169 * consider cache aliasing; therefore we still need 7170 * to flush the cache here. All we gain is the speed-up 7171 * in zero-fill loop itself.. 7172 */ 7173 if ((pg = PHYS_TO_VM_PAGE(pa)) != NULL) { 7174 /* 7175 * The following might not be necessary since the page 7176 * is being cleared because it is about to be allocated, 7177 * i.e., is in use by no one. 7178 */ 7179 if (CACHEINFO.c_vactype != VAC_NONE) 7180 pv_flushcache4m(pg); 7181 } 7182 pte = SRMMU_TEPTE | SRMMU_PG_C | PPROT_N_RWX | (pa >> SRMMU_PPNPASHIFT); 7183 7184 va = cpuinfo.vpage[0]; 7185 setpgt4m(cpuinfo.vpage_pte[0], pte); 7186 for (offset = 0; offset < NBPG; offset += 32) { 7187 sta((char *)va + offset, ASI_BLOCKFILL, 0); 7188 } 7189 /* Remove temporary mapping */ 7190 sp_tlb_flush((int)va, 0, ASI_SRMMUFP_L3); 7191 setpgt4m(cpuinfo.vpage_pte[0], SRMMU_TEINVALID); 7192 kpreempt_enable(); 7193 } 7194 7195 /* 7196 * Copy the given MI physical source page to its destination. 7197 * 7198 * We avoid stomping on the cache as above (with same `XXX' note). 7199 * We must first flush any write-back cache for the source page. 7200 * We go ahead and stomp on the kernel's virtual cache for the 7201 * source page, since the cache can read memory MUCH faster than 7202 * the processor. 7203 */ 7204 void 7205 pmap_copy_page4m(paddr_t src, paddr_t dst) 7206 { 7207 struct vm_page *pg; 7208 void *sva, *dva; 7209 int spte, dpte; 7210 7211 kpreempt_disable(); 7212 if ((pg = PHYS_TO_VM_PAGE(src)) != NULL) { 7213 if (CACHEINFO.c_vactype == VAC_WRITEBACK) 7214 pv_flushcache4m(pg); 7215 } 7216 7217 spte = SRMMU_TEPTE | SRMMU_PG_C | PPROT_N_RX | 7218 (src >> SRMMU_PPNPASHIFT); 7219 7220 if ((pg = PHYS_TO_VM_PAGE(dst)) != NULL) { 7221 /* similar `might not be necessary' comment applies */ 7222 if (CACHEINFO.c_vactype != VAC_NONE) 7223 pv_flushcache4m(pg); 7224 else 7225 pcache_flush_page(dst, 1); 7226 } 7227 7228 dpte = SRMMU_TEPTE | PPROT_N_RWX | (dst >> SRMMU_PPNPASHIFT); 7229 if (CACHEINFO.c_flags & CACHE_MANDATORY) 7230 dpte |= SRMMU_PG_C; 7231 7232 sva = cpuinfo.vpage[0]; 7233 dva = cpuinfo.vpage[1]; 7234 setpgt4m(cpuinfo.vpage_pte[0], spte); 7235 setpgt4m(cpuinfo.vpage_pte[1], dpte); 7236 qcopy(sva, dva, NBPG); /* loads cache, so we must ... */ 7237 cpuinfo.sp_vcache_flush_page((vaddr_t)sva, getcontext4m()); 7238 sp_tlb_flush((int)sva, 0, ASI_SRMMUFP_L3); 7239 setpgt4m(cpuinfo.vpage_pte[0], SRMMU_TEINVALID); 7240 sp_tlb_flush((int)dva, 0, ASI_SRMMUFP_L3); 7241 setpgt4m(cpuinfo.vpage_pte[1], SRMMU_TEINVALID); 7242 kpreempt_enable(); 7243 } 7244 7245 /* 7246 * Viking/MXCC specific version of pmap_copy_page 7247 */ 7248 void 7249 pmap_copy_page_viking_mxcc(paddr_t src, paddr_t dst) 7250 { 7251 u_int offset; 7252 uint64_t v1 = (uint64_t)src; 7253 uint64_t v2 = (uint64_t)dst; 7254 7255 kpreempt_disable(); 7256 /* Enable cache-coherency */ 7257 v1 |= MXCC_STREAM_C; 7258 v2 |= MXCC_STREAM_C; 7259 7260 /* Copy through stream data register */ 7261 for (offset = 0; offset < NBPG; offset += MXCC_STREAM_BLKSZ) { 7262 stda(MXCC_STREAM_SRC, ASI_CONTROL, v1 | offset); 7263 stda(MXCC_STREAM_DST, ASI_CONTROL, v2 | offset); 7264 } 7265 kpreempt_enable(); 7266 } 7267 7268 /* 7269 * HyperSPARC/RT625 specific version of pmap_copy_page 7270 */ 7271 void 7272 pmap_copy_page_hypersparc(paddr_t src, paddr_t dst) 7273 { 7274 struct vm_page *pg; 7275 void *sva, *dva; 7276 int spte, dpte; 7277 int offset; 7278 7279 kpreempt_disable(); 7280 /* 7281 * We still have to map the pages, since ASI_BLOCKCOPY 7282 * takes virtual addresses. This also means we have to 7283 * consider cache aliasing; therefore we still need 7284 * to flush the cache here. All we gain is the speed-up 7285 * in copy loop itself.. 7286 */ 7287 7288 if ((pg = PHYS_TO_VM_PAGE(src)) != NULL) { 7289 if (CACHEINFO.c_vactype == VAC_WRITEBACK) 7290 pv_flushcache4m(pg); 7291 } 7292 7293 spte = SRMMU_TEPTE | SRMMU_PG_C | PPROT_N_RX | 7294 (src >> SRMMU_PPNPASHIFT); 7295 7296 if ((pg = PHYS_TO_VM_PAGE(dst)) != NULL) { 7297 /* similar `might not be necessary' comment applies */ 7298 if (CACHEINFO.c_vactype != VAC_NONE) 7299 pv_flushcache4m(pg); 7300 } 7301 7302 dpte = SRMMU_TEPTE | SRMMU_PG_C | PPROT_N_RWX | 7303 (dst >> SRMMU_PPNPASHIFT); 7304 7305 sva = cpuinfo.vpage[0]; 7306 dva = cpuinfo.vpage[1]; 7307 setpgt4m(cpuinfo.vpage_pte[0], spte); 7308 setpgt4m(cpuinfo.vpage_pte[1], dpte); 7309 7310 for (offset = 0; offset < NBPG; offset += 32) { 7311 sta((char *)dva + offset, ASI_BLOCKCOPY, (char *)sva + offset); 7312 } 7313 7314 sp_tlb_flush((int)sva, 0, ASI_SRMMUFP_L3); 7315 setpgt4m(cpuinfo.vpage_pte[0], SRMMU_TEINVALID); 7316 sp_tlb_flush((int)dva, 0, ASI_SRMMUFP_L3); 7317 setpgt4m(cpuinfo.vpage_pte[1], SRMMU_TEINVALID); 7318 kpreempt_enable(); 7319 } 7320 #endif /* SUN4M || SUN4D */ 7321 7322 /* 7323 * Turn off cache for a given (va, number of pages). 7324 * 7325 * We just assert PG_NC for each PTE; the addresses must reside 7326 * in locked kernel space. A cache flush is also done. 7327 */ 7328 void 7329 kvm_uncache(char *va, int npages) 7330 { 7331 struct vm_page *pg; 7332 int pte; 7333 7334 if (CPU_HAS_SRMMU) { 7335 #if defined(SUN4M) || defined(SUN4D) 7336 for (; --npages >= 0; va = (char *)va + NBPG) { 7337 pte = getpte4m((vaddr_t) va); 7338 if ((pte & SRMMU_TETYPE) != SRMMU_TEPTE) 7339 panic("kvm_uncache: table entry not pte"); 7340 7341 if ((pte & SRMMU_PGTYPE) == PG_SUN4M_OBMEM) { 7342 if ((pg = pvhead4m(pte)) != NULL) { 7343 pv_uncache(pg); 7344 return; 7345 } 7346 cache_flush_page((vaddr_t)va, 0); 7347 } 7348 7349 pte &= ~SRMMU_PG_C; 7350 setpte4m((vaddr_t)va, pte); 7351 } 7352 #endif 7353 } else { 7354 #if defined(SUN4) || defined(SUN4C) 7355 for (; --npages >= 0; va += NBPG) { 7356 pte = getpte4(va); 7357 if ((pte & PG_V) == 0) 7358 panic("kvm_uncache !pg_v"); 7359 7360 if ((pte & PG_TYPE) == PG_OBMEM) { 7361 if ((pg = pvhead4_4c(pte)) != NULL) { 7362 pv_uncache(pg); 7363 return; 7364 } 7365 cache_flush_page((vaddr_t)va, 0); 7366 } 7367 pte |= PG_NC; 7368 setpte4(va, pte); 7369 } 7370 #endif 7371 } 7372 } 7373 7374 #if 0 /* not used */ 7375 /* 7376 * Turn on IO cache for a given (va, number of pages). 7377 * 7378 * We just assert PG_NC for each PTE; the addresses must reside 7379 * in locked kernel space. A cache flush is also done. 7380 */ 7381 void 7382 kvm_iocache(char *va, int npages) 7383 { 7384 7385 #if defined(SUN4M) 7386 if (CPU_ISSUN4M) /* %%%: Implement! */ 7387 panic("kvm_iocache: 4m iocache not implemented"); 7388 #endif 7389 #if defined(SUN4D) 7390 if (CPU_ISSUN4D) /* %%%: Implement! */ 7391 panic("kvm_iocache: 4d iocache not implemented"); 7392 #endif 7393 #if defined(SUN4) || defined(SUN4C) 7394 for (; --npages >= 0; va += NBPG) { 7395 int pte = getpte4(va); 7396 if ((pte & PG_V) == 0) 7397 panic("kvm_iocache !pg_v"); 7398 pte |= PG_IOC; 7399 setpte4(va, pte); 7400 } 7401 #endif 7402 } 7403 #endif 7404 7405 /* 7406 * Find first virtual address >= *va that is 7407 * least likely to cause cache aliases. 7408 * (This will just seg-align mappings.) 7409 */ 7410 void 7411 pmap_prefer(vaddr_t foff, vaddr_t *vap, size_t size, int td) 7412 { 7413 vaddr_t va = *vap; 7414 long m; 7415 7416 m = CACHE_ALIAS_DIST; 7417 if (m == 0) /* m=0 => no cache aliasing */ 7418 return; 7419 7420 if (VA_INHOLE(va)) { 7421 if (td) 7422 va = MMU_HOLE_START - size; 7423 else 7424 va = MMU_HOLE_END; 7425 } 7426 7427 va = (va & ~(m - 1)) | (foff & (m - 1)); 7428 7429 if (td) { 7430 if (va > *vap) 7431 va -= m; 7432 } else { 7433 if (va < *vap) 7434 va += m; 7435 } 7436 *vap = va; 7437 } 7438 7439 void 7440 pmap_redzone(void) 7441 { 7442 7443 pmap_remove(pmap_kernel(), KERNBASE, KERNBASE+NBPG); 7444 } 7445 7446 /* 7447 * Activate the address space for the specified process. If the 7448 * process is the current process, load the new MMU context. 7449 */ 7450 void 7451 pmap_activate(struct lwp *l) 7452 { 7453 pmap_t pm = l->l_proc->p_vmspace->vm_map.pmap; 7454 7455 if (pm == pmap_kernel() || l != curlwp) { 7456 return; 7457 } 7458 7459 mutex_spin_enter(&ctx_lock); 7460 if (pm->pm_ctx == NULL) { 7461 ctx_alloc(pm); /* performs setcontext() */ 7462 } else { 7463 setcontext(pm->pm_ctxnum); 7464 } 7465 PMAP_SET_CPUSET(pm, &cpuinfo); 7466 mutex_spin_exit(&ctx_lock); 7467 } 7468 7469 /* 7470 * Deactivate the address space of the specified process. 7471 */ 7472 void 7473 pmap_deactivate(struct lwp *l) 7474 { 7475 struct proc *p = l->l_proc; 7476 pmap_t pm = p->p_vmspace->vm_map.pmap; 7477 7478 if (pm == pmap_kernel() || l != curlwp) { 7479 return; 7480 } 7481 7482 write_user_windows(); 7483 mutex_spin_enter(&ctx_lock); 7484 if (pm->pm_ctx) { 7485 (*cpuinfo.pure_vcache_flush)(); 7486 7487 #if defined(SUN4M) || defined(SUN4D) 7488 if (CPU_HAS_SRMMU) 7489 sp_tlb_flush(0, pm->pm_ctxnum, ASI_SRMMUFP_L0); 7490 #endif 7491 } 7492 7493 /* we no longer need broadcast tlb flushes for this pmap. */ 7494 PMAP_CLR_CPUSET(pm, &cpuinfo); 7495 mutex_spin_exit(&ctx_lock); 7496 } 7497 7498 #ifdef DEBUG 7499 /* 7500 * Check consistency of a pmap (time consuming!). 7501 */ 7502 void 7503 pm_check(char *s, struct pmap *pm) 7504 { 7505 7506 if (pm == pmap_kernel()) 7507 pm_check_k(s, pm); 7508 else 7509 pm_check_u(s, pm); 7510 } 7511 7512 void 7513 pm_check_u(char *s, struct pmap *pm) 7514 { 7515 struct regmap *rp; 7516 struct segmap *sp; 7517 int cpu, n, vs, vr, j, m, *pte; 7518 7519 cpu = cpuinfo.ci_cpuid; 7520 7521 if (pm->pm_regmap == NULL) 7522 panic("%s: CPU %d: CHK(pmap %p): no region mapping", 7523 s, cpu, pm); 7524 7525 #if defined(SUN4M) || defined(SUN4D) 7526 if (CPU_HAS_SRMMU && 7527 (pm->pm_reg_ptps[cpu] == NULL || 7528 pm->pm_reg_ptps_pa[cpu] != VA2PA((void *)pm->pm_reg_ptps[cpu]))) 7529 panic("%s: CPU %d: CHK(pmap %p): no SRMMU region table or bad pa: " 7530 "tblva=%p, tblpa=0x%x", 7531 s, cpu, pm, pm->pm_reg_ptps[cpu], pm->pm_reg_ptps_pa[cpu]); 7532 7533 if (CPU_HAS_SRMMU && pm->pm_ctx != NULL && 7534 (cpuinfo.ctx_tbl[pm->pm_ctxnum] != ((VA2PA((void *)pm->pm_reg_ptps[cpu]) 7535 >> SRMMU_PPNPASHIFT) | 7536 SRMMU_TEPTD))) 7537 panic("%s: CPU %d: CHK(pmap %p): SRMMU region table at 0x%x not installed " 7538 "for context %d", s, cpu, pm, pm->pm_reg_ptps_pa[cpu], pm->pm_ctxnum); 7539 #endif 7540 7541 for (vr = 0; vr < NUREG; vr++) { 7542 rp = &pm->pm_regmap[vr]; 7543 if (rp->rg_nsegmap == 0) 7544 continue; 7545 if (rp->rg_segmap == NULL) 7546 panic("%s: CPU %d: CHK(vr %d): nsegmap = %d; sp==NULL", 7547 s, cpu, vr, rp->rg_nsegmap); 7548 #if defined(SUN4M) || defined(SUN4D) 7549 if (CPU_HAS_SRMMU && rp->rg_seg_ptps == NULL) 7550 panic("%s: CPU %d: CHK(vr %d): nsegmap=%d; no SRMMU segment table", 7551 s, cpu, vr, rp->rg_nsegmap); 7552 if (CPU_HAS_SRMMU && 7553 pm->pm_reg_ptps[cpu][vr] != ((VA2PA((void *)rp->rg_seg_ptps) >> 7554 SRMMU_PPNPASHIFT) | SRMMU_TEPTD)) 7555 panic("%s: CPU %d: CHK(vr %d): SRMMU segtbl not installed", 7556 s, cpu, vr); 7557 #endif 7558 if ((unsigned int)rp < KERNBASE) 7559 panic("%s: CPU %d: rp=%p", s, cpu, rp); 7560 n = 0; 7561 for (vs = 0; vs < NSEGRG; vs++) { 7562 sp = &rp->rg_segmap[vs]; 7563 if ((unsigned int)sp < KERNBASE) 7564 panic("%s: CPU %d: sp=%p", s, cpu, sp); 7565 if (sp->sg_npte != 0) { 7566 n++; 7567 if (sp->sg_pte == NULL) 7568 panic("%s: CPU %d: CHK(vr %d, vs %d): npte=%d, " 7569 "pte=NULL", s, cpu, vr, vs, sp->sg_npte); 7570 #if defined(SUN4M) || defined(SUN4D) 7571 if (CPU_HAS_SRMMU && 7572 rp->rg_seg_ptps[vs] != 7573 ((VA2PA((void *)sp->sg_pte) 7574 >> SRMMU_PPNPASHIFT) | 7575 SRMMU_TEPTD)) 7576 panic("%s: CPU %d: CHK(vr %d, vs %d): SRMMU page " 7577 "table not installed correctly", 7578 s, cpu, vr, vs); 7579 #endif 7580 pte=sp->sg_pte; 7581 m = 0; 7582 for (j=0; j<NPTESG; j++,pte++) 7583 if ((CPU_HAS_SRMMU 7584 ?((*pte & SRMMU_TETYPE) == SRMMU_TEPTE) 7585 :(*pte & PG_V))) 7586 m++; 7587 if (m != sp->sg_npte) 7588 printf("%s: CPU %d: user CHK(vr %d, vs %d): " 7589 "npte(%d) != # valid(%d)\n", 7590 s, cpu, vr, vs, sp->sg_npte, m); 7591 } 7592 } 7593 if (n != rp->rg_nsegmap) 7594 panic("%s: CPU %d: CHK(vr %d): inconsistent " 7595 "# of pte's: %d, should be %d", 7596 s, cpu, vr, rp->rg_nsegmap, n); 7597 } 7598 return; 7599 } 7600 7601 /* Note: not as extensive as pm_check_u. */ 7602 void 7603 pm_check_k(char *s, struct pmap *pm) 7604 { 7605 struct regmap *rp; 7606 int cpu, vr, vs, n; 7607 7608 cpu = cpu_number(); 7609 7610 if (pm->pm_regmap == NULL) 7611 panic("%s: CHK(pmap %p): no region mapping", s, pm); 7612 7613 #if defined(SUN4M) || defined(SUN4D) 7614 if (CPU_HAS_SRMMU && 7615 (pm->pm_reg_ptps[cpu] == NULL || 7616 pm->pm_reg_ptps_pa[cpu] != VA2PA((void *)pm->pm_reg_ptps[cpu]))) 7617 panic("%s: CPU %d: CHK(pmap %p): no SRMMU region table or bad pa: tblva=%p, tblpa=0x%x", 7618 s, cpu, pm, pm->pm_reg_ptps[cpu], pm->pm_reg_ptps_pa[cpu]); 7619 7620 if (CPU_HAS_SRMMU && 7621 (cpuinfo.ctx_tbl[0] != ((VA2PA((void *)pm->pm_reg_ptps[cpu]) >> 7622 SRMMU_PPNPASHIFT) | SRMMU_TEPTD))) 7623 panic("%s: CPU %d: CHK(pmap %p): SRMMU region table at 0x%x not installed " 7624 "for context %d", s, cpu, pm, pm->pm_reg_ptps_pa[cpu], 0); 7625 #endif 7626 for (vr = NUREG; vr < NUREG+NKREG; vr++) { 7627 rp = &pm->pm_regmap[vr]; 7628 if (rp->rg_segmap == NULL) 7629 panic("%s: CPU %d: CHK(vr %d): nsegmap = %d; sp==NULL", 7630 s, cpu, vr, rp->rg_nsegmap); 7631 if (rp->rg_nsegmap == 0) 7632 continue; 7633 #if defined(SUN4M) || defined(SUN4D) 7634 if (CPU_HAS_SRMMU && rp->rg_seg_ptps == NULL) 7635 panic("%s: CPU %d: CHK(vr %d): nsegmap=%d; no SRMMU segment table", 7636 s, cpu, vr, rp->rg_nsegmap); 7637 7638 if (CPU_HAS_SRMMU && vr != NUREG /* 1st kseg is per CPU */ && 7639 pm->pm_reg_ptps[cpu][vr] != ((VA2PA((void *)rp->rg_seg_ptps) >> 7640 SRMMU_PPNPASHIFT) | SRMMU_TEPTD)) 7641 panic("%s: CPU %d: CHK(vr %d): SRMMU segtbl not installed", 7642 s, cpu, vr); 7643 #endif 7644 if (CPU_HAS_SRMMU) { 7645 n = NSEGRG; 7646 } else { 7647 for (n = 0, vs = 0; vs < NSEGRG; vs++) { 7648 if (rp->rg_segmap[vs].sg_npte) 7649 n++; 7650 } 7651 } 7652 if (n != rp->rg_nsegmap) 7653 printf("%s: CPU %d: kernel CHK(vr %d): inconsistent " 7654 "# of pte's: %d, should be %d\n", 7655 s, cpu, vr, rp->rg_nsegmap, n); 7656 } 7657 return; 7658 } 7659 #endif 7660 7661 /* 7662 * Return the number of disk blocks that pmap_dumpmmu() will dump. 7663 */ 7664 int 7665 pmap_dumpsize(void) 7666 { 7667 int sz; 7668 7669 sz = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t)); 7670 sz += npmemarr * sizeof(phys_ram_seg_t); 7671 sz += sizeof(kernel_segmap_store); 7672 7673 if (CPU_HAS_SUNMMU) 7674 /* For each pmeg in the MMU, we'll write NPTESG PTEs. */ 7675 sz += (seginval + 1) * NPTESG * sizeof(int); 7676 7677 return btodb(sz + DEV_BSIZE - 1); 7678 } 7679 7680 /* 7681 * Write the core dump headers and MD data to the dump device. 7682 * We dump the following items: 7683 * 7684 * kcore_seg_t MI header defined in <sys/kcore.h>) 7685 * cpu_kcore_hdr_t MD header defined in <machine/kcore.h>) 7686 * phys_ram_seg_t[npmemarr] physical memory segments 7687 * segmap_t[NKREG*NSEGRG] the kernel's segment map 7688 * the MMU pmegs on sun4/sun4c 7689 */ 7690 int 7691 pmap_dumpmmu(int (*dump)(dev_t, daddr_t, void *, size_t), 7692 daddr_t blkno) 7693 { 7694 kcore_seg_t *ksegp; 7695 cpu_kcore_hdr_t *kcpup; 7696 phys_ram_seg_t memseg; 7697 int error = 0; 7698 int i, memsegoffset, segmapoffset, pmegoffset; 7699 int buffer[dbtob(1) / sizeof(int)]; 7700 int *bp, *ep; 7701 #if defined(SUN4C) || defined(SUN4) 7702 int pmeg; 7703 #endif 7704 7705 #define EXPEDITE(p,n) do { \ 7706 int *sp = (int *)(p); \ 7707 int sz = (n); \ 7708 while (sz > 0) { \ 7709 *bp++ = *sp++; \ 7710 if (bp >= ep) { \ 7711 error = (*dump)(dumpdev, blkno, \ 7712 (void *)buffer, dbtob(1)); \ 7713 if (error != 0) \ 7714 return (error); \ 7715 ++blkno; \ 7716 bp = buffer; \ 7717 } \ 7718 sz -= 4; \ 7719 } \ 7720 } while (0) 7721 7722 setcontext(0); 7723 7724 /* Setup bookkeeping pointers */ 7725 bp = buffer; 7726 ep = &buffer[sizeof(buffer) / sizeof(buffer[0])]; 7727 7728 /* Fill in MI segment header */ 7729 ksegp = (kcore_seg_t *)bp; 7730 CORE_SETMAGIC(*ksegp, KCORE_MAGIC, MID_MACHINE, CORE_CPU); 7731 ksegp->c_size = dbtob(pmap_dumpsize()) - ALIGN(sizeof(kcore_seg_t)); 7732 7733 /* Fill in MD segment header (interpreted by MD part of libkvm) */ 7734 kcpup = (cpu_kcore_hdr_t *)((int)bp + ALIGN(sizeof(kcore_seg_t))); 7735 kcpup->cputype = cputyp; 7736 kcpup->kernbase = KERNBASE; 7737 kcpup->nmemseg = npmemarr; 7738 kcpup->memsegoffset = memsegoffset = ALIGN(sizeof(cpu_kcore_hdr_t)); 7739 kcpup->nsegmap = NKREG*NSEGRG; 7740 kcpup->segmapoffset = segmapoffset = 7741 memsegoffset + npmemarr * sizeof(phys_ram_seg_t); 7742 7743 kcpup->npmeg = (CPU_HAS_SUNMMU) ? seginval + 1 : 0; 7744 kcpup->pmegoffset = pmegoffset = 7745 segmapoffset + kcpup->nsegmap * sizeof(struct segmap); 7746 7747 /* Note: we have assumed everything fits in buffer[] so far... */ 7748 bp = (int *)((int)kcpup + ALIGN(sizeof(cpu_kcore_hdr_t))); 7749 7750 #if 0 7751 /* Align storage for upcoming quad-aligned segment array */ 7752 while (bp != (int *)ALIGN(bp)) { 7753 int dummy = 0; 7754 EXPEDITE(&dummy, 4); 7755 } 7756 #endif 7757 7758 for (i = 0; i < npmemarr; i++) { 7759 memseg.start = pmemarr[i].addr; 7760 memseg.size = pmemarr[i].len; 7761 EXPEDITE((void *)&memseg, sizeof(phys_ram_seg_t)); 7762 } 7763 7764 EXPEDITE(&kernel_segmap_store, sizeof(kernel_segmap_store)); 7765 7766 if (CPU_HAS_SRMMU) 7767 goto out; 7768 7769 #if defined(SUN4C) || defined(SUN4) 7770 /* 7771 * dump page table entries 7772 * 7773 * We dump each pmeg in order (by segment number). Since the MMU 7774 * automatically maps the given virtual segment to a pmeg we must 7775 * iterate over the segments by incrementing an unused segment slot 7776 * in the MMU. This fixed segment number is used in the virtual 7777 * address argument to getpte(). 7778 */ 7779 7780 /* 7781 * Go through the pmegs and dump each one. 7782 */ 7783 for (pmeg = 0; pmeg <= seginval; ++pmeg) { 7784 int va = 0; 7785 7786 setsegmap(va, pmeg); 7787 i = NPTESG; 7788 do { 7789 int pte = getpte4(va); 7790 EXPEDITE(&pte, sizeof(pte)); 7791 va += NBPG; 7792 } while (--i > 0); 7793 } 7794 setsegmap(0, seginval); 7795 #endif 7796 7797 out: 7798 if (bp != buffer) 7799 error = (*dump)(dumpdev, blkno++, (void *)buffer, dbtob(1)); 7800 7801 return (error); 7802 } 7803 7804 /* 7805 * Helper function for debuggers. 7806 */ 7807 void 7808 pmap_writetext(unsigned char *dst, int ch) 7809 { 7810 int s, pte0, pte, ctx; 7811 vaddr_t va; 7812 7813 s = splvm(); 7814 va = (unsigned long)dst & (~PGOFSET); 7815 cache_flush(dst, 1); 7816 7817 ctx = getcontext(); 7818 setcontext(0); 7819 7820 #if defined(SUN4M) || defined(SUN4D) 7821 if (CPU_HAS_SRMMU) { 7822 pte0 = getpte4m(va); 7823 if ((pte0 & SRMMU_TETYPE) != SRMMU_TEPTE) { 7824 goto out; 7825 } 7826 pte = pte0 | PPROT_WRITE; 7827 setpte4m(va, pte); 7828 *dst = (unsigned char)ch; 7829 setpte4m(va, pte0); 7830 7831 } 7832 #endif 7833 #if defined(SUN4) || defined(SUN4C) 7834 if (CPU_ISSUN4C || CPU_ISSUN4) { 7835 pte0 = getpte4(va); 7836 if ((pte0 & PG_V) == 0) { 7837 goto out; 7838 } 7839 pte = pte0 | PG_W; 7840 setpte4(va, pte); 7841 *dst = (unsigned char)ch; 7842 setpte4(va, pte0); 7843 } 7844 #endif 7845 cache_flush(dst, 1); 7846 7847 out: 7848 setcontext(ctx); 7849 splx(s); 7850 } 7851 7852 #ifdef EXTREME_DEBUG 7853 7854 void debug_pagetables(void); 7855 void print_fe_map(void); 7856 7857 static void test_region(int, int, int); 7858 7859 7860 void 7861 debug_pagetables(void) 7862 { 7863 struct promvec *promvec = romp; 7864 int *regtbl; 7865 int te; 7866 int i; 7867 7868 printf("\nncontext=%d. ", ncontext); 7869 printf("Context table is at va %p. Level 0 PTP: 0x%x\n", 7870 cpuinfo.ctx_tbl, cpuinfo.ctx_tbl[0]); 7871 printf("Context 0 region table is at va %p, pa 0x%x. Contents:\n", 7872 pmap_kernel()->pm_reg_ptps[0], pmap_kernel()->pm_reg_ptps_pa[0]); 7873 7874 regtbl = pmap_kernel()->pm_reg_ptps[0]; 7875 7876 printf("PROM vector is at %p\n", promvec); 7877 printf("PROM reboot routine is at %p\n", promvec->pv_reboot); 7878 printf("PROM abort routine is at %p\n", promvec->pv_abort); 7879 printf("PROM halt routine is at %p\n", promvec->pv_halt); 7880 7881 printf("Testing region 0xfe: "); 7882 test_region(0xfe,0,16*1024*1024); 7883 printf("Testing region 0xff: "); 7884 test_region(0xff,0,16*1024*1024); 7885 printf("Testing kernel region 0x%x: ", VA_VREG(KERNBASE)); 7886 test_region(VA_VREG(KERNBASE), 4096, avail_start); 7887 cngetc(); 7888 7889 for (i = 0; i < SRMMU_L1SIZE; i++) { 7890 te = regtbl[i]; 7891 if ((te & SRMMU_TETYPE) == SRMMU_TEINVALID) 7892 continue; 7893 printf("Region 0x%x: PTE=0x%x <%s> L2PA=0x%x kernL2VA=%p\n", 7894 i, te, ((te & SRMMU_TETYPE) == SRMMU_TEPTE ? "pte" : 7895 ((te & SRMMU_TETYPE) == SRMMU_TEPTD ? "ptd" : 7896 ((te & SRMMU_TETYPE) == SRMMU_TEINVALID ? 7897 "invalid" : "reserved"))), 7898 (te & ~0x3) << SRMMU_PPNPASHIFT, 7899 pmap_kernel()->pm_regmap[i].rg_seg_ptps); 7900 } 7901 printf("Press q to halt...\n"); 7902 if (cngetc()=='q') 7903 callrom(); 7904 } 7905 7906 static u_int 7907 VA2PAsw(int ctx, void *addr, int *pte) 7908 { 7909 int *curtbl; 7910 int curpte; 7911 7912 #ifdef EXTREME_EXTREME_DEBUG 7913 printf("Looking up addr 0x%x in context 0x%x\n",addr,ctx); 7914 #endif 7915 /* L0 */ 7916 *pte = curpte = cpuinfo.ctx_tbl[ctx]; 7917 #ifdef EXTREME_EXTREME_DEBUG 7918 printf("Got L0 pte 0x%x\n",pte); 7919 #endif 7920 if ((curpte & SRMMU_TETYPE) == SRMMU_TEPTE) { 7921 return (((curpte & SRMMU_PPNMASK) << SRMMU_PPNPASHIFT) | 7922 ((u_int)addr & 0xffffffff)); 7923 } 7924 if ((curpte & SRMMU_TETYPE) != SRMMU_TEPTD) { 7925 printf("Bad context table entry 0x%x for context 0x%x\n", 7926 curpte, ctx); 7927 return 0; 7928 } 7929 /* L1 */ 7930 curtbl = (int *)(((curpte & ~0x3) << 4) | KERNBASE); /* correct for krn */ 7931 *pte = curpte = curtbl[VA_VREG(addr)]; 7932 #ifdef EXTREME_EXTREME_DEBUG 7933 printf("L1 table at 0x%x.\nGot L1 pte 0x%x\n",curtbl,curpte); 7934 #endif 7935 if ((curpte & SRMMU_TETYPE) == SRMMU_TEPTE) 7936 return (((curpte & SRMMU_PPNMASK) << SRMMU_PPNPASHIFT) | 7937 ((u_int)addr & 0xffffff)); 7938 if ((curpte & SRMMU_TETYPE) != SRMMU_TEPTD) { 7939 printf("Bad region table entry 0x%x for region 0x%x\n", 7940 curpte, VA_VREG(addr)); 7941 return 0; 7942 } 7943 /* L2 */ 7944 curtbl = (int *)(((curpte & ~0x3) << 4) | KERNBASE); /* correct for krn */ 7945 *pte = curpte = curtbl[VA_VSEG(addr)]; 7946 #ifdef EXTREME_EXTREME_DEBUG 7947 printf("L2 table at 0x%x.\nGot L2 pte 0x%x\n",curtbl,curpte); 7948 #endif 7949 if ((curpte & SRMMU_TETYPE) == SRMMU_TEPTE) 7950 return (((curpte & SRMMU_PPNMASK) << SRMMU_PPNPASHIFT) | 7951 ((u_int)addr & 0x3ffff)); 7952 if ((curpte & SRMMU_TETYPE) != SRMMU_TEPTD) { 7953 printf("Bad segment table entry 0x%x for reg 0x%x, seg 0x%x\n", 7954 curpte, VA_VREG(addr), VA_VSEG(addr)); 7955 return 0; 7956 } 7957 /* L3 */ 7958 curtbl = (int *)(((curpte & ~0x3) << 4) | KERNBASE); /* correct for krn */ 7959 *pte = curpte = curtbl[VA_VPG(addr)]; 7960 #ifdef EXTREME_EXTREME_DEBUG 7961 printf("L3 table at %p.\nGot L3 pte 0x%x\n", curtbl, curpte); 7962 #endif 7963 if ((curpte & SRMMU_TETYPE) == SRMMU_TEPTE) 7964 return (((curpte & SRMMU_PPNMASK) << SRMMU_PPNPASHIFT) | 7965 ((u_int)addr & 0xfff)); 7966 else { 7967 printf("Bad L3 pte 0x%x for reg 0x%x, seg 0x%x, pg 0x%x\n", 7968 curpte, VA_VREG(addr), VA_VSEG(addr), VA_VPG(addr)); 7969 return 0; 7970 } 7971 printf("Bizarreness with address %p!\n", addr); 7972 } 7973 7974 static void 7975 test_region(int reg, int start, int stop) 7976 { 7977 int i; 7978 int addr; 7979 int pte; 7980 int ptesw; 7981 /* int cnt=0; 7982 */ 7983 7984 for (i = start; i < stop; i += NBPG) { 7985 addr = (reg << RGSHIFT) | i; 7986 pte = lda(((u_int)(addr)) | ASI_SRMMUFP_LN, ASI_SRMMUFP); 7987 if (pte) { 7988 /* printf("Valid address 0x%x\n",addr); 7989 if (++cnt == 20) { 7990 cngetc(); 7991 cnt = 0; 7992 } 7993 */ 7994 if (VA2PA((void *)addr) != VA2PAsw(0, (void *)addr, &ptesw)) { 7995 printf("Mismatch at address 0x%x.\n", addr); 7996 if (cngetc() == 'q') 7997 break; 7998 } 7999 if (reg == VA_VREG(KERNBASE)) 8000 /* kernel permissions are different */ 8001 continue; 8002 if ((pte & SRMMU_PROT_MASK) != (ptesw & SRMMU_PROT_MASK)) { 8003 printf("Mismatched protections at address " 8004 "0x%x; pte=0x%x, ptesw=0x%x\n", 8005 addr, pte, ptesw); 8006 if (cngetc() == 'q') 8007 break; 8008 } 8009 } 8010 } 8011 printf("done.\n"); 8012 } 8013 8014 8015 void 8016 print_fe_map(void) 8017 { 8018 u_int i, pte; 8019 8020 printf("map of region 0xfe:\n"); 8021 for (i = 0xfe000000; i < 0xff000000; i += 4096) { 8022 if (((pte = getpte4m(i)) & SRMMU_TETYPE) != SRMMU_TEPTE) 8023 continue; 8024 printf("0x%x -> 0x%x%x (pte 0x%x)\n", i, pte >> 28, 8025 (pte & ~0xff) << 4, pte); 8026 } 8027 printf("done\n"); 8028 } 8029 #endif /* EXTREME_DEBUG */ 8030 8031 #ifdef DDB 8032 int pmap_dump(struct pmap *pm); 8033 8034 int 8035 pmap_dump(struct pmap *pm) 8036 { 8037 int startvr, endvr, vr, vs, i, n; 8038 struct regmap *rp; 8039 struct segmap *sp; 8040 8041 if (pm == NULL) 8042 pm = pmap_kernel(); 8043 8044 if (pm == pmap_kernel()) { 8045 startvr = NUREG; 8046 endvr = 256; 8047 } else { 8048 startvr = 0; 8049 endvr = NUREG; 8050 } 8051 8052 for (vr = startvr; vr < endvr; vr++) { 8053 rp = &pm->pm_regmap[vr]; 8054 if (rp->rg_nsegmap == 0) 8055 continue; 8056 printf("vr %d: %d segments", vr, rp->rg_nsegmap); 8057 if (rp->rg_segmap == NULL) { 8058 printf("[no segments]\n"); 8059 continue; 8060 } 8061 for (vs = 0; vs < NSEGRG; vs++) { 8062 sp = &rp->rg_segmap[vs]; 8063 if (sp->sg_npte == 0) 8064 continue; 8065 if ((vs & 3) == 0) 8066 printf("\n "); 8067 printf(" %d: n %d w %d p %d,", vs, 8068 sp->sg_npte, sp->sg_nwired, sp->sg_pmeg); 8069 if (sp->sg_pte == NULL) { 8070 printf("[no ptes]"); 8071 continue; 8072 } 8073 for (n = 0, i = 0; i < NPTESG; i++) { 8074 if (CPU_HAS_SUNMMU && sp->sg_pte[i] & PG_WIRED) 8075 n++; 8076 if (CPU_HAS_SRMMU && sp->sg_wiremap & (1 << i)) 8077 n++; 8078 } 8079 if (n != sp->sg_nwired) 8080 printf("[wired count %d]", n); 8081 } 8082 printf("\n"); 8083 } 8084 8085 return (0); 8086 } 8087 #endif /* DDB */ 8088