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