pmap_dispatch.c revision 178893
1152179Sgrehan/*- 2152179Sgrehan * Copyright (c) 2005 Peter Grehan 3152179Sgrehan * All rights reserved. 4152179Sgrehan * 5152179Sgrehan * Redistribution and use in source and binary forms, with or without 6152179Sgrehan * modification, are permitted provided that the following conditions 7152179Sgrehan * are met: 8152179Sgrehan * 1. Redistributions of source code must retain the above copyright 9152179Sgrehan * notice, this list of conditions and the following disclaimer. 10152179Sgrehan * 2. Redistributions in binary form must reproduce the above copyright 11152179Sgrehan * notice, this list of conditions and the following disclaimer in the 12152179Sgrehan * documentation and/or other materials provided with the distribution. 13152179Sgrehan * 14152179Sgrehan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15152179Sgrehan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16152179Sgrehan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17152179Sgrehan * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18152179Sgrehan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19152179Sgrehan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20152179Sgrehan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21152179Sgrehan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22152179Sgrehan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23152179Sgrehan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24152179Sgrehan * SUCH DAMAGE. 25152179Sgrehan * 26152179Sgrehan */ 27152179Sgrehan 28152179Sgrehan#include <sys/cdefs.h> 29152179Sgrehan__FBSDID("$FreeBSD: head/sys/powerpc/powerpc/pmap_dispatch.c 178893 2008-05-09 23:31:42Z alc $"); 30152179Sgrehan 31152179Sgrehan/* 32152179Sgrehan * Dispatch MI pmap calls to the appropriate MMU implementation 33152179Sgrehan * through a previously registered kernel object. 34152179Sgrehan * 35152179Sgrehan * Before pmap_bootstrap() can be called, a CPU module must have 36152179Sgrehan * called pmap_mmu_install(). This may be called multiple times: 37152179Sgrehan * the highest priority call will be installed as the default 38152179Sgrehan * MMU handler when pmap_bootstrap() is called. 39152179Sgrehan * 40152179Sgrehan * It is required that kobj_machdep_init() be called before 41152179Sgrehan * pmap_bootstrap() to allow the kobj subsystem to initialise. This 42152179Sgrehan * in turn requires that mutex_init() has been called. 43152179Sgrehan */ 44152179Sgrehan 45152179Sgrehan#include <sys/param.h> 46152179Sgrehan#include <sys/kernel.h> 47152179Sgrehan#include <sys/lock.h> 48152179Sgrehan#include <sys/mutex.h> 49152179Sgrehan#include <sys/systm.h> 50152179Sgrehan 51152179Sgrehan#include <vm/vm.h> 52152179Sgrehan#include <vm/vm_page.h> 53152179Sgrehan 54152179Sgrehan#include <machine/mmuvar.h> 55152179Sgrehan 56152179Sgrehan#include "mmu_if.h" 57152179Sgrehan 58152179Sgrehanstatic mmu_def_t *mmu_def_impl; 59152179Sgrehanstatic mmu_t mmu_obj; 60152179Sgrehanstatic struct mmu_kobj mmu_kernel_obj; 61152179Sgrehanstatic struct kobj_ops mmu_kernel_kops; 62152179Sgrehan 63152179Sgrehan/* 64152179Sgrehan * pmap globals 65152179Sgrehan */ 66152179Sgrehanstruct pmap kernel_pmap_store; 67152179Sgrehan 68152179Sgrehanstruct msgbuf *msgbufp; 69152179Sgrehanvm_offset_t msgbuf_phys; 70152179Sgrehan 71152179Sgrehanvm_offset_t kernel_vm_end; 72152179Sgrehanvm_offset_t phys_avail[PHYS_AVAIL_SZ]; 73152179Sgrehanvm_offset_t virtual_avail; 74152179Sgrehanvm_offset_t virtual_end; 75152179Sgrehan 76152179Sgrehanint pmap_bootstrapped; 77152179Sgrehan 78152179Sgrehanvoid 79152179Sgrehanpmap_change_wiring(pmap_t pmap, vm_offset_t va, boolean_t wired) 80152179Sgrehan{ 81152179Sgrehan MMU_CHANGE_WIRING(mmu_obj, pmap, va, wired); 82152179Sgrehan} 83152179Sgrehan 84152179Sgrehanvoid 85152179Sgrehanpmap_clear_modify(vm_page_t m) 86152179Sgrehan{ 87152179Sgrehan MMU_CLEAR_MODIFY(mmu_obj, m); 88152179Sgrehan} 89152179Sgrehan 90152179Sgrehanvoid 91152179Sgrehanpmap_clear_reference(vm_page_t m) 92152179Sgrehan{ 93152179Sgrehan MMU_CLEAR_REFERENCE(mmu_obj, m); 94152179Sgrehan} 95152179Sgrehan 96152179Sgrehanvoid 97152179Sgrehanpmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, 98152179Sgrehan vm_size_t len, vm_offset_t src_addr) 99152179Sgrehan{ 100152179Sgrehan MMU_COPY(mmu_obj, dst_pmap, src_pmap, dst_addr, len, src_addr); 101152179Sgrehan} 102152179Sgrehan 103152179Sgrehanvoid 104152179Sgrehanpmap_copy_page(vm_page_t src, vm_page_t dst) 105152179Sgrehan{ 106152179Sgrehan MMU_COPY_PAGE(mmu_obj, src, dst); 107152179Sgrehan} 108152179Sgrehan 109152179Sgrehanvoid 110175067Salcpmap_enter(pmap_t pmap, vm_offset_t va, vm_prot_t access, vm_page_t p, 111175067Salc vm_prot_t prot, boolean_t wired) 112152179Sgrehan{ 113152179Sgrehan MMU_ENTER(mmu_obj, pmap, va, p, prot, wired); 114152179Sgrehan} 115152179Sgrehan 116159323Salcvoid 117159323Salcpmap_enter_object(pmap_t pmap, vm_offset_t start, vm_offset_t end, 118159323Salc vm_page_t m_start, vm_prot_t prot) 119159323Salc{ 120159323Salc MMU_ENTER_OBJECT(mmu_obj, pmap, start, end, m_start, prot); 121159323Salc} 122159323Salc 123159627Supsvoid 124159627Supspmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot) 125152179Sgrehan{ 126159627Sups MMU_ENTER_QUICK(mmu_obj, pmap, va, m, prot); 127152179Sgrehan} 128152179Sgrehan 129152179Sgrehanvm_paddr_t 130152179Sgrehanpmap_extract(pmap_t pmap, vm_offset_t va) 131152179Sgrehan{ 132152179Sgrehan return (MMU_EXTRACT(mmu_obj, pmap, va)); 133152179Sgrehan} 134152179Sgrehan 135152179Sgrehanvm_page_t 136152179Sgrehanpmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot) 137152179Sgrehan{ 138152179Sgrehan return (MMU_EXTRACT_AND_HOLD(mmu_obj, pmap, va, prot)); 139152179Sgrehan} 140152179Sgrehan 141152179Sgrehanvoid 142152179Sgrehanpmap_growkernel(vm_offset_t va) 143152179Sgrehan{ 144152179Sgrehan MMU_GROWKERNEL(mmu_obj, va); 145152179Sgrehan} 146152179Sgrehan 147152179Sgrehanvoid 148152179Sgrehanpmap_init(void) 149152179Sgrehan{ 150152179Sgrehan MMU_INIT(mmu_obj); 151152179Sgrehan} 152152179Sgrehan 153152179Sgrehanboolean_t 154152179Sgrehanpmap_is_modified(vm_page_t m) 155152179Sgrehan{ 156152179Sgrehan return (MMU_IS_MODIFIED(mmu_obj, m)); 157152179Sgrehan} 158152179Sgrehan 159152179Sgrehanboolean_t 160152179Sgrehanpmap_is_prefaultable(pmap_t pmap, vm_offset_t va) 161152179Sgrehan{ 162152179Sgrehan return (MMU_IS_PREFAULTABLE(mmu_obj, pmap, va)); 163152179Sgrehan} 164152179Sgrehan 165152179Sgrehanboolean_t 166152179Sgrehanpmap_ts_referenced(vm_page_t m) 167152179Sgrehan{ 168152179Sgrehan return (MMU_TS_REFERENCED(mmu_obj, m)); 169152179Sgrehan} 170152179Sgrehan 171152179Sgrehanvm_offset_t 172152179Sgrehanpmap_map(vm_offset_t *virt, vm_paddr_t start, vm_paddr_t end, int prot) 173152179Sgrehan{ 174152179Sgrehan return (MMU_MAP(mmu_obj, virt, start, end, prot)); 175152179Sgrehan} 176152179Sgrehan 177152179Sgrehanvoid 178152179Sgrehanpmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_object_t object, 179152179Sgrehan vm_pindex_t pindex, vm_size_t size) 180152179Sgrehan{ 181152179Sgrehan MMU_OBJECT_INIT_PT(mmu_obj, pmap, addr, object, pindex, size); 182152179Sgrehan} 183152179Sgrehan 184152179Sgrehanboolean_t 185152179Sgrehanpmap_page_exists_quick(pmap_t pmap, vm_page_t m) 186152179Sgrehan{ 187152179Sgrehan return (MMU_PAGE_EXISTS_QUICK(mmu_obj, pmap, m)); 188152179Sgrehan} 189152179Sgrehan 190152179Sgrehanvoid 191152179Sgrehanpmap_page_init(vm_page_t m) 192152179Sgrehan{ 193152179Sgrehan MMU_PAGE_INIT(mmu_obj, m); 194152179Sgrehan} 195152179Sgrehan 196173361Skibint 197173708Salcpmap_page_wired_mappings(vm_page_t m) 198173708Salc{ 199173708Salc 200173708Salc return (MMU_PAGE_WIRED_MAPPINGS(mmu_obj, m)); 201173708Salc} 202173708Salc 203173708Salcint 204152179Sgrehanpmap_pinit(pmap_t pmap) 205152179Sgrehan{ 206152179Sgrehan MMU_PINIT(mmu_obj, pmap); 207173361Skib return (1); 208152179Sgrehan} 209152179Sgrehan 210152179Sgrehanvoid 211152179Sgrehanpmap_pinit0(pmap_t pmap) 212152179Sgrehan{ 213152179Sgrehan MMU_PINIT0(mmu_obj, pmap); 214152179Sgrehan} 215152179Sgrehan 216152179Sgrehanvoid 217152179Sgrehanpmap_protect(pmap_t pmap, vm_offset_t start, vm_offset_t end, vm_prot_t prot) 218152179Sgrehan{ 219152179Sgrehan MMU_PROTECT(mmu_obj, pmap, start, end, prot); 220152179Sgrehan} 221152179Sgrehan 222152179Sgrehanvoid 223152179Sgrehanpmap_qenter(vm_offset_t start, vm_page_t *m, int count) 224152179Sgrehan{ 225152179Sgrehan MMU_QENTER(mmu_obj, start, m, count); 226152179Sgrehan} 227152179Sgrehan 228152179Sgrehanvoid 229152179Sgrehanpmap_qremove(vm_offset_t start, int count) 230152179Sgrehan{ 231152179Sgrehan MMU_QREMOVE(mmu_obj, start, count); 232152179Sgrehan} 233152179Sgrehan 234152179Sgrehanvoid 235152179Sgrehanpmap_release(pmap_t pmap) 236152179Sgrehan{ 237152179Sgrehan MMU_RELEASE(mmu_obj, pmap); 238152179Sgrehan} 239152179Sgrehan 240152179Sgrehanvoid 241152179Sgrehanpmap_remove(pmap_t pmap, vm_offset_t start, vm_offset_t end) 242152179Sgrehan{ 243152179Sgrehan MMU_REMOVE(mmu_obj, pmap, start, end); 244152179Sgrehan} 245152179Sgrehan 246152179Sgrehanvoid 247152179Sgrehanpmap_remove_all(vm_page_t m) 248152179Sgrehan{ 249152179Sgrehan MMU_REMOVE_ALL(mmu_obj, m); 250152179Sgrehan} 251152179Sgrehan 252152179Sgrehanvoid 253157443Speterpmap_remove_pages(pmap_t pmap) 254152179Sgrehan{ 255157443Speter MMU_REMOVE_PAGES(mmu_obj, pmap); 256152179Sgrehan} 257152179Sgrehan 258152179Sgrehanvoid 259160889Salcpmap_remove_write(vm_page_t m) 260160889Salc{ 261160889Salc MMU_REMOVE_WRITE(mmu_obj, m); 262160889Salc} 263160889Salc 264160889Salcvoid 265152179Sgrehanpmap_zero_page(vm_page_t m) 266152179Sgrehan{ 267152179Sgrehan MMU_ZERO_PAGE(mmu_obj, m); 268152179Sgrehan} 269152179Sgrehan 270152179Sgrehanvoid 271152179Sgrehanpmap_zero_page_area(vm_page_t m, int off, int size) 272152179Sgrehan{ 273152179Sgrehan MMU_ZERO_PAGE_AREA(mmu_obj, m, off, size); 274152179Sgrehan} 275152179Sgrehan 276152179Sgrehanvoid 277152179Sgrehanpmap_zero_page_idle(vm_page_t m) 278152179Sgrehan{ 279152179Sgrehan MMU_ZERO_PAGE_IDLE(mmu_obj, m); 280152179Sgrehan} 281152179Sgrehan 282152179Sgrehanint 283152179Sgrehanpmap_mincore(pmap_t pmap, vm_offset_t addr) 284152179Sgrehan{ 285152179Sgrehan return (MMU_MINCORE(mmu_obj, pmap, addr)); 286152179Sgrehan} 287152179Sgrehan 288152179Sgrehanvoid 289152179Sgrehanpmap_activate(struct thread *td) 290152179Sgrehan{ 291152179Sgrehan MMU_ACTIVATE(mmu_obj, td); 292152179Sgrehan} 293152179Sgrehan 294152179Sgrehanvoid 295152179Sgrehanpmap_deactivate(struct thread *td) 296152179Sgrehan{ 297152179Sgrehan MMU_DEACTIVATE(mmu_obj, td); 298152179Sgrehan} 299152179Sgrehan 300152179Sgrehanvm_offset_t 301152179Sgrehanpmap_addr_hint(vm_object_t obj, vm_offset_t addr, vm_size_t size) 302152179Sgrehan{ 303152179Sgrehan return (MMU_ADDR_HINT(mmu_obj, obj, addr, size)); 304152179Sgrehan} 305152179Sgrehan 306178893Salc/* 307178893Salc * Increase the starting virtual address of the given mapping if a 308178893Salc * different alignment might result in more superpage mappings. 309178893Salc */ 310178893Salcvoid 311178893Salcpmap_align_superpage(vm_object_t object, vm_ooffset_t offset, 312178893Salc vm_offset_t *addr, vm_size_t size) 313178893Salc{ 314178893Salc} 315152179Sgrehan 316152179Sgrehan 317178893Salc 318152179Sgrehan/* 319152179Sgrehan * Routines used in machine-dependent code 320152179Sgrehan */ 321152179Sgrehanvoid 322152179Sgrehanpmap_bootstrap(vm_offset_t start, vm_offset_t end) 323152179Sgrehan{ 324152179Sgrehan mmu_obj = &mmu_kernel_obj; 325152179Sgrehan 326152179Sgrehan /* 327152179Sgrehan * Take care of compiling the selected class, and 328152179Sgrehan * then statically initialise the MMU object 329152179Sgrehan */ 330152179Sgrehan kobj_class_compile_static(mmu_def_impl, &mmu_kernel_kops); 331152179Sgrehan kobj_init((kobj_t)mmu_obj, mmu_def_impl); 332152179Sgrehan 333152179Sgrehan MMU_BOOTSTRAP(mmu_obj, start, end); 334152179Sgrehan} 335152179Sgrehan 336152179Sgrehanvoid * 337152179Sgrehanpmap_mapdev(vm_offset_t pa, vm_size_t size) 338152179Sgrehan{ 339152179Sgrehan return (MMU_MAPDEV(mmu_obj, pa, size)); 340152179Sgrehan} 341152179Sgrehan 342152179Sgrehanvoid 343152179Sgrehanpmap_unmapdev(vm_offset_t va, vm_size_t size) 344152179Sgrehan{ 345152179Sgrehan MMU_UNMAPDEV(mmu_obj, va, size); 346152179Sgrehan} 347152179Sgrehan 348152179Sgrehanvm_offset_t 349152179Sgrehanpmap_kextract(vm_offset_t va) 350152179Sgrehan{ 351152179Sgrehan return (MMU_KEXTRACT(mmu_obj, va)); 352152179Sgrehan} 353152179Sgrehan 354152179Sgrehanvoid 355152179Sgrehanpmap_kenter(vm_offset_t va, vm_offset_t pa) 356152179Sgrehan{ 357152179Sgrehan MMU_KENTER(mmu_obj, va, pa); 358152179Sgrehan} 359152179Sgrehan 360152179Sgrehanboolean_t 361152179Sgrehanpmap_dev_direct_mapped(vm_offset_t pa, vm_size_t size) 362152179Sgrehan{ 363152179Sgrehan return (MMU_DEV_DIRECT_MAPPED(mmu_obj, pa, size)); 364152179Sgrehan} 365152179Sgrehan 366164895Sgrehanboolean_t 367164895Sgrehanpmap_page_executable(vm_page_t pg) 368164895Sgrehan{ 369164895Sgrehan return (MMU_PAGE_EXECUTABLE(mmu_obj, pg)); 370164895Sgrehan} 371152179Sgrehan 372152179Sgrehan/* 373152179Sgrehan * MMU install routines. Highest priority wins, equal priority also 374152179Sgrehan * overrides allowing last-set to win. 375152179Sgrehan */ 376152179SgrehanSET_DECLARE(mmu_set, mmu_def_t); 377152179Sgrehan 378152179Sgrehanboolean_t 379152179Sgrehanpmap_mmu_install(char *name, int prio) 380152179Sgrehan{ 381152179Sgrehan mmu_def_t **mmupp, *mmup; 382152179Sgrehan static int curr_prio = 0; 383152179Sgrehan 384152179Sgrehan /* 385152179Sgrehan * Try and locate the MMU kobj corresponding to the name 386152179Sgrehan */ 387152179Sgrehan SET_FOREACH(mmupp, mmu_set) { 388152179Sgrehan mmup = *mmupp; 389152179Sgrehan 390152179Sgrehan if (mmup->name && 391152179Sgrehan !strcmp(mmup->name, name) && 392152179Sgrehan prio >= curr_prio) { 393152179Sgrehan curr_prio = prio; 394152179Sgrehan mmu_def_impl = mmup; 395152179Sgrehan return (TRUE); 396152179Sgrehan } 397152179Sgrehan } 398152179Sgrehan 399152179Sgrehan return (FALSE); 400152179Sgrehan} 401