1 /* $NetBSD: pmap.c,v 1.65 2009/04/21 21:29:59 cegger Exp $ */ 2 /*- 3 * Copyright (c) 2001 The NetBSD Foundation, Inc. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to The NetBSD Foundation 7 * by Matt Thomas <matt@3am-software.com> of Allegro Networks, Inc. 8 * 9 * Support for PPC64 Bridge mode added by Sanjay Lal <sanjayl@kymasys.com> 10 * of Kyma Systems LLC. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 36 * Copyright (C) 1995, 1996 TooLs GmbH. 37 * All rights reserved. 38 * 39 * Redistribution and use in source and binary forms, with or without 40 * modification, are permitted provided that the following conditions 41 * are met: 42 * 1. Redistributions of source code must retain the above copyright 43 * notice, this list of conditions and the following disclaimer. 44 * 2. Redistributions in binary form must reproduce the above copyright 45 * notice, this list of conditions and the following disclaimer in the 46 * documentation and/or other materials provided with the distribution. 47 * 3. All advertising materials mentioning features or use of this software 48 * must display the following acknowledgement: 49 * This product includes software developed by TooLs GmbH. 50 * 4. The name of TooLs GmbH may not be used to endorse or promote products 51 * derived from this software without specific prior written permission. 52 * 53 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 54 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 55 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 56 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 57 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 58 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 59 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 60 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 61 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 62 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 63 */ 64 65 #include <sys/cdefs.h> 66 __KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.65 2009/04/21 21:29:59 cegger Exp $"); 67 68 #define PMAP_NOOPNAMES 69 70 #include "opt_ppcarch.h" 71 #include "opt_altivec.h" 72 #include "opt_multiprocessor.h" 73 #include "opt_pmap.h" 74 75 #include <sys/param.h> 76 #include <sys/malloc.h> 77 #include <sys/proc.h> 78 #include <sys/user.h> 79 #include <sys/pool.h> 80 #include <sys/queue.h> 81 #include <sys/device.h> /* for evcnt */ 82 #include <sys/systm.h> 83 #include <sys/atomic.h> 84 85 #include <uvm/uvm.h> 86 87 #include <machine/pcb.h> 88 #include <machine/powerpc.h> 89 #include <powerpc/spr.h> 90 #include <powerpc/oea/sr_601.h> 91 #include <powerpc/bat.h> 92 #include <powerpc/stdarg.h> 93 94 #ifdef ALTIVEC 95 int pmap_use_altivec; 96 #endif 97 98 volatile struct pteg *pmap_pteg_table; 99 unsigned int pmap_pteg_cnt; 100 unsigned int pmap_pteg_mask; 101 #ifdef PMAP_MEMLIMIT 102 static paddr_t pmap_memlimit = PMAP_MEMLIMIT; 103 #else 104 static paddr_t pmap_memlimit = -PAGE_SIZE; /* there is no limit */ 105 #endif 106 107 struct pmap kernel_pmap_; 108 unsigned int pmap_pages_stolen; 109 u_long pmap_pte_valid; 110 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK) 111 u_long pmap_pvo_enter_depth; 112 u_long pmap_pvo_remove_depth; 113 #endif 114 115 int physmem; 116 #ifndef MSGBUFADDR 117 extern paddr_t msgbuf_paddr; 118 #endif 119 120 static struct mem_region *mem, *avail; 121 static u_int mem_cnt, avail_cnt; 122 123 #if !defined(PMAP_OEA64) && !defined(PMAP_OEA64_BRIDGE) 124 # define PMAP_OEA 1 125 # if defined(PMAP_EXCLUDE_DECLS) && !defined(PPC_OEA64) && !defined(PPC_OEA64_BRIDGE) 126 # define PMAPNAME(name) pmap_##name 127 # endif 128 #endif 129 130 #if defined(PMAP_OEA64) 131 # if defined(PMAP_EXCLUDE_DECLS) && !defined(PPC_OEA) && !defined(PPC_OEA64_BRIDGE) 132 # define PMAPNAME(name) pmap_##name 133 # endif 134 #endif 135 136 #if defined(PMAP_OEA64_BRIDGE) 137 # if defined(PMAP_EXCLUDE_DECLS) && !defined(PPC_OEA) && !defined(PPC_OEA64) 138 # define PMAPNAME(name) pmap_##name 139 # endif 140 #endif 141 142 #if defined(PMAP_OEA) 143 #define _PRIxpte "lx" 144 #else 145 #define _PRIxpte PRIx64 146 #endif 147 #define _PRIxpa "lx" 148 #define _PRIxva "lx" 149 #define _PRIsr "lx" 150 151 #if defined(PMAP_EXCLUDE_DECLS) && !defined(PMAPNAME) 152 #if defined(PMAP_OEA) 153 #define PMAPNAME(name) pmap32_##name 154 #elif defined(PMAP_OEA64) 155 #define PMAPNAME(name) pmap64_##name 156 #elif defined(PMAP_OEA64_BRIDGE) 157 #define PMAPNAME(name) pmap64bridge_##name 158 #else 159 #error unknown variant for pmap 160 #endif 161 #endif /* PMAP_EXLCUDE_DECLS && !PMAPNAME */ 162 163 #if defined(PMAPNAME) 164 #define STATIC static 165 #define pmap_pte_spill PMAPNAME(pte_spill) 166 #define pmap_real_memory PMAPNAME(real_memory) 167 #define pmap_init PMAPNAME(init) 168 #define pmap_virtual_space PMAPNAME(virtual_space) 169 #define pmap_create PMAPNAME(create) 170 #define pmap_reference PMAPNAME(reference) 171 #define pmap_destroy PMAPNAME(destroy) 172 #define pmap_copy PMAPNAME(copy) 173 #define pmap_update PMAPNAME(update) 174 #define pmap_collect PMAPNAME(collect) 175 #define pmap_enter PMAPNAME(enter) 176 #define pmap_remove PMAPNAME(remove) 177 #define pmap_kenter_pa PMAPNAME(kenter_pa) 178 #define pmap_kremove PMAPNAME(kremove) 179 #define pmap_extract PMAPNAME(extract) 180 #define pmap_protect PMAPNAME(protect) 181 #define pmap_unwire PMAPNAME(unwire) 182 #define pmap_page_protect PMAPNAME(page_protect) 183 #define pmap_query_bit PMAPNAME(query_bit) 184 #define pmap_clear_bit PMAPNAME(clear_bit) 185 186 #define pmap_activate PMAPNAME(activate) 187 #define pmap_deactivate PMAPNAME(deactivate) 188 189 #define pmap_pinit PMAPNAME(pinit) 190 #define pmap_procwr PMAPNAME(procwr) 191 192 #if defined(DEBUG) || defined(PMAPCHECK) || defined(DDB) 193 #define pmap_pte_print PMAPNAME(pte_print) 194 #define pmap_pteg_check PMAPNAME(pteg_check) 195 #define pmap_print_mmruregs PMAPNAME(print_mmuregs) 196 #define pmap_print_pte PMAPNAME(print_pte) 197 #define pmap_pteg_dist PMAPNAME(pteg_dist) 198 #endif 199 #if defined(DEBUG) || defined(PMAPCHECK) 200 #define pmap_pvo_verify PMAPNAME(pvo_verify) 201 #define pmapcheck PMAPNAME(check) 202 #endif 203 #if defined(DEBUG) || defined(PMAPDEBUG) 204 #define pmapdebug PMAPNAME(debug) 205 #endif 206 #define pmap_steal_memory PMAPNAME(steal_memory) 207 #define pmap_bootstrap PMAPNAME(bootstrap) 208 #else 209 #define STATIC /* nothing */ 210 #endif /* PMAPNAME */ 211 212 STATIC int pmap_pte_spill(struct pmap *, vaddr_t, bool); 213 STATIC void pmap_real_memory(paddr_t *, psize_t *); 214 STATIC void pmap_init(void); 215 STATIC void pmap_virtual_space(vaddr_t *, vaddr_t *); 216 STATIC pmap_t pmap_create(void); 217 STATIC void pmap_reference(pmap_t); 218 STATIC void pmap_destroy(pmap_t); 219 STATIC void pmap_copy(pmap_t, pmap_t, vaddr_t, vsize_t, vaddr_t); 220 STATIC void pmap_update(pmap_t); 221 STATIC void pmap_collect(pmap_t); 222 STATIC int pmap_enter(pmap_t, vaddr_t, paddr_t, vm_prot_t, u_int); 223 STATIC void pmap_remove(pmap_t, vaddr_t, vaddr_t); 224 STATIC void pmap_kenter_pa(vaddr_t, paddr_t, vm_prot_t); 225 STATIC void pmap_kremove(vaddr_t, vsize_t); 226 STATIC bool pmap_extract(pmap_t, vaddr_t, paddr_t *); 227 228 STATIC void pmap_protect(pmap_t, vaddr_t, vaddr_t, vm_prot_t); 229 STATIC void pmap_unwire(pmap_t, vaddr_t); 230 STATIC void pmap_page_protect(struct vm_page *, vm_prot_t); 231 STATIC bool pmap_query_bit(struct vm_page *, int); 232 STATIC bool pmap_clear_bit(struct vm_page *, int); 233 234 STATIC void pmap_activate(struct lwp *); 235 STATIC void pmap_deactivate(struct lwp *); 236 237 STATIC void pmap_pinit(pmap_t pm); 238 STATIC void pmap_procwr(struct proc *, vaddr_t, size_t); 239 240 #if defined(DEBUG) || defined(PMAPCHECK) || defined(DDB) 241 STATIC void pmap_pte_print(volatile struct pte *); 242 STATIC void pmap_pteg_check(void); 243 STATIC void pmap_print_mmuregs(void); 244 STATIC void pmap_print_pte(pmap_t, vaddr_t); 245 STATIC void pmap_pteg_dist(void); 246 #endif 247 #if defined(DEBUG) || defined(PMAPCHECK) 248 STATIC void pmap_pvo_verify(void); 249 #endif 250 STATIC vaddr_t pmap_steal_memory(vsize_t, vaddr_t *, vaddr_t *); 251 STATIC void pmap_bootstrap(paddr_t, paddr_t); 252 253 #ifdef PMAPNAME 254 const struct pmap_ops PMAPNAME(ops) = { 255 .pmapop_pte_spill = pmap_pte_spill, 256 .pmapop_real_memory = pmap_real_memory, 257 .pmapop_init = pmap_init, 258 .pmapop_virtual_space = pmap_virtual_space, 259 .pmapop_create = pmap_create, 260 .pmapop_reference = pmap_reference, 261 .pmapop_destroy = pmap_destroy, 262 .pmapop_copy = pmap_copy, 263 .pmapop_update = pmap_update, 264 .pmapop_collect = pmap_collect, 265 .pmapop_enter = pmap_enter, 266 .pmapop_remove = pmap_remove, 267 .pmapop_kenter_pa = pmap_kenter_pa, 268 .pmapop_kremove = pmap_kremove, 269 .pmapop_extract = pmap_extract, 270 .pmapop_protect = pmap_protect, 271 .pmapop_unwire = pmap_unwire, 272 .pmapop_page_protect = pmap_page_protect, 273 .pmapop_query_bit = pmap_query_bit, 274 .pmapop_clear_bit = pmap_clear_bit, 275 .pmapop_activate = pmap_activate, 276 .pmapop_deactivate = pmap_deactivate, 277 .pmapop_pinit = pmap_pinit, 278 .pmapop_procwr = pmap_procwr, 279 #if defined(DEBUG) || defined(PMAPCHECK) || defined(DDB) 280 .pmapop_pte_print = pmap_pte_print, 281 .pmapop_pteg_check = pmap_pteg_check, 282 .pmapop_print_mmuregs = pmap_print_mmuregs, 283 .pmapop_print_pte = pmap_print_pte, 284 .pmapop_pteg_dist = pmap_pteg_dist, 285 #else 286 .pmapop_pte_print = NULL, 287 .pmapop_pteg_check = NULL, 288 .pmapop_print_mmuregs = NULL, 289 .pmapop_print_pte = NULL, 290 .pmapop_pteg_dist = NULL, 291 #endif 292 #if defined(DEBUG) || defined(PMAPCHECK) 293 .pmapop_pvo_verify = pmap_pvo_verify, 294 #else 295 .pmapop_pvo_verify = NULL, 296 #endif 297 .pmapop_steal_memory = pmap_steal_memory, 298 .pmapop_bootstrap = pmap_bootstrap, 299 }; 300 #endif /* !PMAPNAME */ 301 302 /* 303 * The following structure is aligned to 32 bytes 304 */ 305 struct pvo_entry { 306 LIST_ENTRY(pvo_entry) pvo_vlink; /* Link to common virt page */ 307 TAILQ_ENTRY(pvo_entry) pvo_olink; /* Link to overflow entry */ 308 struct pte pvo_pte; /* Prebuilt PTE */ 309 pmap_t pvo_pmap; /* ptr to owning pmap */ 310 vaddr_t pvo_vaddr; /* VA of entry */ 311 #define PVO_PTEGIDX_MASK 0x0007 /* which PTEG slot */ 312 #define PVO_PTEGIDX_VALID 0x0008 /* slot is valid */ 313 #define PVO_WIRED 0x0010 /* PVO entry is wired */ 314 #define PVO_MANAGED 0x0020 /* PVO e. for managed page */ 315 #define PVO_EXECUTABLE 0x0040 /* PVO e. for executable page */ 316 #define PVO_WIRED_P(pvo) ((pvo)->pvo_vaddr & PVO_WIRED) 317 #define PVO_MANAGED_P(pvo) ((pvo)->pvo_vaddr & PVO_MANAGED) 318 #define PVO_EXECUTABLE_P(pvo) ((pvo)->pvo_vaddr & PVO_EXECUTABLE) 319 #define PVO_ENTER_INSERT 0 /* PVO has been removed */ 320 #define PVO_SPILL_UNSET 1 /* PVO has been evicted */ 321 #define PVO_SPILL_SET 2 /* PVO has been spilled */ 322 #define PVO_SPILL_INSERT 3 /* PVO has been inserted */ 323 #define PVO_PMAP_PAGE_PROTECT 4 /* PVO has changed */ 324 #define PVO_PMAP_PROTECT 5 /* PVO has changed */ 325 #define PVO_REMOVE 6 /* PVO has been removed */ 326 #define PVO_WHERE_MASK 15 327 #define PVO_WHERE_SHFT 8 328 } __attribute__ ((aligned (32))); 329 #define PVO_VADDR(pvo) ((pvo)->pvo_vaddr & ~ADDR_POFF) 330 #define PVO_PTEGIDX_GET(pvo) ((pvo)->pvo_vaddr & PVO_PTEGIDX_MASK) 331 #define PVO_PTEGIDX_ISSET(pvo) ((pvo)->pvo_vaddr & PVO_PTEGIDX_VALID) 332 #define PVO_PTEGIDX_CLR(pvo) \ 333 ((void)((pvo)->pvo_vaddr &= ~(PVO_PTEGIDX_VALID|PVO_PTEGIDX_MASK))) 334 #define PVO_PTEGIDX_SET(pvo,i) \ 335 ((void)((pvo)->pvo_vaddr |= (i)|PVO_PTEGIDX_VALID)) 336 #define PVO_WHERE(pvo,w) \ 337 ((pvo)->pvo_vaddr &= ~(PVO_WHERE_MASK << PVO_WHERE_SHFT), \ 338 (pvo)->pvo_vaddr |= ((PVO_ ## w) << PVO_WHERE_SHFT)) 339 340 TAILQ_HEAD(pvo_tqhead, pvo_entry); 341 struct pvo_tqhead *pmap_pvo_table; /* pvo entries by ptegroup index */ 342 static struct pvo_head pmap_pvo_kunmanaged = LIST_HEAD_INITIALIZER(pmap_pvo_kunmanaged); /* list of unmanaged pages */ 343 static struct pvo_head pmap_pvo_unmanaged = LIST_HEAD_INITIALIZER(pmap_pvo_unmanaged); /* list of unmanaged pages */ 344 345 struct pool pmap_pool; /* pool for pmap structures */ 346 struct pool pmap_upvo_pool; /* pool for pvo entries for unmanaged pages */ 347 struct pool pmap_mpvo_pool; /* pool for pvo entries for managed pages */ 348 349 /* 350 * We keep a cache of unmanaged pages to be used for pvo entries for 351 * unmanaged pages. 352 */ 353 struct pvo_page { 354 SIMPLEQ_ENTRY(pvo_page) pvop_link; 355 }; 356 SIMPLEQ_HEAD(pvop_head, pvo_page); 357 static struct pvop_head pmap_upvop_head = SIMPLEQ_HEAD_INITIALIZER(pmap_upvop_head); 358 static struct pvop_head pmap_mpvop_head = SIMPLEQ_HEAD_INITIALIZER(pmap_mpvop_head); 359 u_long pmap_upvop_free; 360 u_long pmap_upvop_maxfree; 361 u_long pmap_mpvop_free; 362 u_long pmap_mpvop_maxfree; 363 364 static void *pmap_pool_ualloc(struct pool *, int); 365 static void *pmap_pool_malloc(struct pool *, int); 366 367 static void pmap_pool_ufree(struct pool *, void *); 368 static void pmap_pool_mfree(struct pool *, void *); 369 370 static struct pool_allocator pmap_pool_mallocator = { 371 .pa_alloc = pmap_pool_malloc, 372 .pa_free = pmap_pool_mfree, 373 .pa_pagesz = 0, 374 }; 375 376 static struct pool_allocator pmap_pool_uallocator = { 377 .pa_alloc = pmap_pool_ualloc, 378 .pa_free = pmap_pool_ufree, 379 .pa_pagesz = 0, 380 }; 381 382 #if defined(DEBUG) || defined(PMAPCHECK) || defined(DDB) 383 void pmap_pte_print(volatile struct pte *); 384 void pmap_pteg_check(void); 385 void pmap_pteg_dist(void); 386 void pmap_print_pte(pmap_t, vaddr_t); 387 void pmap_print_mmuregs(void); 388 #endif 389 390 #if defined(DEBUG) || defined(PMAPCHECK) 391 #ifdef PMAPCHECK 392 int pmapcheck = 1; 393 #else 394 int pmapcheck = 0; 395 #endif 396 void pmap_pvo_verify(void); 397 static void pmap_pvo_check(const struct pvo_entry *); 398 #define PMAP_PVO_CHECK(pvo) \ 399 do { \ 400 if (pmapcheck) \ 401 pmap_pvo_check(pvo); \ 402 } while (0) 403 #else 404 #define PMAP_PVO_CHECK(pvo) do { } while (/*CONSTCOND*/0) 405 #endif 406 static int pmap_pte_insert(int, struct pte *); 407 static int pmap_pvo_enter(pmap_t, struct pool *, struct pvo_head *, 408 vaddr_t, paddr_t, register_t, int); 409 static void pmap_pvo_remove(struct pvo_entry *, int, struct pvo_head *); 410 static void pmap_pvo_free(struct pvo_entry *); 411 static void pmap_pvo_free_list(struct pvo_head *); 412 static struct pvo_entry *pmap_pvo_find_va(pmap_t, vaddr_t, int *); 413 static volatile struct pte *pmap_pvo_to_pte(const struct pvo_entry *, int); 414 static struct pvo_entry *pmap_pvo_reclaim(struct pmap *); 415 static void pvo_set_exec(struct pvo_entry *); 416 static void pvo_clear_exec(struct pvo_entry *); 417 418 static void tlbia(void); 419 420 static void pmap_release(pmap_t); 421 static paddr_t pmap_boot_find_memory(psize_t, psize_t, int); 422 423 static uint32_t pmap_pvo_reclaim_nextidx; 424 #ifdef DEBUG 425 static int pmap_pvo_reclaim_debugctr; 426 #endif 427 428 #define VSID_NBPW (sizeof(uint32_t) * 8) 429 static uint32_t pmap_vsid_bitmap[NPMAPS / VSID_NBPW]; 430 431 static int pmap_initialized; 432 433 #if defined(DEBUG) || defined(PMAPDEBUG) 434 #define PMAPDEBUG_BOOT 0x0001 435 #define PMAPDEBUG_PTE 0x0002 436 #define PMAPDEBUG_EXEC 0x0008 437 #define PMAPDEBUG_PVOENTER 0x0010 438 #define PMAPDEBUG_PVOREMOVE 0x0020 439 #define PMAPDEBUG_ACTIVATE 0x0100 440 #define PMAPDEBUG_CREATE 0x0200 441 #define PMAPDEBUG_ENTER 0x1000 442 #define PMAPDEBUG_KENTER 0x2000 443 #define PMAPDEBUG_KREMOVE 0x4000 444 #define PMAPDEBUG_REMOVE 0x8000 445 446 unsigned int pmapdebug = 0; 447 448 # define DPRINTF(x) printf x 449 # define DPRINTFN(n, x) if (pmapdebug & PMAPDEBUG_ ## n) printf x 450 #else 451 # define DPRINTF(x) 452 # define DPRINTFN(n, x) 453 #endif 454 455 456 #ifdef PMAPCOUNTERS 457 /* 458 * From pmap_subr.c 459 */ 460 extern struct evcnt pmap_evcnt_mappings; 461 extern struct evcnt pmap_evcnt_unmappings; 462 463 extern struct evcnt pmap_evcnt_kernel_mappings; 464 extern struct evcnt pmap_evcnt_kernel_unmappings; 465 466 extern struct evcnt pmap_evcnt_mappings_replaced; 467 468 extern struct evcnt pmap_evcnt_exec_mappings; 469 extern struct evcnt pmap_evcnt_exec_cached; 470 471 extern struct evcnt pmap_evcnt_exec_synced; 472 extern struct evcnt pmap_evcnt_exec_synced_clear_modify; 473 extern struct evcnt pmap_evcnt_exec_synced_pvo_remove; 474 475 extern struct evcnt pmap_evcnt_exec_uncached_page_protect; 476 extern struct evcnt pmap_evcnt_exec_uncached_clear_modify; 477 extern struct evcnt pmap_evcnt_exec_uncached_zero_page; 478 extern struct evcnt pmap_evcnt_exec_uncached_copy_page; 479 extern struct evcnt pmap_evcnt_exec_uncached_pvo_remove; 480 481 extern struct evcnt pmap_evcnt_updates; 482 extern struct evcnt pmap_evcnt_collects; 483 extern struct evcnt pmap_evcnt_copies; 484 485 extern struct evcnt pmap_evcnt_ptes_spilled; 486 extern struct evcnt pmap_evcnt_ptes_unspilled; 487 extern struct evcnt pmap_evcnt_ptes_evicted; 488 489 extern struct evcnt pmap_evcnt_ptes_primary[8]; 490 extern struct evcnt pmap_evcnt_ptes_secondary[8]; 491 extern struct evcnt pmap_evcnt_ptes_removed; 492 extern struct evcnt pmap_evcnt_ptes_changed; 493 extern struct evcnt pmap_evcnt_pvos_reclaimed; 494 extern struct evcnt pmap_evcnt_pvos_failed; 495 496 extern struct evcnt pmap_evcnt_zeroed_pages; 497 extern struct evcnt pmap_evcnt_copied_pages; 498 extern struct evcnt pmap_evcnt_idlezeroed_pages; 499 500 #define PMAPCOUNT(ev) ((pmap_evcnt_ ## ev).ev_count++) 501 #define PMAPCOUNT2(ev) ((ev).ev_count++) 502 #else 503 #define PMAPCOUNT(ev) ((void) 0) 504 #define PMAPCOUNT2(ev) ((void) 0) 505 #endif 506 507 #define TLBIE(va) __asm volatile("tlbie %0" :: "r"(va)) 508 509 /* XXXSL: this needs to be moved to assembler */ 510 #define TLBIEL(va) __asm __volatile("tlbie %0" :: "r"(va)) 511 512 #define TLBSYNC() __asm volatile("tlbsync") 513 #define SYNC() __asm volatile("sync") 514 #define EIEIO() __asm volatile("eieio") 515 #define DCBST(va) __asm __volatile("dcbst 0,%0" :: "r"(va)) 516 #define MFMSR() mfmsr() 517 #define MTMSR(psl) mtmsr(psl) 518 #define MFPVR() mfpvr() 519 #define MFSRIN(va) mfsrin(va) 520 #define MFTB() mfrtcltbl() 521 522 #if defined (PMAP_OEA) || defined (PMAP_OEA64_BRIDGE) 523 static inline register_t 524 mfsrin(vaddr_t va) 525 { 526 register_t sr; 527 __asm volatile ("mfsrin %0,%1" : "=r"(sr) : "r"(va)); 528 return sr; 529 } 530 #endif /* PMAP_OEA*/ 531 532 #if defined (PMAP_OEA64_BRIDGE) 533 extern void mfmsr64 (register64_t *result); 534 #endif /* PMAP_OEA64_BRIDGE */ 535 536 #define PMAP_LOCK() KERNEL_LOCK(1, NULL) 537 #define PMAP_UNLOCK() KERNEL_UNLOCK_ONE(NULL) 538 539 static inline register_t 540 pmap_interrupts_off(void) 541 { 542 register_t msr = MFMSR(); 543 if (msr & PSL_EE) 544 MTMSR(msr & ~PSL_EE); 545 return msr; 546 } 547 548 static void 549 pmap_interrupts_restore(register_t msr) 550 { 551 if (msr & PSL_EE) 552 MTMSR(msr); 553 } 554 555 static inline u_int32_t 556 mfrtcltbl(void) 557 { 558 #ifdef PPC_OEA601 559 if ((MFPVR() >> 16) == MPC601) 560 return (mfrtcl() >> 7); 561 else 562 #endif 563 return (mftbl()); 564 } 565 566 /* 567 * These small routines may have to be replaced, 568 * if/when we support processors other that the 604. 569 */ 570 571 void 572 tlbia(void) 573 { 574 char *i; 575 576 SYNC(); 577 #if defined(PMAP_OEA) 578 /* 579 * Why not use "tlbia"? Because not all processors implement it. 580 * 581 * This needs to be a per-CPU callback to do the appropriate thing 582 * for the CPU. XXX 583 */ 584 for (i = 0; i < (char *)0x00040000; i += 0x00001000) { 585 TLBIE(i); 586 EIEIO(); 587 SYNC(); 588 } 589 #elif defined (PMAP_OEA64) || defined (PMAP_OEA64_BRIDGE) 590 /* This is specifically for the 970, 970UM v1.6 pp. 140. */ 591 for (i = 0; i <= (char *)0xFF000; i += 0x00001000) { 592 TLBIEL(i); 593 EIEIO(); 594 SYNC(); 595 } 596 #endif 597 TLBSYNC(); 598 SYNC(); 599 } 600 601 static inline register_t 602 va_to_vsid(const struct pmap *pm, vaddr_t addr) 603 { 604 #if defined (PMAP_OEA) || defined (PMAP_OEA64_BRIDGE) 605 return (pm->pm_sr[addr >> ADDR_SR_SHFT] & SR_VSID) >> SR_VSID_SHFT; 606 #else /* PMAP_OEA64 */ 607 #if 0 608 const struct ste *ste; 609 register_t hash; 610 int i; 611 612 hash = (addr >> ADDR_ESID_SHFT) & ADDR_ESID_HASH; 613 614 /* 615 * Try the primary group first 616 */ 617 ste = pm->pm_stes[hash].stes; 618 for (i = 0; i < 8; i++, ste++) { 619 if (ste->ste_hi & STE_V) && 620 (addr & ~(ADDR_POFF|ADDR_PIDX)) == (ste->ste_hi & STE_ESID)) 621 return ste; 622 } 623 624 /* 625 * Then the secondary group. 626 */ 627 ste = pm->pm_stes[hash ^ ADDR_ESID_HASH].stes; 628 for (i = 0; i < 8; i++, ste++) { 629 if (ste->ste_hi & STE_V) && 630 (addr & ~(ADDR_POFF|ADDR_PIDX)) == (ste->ste_hi & STE_ESID)) 631 return addr; 632 } 633 634 return NULL; 635 #else 636 /* 637 * Rather than searching the STE groups for the VSID, we know 638 * how we generate that from the ESID and so do that. 639 */ 640 return VSID_MAKE(addr >> ADDR_SR_SHFT, pm->pm_vsid) >> SR_VSID_SHFT; 641 #endif 642 #endif /* PMAP_OEA */ 643 } 644 645 static inline register_t 646 va_to_pteg(const struct pmap *pm, vaddr_t addr) 647 { 648 register_t hash; 649 650 hash = va_to_vsid(pm, addr) ^ ((addr & ADDR_PIDX) >> ADDR_PIDX_SHFT); 651 return hash & pmap_pteg_mask; 652 } 653 654 #if defined(DEBUG) || defined(PMAPCHECK) || defined(DDB) 655 /* 656 * Given a PTE in the page table, calculate the VADDR that hashes to it. 657 * The only bit of magic is that the top 4 bits of the address doesn't 658 * technically exist in the PTE. But we know we reserved 4 bits of the 659 * VSID for it so that's how we get it. 660 */ 661 static vaddr_t 662 pmap_pte_to_va(volatile const struct pte *pt) 663 { 664 vaddr_t va; 665 uintptr_t ptaddr = (uintptr_t) pt; 666 667 if (pt->pte_hi & PTE_HID) 668 ptaddr ^= (pmap_pteg_mask * sizeof(struct pteg)); 669 670 /* PPC Bits 10-19 PPC64 Bits 42-51 */ 671 #if defined(PMAP_OEA) 672 va = ((pt->pte_hi >> PTE_VSID_SHFT) ^ (ptaddr / sizeof(struct pteg))) & 0x3ff; 673 #elif defined (PMAP_OEA64) || defined (PMAP_OEA64_BRIDGE) 674 va = ((pt->pte_hi >> PTE_VSID_SHFT) ^ (ptaddr / sizeof(struct pteg))) & 0x7ff; 675 #endif 676 va <<= ADDR_PIDX_SHFT; 677 678 /* PPC Bits 4-9 PPC64 Bits 36-41 */ 679 va |= (pt->pte_hi & PTE_API) << ADDR_API_SHFT; 680 681 #if defined(PMAP_OEA64) 682 /* PPC63 Bits 0-35 */ 683 /* va |= VSID_TO_SR(pt->pte_hi >> PTE_VSID_SHFT) << ADDR_SR_SHFT; */ 684 #elif defined(PMAP_OEA) || defined(PMAP_OEA64_BRIDGE) 685 /* PPC Bits 0-3 */ 686 va |= VSID_TO_SR(pt->pte_hi >> PTE_VSID_SHFT) << ADDR_SR_SHFT; 687 #endif 688 689 return va; 690 } 691 #endif 692 693 static inline struct pvo_head * 694 pa_to_pvoh(paddr_t pa, struct vm_page **pg_p) 695 { 696 struct vm_page *pg; 697 698 pg = PHYS_TO_VM_PAGE(pa); 699 if (pg_p != NULL) 700 *pg_p = pg; 701 if (pg == NULL) 702 return &pmap_pvo_unmanaged; 703 return &pg->mdpage.mdpg_pvoh; 704 } 705 706 static inline struct pvo_head * 707 vm_page_to_pvoh(struct vm_page *pg) 708 { 709 return &pg->mdpage.mdpg_pvoh; 710 } 711 712 713 static inline void 714 pmap_attr_clear(struct vm_page *pg, int ptebit) 715 { 716 pg->mdpage.mdpg_attrs &= ~ptebit; 717 } 718 719 static inline int 720 pmap_attr_fetch(struct vm_page *pg) 721 { 722 return pg->mdpage.mdpg_attrs; 723 } 724 725 static inline void 726 pmap_attr_save(struct vm_page *pg, int ptebit) 727 { 728 pg->mdpage.mdpg_attrs |= ptebit; 729 } 730 731 static inline int 732 pmap_pte_compare(const volatile struct pte *pt, const struct pte *pvo_pt) 733 { 734 if (pt->pte_hi == pvo_pt->pte_hi 735 #if 0 736 && ((pt->pte_lo ^ pvo_pt->pte_lo) & 737 ~(PTE_REF|PTE_CHG)) == 0 738 #endif 739 ) 740 return 1; 741 return 0; 742 } 743 744 static inline void 745 pmap_pte_create(struct pte *pt, const struct pmap *pm, vaddr_t va, register_t pte_lo) 746 { 747 /* 748 * Construct the PTE. Default to IMB initially. Valid bit 749 * only gets set when the real pte is set in memory. 750 * 751 * Note: Don't set the valid bit for correct operation of tlb update. 752 */ 753 #if defined(PMAP_OEA) 754 pt->pte_hi = (va_to_vsid(pm, va) << PTE_VSID_SHFT) 755 | (((va & ADDR_PIDX) >> (ADDR_API_SHFT - PTE_API_SHFT)) & PTE_API); 756 pt->pte_lo = pte_lo; 757 #elif defined (PMAP_OEA64_BRIDGE) 758 pt->pte_hi = ((u_int64_t)va_to_vsid(pm, va) << PTE_VSID_SHFT) 759 | (((va & ADDR_PIDX) >> (ADDR_API_SHFT - PTE_API_SHFT)) & PTE_API); 760 pt->pte_lo = (u_int64_t) pte_lo; 761 #elif defined (PMAP_OEA64) 762 #error PMAP_OEA64 not supported 763 #endif /* PMAP_OEA */ 764 } 765 766 static inline void 767 pmap_pte_synch(volatile struct pte *pt, struct pte *pvo_pt) 768 { 769 pvo_pt->pte_lo |= pt->pte_lo & (PTE_REF|PTE_CHG); 770 } 771 772 static inline void 773 pmap_pte_clear(volatile struct pte *pt, vaddr_t va, int ptebit) 774 { 775 /* 776 * As shown in Section 7.6.3.2.3 777 */ 778 pt->pte_lo &= ~ptebit; 779 TLBIE(va); 780 SYNC(); 781 EIEIO(); 782 TLBSYNC(); 783 SYNC(); 784 #ifdef MULTIPROCESSOR 785 DCBST(pt); 786 #endif 787 } 788 789 static inline void 790 pmap_pte_set(volatile struct pte *pt, struct pte *pvo_pt) 791 { 792 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK) 793 if (pvo_pt->pte_hi & PTE_VALID) 794 panic("pte_set: setting an already valid pte %p", pvo_pt); 795 #endif 796 pvo_pt->pte_hi |= PTE_VALID; 797 798 /* 799 * Update the PTE as defined in section 7.6.3.1 800 * Note that the REF/CHG bits are from pvo_pt and thus should 801 * have been saved so this routine can restore them (if desired). 802 */ 803 pt->pte_lo = pvo_pt->pte_lo; 804 EIEIO(); 805 pt->pte_hi = pvo_pt->pte_hi; 806 TLBSYNC(); 807 SYNC(); 808 #ifdef MULTIPROCESSOR 809 DCBST(pt); 810 #endif 811 pmap_pte_valid++; 812 } 813 814 static inline void 815 pmap_pte_unset(volatile struct pte *pt, struct pte *pvo_pt, vaddr_t va) 816 { 817 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK) 818 if ((pvo_pt->pte_hi & PTE_VALID) == 0) 819 panic("pte_unset: attempt to unset an inactive pte#1 %p/%p", pvo_pt, pt); 820 if ((pt->pte_hi & PTE_VALID) == 0) 821 panic("pte_unset: attempt to unset an inactive pte#2 %p/%p", pvo_pt, pt); 822 #endif 823 824 pvo_pt->pte_hi &= ~PTE_VALID; 825 /* 826 * Force the ref & chg bits back into the PTEs. 827 */ 828 SYNC(); 829 /* 830 * Invalidate the pte ... (Section 7.6.3.3) 831 */ 832 pt->pte_hi &= ~PTE_VALID; 833 SYNC(); 834 TLBIE(va); 835 SYNC(); 836 EIEIO(); 837 TLBSYNC(); 838 SYNC(); 839 /* 840 * Save the ref & chg bits ... 841 */ 842 pmap_pte_synch(pt, pvo_pt); 843 pmap_pte_valid--; 844 } 845 846 static inline void 847 pmap_pte_change(volatile struct pte *pt, struct pte *pvo_pt, vaddr_t va) 848 { 849 /* 850 * Invalidate the PTE 851 */ 852 pmap_pte_unset(pt, pvo_pt, va); 853 pmap_pte_set(pt, pvo_pt); 854 } 855 856 /* 857 * Try to insert the PTE @ *pvo_pt into the pmap_pteg_table at ptegidx 858 * (either primary or secondary location). 859 * 860 * Note: both the destination and source PTEs must not have PTE_VALID set. 861 */ 862 863 static int 864 pmap_pte_insert(int ptegidx, struct pte *pvo_pt) 865 { 866 volatile struct pte *pt; 867 int i; 868 869 #if defined(DEBUG) 870 DPRINTFN(PTE, ("pmap_pte_insert: idx %#x, pte %#" _PRIxpte " %#" _PRIxpte "\n", 871 ptegidx, pvo_pt->pte_hi, pvo_pt->pte_lo)); 872 #endif 873 /* 874 * First try primary hash. 875 */ 876 for (pt = pmap_pteg_table[ptegidx].pt, i = 0; i < 8; i++, pt++) { 877 if ((pt->pte_hi & PTE_VALID) == 0) { 878 pvo_pt->pte_hi &= ~PTE_HID; 879 pmap_pte_set(pt, pvo_pt); 880 return i; 881 } 882 } 883 884 /* 885 * Now try secondary hash. 886 */ 887 ptegidx ^= pmap_pteg_mask; 888 for (pt = pmap_pteg_table[ptegidx].pt, i = 0; i < 8; i++, pt++) { 889 if ((pt->pte_hi & PTE_VALID) == 0) { 890 pvo_pt->pte_hi |= PTE_HID; 891 pmap_pte_set(pt, pvo_pt); 892 return i; 893 } 894 } 895 return -1; 896 } 897 898 /* 899 * Spill handler. 900 * 901 * Tries to spill a page table entry from the overflow area. 902 * This runs in either real mode (if dealing with a exception spill) 903 * or virtual mode when dealing with manually spilling one of the 904 * kernel's pte entries. In either case, interrupts are already 905 * disabled. 906 */ 907 908 int 909 pmap_pte_spill(struct pmap *pm, vaddr_t addr, bool exec) 910 { 911 struct pvo_entry *source_pvo, *victim_pvo, *next_pvo; 912 struct pvo_entry *pvo; 913 /* XXX: gcc -- vpvoh is always set at either *1* or *2* */ 914 struct pvo_tqhead *pvoh, *vpvoh = NULL; 915 int ptegidx, i, j; 916 volatile struct pteg *pteg; 917 volatile struct pte *pt; 918 919 PMAP_LOCK(); 920 921 ptegidx = va_to_pteg(pm, addr); 922 923 /* 924 * Have to substitute some entry. Use the primary hash for this. 925 * Use low bits of timebase as random generator. Make sure we are 926 * not picking a kernel pte for replacement. 927 */ 928 pteg = &pmap_pteg_table[ptegidx]; 929 i = MFTB() & 7; 930 for (j = 0; j < 8; j++) { 931 pt = &pteg->pt[i]; 932 if ((pt->pte_hi & PTE_VALID) == 0) 933 break; 934 if (VSID_TO_HASH((pt->pte_hi & PTE_VSID) >> PTE_VSID_SHFT) 935 < PHYSMAP_VSIDBITS) 936 break; 937 i = (i + 1) & 7; 938 } 939 KASSERT(j < 8); 940 941 source_pvo = NULL; 942 victim_pvo = NULL; 943 pvoh = &pmap_pvo_table[ptegidx]; 944 TAILQ_FOREACH(pvo, pvoh, pvo_olink) { 945 946 /* 947 * We need to find pvo entry for this address... 948 */ 949 PMAP_PVO_CHECK(pvo); /* sanity check */ 950 951 /* 952 * If we haven't found the source and we come to a PVO with 953 * a valid PTE, then we know we can't find it because all 954 * evicted PVOs always are first in the list. 955 */ 956 if (source_pvo == NULL && (pvo->pvo_pte.pte_hi & PTE_VALID)) 957 break; 958 if (source_pvo == NULL && pm == pvo->pvo_pmap && 959 addr == PVO_VADDR(pvo)) { 960 961 /* 962 * Now we have found the entry to be spilled into the 963 * pteg. Attempt to insert it into the page table. 964 */ 965 j = pmap_pte_insert(ptegidx, &pvo->pvo_pte); 966 if (j >= 0) { 967 PVO_PTEGIDX_SET(pvo, j); 968 PMAP_PVO_CHECK(pvo); /* sanity check */ 969 PVO_WHERE(pvo, SPILL_INSERT); 970 pvo->pvo_pmap->pm_evictions--; 971 PMAPCOUNT(ptes_spilled); 972 PMAPCOUNT2(((pvo->pvo_pte.pte_hi & PTE_HID) 973 ? pmap_evcnt_ptes_secondary 974 : pmap_evcnt_ptes_primary)[j]); 975 976 /* 977 * Since we keep the evicted entries at the 978 * from of the PVO list, we need move this 979 * (now resident) PVO after the evicted 980 * entries. 981 */ 982 next_pvo = TAILQ_NEXT(pvo, pvo_olink); 983 984 /* 985 * If we don't have to move (either we were the 986 * last entry or the next entry was valid), 987 * don't change our position. Otherwise 988 * move ourselves to the tail of the queue. 989 */ 990 if (next_pvo != NULL && 991 !(next_pvo->pvo_pte.pte_hi & PTE_VALID)) { 992 TAILQ_REMOVE(pvoh, pvo, pvo_olink); 993 TAILQ_INSERT_TAIL(pvoh, pvo, pvo_olink); 994 } 995 PMAP_UNLOCK(); 996 return 1; 997 } 998 source_pvo = pvo; 999 if (exec && !PVO_EXECUTABLE_P(source_pvo)) { 1000 return 0; 1001 } 1002 if (victim_pvo != NULL) 1003 break; 1004 } 1005 1006 /* 1007 * We also need the pvo entry of the victim we are replacing 1008 * so save the R & C bits of the PTE. 1009 */ 1010 if ((pt->pte_hi & PTE_HID) == 0 && victim_pvo == NULL && 1011 pmap_pte_compare(pt, &pvo->pvo_pte)) { 1012 vpvoh = pvoh; /* *1* */ 1013 victim_pvo = pvo; 1014 if (source_pvo != NULL) 1015 break; 1016 } 1017 } 1018 1019 if (source_pvo == NULL) { 1020 PMAPCOUNT(ptes_unspilled); 1021 PMAP_UNLOCK(); 1022 return 0; 1023 } 1024 1025 if (victim_pvo == NULL) { 1026 if ((pt->pte_hi & PTE_HID) == 0) 1027 panic("pmap_pte_spill: victim p-pte (%p) has " 1028 "no pvo entry!", pt); 1029 1030 /* 1031 * If this is a secondary PTE, we need to search 1032 * its primary pvo bucket for the matching PVO. 1033 */ 1034 vpvoh = &pmap_pvo_table[ptegidx ^ pmap_pteg_mask]; /* *2* */ 1035 TAILQ_FOREACH(pvo, vpvoh, pvo_olink) { 1036 PMAP_PVO_CHECK(pvo); /* sanity check */ 1037 1038 /* 1039 * We also need the pvo entry of the victim we are 1040 * replacing so save the R & C bits of the PTE. 1041 */ 1042 if (pmap_pte_compare(pt, &pvo->pvo_pte)) { 1043 victim_pvo = pvo; 1044 break; 1045 } 1046 } 1047 if (victim_pvo == NULL) 1048 panic("pmap_pte_spill: victim s-pte (%p) has " 1049 "no pvo entry!", pt); 1050 } 1051 1052 /* 1053 * The victim should be not be a kernel PVO/PTE entry. 1054 */ 1055 KASSERT(victim_pvo->pvo_pmap != pmap_kernel()); 1056 KASSERT(PVO_PTEGIDX_ISSET(victim_pvo)); 1057 KASSERT(PVO_PTEGIDX_GET(victim_pvo) == i); 1058 1059 /* 1060 * We are invalidating the TLB entry for the EA for the 1061 * we are replacing even though its valid; If we don't 1062 * we lose any ref/chg bit changes contained in the TLB 1063 * entry. 1064 */ 1065 source_pvo->pvo_pte.pte_hi &= ~PTE_HID; 1066 1067 /* 1068 * To enforce the PVO list ordering constraint that all 1069 * evicted entries should come before all valid entries, 1070 * move the source PVO to the tail of its list and the 1071 * victim PVO to the head of its list (which might not be 1072 * the same list, if the victim was using the secondary hash). 1073 */ 1074 TAILQ_REMOVE(pvoh, source_pvo, pvo_olink); 1075 TAILQ_INSERT_TAIL(pvoh, source_pvo, pvo_olink); 1076 TAILQ_REMOVE(vpvoh, victim_pvo, pvo_olink); 1077 TAILQ_INSERT_HEAD(vpvoh, victim_pvo, pvo_olink); 1078 pmap_pte_unset(pt, &victim_pvo->pvo_pte, victim_pvo->pvo_vaddr); 1079 pmap_pte_set(pt, &source_pvo->pvo_pte); 1080 victim_pvo->pvo_pmap->pm_evictions++; 1081 source_pvo->pvo_pmap->pm_evictions--; 1082 PVO_WHERE(victim_pvo, SPILL_UNSET); 1083 PVO_WHERE(source_pvo, SPILL_SET); 1084 1085 PVO_PTEGIDX_CLR(victim_pvo); 1086 PVO_PTEGIDX_SET(source_pvo, i); 1087 PMAPCOUNT2(pmap_evcnt_ptes_primary[i]); 1088 PMAPCOUNT(ptes_spilled); 1089 PMAPCOUNT(ptes_evicted); 1090 PMAPCOUNT(ptes_removed); 1091 1092 PMAP_PVO_CHECK(victim_pvo); 1093 PMAP_PVO_CHECK(source_pvo); 1094 1095 PMAP_UNLOCK(); 1096 return 1; 1097 } 1098 1099 /* 1100 * Restrict given range to physical memory 1101 */ 1102 void 1103 pmap_real_memory(paddr_t *start, psize_t *size) 1104 { 1105 struct mem_region *mp; 1106 1107 for (mp = mem; mp->size; mp++) { 1108 if (*start + *size > mp->start 1109 && *start < mp->start + mp->size) { 1110 if (*start < mp->start) { 1111 *size -= mp->start - *start; 1112 *start = mp->start; 1113 } 1114 if (*start + *size > mp->start + mp->size) 1115 *size = mp->start + mp->size - *start; 1116 return; 1117 } 1118 } 1119 *size = 0; 1120 } 1121 1122 /* 1123 * Initialize anything else for pmap handling. 1124 * Called during vm_init(). 1125 */ 1126 void 1127 pmap_init(void) 1128 { 1129 pool_init(&pmap_mpvo_pool, sizeof(struct pvo_entry), 1130 sizeof(struct pvo_entry), 0, 0, "pmap_mpvopl", 1131 &pmap_pool_mallocator, IPL_NONE); 1132 1133 pool_setlowat(&pmap_mpvo_pool, 1008); 1134 1135 pmap_initialized = 1; 1136 1137 } 1138 1139 /* 1140 * How much virtual space does the kernel get? 1141 */ 1142 void 1143 pmap_virtual_space(vaddr_t *start, vaddr_t *end) 1144 { 1145 /* 1146 * For now, reserve one segment (minus some overhead) for kernel 1147 * virtual memory 1148 */ 1149 *start = VM_MIN_KERNEL_ADDRESS; 1150 *end = VM_MAX_KERNEL_ADDRESS; 1151 } 1152 1153 /* 1154 * Allocate, initialize, and return a new physical map. 1155 */ 1156 pmap_t 1157 pmap_create(void) 1158 { 1159 pmap_t pm; 1160 1161 pm = pool_get(&pmap_pool, PR_WAITOK); 1162 memset((void *)pm, 0, sizeof *pm); 1163 pmap_pinit(pm); 1164 1165 DPRINTFN(CREATE,("pmap_create: pm %p:\n" 1166 "\t%#" _PRIsr " %#" _PRIsr " %#" _PRIsr " %#" _PRIsr 1167 " %#" _PRIsr " %#" _PRIsr " %#" _PRIsr " %#" _PRIsr "\n" 1168 "\t%#" _PRIsr " %#" _PRIsr " %#" _PRIsr " %#" _PRIsr 1169 " %#" _PRIsr " %#" _PRIsr " %#" _PRIsr " %#" _PRIsr "\n", 1170 pm, 1171 pm->pm_sr[0], pm->pm_sr[1], 1172 pm->pm_sr[2], pm->pm_sr[3], 1173 pm->pm_sr[4], pm->pm_sr[5], 1174 pm->pm_sr[6], pm->pm_sr[7], 1175 pm->pm_sr[8], pm->pm_sr[9], 1176 pm->pm_sr[10], pm->pm_sr[11], 1177 pm->pm_sr[12], pm->pm_sr[13], 1178 pm->pm_sr[14], pm->pm_sr[15])); 1179 return pm; 1180 } 1181 1182 /* 1183 * Initialize a preallocated and zeroed pmap structure. 1184 */ 1185 void 1186 pmap_pinit(pmap_t pm) 1187 { 1188 register_t entropy = MFTB(); 1189 register_t mask; 1190 int i; 1191 1192 /* 1193 * Allocate some segment registers for this pmap. 1194 */ 1195 pm->pm_refs = 1; 1196 PMAP_LOCK(); 1197 for (i = 0; i < NPMAPS; i += VSID_NBPW) { 1198 static register_t pmap_vsidcontext; 1199 register_t hash; 1200 unsigned int n; 1201 1202 /* Create a new value by multiplying by a prime adding in 1203 * entropy from the timebase register. This is to make the 1204 * VSID more random so that the PT Hash function collides 1205 * less often. (note that the prime causes gcc to do shifts 1206 * instead of a multiply) 1207 */ 1208 pmap_vsidcontext = (pmap_vsidcontext * 0x1105) + entropy; 1209 hash = pmap_vsidcontext & (NPMAPS - 1); 1210 if (hash == 0) { /* 0 is special, avoid it */ 1211 entropy += 0xbadf00d; 1212 continue; 1213 } 1214 n = hash >> 5; 1215 mask = 1L << (hash & (VSID_NBPW-1)); 1216 hash = pmap_vsidcontext; 1217 if (pmap_vsid_bitmap[n] & mask) { /* collision? */ 1218 /* anything free in this bucket? */ 1219 if (~pmap_vsid_bitmap[n] == 0) { 1220 entropy = hash ^ (hash >> 16); 1221 continue; 1222 } 1223 i = ffs(~pmap_vsid_bitmap[n]) - 1; 1224 mask = 1L << i; 1225 hash &= ~(VSID_NBPW-1); 1226 hash |= i; 1227 } 1228 hash &= PTE_VSID >> PTE_VSID_SHFT; 1229 pmap_vsid_bitmap[n] |= mask; 1230 pm->pm_vsid = hash; 1231 #if defined (PMAP_OEA) || defined (PMAP_OEA64_BRIDGE) 1232 for (i = 0; i < 16; i++) 1233 pm->pm_sr[i] = VSID_MAKE(i, hash) | SR_PRKEY | 1234 SR_NOEXEC; 1235 #endif 1236 PMAP_UNLOCK(); 1237 return; 1238 } 1239 PMAP_UNLOCK(); 1240 panic("pmap_pinit: out of segments"); 1241 } 1242 1243 /* 1244 * Add a reference to the given pmap. 1245 */ 1246 void 1247 pmap_reference(pmap_t pm) 1248 { 1249 atomic_inc_uint(&pm->pm_refs); 1250 } 1251 1252 /* 1253 * Retire the given pmap from service. 1254 * Should only be called if the map contains no valid mappings. 1255 */ 1256 void 1257 pmap_destroy(pmap_t pm) 1258 { 1259 if (atomic_dec_uint_nv(&pm->pm_refs) == 0) { 1260 pmap_release(pm); 1261 pool_put(&pmap_pool, pm); 1262 } 1263 } 1264 1265 /* 1266 * Release any resources held by the given physical map. 1267 * Called when a pmap initialized by pmap_pinit is being released. 1268 */ 1269 void 1270 pmap_release(pmap_t pm) 1271 { 1272 int idx, mask; 1273 1274 KASSERT(pm->pm_stats.resident_count == 0); 1275 KASSERT(pm->pm_stats.wired_count == 0); 1276 1277 PMAP_LOCK(); 1278 if (pm->pm_sr[0] == 0) 1279 panic("pmap_release"); 1280 idx = pm->pm_vsid & (NPMAPS-1); 1281 mask = 1 << (idx % VSID_NBPW); 1282 idx /= VSID_NBPW; 1283 1284 KASSERT(pmap_vsid_bitmap[idx] & mask); 1285 pmap_vsid_bitmap[idx] &= ~mask; 1286 PMAP_UNLOCK(); 1287 } 1288 1289 /* 1290 * Copy the range specified by src_addr/len 1291 * from the source map to the range dst_addr/len 1292 * in the destination map. 1293 * 1294 * This routine is only advisory and need not do anything. 1295 */ 1296 void 1297 pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vaddr_t dst_addr, 1298 vsize_t len, vaddr_t src_addr) 1299 { 1300 PMAPCOUNT(copies); 1301 } 1302 1303 /* 1304 * Require that all active physical maps contain no 1305 * incorrect entries NOW. 1306 */ 1307 void 1308 pmap_update(struct pmap *pmap) 1309 { 1310 PMAPCOUNT(updates); 1311 TLBSYNC(); 1312 } 1313 1314 /* 1315 * Garbage collects the physical map system for 1316 * pages which are no longer used. 1317 * Success need not be guaranteed -- that is, there 1318 * may well be pages which are not referenced, but 1319 * others may be collected. 1320 * Called by the pageout daemon when pages are scarce. 1321 */ 1322 void 1323 pmap_collect(pmap_t pm) 1324 { 1325 PMAPCOUNT(collects); 1326 } 1327 1328 static inline int 1329 pmap_pvo_pte_index(const struct pvo_entry *pvo, int ptegidx) 1330 { 1331 int pteidx; 1332 /* 1333 * We can find the actual pte entry without searching by 1334 * grabbing the PTEG index from 3 unused bits in pte_lo[11:9] 1335 * and by noticing the HID bit. 1336 */ 1337 pteidx = ptegidx * 8 + PVO_PTEGIDX_GET(pvo); 1338 if (pvo->pvo_pte.pte_hi & PTE_HID) 1339 pteidx ^= pmap_pteg_mask * 8; 1340 return pteidx; 1341 } 1342 1343 volatile struct pte * 1344 pmap_pvo_to_pte(const struct pvo_entry *pvo, int pteidx) 1345 { 1346 volatile struct pte *pt; 1347 1348 #if !defined(DIAGNOSTIC) && !defined(DEBUG) && !defined(PMAPCHECK) 1349 if ((pvo->pvo_pte.pte_hi & PTE_VALID) == 0) 1350 return NULL; 1351 #endif 1352 1353 /* 1354 * If we haven't been supplied the ptegidx, calculate it. 1355 */ 1356 if (pteidx == -1) { 1357 int ptegidx; 1358 ptegidx = va_to_pteg(pvo->pvo_pmap, pvo->pvo_vaddr); 1359 pteidx = pmap_pvo_pte_index(pvo, ptegidx); 1360 } 1361 1362 pt = &pmap_pteg_table[pteidx >> 3].pt[pteidx & 7]; 1363 1364 #if !defined(DIAGNOSTIC) && !defined(DEBUG) && !defined(PMAPCHECK) 1365 return pt; 1366 #else 1367 if ((pvo->pvo_pte.pte_hi & PTE_VALID) && !PVO_PTEGIDX_ISSET(pvo)) { 1368 panic("pmap_pvo_to_pte: pvo %p: has valid pte in " 1369 "pvo but no valid pte index", pvo); 1370 } 1371 if ((pvo->pvo_pte.pte_hi & PTE_VALID) == 0 && PVO_PTEGIDX_ISSET(pvo)) { 1372 panic("pmap_pvo_to_pte: pvo %p: has valid pte index in " 1373 "pvo but no valid pte", pvo); 1374 } 1375 1376 if ((pt->pte_hi ^ (pvo->pvo_pte.pte_hi & ~PTE_VALID)) == PTE_VALID) { 1377 if ((pvo->pvo_pte.pte_hi & PTE_VALID) == 0) { 1378 #if defined(DEBUG) || defined(PMAPCHECK) 1379 pmap_pte_print(pt); 1380 #endif 1381 panic("pmap_pvo_to_pte: pvo %p: has valid pte in " 1382 "pmap_pteg_table %p but invalid in pvo", 1383 pvo, pt); 1384 } 1385 if (((pt->pte_lo ^ pvo->pvo_pte.pte_lo) & ~(PTE_CHG|PTE_REF)) != 0) { 1386 #if defined(DEBUG) || defined(PMAPCHECK) 1387 pmap_pte_print(pt); 1388 #endif 1389 panic("pmap_pvo_to_pte: pvo %p: pvo pte does " 1390 "not match pte %p in pmap_pteg_table", 1391 pvo, pt); 1392 } 1393 return pt; 1394 } 1395 1396 if (pvo->pvo_pte.pte_hi & PTE_VALID) { 1397 #if defined(DEBUG) || defined(PMAPCHECK) 1398 pmap_pte_print(pt); 1399 #endif 1400 panic("pmap_pvo_to_pte: pvo %p: has nomatching pte %p in " 1401 "pmap_pteg_table but valid in pvo", pvo, pt); 1402 } 1403 return NULL; 1404 #endif /* !(!DIAGNOSTIC && !DEBUG && !PMAPCHECK) */ 1405 } 1406 1407 struct pvo_entry * 1408 pmap_pvo_find_va(pmap_t pm, vaddr_t va, int *pteidx_p) 1409 { 1410 struct pvo_entry *pvo; 1411 int ptegidx; 1412 1413 va &= ~ADDR_POFF; 1414 ptegidx = va_to_pteg(pm, va); 1415 1416 TAILQ_FOREACH(pvo, &pmap_pvo_table[ptegidx], pvo_olink) { 1417 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK) 1418 if ((uintptr_t) pvo >= SEGMENT_LENGTH) 1419 panic("pmap_pvo_find_va: invalid pvo %p on " 1420 "list %#x (%p)", pvo, ptegidx, 1421 &pmap_pvo_table[ptegidx]); 1422 #endif 1423 if (pvo->pvo_pmap == pm && PVO_VADDR(pvo) == va) { 1424 if (pteidx_p) 1425 *pteidx_p = pmap_pvo_pte_index(pvo, ptegidx); 1426 return pvo; 1427 } 1428 } 1429 if ((pm == pmap_kernel()) && (va < SEGMENT_LENGTH)) 1430 panic("%s: returning NULL for %s pmap, va: %#" _PRIxva "\n", 1431 __func__, (pm == pmap_kernel() ? "kernel" : "user"), va); 1432 return NULL; 1433 } 1434 1435 #if defined(DEBUG) || defined(PMAPCHECK) 1436 void 1437 pmap_pvo_check(const struct pvo_entry *pvo) 1438 { 1439 struct pvo_head *pvo_head; 1440 struct pvo_entry *pvo0; 1441 volatile struct pte *pt; 1442 int failed = 0; 1443 1444 PMAP_LOCK(); 1445 1446 if ((uintptr_t)(pvo+1) >= SEGMENT_LENGTH) 1447 panic("pmap_pvo_check: pvo %p: invalid address", pvo); 1448 1449 if ((uintptr_t)(pvo->pvo_pmap+1) >= SEGMENT_LENGTH) { 1450 printf("pmap_pvo_check: pvo %p: invalid pmap address %p\n", 1451 pvo, pvo->pvo_pmap); 1452 failed = 1; 1453 } 1454 1455 if ((uintptr_t)TAILQ_NEXT(pvo, pvo_olink) >= SEGMENT_LENGTH || 1456 (((uintptr_t)TAILQ_NEXT(pvo, pvo_olink)) & 0x1f) != 0) { 1457 printf("pmap_pvo_check: pvo %p: invalid ovlink address %p\n", 1458 pvo, TAILQ_NEXT(pvo, pvo_olink)); 1459 failed = 1; 1460 } 1461 1462 if ((uintptr_t)LIST_NEXT(pvo, pvo_vlink) >= SEGMENT_LENGTH || 1463 (((uintptr_t)LIST_NEXT(pvo, pvo_vlink)) & 0x1f) != 0) { 1464 printf("pmap_pvo_check: pvo %p: invalid ovlink address %p\n", 1465 pvo, LIST_NEXT(pvo, pvo_vlink)); 1466 failed = 1; 1467 } 1468 1469 if (PVO_MANAGED_P(pvo)) { 1470 pvo_head = pa_to_pvoh(pvo->pvo_pte.pte_lo & PTE_RPGN, NULL); 1471 } else { 1472 if (pvo->pvo_vaddr < VM_MIN_KERNEL_ADDRESS) { 1473 printf("pmap_pvo_check: pvo %p: non kernel address " 1474 "on kernel unmanaged list\n", pvo); 1475 failed = 1; 1476 } 1477 pvo_head = &pmap_pvo_kunmanaged; 1478 } 1479 LIST_FOREACH(pvo0, pvo_head, pvo_vlink) { 1480 if (pvo0 == pvo) 1481 break; 1482 } 1483 if (pvo0 == NULL) { 1484 printf("pmap_pvo_check: pvo %p: not present " 1485 "on its vlist head %p\n", pvo, pvo_head); 1486 failed = 1; 1487 } 1488 if (pvo != pmap_pvo_find_va(pvo->pvo_pmap, pvo->pvo_vaddr, NULL)) { 1489 printf("pmap_pvo_check: pvo %p: not present " 1490 "on its olist head\n", pvo); 1491 failed = 1; 1492 } 1493 pt = pmap_pvo_to_pte(pvo, -1); 1494 if (pt == NULL) { 1495 if (pvo->pvo_pte.pte_hi & PTE_VALID) { 1496 printf("pmap_pvo_check: pvo %p: pte_hi VALID but " 1497 "no PTE\n", pvo); 1498 failed = 1; 1499 } 1500 } else { 1501 if ((uintptr_t) pt < (uintptr_t) &pmap_pteg_table[0] || 1502 (uintptr_t) pt >= 1503 (uintptr_t) &pmap_pteg_table[pmap_pteg_cnt]) { 1504 printf("pmap_pvo_check: pvo %p: pte %p not in " 1505 "pteg table\n", pvo, pt); 1506 failed = 1; 1507 } 1508 if (((((uintptr_t) pt) >> 3) & 7) != PVO_PTEGIDX_GET(pvo)) { 1509 printf("pmap_pvo_check: pvo %p: pte_hi VALID but " 1510 "no PTE\n", pvo); 1511 failed = 1; 1512 } 1513 if (pvo->pvo_pte.pte_hi != pt->pte_hi) { 1514 printf("pmap_pvo_check: pvo %p: pte_hi differ: " 1515 "%#" _PRIxpte "/%#" _PRIxpte "\n", pvo, 1516 pvo->pvo_pte.pte_hi, 1517 pt->pte_hi); 1518 failed = 1; 1519 } 1520 if (((pvo->pvo_pte.pte_lo ^ pt->pte_lo) & 1521 (PTE_PP|PTE_WIMG|PTE_RPGN)) != 0) { 1522 printf("pmap_pvo_check: pvo %p: pte_lo differ: " 1523 "%#" _PRIxpte "/%#" _PRIxpte "\n", pvo, 1524 (pvo->pvo_pte.pte_lo & (PTE_PP|PTE_WIMG|PTE_RPGN)), 1525 (pt->pte_lo & (PTE_PP|PTE_WIMG|PTE_RPGN))); 1526 failed = 1; 1527 } 1528 if ((pmap_pte_to_va(pt) ^ PVO_VADDR(pvo)) & 0x0fffffff) { 1529 printf("pmap_pvo_check: pvo %p: PTE %p derived VA %#" _PRIxva "" 1530 " doesn't not match PVO's VA %#" _PRIxva "\n", 1531 pvo, pt, pmap_pte_to_va(pt), PVO_VADDR(pvo)); 1532 failed = 1; 1533 } 1534 if (failed) 1535 pmap_pte_print(pt); 1536 } 1537 if (failed) 1538 panic("pmap_pvo_check: pvo %p, pm %p: bugcheck!", pvo, 1539 pvo->pvo_pmap); 1540 1541 PMAP_UNLOCK(); 1542 } 1543 #endif /* DEBUG || PMAPCHECK */ 1544 1545 /* 1546 * Search the PVO table looking for a non-wired entry. 1547 * If we find one, remove it and return it. 1548 */ 1549 1550 struct pvo_entry * 1551 pmap_pvo_reclaim(struct pmap *pm) 1552 { 1553 struct pvo_tqhead *pvoh; 1554 struct pvo_entry *pvo; 1555 uint32_t idx, endidx; 1556 1557 endidx = pmap_pvo_reclaim_nextidx; 1558 for (idx = (endidx + 1) & pmap_pteg_mask; idx != endidx; 1559 idx = (idx + 1) & pmap_pteg_mask) { 1560 pvoh = &pmap_pvo_table[idx]; 1561 TAILQ_FOREACH(pvo, pvoh, pvo_olink) { 1562 if (!PVO_WIRED_P(pvo)) { 1563 pmap_pvo_remove(pvo, -1, NULL); 1564 pmap_pvo_reclaim_nextidx = idx; 1565 PMAPCOUNT(pvos_reclaimed); 1566 return pvo; 1567 } 1568 } 1569 } 1570 return NULL; 1571 } 1572 1573 /* 1574 * This returns whether this is the first mapping of a page. 1575 */ 1576 int 1577 pmap_pvo_enter(pmap_t pm, struct pool *pl, struct pvo_head *pvo_head, 1578 vaddr_t va, paddr_t pa, register_t pte_lo, int flags) 1579 { 1580 struct pvo_entry *pvo; 1581 struct pvo_tqhead *pvoh; 1582 register_t msr; 1583 int ptegidx; 1584 int i; 1585 int poolflags = PR_NOWAIT; 1586 1587 /* 1588 * Compute the PTE Group index. 1589 */ 1590 va &= ~ADDR_POFF; 1591 ptegidx = va_to_pteg(pm, va); 1592 1593 msr = pmap_interrupts_off(); 1594 1595 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK) 1596 if (pmap_pvo_remove_depth > 0) 1597 panic("pmap_pvo_enter: called while pmap_pvo_remove active!"); 1598 if (++pmap_pvo_enter_depth > 1) 1599 panic("pmap_pvo_enter: called recursively!"); 1600 #endif 1601 1602 /* 1603 * Remove any existing mapping for this page. Reuse the 1604 * pvo entry if there a mapping. 1605 */ 1606 TAILQ_FOREACH(pvo, &pmap_pvo_table[ptegidx], pvo_olink) { 1607 if (pvo->pvo_pmap == pm && PVO_VADDR(pvo) == va) { 1608 #ifdef DEBUG 1609 if ((pmapdebug & PMAPDEBUG_PVOENTER) && 1610 ((pvo->pvo_pte.pte_lo ^ (pa|pte_lo)) & 1611 ~(PTE_REF|PTE_CHG)) == 0 && 1612 va < VM_MIN_KERNEL_ADDRESS) { 1613 printf("pmap_pvo_enter: pvo %p: dup %#" _PRIxpte "/%#" _PRIxpa "\n", 1614 pvo, pvo->pvo_pte.pte_lo, pte_lo|pa); 1615 printf("pmap_pvo_enter: pte_hi=%#" _PRIxpte " sr=%#" _PRIsr "\n", 1616 pvo->pvo_pte.pte_hi, 1617 pm->pm_sr[va >> ADDR_SR_SHFT]); 1618 pmap_pte_print(pmap_pvo_to_pte(pvo, -1)); 1619 #ifdef DDBX 1620 Debugger(); 1621 #endif 1622 } 1623 #endif 1624 PMAPCOUNT(mappings_replaced); 1625 pmap_pvo_remove(pvo, -1, NULL); 1626 break; 1627 } 1628 } 1629 1630 /* 1631 * If we aren't overwriting an mapping, try to allocate 1632 */ 1633 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK) 1634 --pmap_pvo_enter_depth; 1635 #endif 1636 pmap_interrupts_restore(msr); 1637 if (pvo) { 1638 pmap_pvo_free(pvo); 1639 } 1640 pvo = pool_get(pl, poolflags); 1641 1642 #ifdef DEBUG 1643 /* 1644 * Exercise pmap_pvo_reclaim() a little. 1645 */ 1646 if (pvo && (flags & PMAP_CANFAIL) != 0 && 1647 pmap_pvo_reclaim_debugctr++ > 0x1000 && 1648 (pmap_pvo_reclaim_debugctr & 0xff) == 0) { 1649 pool_put(pl, pvo); 1650 pvo = NULL; 1651 } 1652 #endif 1653 1654 msr = pmap_interrupts_off(); 1655 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK) 1656 ++pmap_pvo_enter_depth; 1657 #endif 1658 if (pvo == NULL) { 1659 pvo = pmap_pvo_reclaim(pm); 1660 if (pvo == NULL) { 1661 if ((flags & PMAP_CANFAIL) == 0) 1662 panic("pmap_pvo_enter: failed"); 1663 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK) 1664 pmap_pvo_enter_depth--; 1665 #endif 1666 PMAPCOUNT(pvos_failed); 1667 pmap_interrupts_restore(msr); 1668 return ENOMEM; 1669 } 1670 } 1671 1672 pvo->pvo_vaddr = va; 1673 pvo->pvo_pmap = pm; 1674 pvo->pvo_vaddr &= ~ADDR_POFF; 1675 if (flags & VM_PROT_EXECUTE) { 1676 PMAPCOUNT(exec_mappings); 1677 pvo_set_exec(pvo); 1678 } 1679 if (flags & PMAP_WIRED) 1680 pvo->pvo_vaddr |= PVO_WIRED; 1681 if (pvo_head != &pmap_pvo_kunmanaged) { 1682 pvo->pvo_vaddr |= PVO_MANAGED; 1683 PMAPCOUNT(mappings); 1684 } else { 1685 PMAPCOUNT(kernel_mappings); 1686 } 1687 pmap_pte_create(&pvo->pvo_pte, pm, va, pa | pte_lo); 1688 1689 LIST_INSERT_HEAD(pvo_head, pvo, pvo_vlink); 1690 if (PVO_WIRED_P(pvo)) 1691 pvo->pvo_pmap->pm_stats.wired_count++; 1692 pvo->pvo_pmap->pm_stats.resident_count++; 1693 #if defined(DEBUG) 1694 /* if (pm != pmap_kernel() && va < VM_MIN_KERNEL_ADDRESS) */ 1695 DPRINTFN(PVOENTER, 1696 ("pmap_pvo_enter: pvo %p: pm %p va %#" _PRIxva " pa %#" _PRIxpa "\n", 1697 pvo, pm, va, pa)); 1698 #endif 1699 1700 /* 1701 * We hope this succeeds but it isn't required. 1702 */ 1703 pvoh = &pmap_pvo_table[ptegidx]; 1704 i = pmap_pte_insert(ptegidx, &pvo->pvo_pte); 1705 if (i >= 0) { 1706 PVO_PTEGIDX_SET(pvo, i); 1707 PVO_WHERE(pvo, ENTER_INSERT); 1708 PMAPCOUNT2(((pvo->pvo_pte.pte_hi & PTE_HID) 1709 ? pmap_evcnt_ptes_secondary : pmap_evcnt_ptes_primary)[i]); 1710 TAILQ_INSERT_TAIL(pvoh, pvo, pvo_olink); 1711 1712 } else { 1713 /* 1714 * Since we didn't have room for this entry (which makes it 1715 * and evicted entry), place it at the head of the list. 1716 */ 1717 TAILQ_INSERT_HEAD(pvoh, pvo, pvo_olink); 1718 PMAPCOUNT(ptes_evicted); 1719 pm->pm_evictions++; 1720 /* 1721 * If this is a kernel page, make sure it's active. 1722 */ 1723 if (pm == pmap_kernel()) { 1724 i = pmap_pte_spill(pm, va, false); 1725 KASSERT(i); 1726 } 1727 } 1728 PMAP_PVO_CHECK(pvo); /* sanity check */ 1729 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK) 1730 pmap_pvo_enter_depth--; 1731 #endif 1732 pmap_interrupts_restore(msr); 1733 return 0; 1734 } 1735 1736 static void 1737 pmap_pvo_remove(struct pvo_entry *pvo, int pteidx, struct pvo_head *pvol) 1738 { 1739 volatile struct pte *pt; 1740 int ptegidx; 1741 1742 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK) 1743 if (++pmap_pvo_remove_depth > 1) 1744 panic("pmap_pvo_remove: called recursively!"); 1745 #endif 1746 1747 /* 1748 * If we haven't been supplied the ptegidx, calculate it. 1749 */ 1750 if (pteidx == -1) { 1751 ptegidx = va_to_pteg(pvo->pvo_pmap, pvo->pvo_vaddr); 1752 pteidx = pmap_pvo_pte_index(pvo, ptegidx); 1753 } else { 1754 ptegidx = pteidx >> 3; 1755 if (pvo->pvo_pte.pte_hi & PTE_HID) 1756 ptegidx ^= pmap_pteg_mask; 1757 } 1758 PMAP_PVO_CHECK(pvo); /* sanity check */ 1759 1760 /* 1761 * If there is an active pte entry, we need to deactivate it 1762 * (and save the ref & chg bits). 1763 */ 1764 pt = pmap_pvo_to_pte(pvo, pteidx); 1765 if (pt != NULL) { 1766 pmap_pte_unset(pt, &pvo->pvo_pte, pvo->pvo_vaddr); 1767 PVO_WHERE(pvo, REMOVE); 1768 PVO_PTEGIDX_CLR(pvo); 1769 PMAPCOUNT(ptes_removed); 1770 } else { 1771 KASSERT(pvo->pvo_pmap->pm_evictions > 0); 1772 pvo->pvo_pmap->pm_evictions--; 1773 } 1774 1775 /* 1776 * Account for executable mappings. 1777 */ 1778 if (PVO_EXECUTABLE_P(pvo)) 1779 pvo_clear_exec(pvo); 1780 1781 /* 1782 * Update our statistics. 1783 */ 1784 pvo->pvo_pmap->pm_stats.resident_count--; 1785 if (PVO_WIRED_P(pvo)) 1786 pvo->pvo_pmap->pm_stats.wired_count--; 1787 1788 /* 1789 * Save the REF/CHG bits into their cache if the page is managed. 1790 */ 1791 if (PVO_MANAGED_P(pvo)) { 1792 register_t ptelo = pvo->pvo_pte.pte_lo; 1793 struct vm_page *pg = PHYS_TO_VM_PAGE(ptelo & PTE_RPGN); 1794 1795 if (pg != NULL) { 1796 /* 1797 * If this page was changed and it is mapped exec, 1798 * invalidate it. 1799 */ 1800 if ((ptelo & PTE_CHG) && 1801 (pmap_attr_fetch(pg) & PTE_EXEC)) { 1802 struct pvo_head *pvoh = vm_page_to_pvoh(pg); 1803 if (LIST_EMPTY(pvoh)) { 1804 DPRINTFN(EXEC, ("[pmap_pvo_remove: " 1805 "%#" _PRIxpa ": clear-exec]\n", 1806 VM_PAGE_TO_PHYS(pg))); 1807 pmap_attr_clear(pg, PTE_EXEC); 1808 PMAPCOUNT(exec_uncached_pvo_remove); 1809 } else { 1810 DPRINTFN(EXEC, ("[pmap_pvo_remove: " 1811 "%#" _PRIxpa ": syncicache]\n", 1812 VM_PAGE_TO_PHYS(pg))); 1813 pmap_syncicache(VM_PAGE_TO_PHYS(pg), 1814 PAGE_SIZE); 1815 PMAPCOUNT(exec_synced_pvo_remove); 1816 } 1817 } 1818 1819 pmap_attr_save(pg, ptelo & (PTE_REF|PTE_CHG)); 1820 } 1821 PMAPCOUNT(unmappings); 1822 } else { 1823 PMAPCOUNT(kernel_unmappings); 1824 } 1825 1826 /* 1827 * Remove the PVO from its lists and return it to the pool. 1828 */ 1829 LIST_REMOVE(pvo, pvo_vlink); 1830 TAILQ_REMOVE(&pmap_pvo_table[ptegidx], pvo, pvo_olink); 1831 if (pvol) { 1832 LIST_INSERT_HEAD(pvol, pvo, pvo_vlink); 1833 } 1834 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK) 1835 pmap_pvo_remove_depth--; 1836 #endif 1837 } 1838 1839 void 1840 pmap_pvo_free(struct pvo_entry *pvo) 1841 { 1842 1843 pool_put(PVO_MANAGED_P(pvo) ? &pmap_mpvo_pool : &pmap_upvo_pool, pvo); 1844 } 1845 1846 void 1847 pmap_pvo_free_list(struct pvo_head *pvol) 1848 { 1849 struct pvo_entry *pvo, *npvo; 1850 1851 for (pvo = LIST_FIRST(pvol); pvo != NULL; pvo = npvo) { 1852 npvo = LIST_NEXT(pvo, pvo_vlink); 1853 LIST_REMOVE(pvo, pvo_vlink); 1854 pmap_pvo_free(pvo); 1855 } 1856 } 1857 1858 /* 1859 * Mark a mapping as executable. 1860 * If this is the first executable mapping in the segment, 1861 * clear the noexec flag. 1862 */ 1863 static void 1864 pvo_set_exec(struct pvo_entry *pvo) 1865 { 1866 struct pmap *pm = pvo->pvo_pmap; 1867 1868 if (pm == pmap_kernel() || PVO_EXECUTABLE_P(pvo)) { 1869 return; 1870 } 1871 pvo->pvo_vaddr |= PVO_EXECUTABLE; 1872 #if defined (PMAP_OEA) || defined (PMAP_OEA64_BRIDGE) 1873 { 1874 int sr = PVO_VADDR(pvo) >> ADDR_SR_SHFT; 1875 if (pm->pm_exec[sr]++ == 0) { 1876 pm->pm_sr[sr] &= ~SR_NOEXEC; 1877 } 1878 } 1879 #endif 1880 } 1881 1882 /* 1883 * Mark a mapping as non-executable. 1884 * If this was the last executable mapping in the segment, 1885 * set the noexec flag. 1886 */ 1887 static void 1888 pvo_clear_exec(struct pvo_entry *pvo) 1889 { 1890 struct pmap *pm = pvo->pvo_pmap; 1891 1892 if (pm == pmap_kernel() || !PVO_EXECUTABLE_P(pvo)) { 1893 return; 1894 } 1895 pvo->pvo_vaddr &= ~PVO_EXECUTABLE; 1896 #if defined (PMAP_OEA) || defined (PMAP_OEA64_BRIDGE) 1897 { 1898 int sr = PVO_VADDR(pvo) >> ADDR_SR_SHFT; 1899 if (--pm->pm_exec[sr] == 0) { 1900 pm->pm_sr[sr] |= SR_NOEXEC; 1901 } 1902 } 1903 #endif 1904 } 1905 1906 /* 1907 * Insert physical page at pa into the given pmap at virtual address va. 1908 */ 1909 int 1910 pmap_enter(pmap_t pm, vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags) 1911 { 1912 struct mem_region *mp; 1913 struct pvo_head *pvo_head; 1914 struct vm_page *pg; 1915 struct pool *pl; 1916 register_t pte_lo; 1917 int error; 1918 u_int pvo_flags; 1919 u_int was_exec = 0; 1920 1921 PMAP_LOCK(); 1922 1923 if (__predict_false(!pmap_initialized)) { 1924 pvo_head = &pmap_pvo_kunmanaged; 1925 pl = &pmap_upvo_pool; 1926 pvo_flags = 0; 1927 pg = NULL; 1928 was_exec = PTE_EXEC; 1929 } else { 1930 pvo_head = pa_to_pvoh(pa, &pg); 1931 pl = &pmap_mpvo_pool; 1932 pvo_flags = PVO_MANAGED; 1933 } 1934 1935 DPRINTFN(ENTER, 1936 ("pmap_enter(%p, %#" _PRIxva ", %#" _PRIxpa ", 0x%x, 0x%x):", 1937 pm, va, pa, prot, flags)); 1938 1939 /* 1940 * If this is a managed page, and it's the first reference to the 1941 * page clear the execness of the page. Otherwise fetch the execness. 1942 */ 1943 if (pg != NULL) 1944 was_exec = pmap_attr_fetch(pg) & PTE_EXEC; 1945 1946 DPRINTFN(ENTER, (" was_exec=%d", was_exec)); 1947 1948 /* 1949 * Assume the page is cache inhibited and access is guarded unless 1950 * it's in our available memory array. If it is in the memory array, 1951 * asssume it's in memory coherent memory. 1952 */ 1953 pte_lo = PTE_IG; 1954 if ((flags & PMAP_NC) == 0) { 1955 for (mp = mem; mp->size; mp++) { 1956 if (pa >= mp->start && pa < mp->start + mp->size) { 1957 pte_lo = PTE_M; 1958 break; 1959 } 1960 } 1961 } 1962 1963 if (prot & VM_PROT_WRITE) 1964 pte_lo |= PTE_BW; 1965 else 1966 pte_lo |= PTE_BR; 1967 1968 /* 1969 * If this was in response to a fault, "pre-fault" the PTE's 1970 * changed/referenced bit appropriately. 1971 */ 1972 if (flags & VM_PROT_WRITE) 1973 pte_lo |= PTE_CHG; 1974 if (flags & VM_PROT_ALL) 1975 pte_lo |= PTE_REF; 1976 1977 /* 1978 * We need to know if this page can be executable 1979 */ 1980 flags |= (prot & VM_PROT_EXECUTE); 1981 1982 /* 1983 * Record mapping for later back-translation and pte spilling. 1984 * This will overwrite any existing mapping. 1985 */ 1986 error = pmap_pvo_enter(pm, pl, pvo_head, va, pa, pte_lo, flags); 1987 1988 /* 1989 * Flush the real page from the instruction cache if this page is 1990 * mapped executable and cacheable and has not been flushed since 1991 * the last time it was modified. 1992 */ 1993 if (error == 0 && 1994 (flags & VM_PROT_EXECUTE) && 1995 (pte_lo & PTE_I) == 0 && 1996 was_exec == 0) { 1997 DPRINTFN(ENTER, (" syncicache")); 1998 PMAPCOUNT(exec_synced); 1999 pmap_syncicache(pa, PAGE_SIZE); 2000 if (pg != NULL) { 2001 pmap_attr_save(pg, PTE_EXEC); 2002 PMAPCOUNT(exec_cached); 2003 #if defined(DEBUG) || defined(PMAPDEBUG) 2004 if (pmapdebug & PMAPDEBUG_ENTER) 2005 printf(" marked-as-exec"); 2006 else if (pmapdebug & PMAPDEBUG_EXEC) 2007 printf("[pmap_enter: %#" _PRIxpa ": marked-as-exec]\n", 2008 VM_PAGE_TO_PHYS(pg)); 2009 2010 #endif 2011 } 2012 } 2013 2014 DPRINTFN(ENTER, (": error=%d\n", error)); 2015 2016 PMAP_UNLOCK(); 2017 2018 return error; 2019 } 2020 2021 void 2022 pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot) 2023 { 2024 struct mem_region *mp; 2025 register_t pte_lo; 2026 int error; 2027 2028 #if defined (PMAP_OEA64_BRIDGE) 2029 if (va < VM_MIN_KERNEL_ADDRESS) 2030 panic("pmap_kenter_pa: attempt to enter " 2031 "non-kernel address %#" _PRIxva "!", va); 2032 #endif 2033 2034 DPRINTFN(KENTER, 2035 ("pmap_kenter_pa(%#" _PRIxva ",%#" _PRIxpa ",%#x)\n", va, pa, prot)); 2036 2037 PMAP_LOCK(); 2038 2039 /* 2040 * Assume the page is cache inhibited and access is guarded unless 2041 * it's in our available memory array. If it is in the memory array, 2042 * asssume it's in memory coherent memory. 2043 */ 2044 pte_lo = PTE_IG; 2045 if ((prot & PMAP_NC) == 0) { 2046 for (mp = mem; mp->size; mp++) { 2047 if (pa >= mp->start && pa < mp->start + mp->size) { 2048 pte_lo = PTE_M; 2049 break; 2050 } 2051 } 2052 } 2053 2054 if (prot & VM_PROT_WRITE) 2055 pte_lo |= PTE_BW; 2056 else 2057 pte_lo |= PTE_BR; 2058 2059 /* 2060 * We don't care about REF/CHG on PVOs on the unmanaged list. 2061 */ 2062 error = pmap_pvo_enter(pmap_kernel(), &pmap_upvo_pool, 2063 &pmap_pvo_kunmanaged, va, pa, pte_lo, prot|PMAP_WIRED); 2064 2065 if (error != 0) 2066 panic("pmap_kenter_pa: failed to enter va %#" _PRIxva " pa %#" _PRIxpa ": %d", 2067 va, pa, error); 2068 2069 PMAP_UNLOCK(); 2070 } 2071 2072 void 2073 pmap_kremove(vaddr_t va, vsize_t len) 2074 { 2075 if (va < VM_MIN_KERNEL_ADDRESS) 2076 panic("pmap_kremove: attempt to remove " 2077 "non-kernel address %#" _PRIxva "!", va); 2078 2079 DPRINTFN(KREMOVE,("pmap_kremove(%#" _PRIxva ",%#" _PRIxva ")\n", va, len)); 2080 pmap_remove(pmap_kernel(), va, va + len); 2081 } 2082 2083 /* 2084 * Remove the given range of mapping entries. 2085 */ 2086 void 2087 pmap_remove(pmap_t pm, vaddr_t va, vaddr_t endva) 2088 { 2089 struct pvo_head pvol; 2090 struct pvo_entry *pvo; 2091 register_t msr; 2092 int pteidx; 2093 2094 PMAP_LOCK(); 2095 LIST_INIT(&pvol); 2096 msr = pmap_interrupts_off(); 2097 for (; va < endva; va += PAGE_SIZE) { 2098 pvo = pmap_pvo_find_va(pm, va, &pteidx); 2099 if (pvo != NULL) { 2100 pmap_pvo_remove(pvo, pteidx, &pvol); 2101 } 2102 } 2103 pmap_interrupts_restore(msr); 2104 pmap_pvo_free_list(&pvol); 2105 PMAP_UNLOCK(); 2106 } 2107 2108 /* 2109 * Get the physical page address for the given pmap/virtual address. 2110 */ 2111 bool 2112 pmap_extract(pmap_t pm, vaddr_t va, paddr_t *pap) 2113 { 2114 struct pvo_entry *pvo; 2115 register_t msr; 2116 2117 PMAP_LOCK(); 2118 2119 /* 2120 * If this is a kernel pmap lookup, also check the battable 2121 * and if we get a hit, translate the VA to a PA using the 2122 * BAT entries. Don't check for VM_MAX_KERNEL_ADDRESS is 2123 * that will wrap back to 0. 2124 */ 2125 if (pm == pmap_kernel() && 2126 (va < VM_MIN_KERNEL_ADDRESS || 2127 (KERNEL2_SR < 15 && VM_MAX_KERNEL_ADDRESS <= va))) { 2128 KASSERT((va >> ADDR_SR_SHFT) != USER_SR); 2129 #if defined (PMAP_OEA) 2130 #ifdef PPC_OEA601 2131 if ((MFPVR() >> 16) == MPC601) { 2132 register_t batu = battable[va >> 23].batu; 2133 register_t batl = battable[va >> 23].batl; 2134 register_t sr = iosrtable[va >> ADDR_SR_SHFT]; 2135 if (BAT601_VALID_P(batl) && 2136 BAT601_VA_MATCH_P(batu, batl, va)) { 2137 register_t mask = 2138 (~(batl & BAT601_BSM) << 17) & ~0x1ffffL; 2139 if (pap) 2140 *pap = (batl & mask) | (va & ~mask); 2141 PMAP_UNLOCK(); 2142 return true; 2143 } else if (SR601_VALID_P(sr) && 2144 SR601_PA_MATCH_P(sr, va)) { 2145 if (pap) 2146 *pap = va; 2147 PMAP_UNLOCK(); 2148 return true; 2149 } 2150 } else 2151 #endif /* PPC_OEA601 */ 2152 { 2153 register_t batu = battable[va >> ADDR_SR_SHFT].batu; 2154 if (BAT_VALID_P(batu,0) && BAT_VA_MATCH_P(batu,va)) { 2155 register_t batl = 2156 battable[va >> ADDR_SR_SHFT].batl; 2157 register_t mask = 2158 (~(batu & BAT_BL) << 15) & ~0x1ffffL; 2159 if (pap) 2160 *pap = (batl & mask) | (va & ~mask); 2161 PMAP_UNLOCK(); 2162 return true; 2163 } 2164 } 2165 return false; 2166 #elif defined (PMAP_OEA64_BRIDGE) 2167 if (va >= SEGMENT_LENGTH) 2168 panic("%s: pm: %s va >= SEGMENT_LENGTH, va: 0x%08lx\n", 2169 __func__, (pm == pmap_kernel() ? "kernel" : "user"), va); 2170 else { 2171 if (pap) 2172 *pap = va; 2173 PMAP_UNLOCK(); 2174 return true; 2175 } 2176 #elif defined (PMAP_OEA64) 2177 #error PPC_OEA64 not supported 2178 #endif /* PPC_OEA */ 2179 } 2180 2181 msr = pmap_interrupts_off(); 2182 pvo = pmap_pvo_find_va(pm, va & ~ADDR_POFF, NULL); 2183 if (pvo != NULL) { 2184 PMAP_PVO_CHECK(pvo); /* sanity check */ 2185 if (pap) 2186 *pap = (pvo->pvo_pte.pte_lo & PTE_RPGN) 2187 | (va & ADDR_POFF); 2188 } 2189 pmap_interrupts_restore(msr); 2190 PMAP_UNLOCK(); 2191 return pvo != NULL; 2192 } 2193 2194 /* 2195 * Lower the protection on the specified range of this pmap. 2196 */ 2197 void 2198 pmap_protect(pmap_t pm, vaddr_t va, vaddr_t endva, vm_prot_t prot) 2199 { 2200 struct pvo_entry *pvo; 2201 volatile struct pte *pt; 2202 register_t msr; 2203 int pteidx; 2204 2205 /* 2206 * Since this routine only downgrades protection, we should 2207 * always be called with at least one bit not set. 2208 */ 2209 KASSERT(prot != VM_PROT_ALL); 2210 2211 /* 2212 * If there is no protection, this is equivalent to 2213 * remove the pmap from the pmap. 2214 */ 2215 if ((prot & VM_PROT_READ) == 0) { 2216 pmap_remove(pm, va, endva); 2217 return; 2218 } 2219 2220 PMAP_LOCK(); 2221 2222 msr = pmap_interrupts_off(); 2223 for (; va < endva; va += PAGE_SIZE) { 2224 pvo = pmap_pvo_find_va(pm, va, &pteidx); 2225 if (pvo == NULL) 2226 continue; 2227 PMAP_PVO_CHECK(pvo); /* sanity check */ 2228 2229 /* 2230 * Revoke executable if asked to do so. 2231 */ 2232 if ((prot & VM_PROT_EXECUTE) == 0) 2233 pvo_clear_exec(pvo); 2234 2235 #if 0 2236 /* 2237 * If the page is already read-only, no change 2238 * needs to be made. 2239 */ 2240 if ((pvo->pvo_pte.pte_lo & PTE_PP) == PTE_BR) 2241 continue; 2242 #endif 2243 /* 2244 * Grab the PTE pointer before we diddle with 2245 * the cached PTE copy. 2246 */ 2247 pt = pmap_pvo_to_pte(pvo, pteidx); 2248 /* 2249 * Change the protection of the page. 2250 */ 2251 pvo->pvo_pte.pte_lo &= ~PTE_PP; 2252 pvo->pvo_pte.pte_lo |= PTE_BR; 2253 2254 /* 2255 * If the PVO is in the page table, update 2256 * that pte at well. 2257 */ 2258 if (pt != NULL) { 2259 pmap_pte_change(pt, &pvo->pvo_pte, pvo->pvo_vaddr); 2260 PVO_WHERE(pvo, PMAP_PROTECT); 2261 PMAPCOUNT(ptes_changed); 2262 } 2263 2264 PMAP_PVO_CHECK(pvo); /* sanity check */ 2265 } 2266 pmap_interrupts_restore(msr); 2267 PMAP_UNLOCK(); 2268 } 2269 2270 void 2271 pmap_unwire(pmap_t pm, vaddr_t va) 2272 { 2273 struct pvo_entry *pvo; 2274 register_t msr; 2275 2276 PMAP_LOCK(); 2277 msr = pmap_interrupts_off(); 2278 pvo = pmap_pvo_find_va(pm, va, NULL); 2279 if (pvo != NULL) { 2280 if (PVO_WIRED_P(pvo)) { 2281 pvo->pvo_vaddr &= ~PVO_WIRED; 2282 pm->pm_stats.wired_count--; 2283 } 2284 PMAP_PVO_CHECK(pvo); /* sanity check */ 2285 } 2286 pmap_interrupts_restore(msr); 2287 PMAP_UNLOCK(); 2288 } 2289 2290 /* 2291 * Lower the protection on the specified physical page. 2292 */ 2293 void 2294 pmap_page_protect(struct vm_page *pg, vm_prot_t prot) 2295 { 2296 struct pvo_head *pvo_head, pvol; 2297 struct pvo_entry *pvo, *next_pvo; 2298 volatile struct pte *pt; 2299 register_t msr; 2300 2301 PMAP_LOCK(); 2302 2303 KASSERT(prot != VM_PROT_ALL); 2304 LIST_INIT(&pvol); 2305 msr = pmap_interrupts_off(); 2306 2307 /* 2308 * When UVM reuses a page, it does a pmap_page_protect with 2309 * VM_PROT_NONE. At that point, we can clear the exec flag 2310 * since we know the page will have different contents. 2311 */ 2312 if ((prot & VM_PROT_READ) == 0) { 2313 DPRINTFN(EXEC, ("[pmap_page_protect: %#" _PRIxpa ": clear-exec]\n", 2314 VM_PAGE_TO_PHYS(pg))); 2315 if (pmap_attr_fetch(pg) & PTE_EXEC) { 2316 PMAPCOUNT(exec_uncached_page_protect); 2317 pmap_attr_clear(pg, PTE_EXEC); 2318 } 2319 } 2320 2321 pvo_head = vm_page_to_pvoh(pg); 2322 for (pvo = LIST_FIRST(pvo_head); pvo != NULL; pvo = next_pvo) { 2323 next_pvo = LIST_NEXT(pvo, pvo_vlink); 2324 PMAP_PVO_CHECK(pvo); /* sanity check */ 2325 2326 /* 2327 * Downgrading to no mapping at all, we just remove the entry. 2328 */ 2329 if ((prot & VM_PROT_READ) == 0) { 2330 pmap_pvo_remove(pvo, -1, &pvol); 2331 continue; 2332 } 2333 2334 /* 2335 * If EXEC permission is being revoked, just clear the 2336 * flag in the PVO. 2337 */ 2338 if ((prot & VM_PROT_EXECUTE) == 0) 2339 pvo_clear_exec(pvo); 2340 2341 /* 2342 * If this entry is already RO, don't diddle with the 2343 * page table. 2344 */ 2345 if ((pvo->pvo_pte.pte_lo & PTE_PP) == PTE_BR) { 2346 PMAP_PVO_CHECK(pvo); 2347 continue; 2348 } 2349 2350 /* 2351 * Grab the PTE before the we diddle the bits so 2352 * pvo_to_pte can verify the pte contents are as 2353 * expected. 2354 */ 2355 pt = pmap_pvo_to_pte(pvo, -1); 2356 pvo->pvo_pte.pte_lo &= ~PTE_PP; 2357 pvo->pvo_pte.pte_lo |= PTE_BR; 2358 if (pt != NULL) { 2359 pmap_pte_change(pt, &pvo->pvo_pte, pvo->pvo_vaddr); 2360 PVO_WHERE(pvo, PMAP_PAGE_PROTECT); 2361 PMAPCOUNT(ptes_changed); 2362 } 2363 PMAP_PVO_CHECK(pvo); /* sanity check */ 2364 } 2365 pmap_interrupts_restore(msr); 2366 pmap_pvo_free_list(&pvol); 2367 2368 PMAP_UNLOCK(); 2369 } 2370 2371 /* 2372 * Activate the address space for the specified process. If the process 2373 * is the current process, load the new MMU context. 2374 */ 2375 void 2376 pmap_activate(struct lwp *l) 2377 { 2378 struct pcb *pcb = &l->l_addr->u_pcb; 2379 pmap_t pmap = l->l_proc->p_vmspace->vm_map.pmap; 2380 2381 DPRINTFN(ACTIVATE, 2382 ("pmap_activate: lwp %p (curlwp %p)\n", l, curlwp)); 2383 2384 /* 2385 * XXX Normally performed in cpu_fork(). 2386 */ 2387 pcb->pcb_pm = pmap; 2388 2389 /* 2390 * In theory, the SR registers need only be valid on return 2391 * to user space wait to do them there. 2392 */ 2393 if (l == curlwp) { 2394 /* Store pointer to new current pmap. */ 2395 curpm = pmap; 2396 } 2397 } 2398 2399 /* 2400 * Deactivate the specified process's address space. 2401 */ 2402 void 2403 pmap_deactivate(struct lwp *l) 2404 { 2405 } 2406 2407 bool 2408 pmap_query_bit(struct vm_page *pg, int ptebit) 2409 { 2410 struct pvo_entry *pvo; 2411 volatile struct pte *pt; 2412 register_t msr; 2413 2414 PMAP_LOCK(); 2415 2416 if (pmap_attr_fetch(pg) & ptebit) { 2417 PMAP_UNLOCK(); 2418 return true; 2419 } 2420 2421 msr = pmap_interrupts_off(); 2422 LIST_FOREACH(pvo, vm_page_to_pvoh(pg), pvo_vlink) { 2423 PMAP_PVO_CHECK(pvo); /* sanity check */ 2424 /* 2425 * See if we saved the bit off. If so cache, it and return 2426 * success. 2427 */ 2428 if (pvo->pvo_pte.pte_lo & ptebit) { 2429 pmap_attr_save(pg, ptebit); 2430 PMAP_PVO_CHECK(pvo); /* sanity check */ 2431 pmap_interrupts_restore(msr); 2432 PMAP_UNLOCK(); 2433 return true; 2434 } 2435 } 2436 /* 2437 * No luck, now go thru the hard part of looking at the ptes 2438 * themselves. Sync so any pending REF/CHG bits are flushed 2439 * to the PTEs. 2440 */ 2441 SYNC(); 2442 LIST_FOREACH(pvo, vm_page_to_pvoh(pg), pvo_vlink) { 2443 PMAP_PVO_CHECK(pvo); /* sanity check */ 2444 /* 2445 * See if this pvo have a valid PTE. If so, fetch the 2446 * REF/CHG bits from the valid PTE. If the appropriate 2447 * ptebit is set, cache, it and return success. 2448 */ 2449 pt = pmap_pvo_to_pte(pvo, -1); 2450 if (pt != NULL) { 2451 pmap_pte_synch(pt, &pvo->pvo_pte); 2452 if (pvo->pvo_pte.pte_lo & ptebit) { 2453 pmap_attr_save(pg, ptebit); 2454 PMAP_PVO_CHECK(pvo); /* sanity check */ 2455 pmap_interrupts_restore(msr); 2456 PMAP_UNLOCK(); 2457 return true; 2458 } 2459 } 2460 } 2461 pmap_interrupts_restore(msr); 2462 PMAP_UNLOCK(); 2463 return false; 2464 } 2465 2466 bool 2467 pmap_clear_bit(struct vm_page *pg, int ptebit) 2468 { 2469 struct pvo_head *pvoh = vm_page_to_pvoh(pg); 2470 struct pvo_entry *pvo; 2471 volatile struct pte *pt; 2472 register_t msr; 2473 int rv = 0; 2474 2475 PMAP_LOCK(); 2476 msr = pmap_interrupts_off(); 2477 2478 /* 2479 * Fetch the cache value 2480 */ 2481 rv |= pmap_attr_fetch(pg); 2482 2483 /* 2484 * Clear the cached value. 2485 */ 2486 pmap_attr_clear(pg, ptebit); 2487 2488 /* 2489 * Sync so any pending REF/CHG bits are flushed to the PTEs (so we 2490 * can reset the right ones). Note that since the pvo entries and 2491 * list heads are accessed via BAT0 and are never placed in the 2492 * page table, we don't have to worry about further accesses setting 2493 * the REF/CHG bits. 2494 */ 2495 SYNC(); 2496 2497 /* 2498 * For each pvo entry, clear pvo's ptebit. If this pvo have a 2499 * valid PTE. If so, clear the ptebit from the valid PTE. 2500 */ 2501 LIST_FOREACH(pvo, pvoh, pvo_vlink) { 2502 PMAP_PVO_CHECK(pvo); /* sanity check */ 2503 pt = pmap_pvo_to_pte(pvo, -1); 2504 if (pt != NULL) { 2505 /* 2506 * Only sync the PTE if the bit we are looking 2507 * for is not already set. 2508 */ 2509 if ((pvo->pvo_pte.pte_lo & ptebit) == 0) 2510 pmap_pte_synch(pt, &pvo->pvo_pte); 2511 /* 2512 * If the bit we are looking for was already set, 2513 * clear that bit in the pte. 2514 */ 2515 if (pvo->pvo_pte.pte_lo & ptebit) 2516 pmap_pte_clear(pt, PVO_VADDR(pvo), ptebit); 2517 } 2518 rv |= pvo->pvo_pte.pte_lo & (PTE_CHG|PTE_REF); 2519 pvo->pvo_pte.pte_lo &= ~ptebit; 2520 PMAP_PVO_CHECK(pvo); /* sanity check */ 2521 } 2522 pmap_interrupts_restore(msr); 2523 2524 /* 2525 * If we are clearing the modify bit and this page was marked EXEC 2526 * and the user of the page thinks the page was modified, then we 2527 * need to clean it from the icache if it's mapped or clear the EXEC 2528 * bit if it's not mapped. The page itself might not have the CHG 2529 * bit set if the modification was done via DMA to the page. 2530 */ 2531 if ((ptebit & PTE_CHG) && (rv & PTE_EXEC)) { 2532 if (LIST_EMPTY(pvoh)) { 2533 DPRINTFN(EXEC, ("[pmap_clear_bit: %#" _PRIxpa ": clear-exec]\n", 2534 VM_PAGE_TO_PHYS(pg))); 2535 pmap_attr_clear(pg, PTE_EXEC); 2536 PMAPCOUNT(exec_uncached_clear_modify); 2537 } else { 2538 DPRINTFN(EXEC, ("[pmap_clear_bit: %#" _PRIxpa ": syncicache]\n", 2539 VM_PAGE_TO_PHYS(pg))); 2540 pmap_syncicache(VM_PAGE_TO_PHYS(pg), PAGE_SIZE); 2541 PMAPCOUNT(exec_synced_clear_modify); 2542 } 2543 } 2544 PMAP_UNLOCK(); 2545 return (rv & ptebit) != 0; 2546 } 2547 2548 void 2549 pmap_procwr(struct proc *p, vaddr_t va, size_t len) 2550 { 2551 struct pvo_entry *pvo; 2552 size_t offset = va & ADDR_POFF; 2553 int s; 2554 2555 PMAP_LOCK(); 2556 s = splvm(); 2557 while (len > 0) { 2558 size_t seglen = PAGE_SIZE - offset; 2559 if (seglen > len) 2560 seglen = len; 2561 pvo = pmap_pvo_find_va(p->p_vmspace->vm_map.pmap, va, NULL); 2562 if (pvo != NULL && PVO_EXECUTABLE_P(pvo)) { 2563 pmap_syncicache( 2564 (pvo->pvo_pte.pte_lo & PTE_RPGN) | offset, seglen); 2565 PMAP_PVO_CHECK(pvo); 2566 } 2567 va += seglen; 2568 len -= seglen; 2569 offset = 0; 2570 } 2571 splx(s); 2572 PMAP_UNLOCK(); 2573 } 2574 2575 #if defined(DEBUG) || defined(PMAPCHECK) || defined(DDB) 2576 void 2577 pmap_pte_print(volatile struct pte *pt) 2578 { 2579 printf("PTE %p: ", pt); 2580 2581 #if defined(PMAP_OEA) 2582 /* High word: */ 2583 printf("%#" _PRIxpte ": [", pt->pte_hi); 2584 #else 2585 printf("%#" _PRIxpte ": [", pt->pte_hi); 2586 #endif /* PMAP_OEA */ 2587 2588 printf("%c ", (pt->pte_hi & PTE_VALID) ? 'v' : 'i'); 2589 printf("%c ", (pt->pte_hi & PTE_HID) ? 'h' : '-'); 2590 2591 printf("%#" _PRIxpte " %#" _PRIxpte "", 2592 (pt->pte_hi &~ PTE_VALID)>>PTE_VSID_SHFT, 2593 pt->pte_hi & PTE_API); 2594 #if defined(PMAP_OEA) || defined(PMAP_OEA64_BRIDGE) 2595 printf(" (va %#" _PRIxva ")] ", pmap_pte_to_va(pt)); 2596 #else 2597 printf(" (va %#" _PRIxva ")] ", pmap_pte_to_va(pt)); 2598 #endif /* PMAP_OEA */ 2599 2600 /* Low word: */ 2601 #if defined (PMAP_OEA) 2602 printf(" %#" _PRIxpte ": [", pt->pte_lo); 2603 printf("%#" _PRIxpte "... ", pt->pte_lo >> 12); 2604 #else 2605 printf(" %#" _PRIxpte ": [", pt->pte_lo); 2606 printf("%#" _PRIxpte "... ", pt->pte_lo >> 12); 2607 #endif 2608 printf("%c ", (pt->pte_lo & PTE_REF) ? 'r' : 'u'); 2609 printf("%c ", (pt->pte_lo & PTE_CHG) ? 'c' : 'n'); 2610 printf("%c", (pt->pte_lo & PTE_W) ? 'w' : '.'); 2611 printf("%c", (pt->pte_lo & PTE_I) ? 'i' : '.'); 2612 printf("%c", (pt->pte_lo & PTE_M) ? 'm' : '.'); 2613 printf("%c ", (pt->pte_lo & PTE_G) ? 'g' : '.'); 2614 switch (pt->pte_lo & PTE_PP) { 2615 case PTE_BR: printf("br]\n"); break; 2616 case PTE_BW: printf("bw]\n"); break; 2617 case PTE_SO: printf("so]\n"); break; 2618 case PTE_SW: printf("sw]\n"); break; 2619 } 2620 } 2621 #endif 2622 2623 #if defined(DDB) 2624 void 2625 pmap_pteg_check(void) 2626 { 2627 volatile struct pte *pt; 2628 int i; 2629 int ptegidx; 2630 u_int p_valid = 0; 2631 u_int s_valid = 0; 2632 u_int invalid = 0; 2633 2634 for (ptegidx = 0; ptegidx < pmap_pteg_cnt; ptegidx++) { 2635 for (pt = pmap_pteg_table[ptegidx].pt, i = 8; --i >= 0; pt++) { 2636 if (pt->pte_hi & PTE_VALID) { 2637 if (pt->pte_hi & PTE_HID) 2638 s_valid++; 2639 else 2640 { 2641 p_valid++; 2642 } 2643 } else 2644 invalid++; 2645 } 2646 } 2647 printf("pteg_check: v(p) %#x (%d), v(s) %#x (%d), i %#x (%d)\n", 2648 p_valid, p_valid, s_valid, s_valid, 2649 invalid, invalid); 2650 } 2651 2652 void 2653 pmap_print_mmuregs(void) 2654 { 2655 int i; 2656 u_int cpuvers; 2657 #ifndef PMAP_OEA64 2658 vaddr_t addr; 2659 register_t soft_sr[16]; 2660 #endif 2661 #if defined (PMAP_OEA) || defined (PMAP_OEA_BRIDGE) 2662 struct bat soft_ibat[4]; 2663 struct bat soft_dbat[4]; 2664 #endif 2665 paddr_t sdr1; 2666 2667 cpuvers = MFPVR() >> 16; 2668 __asm volatile ("mfsdr1 %0" : "=r"(sdr1)); 2669 #ifndef PMAP_OEA64 2670 addr = 0; 2671 for (i = 0; i < 16; i++) { 2672 soft_sr[i] = MFSRIN(addr); 2673 addr += (1 << ADDR_SR_SHFT); 2674 } 2675 #endif 2676 2677 #if defined (PMAP_OEA) || defined (PMAP_OEA_BRIDGE) 2678 /* read iBAT (601: uBAT) registers */ 2679 __asm volatile ("mfibatu %0,0" : "=r"(soft_ibat[0].batu)); 2680 __asm volatile ("mfibatl %0,0" : "=r"(soft_ibat[0].batl)); 2681 __asm volatile ("mfibatu %0,1" : "=r"(soft_ibat[1].batu)); 2682 __asm volatile ("mfibatl %0,1" : "=r"(soft_ibat[1].batl)); 2683 __asm volatile ("mfibatu %0,2" : "=r"(soft_ibat[2].batu)); 2684 __asm volatile ("mfibatl %0,2" : "=r"(soft_ibat[2].batl)); 2685 __asm volatile ("mfibatu %0,3" : "=r"(soft_ibat[3].batu)); 2686 __asm volatile ("mfibatl %0,3" : "=r"(soft_ibat[3].batl)); 2687 2688 2689 if (cpuvers != MPC601) { 2690 /* read dBAT registers */ 2691 __asm volatile ("mfdbatu %0,0" : "=r"(soft_dbat[0].batu)); 2692 __asm volatile ("mfdbatl %0,0" : "=r"(soft_dbat[0].batl)); 2693 __asm volatile ("mfdbatu %0,1" : "=r"(soft_dbat[1].batu)); 2694 __asm volatile ("mfdbatl %0,1" : "=r"(soft_dbat[1].batl)); 2695 __asm volatile ("mfdbatu %0,2" : "=r"(soft_dbat[2].batu)); 2696 __asm volatile ("mfdbatl %0,2" : "=r"(soft_dbat[2].batl)); 2697 __asm volatile ("mfdbatu %0,3" : "=r"(soft_dbat[3].batu)); 2698 __asm volatile ("mfdbatl %0,3" : "=r"(soft_dbat[3].batl)); 2699 } 2700 #endif 2701 2702 printf("SDR1:\t%#" _PRIxpa "\n", sdr1); 2703 #ifndef PMAP_OEA64 2704 printf("SR[]:\t"); 2705 for (i = 0; i < 4; i++) 2706 printf("0x%08lx, ", soft_sr[i]); 2707 printf("\n\t"); 2708 for ( ; i < 8; i++) 2709 printf("0x%08lx, ", soft_sr[i]); 2710 printf("\n\t"); 2711 for ( ; i < 12; i++) 2712 printf("0x%08lx, ", soft_sr[i]); 2713 printf("\n\t"); 2714 for ( ; i < 16; i++) 2715 printf("0x%08lx, ", soft_sr[i]); 2716 printf("\n"); 2717 #endif 2718 2719 #if defined(PMAP_OEA) || defined(PMAP_OEA_BRIDGE) 2720 printf("%cBAT[]:\t", cpuvers == MPC601 ? 'u' : 'i'); 2721 for (i = 0; i < 4; i++) { 2722 printf("0x%08lx 0x%08lx, ", 2723 soft_ibat[i].batu, soft_ibat[i].batl); 2724 if (i == 1) 2725 printf("\n\t"); 2726 } 2727 if (cpuvers != MPC601) { 2728 printf("\ndBAT[]:\t"); 2729 for (i = 0; i < 4; i++) { 2730 printf("0x%08lx 0x%08lx, ", 2731 soft_dbat[i].batu, soft_dbat[i].batl); 2732 if (i == 1) 2733 printf("\n\t"); 2734 } 2735 } 2736 printf("\n"); 2737 #endif /* PMAP_OEA... */ 2738 } 2739 2740 void 2741 pmap_print_pte(pmap_t pm, vaddr_t va) 2742 { 2743 struct pvo_entry *pvo; 2744 volatile struct pte *pt; 2745 int pteidx; 2746 2747 pvo = pmap_pvo_find_va(pm, va, &pteidx); 2748 if (pvo != NULL) { 2749 pt = pmap_pvo_to_pte(pvo, pteidx); 2750 if (pt != NULL) { 2751 printf("VA %#" _PRIxva " -> %p -> %s %#" _PRIxpte ", %#" _PRIxpte "\n", 2752 va, pt, 2753 pt->pte_hi & PTE_HID ? "(sec)" : "(pri)", 2754 pt->pte_hi, pt->pte_lo); 2755 } else { 2756 printf("No valid PTE found\n"); 2757 } 2758 } else { 2759 printf("Address not in pmap\n"); 2760 } 2761 } 2762 2763 void 2764 pmap_pteg_dist(void) 2765 { 2766 struct pvo_entry *pvo; 2767 int ptegidx; 2768 int depth; 2769 int max_depth = 0; 2770 unsigned int depths[64]; 2771 2772 memset(depths, 0, sizeof(depths)); 2773 for (ptegidx = 0; ptegidx < pmap_pteg_cnt; ptegidx++) { 2774 depth = 0; 2775 TAILQ_FOREACH(pvo, &pmap_pvo_table[ptegidx], pvo_olink) { 2776 depth++; 2777 } 2778 if (depth > max_depth) 2779 max_depth = depth; 2780 if (depth > 63) 2781 depth = 63; 2782 depths[depth]++; 2783 } 2784 2785 for (depth = 0; depth < 64; depth++) { 2786 printf(" [%2d]: %8u", depth, depths[depth]); 2787 if ((depth & 3) == 3) 2788 printf("\n"); 2789 if (depth == max_depth) 2790 break; 2791 } 2792 if ((depth & 3) != 3) 2793 printf("\n"); 2794 printf("Max depth found was %d\n", max_depth); 2795 } 2796 #endif /* DEBUG */ 2797 2798 #if defined(PMAPCHECK) || defined(DEBUG) 2799 void 2800 pmap_pvo_verify(void) 2801 { 2802 int ptegidx; 2803 int s; 2804 2805 s = splvm(); 2806 for (ptegidx = 0; ptegidx < pmap_pteg_cnt; ptegidx++) { 2807 struct pvo_entry *pvo; 2808 TAILQ_FOREACH(pvo, &pmap_pvo_table[ptegidx], pvo_olink) { 2809 if ((uintptr_t) pvo >= SEGMENT_LENGTH) 2810 panic("pmap_pvo_verify: invalid pvo %p " 2811 "on list %#x", pvo, ptegidx); 2812 pmap_pvo_check(pvo); 2813 } 2814 } 2815 splx(s); 2816 } 2817 #endif /* PMAPCHECK */ 2818 2819 2820 void * 2821 pmap_pool_ualloc(struct pool *pp, int flags) 2822 { 2823 struct pvo_page *pvop; 2824 2825 if (uvm.page_init_done != true) { 2826 return (void *) uvm_pageboot_alloc(PAGE_SIZE); 2827 } 2828 2829 PMAP_LOCK(); 2830 pvop = SIMPLEQ_FIRST(&pmap_upvop_head); 2831 if (pvop != NULL) { 2832 pmap_upvop_free--; 2833 SIMPLEQ_REMOVE_HEAD(&pmap_upvop_head, pvop_link); 2834 PMAP_UNLOCK(); 2835 return pvop; 2836 } 2837 PMAP_UNLOCK(); 2838 return pmap_pool_malloc(pp, flags); 2839 } 2840 2841 void * 2842 pmap_pool_malloc(struct pool *pp, int flags) 2843 { 2844 struct pvo_page *pvop; 2845 struct vm_page *pg; 2846 2847 PMAP_LOCK(); 2848 pvop = SIMPLEQ_FIRST(&pmap_mpvop_head); 2849 if (pvop != NULL) { 2850 pmap_mpvop_free--; 2851 SIMPLEQ_REMOVE_HEAD(&pmap_mpvop_head, pvop_link); 2852 PMAP_UNLOCK(); 2853 return pvop; 2854 } 2855 PMAP_UNLOCK(); 2856 again: 2857 pg = uvm_pagealloc_strat(NULL, 0, NULL, UVM_PGA_USERESERVE, 2858 UVM_PGA_STRAT_ONLY, VM_FREELIST_FIRST256); 2859 if (__predict_false(pg == NULL)) { 2860 if (flags & PR_WAITOK) { 2861 uvm_wait("plpg"); 2862 goto again; 2863 } else { 2864 return (0); 2865 } 2866 } 2867 KDASSERT(VM_PAGE_TO_PHYS(pg) == (uintptr_t)VM_PAGE_TO_PHYS(pg)); 2868 return (void *)(uintptr_t) VM_PAGE_TO_PHYS(pg); 2869 } 2870 2871 void 2872 pmap_pool_ufree(struct pool *pp, void *va) 2873 { 2874 struct pvo_page *pvop; 2875 #if 0 2876 if (PHYS_TO_VM_PAGE((paddr_t) va) != NULL) { 2877 pmap_pool_mfree(va, size, tag); 2878 return; 2879 } 2880 #endif 2881 PMAP_LOCK(); 2882 pvop = va; 2883 SIMPLEQ_INSERT_HEAD(&pmap_upvop_head, pvop, pvop_link); 2884 pmap_upvop_free++; 2885 if (pmap_upvop_free > pmap_upvop_maxfree) 2886 pmap_upvop_maxfree = pmap_upvop_free; 2887 PMAP_UNLOCK(); 2888 } 2889 2890 void 2891 pmap_pool_mfree(struct pool *pp, void *va) 2892 { 2893 struct pvo_page *pvop; 2894 2895 PMAP_LOCK(); 2896 pvop = va; 2897 SIMPLEQ_INSERT_HEAD(&pmap_mpvop_head, pvop, pvop_link); 2898 pmap_mpvop_free++; 2899 if (pmap_mpvop_free > pmap_mpvop_maxfree) 2900 pmap_mpvop_maxfree = pmap_mpvop_free; 2901 PMAP_UNLOCK(); 2902 #if 0 2903 uvm_pagefree(PHYS_TO_VM_PAGE((paddr_t) va)); 2904 #endif 2905 } 2906 2907 /* 2908 * This routine in bootstraping to steal to-be-managed memory (which will 2909 * then be unmanaged). We use it to grab from the first 256MB for our 2910 * pmap needs and above 256MB for other stuff. 2911 */ 2912 vaddr_t 2913 pmap_steal_memory(vsize_t vsize, vaddr_t *vstartp, vaddr_t *vendp) 2914 { 2915 vsize_t size; 2916 vaddr_t va; 2917 paddr_t pa = 0; 2918 int npgs, bank; 2919 struct vm_physseg *ps; 2920 2921 if (uvm.page_init_done == true) 2922 panic("pmap_steal_memory: called _after_ bootstrap"); 2923 2924 *vstartp = VM_MIN_KERNEL_ADDRESS; 2925 *vendp = VM_MAX_KERNEL_ADDRESS; 2926 2927 size = round_page(vsize); 2928 npgs = atop(size); 2929 2930 /* 2931 * PA 0 will never be among those given to UVM so we can use it 2932 * to indicate we couldn't steal any memory. 2933 */ 2934 for (ps = vm_physmem, bank = 0; bank < vm_nphysseg; bank++, ps++) { 2935 if (ps->free_list == VM_FREELIST_FIRST256 && 2936 ps->avail_end - ps->avail_start >= npgs) { 2937 pa = ptoa(ps->avail_start); 2938 break; 2939 } 2940 } 2941 2942 if (pa == 0) 2943 panic("pmap_steal_memory: no approriate memory to steal!"); 2944 2945 ps->avail_start += npgs; 2946 ps->start += npgs; 2947 2948 /* 2949 * If we've used up all the pages in the segment, remove it and 2950 * compact the list. 2951 */ 2952 if (ps->avail_start == ps->end) { 2953 /* 2954 * If this was the last one, then a very bad thing has occurred 2955 */ 2956 if (--vm_nphysseg == 0) 2957 panic("pmap_steal_memory: out of memory!"); 2958 2959 printf("pmap_steal_memory: consumed bank %d\n", bank); 2960 for (; bank < vm_nphysseg; bank++, ps++) { 2961 ps[0] = ps[1]; 2962 } 2963 } 2964 2965 va = (vaddr_t) pa; 2966 memset((void *) va, 0, size); 2967 pmap_pages_stolen += npgs; 2968 #ifdef DEBUG 2969 if (pmapdebug && npgs > 1) { 2970 u_int cnt = 0; 2971 for (bank = 0, ps = vm_physmem; bank < vm_nphysseg; bank++, ps++) 2972 cnt += ps->avail_end - ps->avail_start; 2973 printf("pmap_steal_memory: stole %u (total %u) pages (%u left)\n", 2974 npgs, pmap_pages_stolen, cnt); 2975 } 2976 #endif 2977 2978 return va; 2979 } 2980 2981 /* 2982 * Find a chuck of memory with right size and alignment. 2983 */ 2984 paddr_t 2985 pmap_boot_find_memory(psize_t size, psize_t alignment, int at_end) 2986 { 2987 struct mem_region *mp; 2988 paddr_t s, e; 2989 int i, j; 2990 2991 size = round_page(size); 2992 2993 DPRINTFN(BOOT, 2994 ("pmap_boot_find_memory: size=%#" _PRIxpa ", alignment=%#" _PRIxpa ", at_end=%d", 2995 size, alignment, at_end)); 2996 2997 if (alignment < PAGE_SIZE || (alignment & (alignment-1)) != 0) 2998 panic("pmap_boot_find_memory: invalid alignment %#" _PRIxpa, 2999 alignment); 3000 3001 if (at_end) { 3002 if (alignment != PAGE_SIZE) 3003 panic("pmap_boot_find_memory: invalid ending " 3004 "alignment %#" _PRIxpa, alignment); 3005 3006 for (mp = &avail[avail_cnt-1]; mp >= avail; mp--) { 3007 s = mp->start + mp->size - size; 3008 if (s >= mp->start && mp->size >= size) { 3009 DPRINTFN(BOOT,(": %#" _PRIxpa "\n", s)); 3010 DPRINTFN(BOOT, 3011 ("pmap_boot_find_memory: b-avail[%d] start " 3012 "%#" _PRIxpa " size %#" _PRIxpa "\n", mp - avail, 3013 mp->start, mp->size)); 3014 mp->size -= size; 3015 DPRINTFN(BOOT, 3016 ("pmap_boot_find_memory: a-avail[%d] start " 3017 "%#" _PRIxpa " size %#" _PRIxpa "\n", mp - avail, 3018 mp->start, mp->size)); 3019 return s; 3020 } 3021 } 3022 panic("pmap_boot_find_memory: no available memory"); 3023 } 3024 3025 for (mp = avail, i = 0; i < avail_cnt; i++, mp++) { 3026 s = (mp->start + alignment - 1) & ~(alignment-1); 3027 e = s + size; 3028 3029 /* 3030 * Is the calculated region entirely within the region? 3031 */ 3032 if (s < mp->start || e > mp->start + mp->size) 3033 continue; 3034 3035 DPRINTFN(BOOT,(": %#" _PRIxpa "\n", s)); 3036 if (s == mp->start) { 3037 /* 3038 * If the block starts at the beginning of region, 3039 * adjust the size & start. (the region may now be 3040 * zero in length) 3041 */ 3042 DPRINTFN(BOOT, 3043 ("pmap_boot_find_memory: b-avail[%d] start " 3044 "%#" _PRIxpa " size %#" _PRIxpa "\n", i, mp->start, mp->size)); 3045 mp->start += size; 3046 mp->size -= size; 3047 DPRINTFN(BOOT, 3048 ("pmap_boot_find_memory: a-avail[%d] start " 3049 "%#" _PRIxpa " size %#" _PRIxpa "\n", i, mp->start, mp->size)); 3050 } else if (e == mp->start + mp->size) { 3051 /* 3052 * If the block starts at the beginning of region, 3053 * adjust only the size. 3054 */ 3055 DPRINTFN(BOOT, 3056 ("pmap_boot_find_memory: b-avail[%d] start " 3057 "%#" _PRIxpa " size %#" _PRIxpa "\n", i, mp->start, mp->size)); 3058 mp->size -= size; 3059 DPRINTFN(BOOT, 3060 ("pmap_boot_find_memory: a-avail[%d] start " 3061 "%#" _PRIxpa " size %#" _PRIxpa "\n", i, mp->start, mp->size)); 3062 } else { 3063 /* 3064 * Block is in the middle of the region, so we 3065 * have to split it in two. 3066 */ 3067 for (j = avail_cnt; j > i + 1; j--) { 3068 avail[j] = avail[j-1]; 3069 } 3070 DPRINTFN(BOOT, 3071 ("pmap_boot_find_memory: b-avail[%d] start " 3072 "%#" _PRIxpa " size %#" _PRIxpa "\n", i, mp->start, mp->size)); 3073 mp[1].start = e; 3074 mp[1].size = mp[0].start + mp[0].size - e; 3075 mp[0].size = s - mp[0].start; 3076 avail_cnt++; 3077 for (; i < avail_cnt; i++) { 3078 DPRINTFN(BOOT, 3079 ("pmap_boot_find_memory: a-avail[%d] " 3080 "start %#" _PRIxpa " size %#" _PRIxpa "\n", i, 3081 avail[i].start, avail[i].size)); 3082 } 3083 } 3084 KASSERT(s == (uintptr_t) s); 3085 return s; 3086 } 3087 panic("pmap_boot_find_memory: not enough memory for " 3088 "%#" _PRIxpa "/%#" _PRIxpa " allocation?", size, alignment); 3089 } 3090 3091 /* XXXSL: we dont have any BATs to do this, map in Segment 0 1:1 using page tables */ 3092 #if defined (PMAP_OEA64_BRIDGE) 3093 int 3094 pmap_setup_segment0_map(int use_large_pages, ...) 3095 { 3096 vaddr_t va; 3097 3098 register_t pte_lo = 0x0; 3099 int ptegidx = 0, i = 0; 3100 struct pte pte; 3101 va_list ap; 3102 3103 /* Coherent + Supervisor RW, no user access */ 3104 pte_lo = PTE_M; 3105 3106 /* XXXSL 3107 * Map in 1st segment 1:1, we'll be careful not to spill kernel entries later, 3108 * these have to take priority. 3109 */ 3110 for (va = 0x0; va < SEGMENT_LENGTH; va += 0x1000) { 3111 ptegidx = va_to_pteg(pmap_kernel(), va); 3112 pmap_pte_create(&pte, pmap_kernel(), va, va | pte_lo); 3113 i = pmap_pte_insert(ptegidx, &pte); 3114 } 3115 3116 va_start(ap, use_large_pages); 3117 while (1) { 3118 paddr_t pa; 3119 size_t size; 3120 3121 va = va_arg(ap, vaddr_t); 3122 3123 if (va == 0) 3124 break; 3125 3126 pa = va_arg(ap, paddr_t); 3127 size = va_arg(ap, size_t); 3128 3129 for (; va < (va + size); va += 0x1000, pa += 0x1000) { 3130 #if 0 3131 printf("%s: Inserting: va: %#" _PRIxva ", pa: %#" _PRIxpa "\n", __func__, va, pa); 3132 #endif 3133 ptegidx = va_to_pteg(pmap_kernel(), va); 3134 pmap_pte_create(&pte, pmap_kernel(), va, pa | pte_lo); 3135 i = pmap_pte_insert(ptegidx, &pte); 3136 } 3137 } 3138 3139 TLBSYNC(); 3140 SYNC(); 3141 return (0); 3142 } 3143 #endif /* PMAP_OEA64_BRIDGE */ 3144 3145 /* 3146 * This is not part of the defined PMAP interface and is specific to the 3147 * PowerPC architecture. This is called during initppc, before the system 3148 * is really initialized. 3149 */ 3150 void 3151 pmap_bootstrap(paddr_t kernelstart, paddr_t kernelend) 3152 { 3153 struct mem_region *mp, tmp; 3154 paddr_t s, e; 3155 psize_t size; 3156 int i, j; 3157 3158 /* 3159 * Get memory. 3160 */ 3161 mem_regions(&mem, &avail); 3162 #if defined(DEBUG) 3163 if (pmapdebug & PMAPDEBUG_BOOT) { 3164 printf("pmap_bootstrap: memory configuration:\n"); 3165 for (mp = mem; mp->size; mp++) { 3166 printf("pmap_bootstrap: mem start %#" _PRIxpa " size %#" _PRIxpa "\n", 3167 mp->start, mp->size); 3168 } 3169 for (mp = avail; mp->size; mp++) { 3170 printf("pmap_bootstrap: avail start %#" _PRIxpa " size %#" _PRIxpa "\n", 3171 mp->start, mp->size); 3172 } 3173 } 3174 #endif 3175 3176 /* 3177 * Find out how much physical memory we have and in how many chunks. 3178 */ 3179 for (mem_cnt = 0, mp = mem; mp->size; mp++) { 3180 if (mp->start >= pmap_memlimit) 3181 continue; 3182 if (mp->start + mp->size > pmap_memlimit) { 3183 size = pmap_memlimit - mp->start; 3184 physmem += btoc(size); 3185 } else { 3186 physmem += btoc(mp->size); 3187 } 3188 mem_cnt++; 3189 } 3190 3191 /* 3192 * Count the number of available entries. 3193 */ 3194 for (avail_cnt = 0, mp = avail; mp->size; mp++) 3195 avail_cnt++; 3196 3197 /* 3198 * Page align all regions. 3199 */ 3200 kernelstart = trunc_page(kernelstart); 3201 kernelend = round_page(kernelend); 3202 for (mp = avail, i = 0; i < avail_cnt; i++, mp++) { 3203 s = round_page(mp->start); 3204 mp->size -= (s - mp->start); 3205 mp->size = trunc_page(mp->size); 3206 mp->start = s; 3207 e = mp->start + mp->size; 3208 3209 DPRINTFN(BOOT, 3210 ("pmap_bootstrap: b-avail[%d] start %#" _PRIxpa " size %#" _PRIxpa "\n", 3211 i, mp->start, mp->size)); 3212 3213 /* 3214 * Don't allow the end to run beyond our artificial limit 3215 */ 3216 if (e > pmap_memlimit) 3217 e = pmap_memlimit; 3218 3219 /* 3220 * Is this region empty or strange? skip it. 3221 */ 3222 if (e <= s) { 3223 mp->start = 0; 3224 mp->size = 0; 3225 continue; 3226 } 3227 3228 /* 3229 * Does this overlap the beginning of kernel? 3230 * Does extend past the end of the kernel? 3231 */ 3232 else if (s < kernelstart && e > kernelstart) { 3233 if (e > kernelend) { 3234 avail[avail_cnt].start = kernelend; 3235 avail[avail_cnt].size = e - kernelend; 3236 avail_cnt++; 3237 } 3238 mp->size = kernelstart - s; 3239 } 3240 /* 3241 * Check whether this region overlaps the end of the kernel. 3242 */ 3243 else if (s < kernelend && e > kernelend) { 3244 mp->start = kernelend; 3245 mp->size = e - kernelend; 3246 } 3247 /* 3248 * Look whether this regions is completely inside the kernel. 3249 * Nuke it if it does. 3250 */ 3251 else if (s >= kernelstart && e <= kernelend) { 3252 mp->start = 0; 3253 mp->size = 0; 3254 } 3255 /* 3256 * If the user imposed a memory limit, enforce it. 3257 */ 3258 else if (s >= pmap_memlimit) { 3259 mp->start = -PAGE_SIZE; /* let's know why */ 3260 mp->size = 0; 3261 } 3262 else { 3263 mp->start = s; 3264 mp->size = e - s; 3265 } 3266 DPRINTFN(BOOT, 3267 ("pmap_bootstrap: a-avail[%d] start %#" _PRIxpa " size %#" _PRIxpa "\n", 3268 i, mp->start, mp->size)); 3269 } 3270 3271 /* 3272 * Move (and uncount) all the null return to the end. 3273 */ 3274 for (mp = avail, i = 0; i < avail_cnt; i++, mp++) { 3275 if (mp->size == 0) { 3276 tmp = avail[i]; 3277 avail[i] = avail[--avail_cnt]; 3278 avail[avail_cnt] = avail[i]; 3279 } 3280 } 3281 3282 /* 3283 * (Bubble)sort them into ascending order. 3284 */ 3285 for (i = 0; i < avail_cnt; i++) { 3286 for (j = i + 1; j < avail_cnt; j++) { 3287 if (avail[i].start > avail[j].start) { 3288 tmp = avail[i]; 3289 avail[i] = avail[j]; 3290 avail[j] = tmp; 3291 } 3292 } 3293 } 3294 3295 /* 3296 * Make sure they don't overlap. 3297 */ 3298 for (mp = avail, i = 0; i < avail_cnt - 1; i++, mp++) { 3299 if (mp[0].start + mp[0].size > mp[1].start) { 3300 mp[0].size = mp[1].start - mp[0].start; 3301 } 3302 DPRINTFN(BOOT, 3303 ("pmap_bootstrap: avail[%d] start %#" _PRIxpa " size %#" _PRIxpa "\n", 3304 i, mp->start, mp->size)); 3305 } 3306 DPRINTFN(BOOT, 3307 ("pmap_bootstrap: avail[%d] start %#" _PRIxpa " size %#" _PRIxpa "\n", 3308 i, mp->start, mp->size)); 3309 3310 #ifdef PTEGCOUNT 3311 pmap_pteg_cnt = PTEGCOUNT; 3312 #else /* PTEGCOUNT */ 3313 3314 pmap_pteg_cnt = 0x1000; 3315 3316 while (pmap_pteg_cnt < physmem) 3317 pmap_pteg_cnt <<= 1; 3318 3319 pmap_pteg_cnt >>= 1; 3320 #endif /* PTEGCOUNT */ 3321 3322 #ifdef DEBUG 3323 DPRINTFN(BOOT, 3324 ("pmap_pteg_cnt: 0x%x\n", pmap_pteg_cnt)); 3325 #endif 3326 3327 /* 3328 * Find suitably aligned memory for PTEG hash table. 3329 */ 3330 size = pmap_pteg_cnt * sizeof(struct pteg); 3331 pmap_pteg_table = (void *)(uintptr_t) pmap_boot_find_memory(size, size, 0); 3332 3333 #ifdef DEBUG 3334 DPRINTFN(BOOT, 3335 ("PTEG cnt: 0x%x HTAB size: 0x%08x bytes, address: %p\n", pmap_pteg_cnt, (unsigned int)size, pmap_pteg_table)); 3336 #endif 3337 3338 3339 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK) 3340 if ( (uintptr_t) pmap_pteg_table + size > SEGMENT_LENGTH) 3341 panic("pmap_bootstrap: pmap_pteg_table end (%p + %#" _PRIxpa ") > 256MB", 3342 pmap_pteg_table, size); 3343 #endif 3344 3345 memset(__UNVOLATILE(pmap_pteg_table), 0, 3346 pmap_pteg_cnt * sizeof(struct pteg)); 3347 pmap_pteg_mask = pmap_pteg_cnt - 1; 3348 3349 /* 3350 * We cannot do pmap_steal_memory here since UVM hasn't been loaded 3351 * with pages. So we just steal them before giving them to UVM. 3352 */ 3353 size = sizeof(pmap_pvo_table[0]) * pmap_pteg_cnt; 3354 pmap_pvo_table = (void *)(uintptr_t) pmap_boot_find_memory(size, PAGE_SIZE, 0); 3355 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK) 3356 if ( (uintptr_t) pmap_pvo_table + size > SEGMENT_LENGTH) 3357 panic("pmap_bootstrap: pmap_pvo_table end (%p + %#" _PRIxpa ") > 256MB", 3358 pmap_pvo_table, size); 3359 #endif 3360 3361 for (i = 0; i < pmap_pteg_cnt; i++) 3362 TAILQ_INIT(&pmap_pvo_table[i]); 3363 3364 #ifndef MSGBUFADDR 3365 /* 3366 * Allocate msgbuf in high memory. 3367 */ 3368 msgbuf_paddr = pmap_boot_find_memory(MSGBUFSIZE, PAGE_SIZE, 1); 3369 #endif 3370 3371 for (mp = avail, i = 0; i < avail_cnt; mp++, i++) { 3372 paddr_t pfstart = atop(mp->start); 3373 paddr_t pfend = atop(mp->start + mp->size); 3374 if (mp->size == 0) 3375 continue; 3376 if (mp->start + mp->size <= SEGMENT_LENGTH) { 3377 uvm_page_physload(pfstart, pfend, pfstart, pfend, 3378 VM_FREELIST_FIRST256); 3379 } else if (mp->start >= SEGMENT_LENGTH) { 3380 uvm_page_physload(pfstart, pfend, pfstart, pfend, 3381 VM_FREELIST_DEFAULT); 3382 } else { 3383 pfend = atop(SEGMENT_LENGTH); 3384 uvm_page_physload(pfstart, pfend, pfstart, pfend, 3385 VM_FREELIST_FIRST256); 3386 pfstart = atop(SEGMENT_LENGTH); 3387 pfend = atop(mp->start + mp->size); 3388 uvm_page_physload(pfstart, pfend, pfstart, pfend, 3389 VM_FREELIST_DEFAULT); 3390 } 3391 } 3392 3393 /* 3394 * Make sure kernel vsid is allocated as well as VSID 0. 3395 */ 3396 pmap_vsid_bitmap[(KERNEL_VSIDBITS & (NPMAPS-1)) / VSID_NBPW] 3397 |= 1 << (KERNEL_VSIDBITS % VSID_NBPW); 3398 pmap_vsid_bitmap[(PHYSMAP_VSIDBITS & (NPMAPS-1)) / VSID_NBPW] 3399 |= 1 << (PHYSMAP_VSIDBITS % VSID_NBPW); 3400 pmap_vsid_bitmap[0] |= 1; 3401 3402 /* 3403 * Initialize kernel pmap and hardware. 3404 */ 3405 3406 /* PMAP_OEA64_BRIDGE does support these instructions */ 3407 #if defined (PMAP_OEA) || defined (PMAP_OEA64_BRIDGE) 3408 for (i = 0; i < 16; i++) { 3409 pmap_kernel()->pm_sr[i] = KERNELN_SEGMENT(i)|SR_PRKEY; 3410 __asm volatile ("mtsrin %0,%1" 3411 :: "r"(KERNELN_SEGMENT(i)|SR_PRKEY), "r"(i << ADDR_SR_SHFT)); 3412 } 3413 3414 pmap_kernel()->pm_sr[KERNEL_SR] = KERNEL_SEGMENT|SR_SUKEY|SR_PRKEY; 3415 __asm volatile ("mtsr %0,%1" 3416 :: "n"(KERNEL_SR), "r"(KERNEL_SEGMENT)); 3417 #ifdef KERNEL2_SR 3418 pmap_kernel()->pm_sr[KERNEL2_SR] = KERNEL2_SEGMENT|SR_SUKEY|SR_PRKEY; 3419 __asm volatile ("mtsr %0,%1" 3420 :: "n"(KERNEL2_SR), "r"(KERNEL2_SEGMENT)); 3421 #endif 3422 #endif /* PMAP_OEA || PMAP_OEA64_BRIDGE */ 3423 #if defined (PMAP_OEA) 3424 for (i = 0; i < 16; i++) { 3425 if (iosrtable[i] & SR601_T) { 3426 pmap_kernel()->pm_sr[i] = iosrtable[i]; 3427 __asm volatile ("mtsrin %0,%1" 3428 :: "r"(iosrtable[i]), "r"(i << ADDR_SR_SHFT)); 3429 } 3430 } 3431 __asm volatile ("sync; mtsdr1 %0; isync" 3432 :: "r"((uintptr_t)pmap_pteg_table | (pmap_pteg_mask >> 10))); 3433 #elif defined (PMAP_OEA64) || defined (PMAP_OEA64_BRIDGE) 3434 __asm __volatile ("sync; mtsdr1 %0; isync" 3435 :: "r"((uintptr_t)pmap_pteg_table | (32 - cntlzw(pmap_pteg_mask >> 11)))); 3436 #endif 3437 tlbia(); 3438 3439 #ifdef ALTIVEC 3440 pmap_use_altivec = cpu_altivec; 3441 #endif 3442 3443 #ifdef DEBUG 3444 if (pmapdebug & PMAPDEBUG_BOOT) { 3445 u_int cnt; 3446 int bank; 3447 char pbuf[9]; 3448 for (cnt = 0, bank = 0; bank < vm_nphysseg; bank++) { 3449 cnt += vm_physmem[bank].avail_end - vm_physmem[bank].avail_start; 3450 printf("pmap_bootstrap: vm_physmem[%d]=%#" _PRIxpa "-%#" _PRIxpa "/%#" _PRIxpa "\n", 3451 bank, 3452 ptoa(vm_physmem[bank].avail_start), 3453 ptoa(vm_physmem[bank].avail_end), 3454 ptoa(vm_physmem[bank].avail_end - vm_physmem[bank].avail_start)); 3455 } 3456 format_bytes(pbuf, sizeof(pbuf), ptoa((u_int64_t) cnt)); 3457 printf("pmap_bootstrap: UVM memory = %s (%u pages)\n", 3458 pbuf, cnt); 3459 } 3460 #endif 3461 3462 pool_init(&pmap_upvo_pool, sizeof(struct pvo_entry), 3463 sizeof(struct pvo_entry), 0, 0, "pmap_upvopl", 3464 &pmap_pool_uallocator, IPL_VM); 3465 3466 pool_setlowat(&pmap_upvo_pool, 252); 3467 3468 pool_init(&pmap_pool, sizeof(struct pmap), 3469 sizeof(void *), 0, 0, "pmap_pl", &pmap_pool_uallocator, 3470 IPL_NONE); 3471 3472 #if defined(PMAP_NEED_MAPKERNEL) || 1 3473 { 3474 struct pmap *pm = pmap_kernel(); 3475 #if defined(PMAP_NEED_FULL_MAPKERNEL) 3476 extern int etext[], kernel_text[]; 3477 vaddr_t va, va_etext = (paddr_t) etext; 3478 #endif 3479 paddr_t pa, pa_end; 3480 register_t sr; 3481 struct pte pt; 3482 unsigned int ptegidx; 3483 int bank; 3484 3485 sr = PHYSMAPN_SEGMENT(0) | SR_SUKEY|SR_PRKEY; 3486 pm->pm_sr[0] = sr; 3487 3488 for (bank = 0; bank < vm_nphysseg; bank++) { 3489 pa_end = ptoa(vm_physmem[bank].avail_end); 3490 pa = ptoa(vm_physmem[bank].avail_start); 3491 for (; pa < pa_end; pa += PAGE_SIZE) { 3492 ptegidx = va_to_pteg(pm, pa); 3493 pmap_pte_create(&pt, pm, pa, pa | PTE_M|PTE_BW); 3494 pmap_pte_insert(ptegidx, &pt); 3495 } 3496 } 3497 3498 #if defined(PMAP_NEED_FULL_MAPKERNEL) 3499 va = (vaddr_t) kernel_text; 3500 3501 for (pa = kernelstart; va < va_etext; 3502 pa += PAGE_SIZE, va += PAGE_SIZE) { 3503 ptegidx = va_to_pteg(pm, va); 3504 pmap_pte_create(&pt, pm, va, pa | PTE_M|PTE_BR); 3505 pmap_pte_insert(ptegidx, &pt); 3506 } 3507 3508 for (; pa < kernelend; 3509 pa += PAGE_SIZE, va += PAGE_SIZE) { 3510 ptegidx = va_to_pteg(pm, va); 3511 pmap_pte_create(&pt, pm, va, pa | PTE_M|PTE_BW); 3512 pmap_pte_insert(ptegidx, &pt); 3513 } 3514 3515 for (va = 0, pa = 0; va < kernelstart; 3516 pa += PAGE_SIZE, va += PAGE_SIZE) { 3517 ptegidx = va_to_pteg(pm, va); 3518 if (va < 0x3000) 3519 pmap_pte_create(&pt, pm, va, pa | PTE_M|PTE_BR); 3520 else 3521 pmap_pte_create(&pt, pm, va, pa | PTE_M|PTE_BW); 3522 pmap_pte_insert(ptegidx, &pt); 3523 } 3524 for (va = kernelend, pa = kernelend; va < SEGMENT_LENGTH; 3525 pa += PAGE_SIZE, va += PAGE_SIZE) { 3526 ptegidx = va_to_pteg(pm, va); 3527 pmap_pte_create(&pt, pm, va, pa | PTE_M|PTE_BW); 3528 pmap_pte_insert(ptegidx, &pt); 3529 } 3530 #endif 3531 3532 __asm volatile ("mtsrin %0,%1" 3533 :: "r"(sr), "r"(kernelstart)); 3534 } 3535 #endif 3536 } 3537