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