pmap.c revision 81384
1/*- 2 * Copyright (c) 2001 Jake Burkholder. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD: head/sys/sparc64/sparc64/pmap.c 81384 2001-08-10 04:37:03Z jake $ 27 */ 28 29/* 30 * Manages physical address maps. 31 * 32 * In addition to hardware address maps, this module is called upon to 33 * provide software-use-only maps which may or may not be stored in the 34 * same form as hardware maps. These pseudo-maps are used to store 35 * intermediate results from copy operations to and from address spaces. 36 * 37 * Since the information managed by this module is also stored by the 38 * logical address mapping module, this module may throw away valid virtual 39 * to physical mappings at almost any time. However, invalidations of 40 * mappings must be done as requested. 41 * 42 * In order to cope with hardware architectures which make virtual to 43 * physical map invalidates expensive, this module may delay invalidate 44 * reduced protection operations until such time as they are actually 45 * necessary. This module is given full information as to which processors 46 * are currently using which maps, and to when physical maps must be made 47 * correct. 48 */ 49 50#include <sys/param.h> 51#include <sys/lock.h> 52#include <sys/mutex.h> 53#include <sys/proc.h> 54#include <sys/systm.h> 55#include <sys/vmmeter.h> 56 57#include <dev/ofw/openfirm.h> 58 59#include <vm/vm.h> 60#include <vm/vm_param.h> 61#include <vm/vm_kern.h> 62#include <vm/vm_page.h> 63#include <vm/vm_map.h> 64#include <vm/vm_object.h> 65#include <vm/vm_extern.h> 66#include <vm/vm_pageout.h> 67#include <vm/vm_pager.h> 68#include <vm/vm_zone.h> 69 70#include <machine/frame.h> 71#include <machine/pv.h> 72#include <machine/tlb.h> 73#include <machine/tte.h> 74#include <machine/tsb.h> 75 76#define PMAP_DEBUG 77 78#define PMAP_LOCK(pm) 79#define PMAP_UNLOCK(pm) 80 81#define dcache_global_flush(pa) 82#define icache_global_flush(pa) 83 84struct mem_region { 85 vm_offset_t mr_start; 86 vm_offset_t mr_size; 87}; 88 89struct ofw_map { 90 vm_offset_t om_start; 91 vm_offset_t om_size; 92 u_long om_tte; 93}; 94 95/* 96 * Virtual address of message buffer. 97 */ 98struct msgbuf *msgbufp; 99 100/* 101 * Physical addresses of first and last available physical page. 102 */ 103vm_offset_t avail_start; 104vm_offset_t avail_end; 105 106/* 107 * Map of physical memory reagions. 108 */ 109vm_offset_t phys_avail[10]; 110 111/* 112 * First and last available kernel virtual addresses. 113 */ 114vm_offset_t virtual_avail; 115vm_offset_t virtual_end; 116vm_offset_t kernel_vm_end; 117 118/* 119 * Kernel pmap handle and associated storage. 120 */ 121pmap_t kernel_pmap; 122static struct pmap kernel_pmap_store; 123 124/* 125 * Map of free and in use hardware contexts and index of first potentially 126 * free context. 127 */ 128static char pmap_context_map[PMAP_CONTEXT_MAX]; 129static u_int pmap_context_base; 130 131/* 132 * Virtual addresses of free space for temporary mappings. Used for copying 133 * and zeroing physical pages. 134 */ 135static vm_offset_t CADDR1; 136static vm_offset_t CADDR2; 137 138/* 139 * Allocate and free hardware context numbers. 140 */ 141static u_int pmap_context_alloc(void); 142static void pmap_context_destroy(u_int i); 143 144/* 145 * Allocate physical memory for use in pmap_bootstrap. 146 */ 147static vm_offset_t pmap_bootstrap_alloc(vm_size_t size); 148 149/* 150 * Quick sort callout for comparing memory regions. 151 */ 152static int mr_cmp(const void *a, const void *b); 153static int 154mr_cmp(const void *a, const void *b) 155{ 156 return ((const struct mem_region *)a)->mr_start - 157 ((const struct mem_region *)b)->mr_start; 158} 159 160/* 161 * Bootstrap the system enough to run with virtual memory. 162 */ 163void 164pmap_bootstrap(vm_offset_t skpa, vm_offset_t ekva) 165{ 166 struct mem_region mra[8]; 167 ihandle_t pmem; 168 struct pmap *pm; 169 vm_offset_t pa; 170 vm_offset_t va; 171 struct tte tte; 172 int sz; 173 int i; 174 int j; 175 176 /* 177 * Find out what physical memory is available from the prom and 178 * initialize the phys_avail array. 179 */ 180 if ((pmem = OF_finddevice("/memory")) == -1) 181 panic("pmap_bootstrap: finddevice /memory"); 182 if ((sz = OF_getproplen(pmem, "available")) == -1) 183 panic("pmap_bootstrap: getproplen /memory/available"); 184 if (sizeof(phys_avail) < sz) 185 panic("pmap_bootstrap: phys_avail too small"); 186 bzero(mra, sz); 187 if (OF_getprop(pmem, "available", mra, sz) == -1) 188 panic("pmap_bootstrap: getprop /memory/available"); 189 sz /= sizeof(*mra); 190 qsort(mra, sz, sizeof *mra, mr_cmp); 191 for (i = 0, j = 0; i < sz; i++, j += 2) { 192 phys_avail[j] = mra[i].mr_start; 193 phys_avail[j + 1] = mra[i].mr_start + mra[i].mr_size; 194 } 195 196 /* 197 * Initialize the kernel pmap (which is statically allocated). 198 */ 199 pm = &kernel_pmap_store; 200 pm->pm_context = TLB_CTX_KERNEL; 201 pm->pm_active = ~0; 202 pm->pm_count = 1; 203 kernel_pmap = pm; 204 205 /* 206 * Allocate the kernel tsb and lock it in the tlb. 207 */ 208 pa = pmap_bootstrap_alloc(TSB_KERNEL_SIZE); 209 if (pa & PAGE_MASK_4M) 210 panic("pmap_bootstrap: tsb unaligned\n"); 211 tsb_kernel_phys = pa; 212 for (i = 0; i < TSB_KERNEL_PAGES; i++) { 213 va = TSB_KERNEL_MIN_ADDRESS + i * PAGE_SIZE_4M; 214 tte.tte_tag = TT_CTX(TLB_CTX_KERNEL) | TT_VA(va); 215 tte.tte_data = TD_V | TD_4M | TD_VA_LOW(va) | TD_PA(pa) | 216 TD_MOD | TD_REF | TD_TSB | TD_L | TD_CP | TD_P | TD_W; 217 tlb_store_slot(TLB_DTLB, va, TLB_CTX_KERNEL, tte, 218 TLB_SLOT_TSB_KERNEL_MIN + i); 219 } 220 bzero((void *)va, TSB_KERNEL_SIZE); 221 stxa(AA_IMMU_TSB, ASI_IMMU, 222 (va >> (STTE_SHIFT - TTE_SHIFT)) | TSB_SIZE_REG); 223 stxa(AA_DMMU_TSB, ASI_DMMU, 224 (va >> (STTE_SHIFT - TTE_SHIFT)) | TSB_SIZE_REG); 225 membar(Sync); 226 227 /* 228 * Calculate the first and last available physical addresses. 229 */ 230 avail_start = phys_avail[0]; 231 for (i = 0; phys_avail[i + 2] != 0; i += 2) 232 ; 233 avail_end = phys_avail[i + 1]; 234 235 /* 236 * Allocate physical memory for the heads of the stte alias chains. 237 */ 238 sz = round_page(((avail_end - avail_start) >> PAGE_SHIFT) * 239 sizeof(struct pv_head)); 240 pv_table = pmap_bootstrap_alloc(sz); 241 /* XXX */ 242 avail_start += sz; 243 for (i = 0; i < sz; i += sizeof(struct pv_head)) 244 pvh_set_first(pv_table + i, 0); 245 246 /* 247 * Set the start and end of kva. The kernel is loaded at the first 248 * available 4 meg super page, so round up to the end of the page. 249 */ 250 virtual_avail = roundup(ekva, PAGE_SIZE_4M); 251 virtual_end = VM_MAX_KERNEL_ADDRESS; 252 253 /* 254 * Allocate virtual address space for copying and zeroing pages of 255 * physical memory. 256 */ 257 CADDR1 = virtual_avail; 258 virtual_avail += PAGE_SIZE; 259 CADDR2 = virtual_avail; 260 virtual_avail += PAGE_SIZE; 261 262 /* 263 * Set the secondary context to be the kernel context (needed for 264 * fp block operations in the kernel). 265 */ 266 stxa(AA_DMMU_SCXR, ASI_DMMU, TLB_CTX_KERNEL); 267 membar(Sync); 268} 269 270/* 271 * Allocate a physical page of memory directly from the phys_avail map. 272 * Can only be called from pmap_bootstrap before avail start and end are 273 * calculated. 274 */ 275static vm_offset_t 276pmap_bootstrap_alloc(vm_size_t size) 277{ 278 vm_offset_t pa; 279 int i; 280 281 size = round_page(size); 282 for (i = 0; phys_avail[i + 1] != 0; i += 2) { 283 if (phys_avail[i + 1] - phys_avail[i] < size) 284 continue; 285 pa = phys_avail[i]; 286 phys_avail[i] += size; 287 return (pa); 288 } 289 panic("pmap_bootstrap_alloc"); 290} 291 292/* 293 * Allocate a hardware context number from the context map. 294 */ 295static u_int 296pmap_context_alloc(void) 297{ 298 u_int i; 299 300 i = pmap_context_base; 301 do { 302 if (pmap_context_map[i] == 0) { 303 pmap_context_map[i] = 1; 304 pmap_context_base = (i + 1) & (PMAP_CONTEXT_MAX - 1); 305 return (i); 306 } 307 } while ((i = (i + 1) & (PMAP_CONTEXT_MAX - 1)) != pmap_context_base); 308 panic("pmap_context_alloc"); 309} 310 311/* 312 * Free a hardware context number back to the context map. 313 */ 314static void 315pmap_context_destroy(u_int i) 316{ 317 318 pmap_context_map[i] = 0; 319} 320 321/* 322 * Map a range of physical addresses into kernel virtual address space. 323 * 324 * The value passed in *virt is a suggested virtual address for the mapping. 325 * Architectures which can support a direct-mapped physical to virtual region 326 * can return the appropriate address within that region, leaving '*virt' 327 * unchanged. We cannot and therefore do not; *virt is updated with the 328 * first usable address after the mapped region. 329 */ 330vm_offset_t 331pmap_map(vm_offset_t *virt, vm_offset_t pa_start, vm_offset_t pa_end, int prot) 332{ 333 vm_offset_t sva; 334 vm_offset_t va; 335 336 sva = *virt; 337 va = sva; 338 for (; pa_start < pa_end; pa_start += PAGE_SIZE, va += PAGE_SIZE) 339 pmap_kenter(va, pa_start); 340 *virt = va; 341 return (sva); 342} 343 344/* 345 * Map a wired page into kernel virtual address space. 346 */ 347void 348pmap_kenter(vm_offset_t va, vm_offset_t pa) 349{ 350 struct stte *stp; 351 struct tte tte; 352 353 tte.tte_tag = TT_CTX(TLB_CTX_KERNEL) | TT_VA(va); 354 tte.tte_data = TD_V | TD_8K | TD_VA_LOW(va) | TD_PA(pa) | 355 TD_MOD | TD_REF | TD_CP | TD_P | TD_W; 356 stp = tsb_kvtostte(va); 357 stp->st_tte = tte; 358} 359 360/* 361 * Remove a wired page from kernel virtual address space. 362 */ 363void 364pmap_kremove(vm_offset_t va) 365{ 366 struct stte *stp; 367 368 stp = tsb_kvtostte(va); 369 tte_invalidate(&stp->st_tte); 370} 371 372/* 373 * Map a list of wired pages into kernel virtual address space. This is 374 * intended for temporary mappings which do not need page modification or 375 * references recorded. Existing mappings in the region are overwritten. 376 */ 377void 378pmap_qenter(vm_offset_t va, vm_page_t *m, int count) 379{ 380 int i; 381 382 for (i = 0; i < count; i++, va += PAGE_SIZE) 383 pmap_kenter(va, VM_PAGE_TO_PHYS(m[i])); 384} 385 386/* 387 * Remove page mappings from kernel virtual address space. Intended for 388 * temporary mappings entered by pmap_qenter. 389 */ 390void 391pmap_qremove(vm_offset_t va, int count) 392{ 393 int i; 394 395 for (i = 0; i < count; i++, va += PAGE_SIZE) 396 pmap_kremove(va); 397} 398 399/* 400 * Map the given physical page at the specified virtual address in the 401 * target pmap with the protection requested. If specified the page 402 * will be wired down. 403 */ 404void 405pmap_enter(pmap_t pm, vm_offset_t va, vm_page_t m, vm_prot_t prot, 406 boolean_t wired) 407{ 408 struct stte *stp; 409 struct tte tte; 410 vm_offset_t pa; 411 412 pa = VM_PAGE_TO_PHYS(m); 413 tte.tte_tag = TT_CTX(pm->pm_context) | TT_VA(va); 414 tte.tte_data = TD_V | TD_8K | TD_VA_LOW(va) | TD_PA(pa) | 415 TD_CP | TD_CV; 416 if (pm->pm_context == TLB_CTX_KERNEL) 417 tte.tte_data |= TD_P; 418 if (wired == TRUE) { 419 tte.tte_data |= TD_REF; 420 if (prot & VM_PROT_WRITE) 421 tte.tte_data |= TD_MOD; 422 } 423 if (prot & VM_PROT_WRITE) 424 tte.tte_data |= TD_W; 425 if (prot & VM_PROT_EXECUTE) { 426 tte.tte_data |= TD_EXEC; 427 icache_global_flush(pa); 428 } 429 if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0) 430 tte.tte_data |= TD_MNG; 431 432 PMAP_LOCK(pm); 433 if ((stp = tsb_stte_lookup(pm, va)) != NULL) { 434 if (stp->st_tte.tte_data & TD_MNG) 435 pv_remove_virt(stp); 436 tsb_stte_remove(stp); 437 if (tte.tte_data & TD_MNG) 438 pv_insert(pm, pa, va, stp); 439 stp->st_tte = tte; 440 } else { 441 tsb_tte_enter(pm, va, tte); 442 } 443 PMAP_UNLOCK(pm); 444} 445 446void 447pmap_remove(pmap_t pm, vm_offset_t start, vm_offset_t end) 448{ 449 struct stte *stp; 450 451 PMAP_LOCK(pm); 452 for (; start < end; start += PAGE_SIZE) { 453 if ((stp = tsb_stte_lookup(pm, start)) == NULL) 454 continue; 455 if (stp->st_tte.tte_data & TD_MNG) 456 pv_remove_virt(stp); 457 tsb_stte_remove(stp); 458 } 459 PMAP_UNLOCK(pm); 460} 461 462/* 463 * Initialize the pmap module. 464 */ 465void 466pmap_init(vm_offset_t phys_start, vm_offset_t phys_end) 467{ 468} 469 470void 471pmap_init2(void) 472{ 473} 474 475/* 476 * Initialize the pmap associated with process 0. 477 */ 478void 479pmap_pinit0(pmap_t pm) 480{ 481 482 pm = &kernel_pmap_store; 483 pm->pm_context = pmap_context_alloc(); 484 pm->pm_active = 0; 485 pm->pm_count = 1; 486 bzero(&pm->pm_stats, sizeof(pm->pm_stats)); 487} 488 489/* 490 * Initialize a preallocated and zeroed pmap structure. 491 */ 492void 493pmap_pinit(pmap_t pm) 494{ 495 struct stte *stp; 496 497 pm->pm_object = vm_object_allocate(OBJT_DEFAULT, 16); 498 pm->pm_context = pmap_context_alloc(); 499 pm->pm_active = 0; 500 pm->pm_count = 1; 501 stp = &pm->pm_stte; 502 stp->st_tte = tsb_page_alloc(pm, (vm_offset_t)tsb_base(0)); 503 bzero(&pm->pm_stats, sizeof(pm->pm_stats)); 504} 505 506void 507pmap_pinit2(pmap_t pmap) 508{ 509} 510 511/* 512 * Grow the number of kernel page table entries. Unneeded. 513 */ 514void 515pmap_growkernel(vm_offset_t addr) 516{ 517} 518 519/* 520 * Zero a page of physical memory by temporarily mapping it into the tlb. 521 */ 522void 523pmap_zero_page(vm_offset_t pa) 524{ 525 struct tte tte; 526 vm_offset_t va; 527 528 va = CADDR2; 529 tte.tte_tag = TT_CTX(TLB_CTX_KERNEL) | TT_VA(va); 530 tte.tte_data = TD_V | TD_8K | TD_PA(pa) | TD_L | TD_CP | TD_P | TD_W; 531 tlb_store(TLB_DTLB, va, TLB_CTX_KERNEL, tte); 532 bzero((void *)va, PAGE_SIZE); 533 tlb_page_demap(TLB_DTLB, TLB_CTX_KERNEL, va); 534} 535 536/* 537 * Make the specified page pageable (or not). Unneeded. 538 */ 539void 540pmap_pageable(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, 541 boolean_t pageable) 542{ 543} 544 545/* 546 * Create the kernel stack and user structure for a new process. This 547 * routine directly affects the performance of fork(). 548 */ 549void 550pmap_new_proc(struct proc *p) 551{ 552 struct user *u; 553 vm_object_t o; 554 vm_page_t m; 555 u_int i; 556 557 if ((o = p->p_upages_obj) == NULL) { 558 o = vm_object_allocate(OBJT_DEFAULT, UPAGES); 559 p->p_upages_obj = o; 560 } 561 if ((u = p->p_addr) == NULL) { 562 u = (struct user *)kmem_alloc_nofault(kernel_map, 563 UPAGES * PAGE_SIZE); 564 KASSERT(u != NULL, ("pmap_new_proc: u area\n")); 565 p->p_addr = u; 566 } 567 for (i = 0; i < UPAGES; i++) { 568 m = vm_page_grab(o, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); 569 m->wire_count++; 570 cnt.v_wire_count++; 571 572 pmap_kenter((vm_offset_t)u + i * PAGE_SIZE, 573 VM_PAGE_TO_PHYS(m)); 574 575 vm_page_wakeup(m); 576 vm_page_flag_clear(m, PG_ZERO); 577 vm_page_flag_set(m, PG_MAPPED | PG_WRITEABLE); 578 m->valid = VM_PAGE_BITS_ALL; 579 } 580} 581 582void 583pmap_page_protect(vm_page_t m, vm_prot_t prot) 584{ 585 586 if (m->flags & PG_FICTITIOUS || prot & VM_PROT_WRITE) 587 return; 588 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) 589 pv_bit_clear(m, TD_W); 590 else 591 pv_global_remove_all(m); 592} 593 594void 595pmap_clear_modify(vm_page_t m) 596{ 597 598 if (m->flags & PG_FICTITIOUS) 599 return; 600 pv_bit_clear(m, TD_MOD); 601} 602 603void 604pmap_activate(struct proc *p) 605{ 606 TODO; 607} 608 609vm_offset_t 610pmap_addr_hint(vm_object_t object, vm_offset_t va, vm_size_t size) 611{ 612 TODO; 613 return (0); 614} 615 616void 617pmap_change_wiring(pmap_t pmap, vm_offset_t va, boolean_t wired) 618{ 619 TODO; 620} 621 622void 623pmap_collect(void) 624{ 625 TODO; 626} 627 628void 629pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, 630 vm_size_t len, vm_offset_t src_addr) 631{ 632 TODO; 633} 634 635void 636pmap_copy_page(vm_offset_t src, vm_offset_t dst) 637{ 638 TODO; 639} 640 641void 642pmap_zero_page_area(vm_offset_t pa, int off, int size) 643{ 644 struct tte tte; 645 vm_offset_t va; 646 647 KASSERT(off + size <= PAGE_SIZE, ("pmap_zero_page_area: bad off/size")); 648 va = CADDR2; 649 tte.tte_tag = TT_CTX(TLB_CTX_KERNEL) | TT_VA(va); 650 tte.tte_data = TD_V | TD_8K | TD_PA(pa) | TD_L | TD_CP | TD_P | TD_W; 651 tlb_store(TLB_DTLB, va, TLB_CTX_KERNEL, tte); 652 bzero((char *)va + off, size); 653 tlb_page_demap(TLB_DTLB, TLB_CTX_KERNEL, va); 654} 655 656vm_offset_t 657pmap_extract(pmap_t pmap, vm_offset_t va) 658{ 659 TODO; 660 return (0); 661} 662 663boolean_t 664pmap_is_modified(vm_page_t m) 665{ 666 TODO; 667 return (0); 668} 669 670void 671pmap_clear_reference(vm_page_t m) 672{ 673 TODO; 674} 675 676int 677pmap_ts_referenced(vm_page_t m) 678{ 679 TODO; 680 return (0); 681} 682 683vm_offset_t 684pmap_kextract(vm_offset_t va) 685{ 686 TODO; 687 return (0); 688} 689 690int 691pmap_mincore(pmap_t pmap, vm_offset_t addr) 692{ 693 TODO; 694 return (0); 695} 696 697void 698pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_object_t object, 699 vm_pindex_t pindex, vm_size_t size, int limit) 700{ 701 /* XXX */ 702} 703 704boolean_t 705pmap_page_exists(pmap_t pmap, vm_page_t m) 706{ 707 TODO; 708 return (0); 709} 710 711void 712pmap_prefault(pmap_t pmap, vm_offset_t va, vm_map_entry_t entry) 713{ 714 /* XXX */ 715} 716 717void 718pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot) 719{ 720 /* XXX */ 721} 722 723vm_offset_t 724pmap_phys_address(int ppn) 725{ 726 TODO; 727 return (0); 728} 729 730void 731pmap_reference(pmap_t pm) 732{ 733 if (pm != NULL) 734 pm->pm_count++; 735} 736 737void 738pmap_release(pmap_t pmap) 739{ 740 TODO; 741} 742 743void 744pmap_remove_pages(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) 745{ 746 747 /* XXX */ 748} 749 750void 751pmap_swapin_proc(struct proc *p) 752{ 753 TODO; 754} 755 756void 757pmap_swapout_proc(struct proc *p) 758{ 759 TODO; 760} 761