mmu_if.m revision 179081
150276Speter#- 250276Speter# Copyright (c) 2005 Peter Grehan 350276Speter# All rights reserved. 450276Speter# 550276Speter# Redistribution and use in source and binary forms, with or without 650276Speter# modification, are permitted provided that the following conditions 750276Speter# are met: 850276Speter# 1. Redistributions of source code must retain the above copyright 950276Speter# notice, this list of conditions and the following disclaimer. 1050276Speter# 2. Redistributions in binary form must reproduce the above copyright 1150276Speter# notice, this list of conditions and the following disclaimer in the 1250276Speter# documentation and/or other materials provided with the distribution. 1350276Speter# 1450276Speter# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1550276Speter# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1650276Speter# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1750276Speter# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1850276Speter# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1950276Speter# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2050276Speter# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2150276Speter# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2250276Speter# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2350276Speter# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2450276Speter# SUCH DAMAGE. 2550276Speter# 2650276Speter# $FreeBSD: head/sys/powerpc/powerpc/mmu_if.m 179081 2008-05-18 04:16:57Z alc $ 2750276Speter# 2850276Speter 2950276Speter#include <sys/param.h> 3050276Speter#include <sys/lock.h> 3150276Speter#include <sys/mutex.h> 3250276Speter#include <sys/systm.h> 3350276Speter 3450276Speter#include <vm/vm.h> 3550276Speter#include <vm/vm_page.h> 3650276Speter 3750276Speter#include <machine/mmuvar.h> 3850276Speter 3950276Speter/** 4050276Speter * @defgroup MMU mmu - KObj methods for PowerPC MMU implementations 4150276Speter * @brief A set of methods required by all MMU implementations. These 4250276Speter * are basically direct call-thru's from the pmap machine-dependent 4350276Speter * code. 4450276Speter * Thanks to Bruce M Simpson's pmap man pages for routine descriptions. 4550276Speter *@{ 4650276Speter */ 4750276Speter 4850276SpeterINTERFACE mmu; 4950276Speter 5050276Speter# 5150276Speter# Default implementations of some methods 5250276Speter# 5350276SpeterCODE { 5450276Speter static void mmu_null_copy(mmu_t mmu, pmap_t dst_pmap, pmap_t src_pmap, 5550276Speter vm_offset_t dst_addr, vm_size_t len, vm_offset_t src_addr) 5650276Speter { 5750276Speter return; 5850276Speter } 5950276Speter 6050276Speter static void mmu_null_growkernel(mmu_t mmu, vm_offset_t addr) 6150276Speter { 6250276Speter return; 6350276Speter } 6450276Speter 6550276Speter static void mmu_null_init(mmu_t mmu) 6650276Speter { 6750276Speter return; 6850276Speter } 6950276Speter 7050276Speter static boolean_t mmu_null_is_prefaultable(mmu_t mmu, pmap_t pmap, 7150276Speter vm_offset_t va) 7250276Speter { 7350276Speter return (FALSE); 7450276Speter } 7550276Speter 7650276Speter static void mmu_null_object_init_pt(mmu_t mmu, pmap_t pmap, 7750276Speter vm_offset_t addr, vm_object_t object, vm_pindex_t index, 7850276Speter vm_size_t size) 7950276Speter { 8050276Speter return; 8150276Speter } 8250276Speter 8350276Speter static void mmu_null_page_init(mmu_t mmu, vm_page_t m) 8450276Speter { 8550276Speter return; 8650276Speter } 8750276Speter 8850276Speter static void mmu_null_remove_pages(mmu_t mmu, pmap_t pmap) 8950276Speter { 9050276Speter return; 9150276Speter } 9250276Speter 9350276Speter static int mmu_null_mincore(mmu_t mmu, pmap_t pmap, vm_offset_t addr) 9450276Speter { 9550276Speter return (0); 9650276Speter } 9750276Speter 9850276Speter static void mmu_null_deactivate(struct thread *td) 9950276Speter { 10050276Speter return; 10150276Speter } 10250276Speter 10350276Speter static void mmu_null_align_superpage(mmu_t mmu, vm_object_t object, 10450276Speter vm_ooffset_t offset, vm_offset_t *addr, vm_size_t size) 10550276Speter { 10650276Speter return; 10750276Speter } 10850276Speter}; 10950276Speter 11050276Speter 11150276Speter/** 11250276Speter * @brief Change the wiring attribute for the page in the given physical 11350276Speter * map and virtual address. 11450276Speter * 11550276Speter * @param _pmap physical map of page 11650276Speter * @param _va page virtual address 11750276Speter * @param _wired TRUE to increment wired count, FALSE to decrement 11850276Speter */ 11950276SpeterMETHOD void change_wiring { 12050276Speter mmu_t _mmu; 12150276Speter pmap_t _pmap; 12250276Speter vm_offset_t _va; 12350276Speter boolean_t _wired; 12450276Speter}; 12550276Speter 12650276Speter 12750276Speter/** 12850276Speter * @brief Clear the 'modified' bit on the given physical page 12950276Speter * 13050276Speter * @param _pg physical page 13150276Speter */ 13250276SpeterMETHOD void clear_modify { 13350276Speter mmu_t _mmu; 13450276Speter vm_page_t _pg; 13550276Speter}; 13650276Speter 13750276Speter 13850276Speter/** 13950276Speter * @brief Clear the 'referenced' bit on the given physical page 14050276Speter * 14150276Speter * @param _pg physical page 14250276Speter */ 14350276SpeterMETHOD void clear_reference { 14450276Speter mmu_t _mmu; 14550276Speter vm_page_t _pg; 14650276Speter}; 14750276Speter 14850276Speter 14950276Speter/** 15050276Speter * @brief Clear the write and modified bits in each of the given 15150276Speter * physical page's mappings 15250276Speter * 15350276Speter * @param _pg physical page 15450276Speter */ 15550276SpeterMETHOD void remove_write { 15650276Speter mmu_t _mmu; 15750276Speter vm_page_t _pg; 15850276Speter}; 15950276Speter 16050276Speter 16150276Speter/** 16250276Speter * @brief Copy the address range given by the source physical map, virtual 16350276Speter * address and length to the destination physical map and virtual address. 16450276Speter * This routine is optional (xxx default null implementation ?) 16550276Speter * 16650276Speter * @param _dst_pmap destination physical map 16750276Speter * @param _src_pmap source physical map 16850276Speter * @param _dst_addr destination virtual address 16950276Speter * @param _len size of range 17050276Speter * @param _src_addr source virtual address 17150276Speter */ 17250276SpeterMETHOD void copy { 17350276Speter mmu_t _mmu; 17450276Speter pmap_t _dst_pmap; 17550276Speter pmap_t _src_pmap; 17650276Speter vm_offset_t _dst_addr; 17750276Speter vm_size_t _len; 17850276Speter vm_offset_t _src_addr; 17950276Speter} DEFAULT mmu_null_copy; 18050276Speter 18150276Speter 18250276Speter/** 18350276Speter * @brief Copy the source physical page to the destination physical page 18450276Speter * 18550276Speter * @param _src source physical page 18650276Speter * @param _dst destination physical page 18750276Speter */ 18850276SpeterMETHOD void copy_page { 18950276Speter mmu_t _mmu; 19050276Speter vm_page_t _src; 19150276Speter vm_page_t _dst; 19250276Speter}; 19350276Speter 19450276Speter 19550276Speter/** 19650276Speter * @brief Create a mapping between a virtual/physical address pair in the 19750276Speter * passed physical map with the specified protection and wiring 19850276Speter * 19950276Speter * @param _pmap physical map 20050276Speter * @param _va mapping virtual address 20150276Speter * @param _p mapping physical page 20250276Speter * @param _prot mapping page protection 20350276Speter * @param _wired TRUE if page will be wired 20450276Speter */ 20550276SpeterMETHOD void enter { 20650276Speter mmu_t _mmu; 20750276Speter pmap_t _pmap; 20850276Speter vm_offset_t _va; 20950276Speter vm_page_t _p; 21050276Speter vm_prot_t _prot; 21150276Speter boolean_t _wired; 21250276Speter}; 21350276Speter 21450276Speter 21550276Speter/** 21650276Speter * @brief Maps a sequence of resident pages belonging to the same object. 21750276Speter * 21850276Speter * @param _pmap physical map 21950276Speter * @param _start virtual range start 22050276Speter * @param _end virtual range end 22150276Speter * @param _m_start physical page mapped at start 22250276Speter * @param _prot mapping page protection 22350276Speter */ 22450276SpeterMETHOD void enter_object { 22550276Speter mmu_t _mmu; 22650276Speter pmap_t _pmap; 22750276Speter vm_offset_t _start; 22850276Speter vm_offset_t _end; 22950276Speter vm_page_t _m_start; 23050276Speter vm_prot_t _prot; 23150276Speter}; 23250276Speter 23350276Speter 23450276Speter/** 23550276Speter * @brief A faster entry point for page mapping where it is possible 23650276Speter * to short-circuit some of the tests in pmap_enter. 23750276Speter * 23850276Speter * @param _pmap physical map (and also currently active pmap) 23950276Speter * @param _va mapping virtual address 24050276Speter * @param _pg mapping physical page 24150276Speter * @param _prot new page protection - used to see if page is exec. 24250276Speter */ 24350276SpeterMETHOD void enter_quick { 24450276Speter mmu_t _mmu; 24550276Speter pmap_t _pmap; 24650276Speter vm_offset_t _va; 24750276Speter vm_page_t _pg; 24850276Speter vm_prot_t _prot; 24950276Speter}; 25050276Speter 25150276Speter 25250276Speter/** 25350276Speter * @brief Reverse map the given virtual address, returning the physical 25450276Speter * page associated with the address if a mapping exists. 25550276Speter * 25650276Speter * @param _pmap physical map 25750276Speter * @param _va mapping virtual address 25850276Speter * 25950276Speter * @retval 0 No mapping found 26050276Speter * @retval addr The mapping physical address 26150276Speter */ 26250276SpeterMETHOD vm_paddr_t extract { 26350276Speter mmu_t _mmu; 26450276Speter pmap_t _pmap; 26550276Speter vm_offset_t _va; 26650276Speter}; 26750276Speter 26850276Speter 26950276Speter/** 27050276Speter * @brief Reverse map the given virtual address, returning the 27150276Speter * physical page if found. The page must be held (by calling 27250276Speter * vm_page_hold) if the page protection matches the given protection 27350276Speter * 27450276Speter * @param _pmap physical map 27550276Speter * @param _va mapping virtual address 27650276Speter * @param _prot protection used to determine if physical page 27750276Speter * should be locked 27850276Speter * 27950276Speter * @retval NULL No mapping found 28050276Speter * @retval page Pointer to physical page. Held if protections match 28150276Speter */ 28250276SpeterMETHOD vm_page_t extract_and_hold { 28350276Speter mmu_t _mmu; 28450276Speter pmap_t _pmap; 28550276Speter vm_offset_t _va; 28650276Speter vm_prot_t _prot; 28750276Speter}; 28850276Speter 28950276Speter 29050276Speter/** 29150276Speter * @brief Increase kernel virtual address space to the given virtual address. 29250276Speter * Not really required for PowerPC, so optional unless the MMU implementation 29350276Speter * can use it. 29450276Speter * 29550276Speter * @param _va new upper limit for kernel virtual address space 29650276Speter */ 29750276SpeterMETHOD void growkernel { 29850276Speter mmu_t _mmu; 29950276Speter vm_offset_t _va; 30050276Speter} DEFAULT mmu_null_growkernel; 30150276Speter 30250276Speter 30350276Speter/** 30450276Speter * @brief Called from vm_mem_init. Zone allocation is available at 30550276Speter * this stage so a convenient time to create zones. This routine is 30650276Speter * for MMU-implementation convenience and is optional. 30750276Speter */ 30850276SpeterMETHOD void init { 30950276Speter mmu_t _mmu; 31050276Speter} DEFAULT mmu_null_init; 31150276Speter 31250276Speter 31350276Speter/** 31450276Speter * @brief Return if the page has been marked by MMU hardware to have been 31550276Speter * modified 31650276Speter * 31750276Speter * @param _pg physical page to test 31850276Speter * 31950276Speter * @retval boolean TRUE if page has been modified 32050276Speter */ 32150276SpeterMETHOD boolean_t is_modified { 32250276Speter mmu_t _mmu; 32350276Speter vm_page_t _pg; 32450276Speter}; 32550276Speter 32650276Speter 32750276Speter/** 32850276Speter * @brief Return whether the specified virtual address is a candidate to be 32950276Speter * prefaulted in. This routine is optional. 33050276Speter * 33150276Speter * @param _pmap physical map 33250276Speter * @param _va virtual address to test 33350276Speter * 33450276Speter * @retval boolean TRUE if the address is a candidate. 33550276Speter */ 33650276SpeterMETHOD boolean_t is_prefaultable { 33750276Speter mmu_t _mmu; 33850276Speter pmap_t _pmap; 33950276Speter vm_offset_t _va; 34050276Speter} DEFAULT mmu_null_is_prefaultable; 34150276Speter 34250276Speter 34350276Speter/** 34450276Speter * @brief Return a count of referenced bits for a page, clearing those bits. 34550276Speter * Not all referenced bits need to be cleared, but it is necessary that 0 34650276Speter * only be returned when there are none set. 34750276Speter * 34850276Speter * @params _m physical page 34950276Speter * 35050276Speter * @retval int count of referenced bits 35150276Speter */ 35250276SpeterMETHOD boolean_t ts_referenced { 35350276Speter mmu_t _mmu; 35450276Speter vm_page_t _pg; 35550276Speter}; 35650276Speter 35750276Speter 35850276Speter/** 35950276Speter * @brief Map the requested physical address range into kernel virtual 36050276Speter * address space. The value in _virt is taken as a hint. The virtual 36150276Speter * address of the range is returned, or NULL if the mapping could not 36250276Speter * be created. The range can be direct-mapped if that is supported. 36350276Speter * 36450276Speter * @param *_virt Hint for start virtual address, and also return 36550276Speter * value 36650276Speter * @param _start physical address range start 36750276Speter * @param _end physical address range end 36850276Speter * @param _prot protection of range (currently ignored) 36950276Speter * 37050276Speter * @retval NULL could not map the area 37150276Speter * @retval addr, *_virt mapping start virtual address 37250276Speter */ 37350276SpeterMETHOD vm_offset_t map { 37450276Speter mmu_t _mmu; 37550276Speter vm_offset_t *_virt; 37650276Speter vm_paddr_t _start; 37750276Speter vm_paddr_t _end; 37850276Speter int _prot; 37950276Speter}; 38050276Speter 38150276Speter 38250276Speter/** 38350276Speter * @brief Used to create a contiguous set of read-only mappings for a 38450276Speter * given object to try and eliminate a cascade of on-demand faults as 38550276Speter * the object is accessed sequentially. This routine is optional. 38650276Speter * 38750276Speter * @param _pmap physical map 38850276Speter * @param _addr mapping start virtual address 38950276Speter * @param _object device-backed V.M. object to be mapped 39050276Speter * @param _pindex page-index within object of mapping start 39150276Speter * @param _size size in bytes of mapping 39250276Speter */ 39350276SpeterMETHOD void object_init_pt { 39450276Speter mmu_t _mmu; 39550276Speter pmap_t _pmap; 39650276Speter vm_offset_t _addr; 39750276Speter vm_object_t _object; 39850276Speter vm_pindex_t _pindex; 39950276Speter vm_size_t _size; 40050276Speter} DEFAULT mmu_null_object_init_pt; 40150276Speter 40250276Speter 40350276Speter/** 40450276Speter * @brief Used to determine if the specified page has a mapping for the 40550276Speter * given physical map, by scanning the list of reverse-mappings from the 40650276Speter * page. The list is scanned to a maximum of 16 entries. 40750276Speter * 40850276Speter * @param _pmap physical map 40950276Speter * @param _pg physical page 41050276Speter * 41150276Speter * @retval bool TRUE if the physical map was found in the first 16 41250276Speter * reverse-map list entries off the physical page. 41350276Speter */ 41450276SpeterMETHOD boolean_t page_exists_quick { 41550276Speter mmu_t _mmu; 41650276Speter pmap_t _pmap; 41750276Speter vm_page_t _pg; 41850276Speter}; 41950276Speter 42050276Speter 42150276Speter/** 42250276Speter * @brief Initialise the machine-dependent section of the physical page 42350276Speter * data structure. This routine is optional. 42450276Speter * 42550276Speter * @param _pg physical page 42650276Speter */ 42750276SpeterMETHOD void page_init { 42850276Speter mmu_t _mmu; 42950276Speter vm_page_t _pg; 43050276Speter} DEFAULT mmu_null_page_init; 43150276Speter 43250276Speter 43350276Speter/** 43450276Speter * @brief Count the number of managed mappings to the given physical 43550276Speter * page that are wired. 43650276Speter * 43750276Speter * @param _pg physical page 43850276Speter * 43950276Speter * @retval int the number of wired, managed mappings to the 44050276Speter * given physical page 44150276Speter */ 44250276SpeterMETHOD int page_wired_mappings { 44350276Speter mmu_t _mmu; 44450276Speter vm_page_t _pg; 44550276Speter}; 44650276Speter 44750276Speter 44850276Speter/** 44950276Speter * @brief Initialise a physical map data structure 45050276Speter * 45150276Speter * @param _pmap physical map 45250276Speter */ 45350276SpeterMETHOD void pinit { 45450276Speter mmu_t _mmu; 45550276Speter pmap_t _pmap; 45650276Speter}; 45750276Speter 45850276Speter 45950276Speter/** 46050276Speter * @brief Initialise the physical map for process 0, the initial process 46150276Speter * in the system. 46250276Speter * XXX default to pinit ? 46350276Speter * 46450276Speter * @param _pmap physical map 46550276Speter */ 46650276SpeterMETHOD void pinit0 { 46750276Speter mmu_t _mmu; 46850276Speter pmap_t _pmap; 46950276Speter}; 47050276Speter 47150276Speter 47250276Speter/** 47350276Speter * @brief Set the protection for physical pages in the given virtual address 47450276Speter * range to the given value. 47550276Speter * 47650276Speter * @param _pmap physical map 47750276Speter * @param _start virtual range start 47850276Speter * @param _end virtual range end 47950276Speter * @param _prot new page protection 48050276Speter */ 48150276SpeterMETHOD void protect { 48250276Speter mmu_t _mmu; 48350276Speter pmap_t _pmap; 48450276Speter vm_offset_t _start; 48550276Speter vm_offset_t _end; 48650276Speter vm_prot_t _prot; 48750276Speter}; 48850276Speter 48950276Speter 49050276Speter/** 49150276Speter * @brief Create a mapping in kernel virtual address space for the given array 49250276Speter * of wired physical pages. 49350276Speter * 49450276Speter * @param _start mapping virtual address start 49550276Speter * @param *_m array of physical page pointers 49650276Speter * @param _count array elements 49750276Speter */ 49850276SpeterMETHOD void qenter { 49950276Speter mmu_t _mmu; 50050276Speter vm_offset_t _start; 50150276Speter vm_page_t *_pg; 50250276Speter int _count; 50350276Speter}; 50450276Speter 50550276Speter 50650276Speter/** 50750276Speter * @brief Remove the temporary mappings created by qenter. 50850276Speter * 50950276Speter * @param _start mapping virtual address start 51050276Speter * @param _count number of pages in mapping 51150276Speter */ 51250276SpeterMETHOD void qremove { 51350276Speter mmu_t _mmu; 51450276Speter vm_offset_t _start; 51550276Speter int _count; 51650276Speter}; 51750276Speter 51850276Speter 51950276Speter/** 52050276Speter * @brief Release per-pmap resources, e.g. mutexes, allocated memory etc. There 52150276Speter * should be no existing mappings for the physical map at this point 52250276Speter * 52350276Speter * @param _pmap physical map 52450276Speter */ 52550276SpeterMETHOD void release { 52650276Speter mmu_t _mmu; 52750276Speter pmap_t _pmap; 52850276Speter}; 52950276Speter 53050276Speter 53150276Speter/** 53250276Speter * @brief Remove all mappings in the given physical map for the start/end 53350276Speter * virtual address range. The range will be page-aligned. 53450276Speter * 53550276Speter * @param _pmap physical map 53650276Speter * @param _start mapping virtual address start 53750276Speter * @param _end mapping virtual address end 53850276Speter */ 53950276SpeterMETHOD void remove { 54050276Speter mmu_t _mmu; 54150276Speter pmap_t _pmap; 54250276Speter vm_offset_t _start; 54350276Speter vm_offset_t _end; 54450276Speter}; 54550276Speter 54650276Speter 54750276Speter/** 54850276Speter * @brief Traverse the reverse-map list off the given physical page and 54950276Speter * remove all mappings. Clear the PG_WRITEABLE attribute from the page. 55050276Speter * 55150276Speter * @param _pg physical page 55250276Speter */ 55350276SpeterMETHOD void remove_all { 55450276Speter mmu_t _mmu; 55550276Speter vm_page_t _pg; 55650276Speter}; 55750276Speter 55850276Speter 55950276Speter/** 56050276Speter * @brief Remove all mappings in the given start/end virtual address range 56150276Speter * for the given physical map. Similar to the remove method, but it used 56250276Speter * when tearing down all mappings in an address space. This method is 56350276Speter * optional, since pmap_remove will be called for each valid vm_map in 56450276Speter * the address space later. 56550276Speter * 56650276Speter * @param _pmap physical map 56750276Speter * @param _start mapping virtual address start 56850276Speter * @param _end mapping virtual address end 56950276Speter */ 57050276SpeterMETHOD void remove_pages { 57150276Speter mmu_t _mmu; 57250276Speter pmap_t _pmap; 57350276Speter} DEFAULT mmu_null_remove_pages; 57450276Speter 57550276Speter 57650276Speter/** 57750276Speter * @brief Zero a physical page. It is not assumed that the page is mapped, 57850276Speter * so a temporary (or direct) mapping may need to be used. 57950276Speter * 58050276Speter * @param _pg physical page 58150276Speter */ 58250276SpeterMETHOD void zero_page { 58350276Speter mmu_t _mmu; 58450276Speter vm_page_t _pg; 58550276Speter}; 58650276Speter 58750276Speter 58850276Speter/** 58950276Speter * @brief Zero a portion of a physical page, starting at a given offset and 59050276Speter * for a given size (multiples of 512 bytes for 4k pages). 59150276Speter * 59250276Speter * @param _pg physical page 59350276Speter * @param _off byte offset from start of page 59450276Speter * @param _size size of area to zero 59550276Speter */ 59650276SpeterMETHOD void zero_page_area { 59750276Speter mmu_t _mmu; 59850276Speter vm_page_t _pg; 59950276Speter int _off; 60050276Speter int _size; 60150276Speter}; 60250276Speter 60350276Speter 60450276Speter/** 60550276Speter * @brief Called from the idle loop to zero pages. XXX I think locking 60650276Speter * constraints might be different here compared to zero_page. 60750276Speter * 60850276Speter * @param _pg physical page 60950276Speter */ 61050276SpeterMETHOD void zero_page_idle { 61150276Speter mmu_t _mmu; 61250276Speter vm_page_t _pg; 61350276Speter}; 61450276Speter 61550276Speter 61650276Speter/** 61750276Speter * @brief Extract mincore(2) information from a mapping. This routine is 61850276Speter * optional and is an optimisation: the mincore code will call is_modified 61950276Speter * and ts_referenced if no result is returned. 62050276Speter * 62150276Speter * @param _pmap physical map 62250276Speter * @param _addr page virtual address 62350276Speter * 62450276Speter * @retval 0 no result 62550276Speter * @retval non-zero mincore(2) flag values 62650276Speter */ 62750276SpeterMETHOD int mincore { 62850276Speter mmu_t _mmu; 62950276Speter pmap_t _pmap; 63050276Speter vm_offset_t _addr; 63150276Speter} DEFAULT mmu_null_mincore; 63250276Speter 63350276Speter 63450276Speter/** 63550276Speter * @brief Perform any operations required to allow a physical map to be used 63650276Speter * before it's address space is accessed. 63750276Speter * 63850276Speter * @param _td thread associated with physical map 63950276Speter */ 64050276SpeterMETHOD void activate { 64150276Speter mmu_t _mmu; 64250276Speter struct thread *_td; 64350276Speter}; 64450276Speter 64550276Speter/** 64650276Speter * @brief Perform any operations required to deactivate a physical map, 64750276Speter * for instance as it is context-switched out. 64850276Speter * 64950276Speter * @param _td thread associated with physical map 65050276Speter */ 65150276SpeterMETHOD void deactivate { 65250276Speter mmu_t _mmu; 65350276Speter struct thread *_td; 65450276Speter} DEFAULT mmu_null_deactivate; 65550276Speter 65650276Speter/** 65750276Speter * @brief Return a hint for the best virtual address to map a tentative 65850276Speter * virtual address range in a given VM object. The default is to just 65950276Speter * return the given tentative start address. 66050276Speter * 66150276Speter * @param _obj VM backing object 66250276Speter * @param _offset starting offset with the VM object 66350276Speter * @param _addr initial guess at virtual address 66450276Speter * @param _size size of virtual address range 66550276Speter */ 66650276SpeterMETHOD void align_superpage { 66750276Speter mmu_t _mmu; 66850276Speter vm_object_t _obj; 66950276Speter vm_ooffset_t _offset; 67050276Speter vm_offset_t *_addr; 67150276Speter vm_size_t _size; 67250276Speter} DEFAULT mmu_null_align_superpage; 67350276Speter 67450276Speter 67550276Speter 67650276Speter 67750276Speter/** 67850276Speter * INTERNAL INTERFACES 67950276Speter */ 68050276Speter 68150276Speter/** 68250276Speter * @brief Bootstrap the VM system. At the completion of this routine, the 68350276Speter * kernel will be running in it's own address space with full control over 68450276Speter * paging. 68550276Speter * 68650276Speter * @param _start start of reserved memory (obsolete ???) 68750276Speter * @param _end end of reserved memory (obsolete ???) 68850276Speter * XXX I think the intent of these was to allow 68950276Speter * the memory used by kernel text+data+bss and 69050276Speter * loader variables/load-time kld's to be carved out 69150276Speter * of available physical mem. 69250276Speter * 69350276Speter */ 69450276SpeterMETHOD void bootstrap { 69550276Speter mmu_t _mmu; 69650276Speter vm_offset_t _start; 69750276Speter vm_offset_t _end; 69850276Speter}; 69950276Speter 70050276Speter 70150276Speter/** 70250276Speter * @brief Create a kernel mapping for a given physical address range. 70350276Speter * Called by bus code on behalf of device drivers. The mapping does not 70450276Speter * have to be a virtual address: it can be a direct-mapped physical address 70550276Speter * if that is supported by the MMU. 70650276Speter * 70750276Speter * @param _pa start physical address 70850276Speter * @param _size size in bytes of mapping 70950276Speter * 71050276Speter * @retval addr address of mapping. 71150276Speter */ 71250276SpeterMETHOD void * mapdev { 71350276Speter mmu_t _mmu; 71450276Speter vm_offset_t _pa; 71550276Speter vm_size_t _size; 71650276Speter}; 71750276Speter 71850276Speter 71950276Speter/** 72050276Speter * @brief Remove the mapping created by mapdev. Called when a driver 72150276Speter * is unloaded. 72250276Speter * 72350276Speter * @param _va Mapping address returned from mapdev 72450276Speter * @param _size size in bytes of mapping 72550276Speter */ 72650276SpeterMETHOD void unmapdev { 72750276Speter mmu_t _mmu; 72850276Speter vm_offset_t _va; 72950276Speter vm_size_t _size; 73050276Speter}; 73150276Speter 73250276Speter 73350276Speter/** 73450276Speter * @brief Reverse-map a kernel virtual address 73550276Speter * 73650276Speter * @param _va kernel virtual address to reverse-map 73750276Speter * 73850276Speter * @retval pa physical address corresponding to mapping 73950276Speter */ 74050276SpeterMETHOD vm_offset_t kextract { 74150276Speter mmu_t _mmu; 74250276Speter vm_offset_t _va; 74350276Speter}; 74450276Speter 74550276Speter 74650276Speter/** 74750276Speter * @brief Map a wired page into kernel virtual address space 74850276Speter * 74950276Speter * @param _va mapping virtual address 75050276Speter * @param _pa mapping physical address 75150276Speter */ 75250276SpeterMETHOD void kenter { 75350276Speter mmu_t _mmu; 75450276Speter vm_offset_t _va; 75550276Speter vm_offset_t _pa; 75650276Speter}; 757 758 759/** 760 * @brief Determine if the given physical address range has been direct-mapped. 761 * 762 * @param _pa physical address start 763 * @param _size physical address range size 764 * 765 * @retval bool TRUE if the range is direct-mapped. 766 */ 767METHOD boolean_t dev_direct_mapped { 768 mmu_t _mmu; 769 vm_offset_t _pa; 770 vm_size_t _size; 771}; 772 773 774/** 775 * @brief Evaluate if a physical page has an executable mapping 776 * 777 * @param _pg physical page 778 * 779 * @retval bool TRUE if a physical mapping exists for the given page. 780 */ 781METHOD boolean_t page_executable { 782 mmu_t _mmu; 783 vm_page_t _pg; 784}; 785 786