pmap_dispatch.c revision 173361
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 173361 2007-11-05 11:36:16Z kib $"); 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 110152179Sgrehanpmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t p, vm_prot_t prot, 111152179Sgrehan 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 197152179Sgrehanpmap_pinit(pmap_t pmap) 198152179Sgrehan{ 199152179Sgrehan MMU_PINIT(mmu_obj, pmap); 200173361Skib return (1); 201152179Sgrehan} 202152179Sgrehan 203152179Sgrehanvoid 204152179Sgrehanpmap_pinit0(pmap_t pmap) 205152179Sgrehan{ 206152179Sgrehan MMU_PINIT0(mmu_obj, pmap); 207152179Sgrehan} 208152179Sgrehan 209152179Sgrehanvoid 210152179Sgrehanpmap_protect(pmap_t pmap, vm_offset_t start, vm_offset_t end, vm_prot_t prot) 211152179Sgrehan{ 212152179Sgrehan MMU_PROTECT(mmu_obj, pmap, start, end, prot); 213152179Sgrehan} 214152179Sgrehan 215152179Sgrehanvoid 216152179Sgrehanpmap_qenter(vm_offset_t start, vm_page_t *m, int count) 217152179Sgrehan{ 218152179Sgrehan MMU_QENTER(mmu_obj, start, m, count); 219152179Sgrehan} 220152179Sgrehan 221152179Sgrehanvoid 222152179Sgrehanpmap_qremove(vm_offset_t start, int count) 223152179Sgrehan{ 224152179Sgrehan MMU_QREMOVE(mmu_obj, start, count); 225152179Sgrehan} 226152179Sgrehan 227152179Sgrehanvoid 228152179Sgrehanpmap_release(pmap_t pmap) 229152179Sgrehan{ 230152179Sgrehan MMU_RELEASE(mmu_obj, pmap); 231152179Sgrehan} 232152179Sgrehan 233152179Sgrehanvoid 234152179Sgrehanpmap_remove(pmap_t pmap, vm_offset_t start, vm_offset_t end) 235152179Sgrehan{ 236152179Sgrehan MMU_REMOVE(mmu_obj, pmap, start, end); 237152179Sgrehan} 238152179Sgrehan 239152179Sgrehanvoid 240152179Sgrehanpmap_remove_all(vm_page_t m) 241152179Sgrehan{ 242152179Sgrehan MMU_REMOVE_ALL(mmu_obj, m); 243152179Sgrehan} 244152179Sgrehan 245152179Sgrehanvoid 246157443Speterpmap_remove_pages(pmap_t pmap) 247152179Sgrehan{ 248157443Speter MMU_REMOVE_PAGES(mmu_obj, pmap); 249152179Sgrehan} 250152179Sgrehan 251152179Sgrehanvoid 252160889Salcpmap_remove_write(vm_page_t m) 253160889Salc{ 254160889Salc MMU_REMOVE_WRITE(mmu_obj, m); 255160889Salc} 256160889Salc 257160889Salcvoid 258152179Sgrehanpmap_zero_page(vm_page_t m) 259152179Sgrehan{ 260152179Sgrehan MMU_ZERO_PAGE(mmu_obj, m); 261152179Sgrehan} 262152179Sgrehan 263152179Sgrehanvoid 264152179Sgrehanpmap_zero_page_area(vm_page_t m, int off, int size) 265152179Sgrehan{ 266152179Sgrehan MMU_ZERO_PAGE_AREA(mmu_obj, m, off, size); 267152179Sgrehan} 268152179Sgrehan 269152179Sgrehanvoid 270152179Sgrehanpmap_zero_page_idle(vm_page_t m) 271152179Sgrehan{ 272152179Sgrehan MMU_ZERO_PAGE_IDLE(mmu_obj, m); 273152179Sgrehan} 274152179Sgrehan 275152179Sgrehanint 276152179Sgrehanpmap_mincore(pmap_t pmap, vm_offset_t addr) 277152179Sgrehan{ 278152179Sgrehan return (MMU_MINCORE(mmu_obj, pmap, addr)); 279152179Sgrehan} 280152179Sgrehan 281152179Sgrehanvoid 282152179Sgrehanpmap_activate(struct thread *td) 283152179Sgrehan{ 284152179Sgrehan MMU_ACTIVATE(mmu_obj, td); 285152179Sgrehan} 286152179Sgrehan 287152179Sgrehanvoid 288152179Sgrehanpmap_deactivate(struct thread *td) 289152179Sgrehan{ 290152179Sgrehan MMU_DEACTIVATE(mmu_obj, td); 291152179Sgrehan} 292152179Sgrehan 293152179Sgrehanvm_offset_t 294152179Sgrehanpmap_addr_hint(vm_object_t obj, vm_offset_t addr, vm_size_t size) 295152179Sgrehan{ 296152179Sgrehan return (MMU_ADDR_HINT(mmu_obj, obj, addr, size)); 297152179Sgrehan} 298152179Sgrehan 299152179Sgrehan 300152179Sgrehan 301152179Sgrehan/* 302152179Sgrehan * Routines used in machine-dependent code 303152179Sgrehan */ 304152179Sgrehanvoid 305152179Sgrehanpmap_bootstrap(vm_offset_t start, vm_offset_t end) 306152179Sgrehan{ 307152179Sgrehan mmu_obj = &mmu_kernel_obj; 308152179Sgrehan 309152179Sgrehan /* 310152179Sgrehan * Take care of compiling the selected class, and 311152179Sgrehan * then statically initialise the MMU object 312152179Sgrehan */ 313152179Sgrehan kobj_class_compile_static(mmu_def_impl, &mmu_kernel_kops); 314152179Sgrehan kobj_init((kobj_t)mmu_obj, mmu_def_impl); 315152179Sgrehan 316152179Sgrehan MMU_BOOTSTRAP(mmu_obj, start, end); 317152179Sgrehan} 318152179Sgrehan 319152179Sgrehanvoid * 320152179Sgrehanpmap_mapdev(vm_offset_t pa, vm_size_t size) 321152179Sgrehan{ 322152179Sgrehan return (MMU_MAPDEV(mmu_obj, pa, size)); 323152179Sgrehan} 324152179Sgrehan 325152179Sgrehanvoid 326152179Sgrehanpmap_unmapdev(vm_offset_t va, vm_size_t size) 327152179Sgrehan{ 328152179Sgrehan MMU_UNMAPDEV(mmu_obj, va, size); 329152179Sgrehan} 330152179Sgrehan 331152179Sgrehanvm_offset_t 332152179Sgrehanpmap_kextract(vm_offset_t va) 333152179Sgrehan{ 334152179Sgrehan return (MMU_KEXTRACT(mmu_obj, va)); 335152179Sgrehan} 336152179Sgrehan 337152179Sgrehanvoid 338152179Sgrehanpmap_kenter(vm_offset_t va, vm_offset_t pa) 339152179Sgrehan{ 340152179Sgrehan MMU_KENTER(mmu_obj, va, pa); 341152179Sgrehan} 342152179Sgrehan 343152179Sgrehanboolean_t 344152179Sgrehanpmap_dev_direct_mapped(vm_offset_t pa, vm_size_t size) 345152179Sgrehan{ 346152179Sgrehan return (MMU_DEV_DIRECT_MAPPED(mmu_obj, pa, size)); 347152179Sgrehan} 348152179Sgrehan 349164895Sgrehanboolean_t 350164895Sgrehanpmap_page_executable(vm_page_t pg) 351164895Sgrehan{ 352164895Sgrehan return (MMU_PAGE_EXECUTABLE(mmu_obj, pg)); 353164895Sgrehan} 354152179Sgrehan 355152179Sgrehan/* 356152179Sgrehan * MMU install routines. Highest priority wins, equal priority also 357152179Sgrehan * overrides allowing last-set to win. 358152179Sgrehan */ 359152179SgrehanSET_DECLARE(mmu_set, mmu_def_t); 360152179Sgrehan 361152179Sgrehanboolean_t 362152179Sgrehanpmap_mmu_install(char *name, int prio) 363152179Sgrehan{ 364152179Sgrehan mmu_def_t **mmupp, *mmup; 365152179Sgrehan static int curr_prio = 0; 366152179Sgrehan 367152179Sgrehan /* 368152179Sgrehan * Try and locate the MMU kobj corresponding to the name 369152179Sgrehan */ 370152179Sgrehan SET_FOREACH(mmupp, mmu_set) { 371152179Sgrehan mmup = *mmupp; 372152179Sgrehan 373152179Sgrehan if (mmup->name && 374152179Sgrehan !strcmp(mmup->name, name) && 375152179Sgrehan prio >= curr_prio) { 376152179Sgrehan curr_prio = prio; 377152179Sgrehan mmu_def_impl = mmup; 378152179Sgrehan return (TRUE); 379152179Sgrehan } 380152179Sgrehan } 381152179Sgrehan 382152179Sgrehan return (FALSE); 383152179Sgrehan} 384