|
[ source navigation ] [ diff markup ] [ identifier search ] [ general search ] |
|||
|
001 /* Copyright (C) 2004 David Decotigny 002 003 This program is free software; you can redistribute it and/or 004 modify it under the terms of the GNU General Public License 005 as published by the Free Software Foundation; either version 2 006 of the License, or (at your option) any later version. 007 008 This program is distributed in the hope that it will be useful, 009 but WITHOUT ANY WARRANTY; without even the implied warranty of 010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 011 GNU General Public License for more details. 012 013 You should have received a copy of the GNU General Public License 014 along with this program; if not, write to the Free Software 015 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 016 USA. 017 */ 018 #ifndef _SOS_PAGING_H_ 019 #define _SOS_PAGING_H_ 020 021 /** 022 * @file paging.h 023 * 024 * MMU management routines (arch-dependent). Setup the MMU without 025 * identity-mapping physical<->virtual addresses over the whole 026 * physical address space: a single, restricted and known, area is 027 * identity-mapped, the remaining kernel/user space is not. To access 028 * and manage the MMU translation tables (PD/PT on x86), we rely on a 029 * particular configuration, called "mirroring", where the top-level 030 * translation table (PD on x86) maps itself at a known and fixed (virtual) 031 * address. The only assumption for this to be possible is that the 032 * structure of the translation table entries are compatible at the 033 * different levels of vadddr->paddr translation process (PDE and PTE 034 * on x86 are Ok). Credits go to Christophe Avoinne for that. 035 */ 036 037 #include <sos/types.h> 038 #include <sos/errno.h> 039 040 041 /** 042 * Basic SOS virtual memory organization 043 */ 044 /** Frontier between kernel and user space virtual addresses */ 045 #define SOS_PAGING_BASE_USER_ADDRESS (0x40000000) /* 1GB (must be 4MB-aligned) */ 046 #define SOS_PAGING_TOP_USER_ADDRESS (0xFFFFFFFF) /* 4GB - 1B */ 047 #define SOS_PAGING_USER_SPACE_SIZE (0xc0000000) /* 3GB */ 048 049 /** Length of the space reserved for the mirroring in the kernel 050 virtual space */ 051 #define SOS_PAGING_MIRROR_SIZE (1 << 22) /* 1 PD = 1024 Page Tables = 4MB */ 052 053 /** Virtual address where the mirroring takes place */ 054 #define SOS_PAGING_MIRROR_VADDR \ 055 (SOS_PAGING_BASE_USER_ADDRESS - SOS_PAGING_MIRROR_SIZE) 056 057 058 /** 059 * sos_paging_map flags 060 */ 061 /** Usual virtual memory access rights */ 062 #define SOS_VM_MAP_PROT_NONE 0 063 #define SOS_VM_MAP_PROT_READ (1<<0) 064 #define SOS_VM_MAP_PROT_WRITE (1<<1) 065 #define SOS_VM_MAP_PROT_EXEC (1<<2) /* Not supported on IA32 */ 066 067 /** Mapping a page may involve an physical page allocation (for a new 068 PT), hence may potentially block */ 069 #define SOS_VM_MAP_ATOMIC (1<<31) 070 071 072 /** 073 * Setup initial page directory structure where the kernel is 074 * identically-mapped, and the mirroring. This routine also 075 * identity-maps the BIOS and video areas, to allow some debugging 076 * text to be printed to the console. Finally, this routine installs 077 * the whole configuration into the MMU. 078 */ 079 sos_ret_t sos_paging_subsystem_setup(sos_paddr_t identity_mapping_base, 080 sos_paddr_t identity_mapping_top); 081 082 083 /** 084 * Map the given physical page at the given virtual address in the 085 * current address space. 086 * 087 * @note *IMPORTANT*: The physical page ppage_paddr *MUST* have been 088 * referenced by the caller through either a call to 089 * sos_physmem_ref_physpage_new() or sos_physmem_ref_physpage_at(). It 090 * would work if this were untrue, but this would be INCORRECT (it is 091 * expected that one is owning the page before mapping it, or 092 * otherwise the page could have been stolen by an interrupt or 093 * another thread). 094 * 095 * @param ppage_paddr The address of a physical page (page-aligned) 096 * @param vpage_vaddr The address of the virtual page (page-aligned) 097 * @param is_user_page TRUE when the page is available from user space 098 * @param flags A mask made of SOS_VM_* bits 099 * 100 * @note Unless the SOS_VM_MAP_ATOMIC bit is set in the flags, the 101 * function may potentially block, because a physical page may be 102 * allocated for a new PT. 103 */ 104 sos_ret_t sos_paging_map(sos_paddr_t ppage_paddr, 105 sos_vaddr_t vpage_vaddr, 106 sos_bool_t is_user_page, 107 sos_ui32_t flags); 108 109 /** 110 * Undo the mapping from vaddr to the underlying physical page (if any) 111 * @param vpage_vaddr The address of the virtual page (page-aligned) 112 * 113 * @return >= 0 when OK (the number of bytes of RAM unmapped), < 0 on error 114 */ 115 sos_ret_t sos_paging_unmap(sos_vaddr_t vpage_vaddr); 116 117 /** 118 * Undo the mapping from [vaddr .. vaddr + size[ to the underlying 119 * physical pages (if any) 120 * @param vpage_vaddr The address of the virtual page (page-aligned) 121 * @param size The size (in bytes) to unmap. MUST be page-aligned 122 */ 123 sos_ret_t sos_paging_unmap_interval(sos_vaddr_t base_vpage_vaddr, 124 sos_size_t size); 125 126 /** 127 * Return the page protection flags (SOS_VM_MAP_PROT_*) associated 128 * with the address, or SOS_VM_MAP_PROT_NONE when page is not mapped 129 */ 130 sos_ui32_t sos_paging_get_prot(sos_vaddr_t vaddr); 131 132 /** 133 * Change the page access rights 134 */ 135 sos_ret_t sos_paging_set_prot(sos_vaddr_t vaddr, 136 sos_ui32_t new_prot); 137 138 139 /** 140 * Get the "dirty" status of the page 141 */ 142 sos_bool_t sos_paging_is_dirty(sos_vaddr_t vaddr); 143 144 /** 145 * Change the "dirty" status of the page 146 */ 147 sos_ret_t sos_paging_set_dirty(sos_vaddr_t vaddr, 148 sos_bool_t is_dirty); 149 150 151 /** 152 * Change the access rights of the mapping from [vaddr .. vaddr + 153 * size[ to the underlying physical pages (if any) 154 * @param vpage_vaddr The address of the virtual page (page-aligned) 155 * @param size The size (in bytes) to unmap. MUST be page-aligned 156 */ 157 sos_ret_t sos_paging_set_prot_of_interval(sos_vaddr_t vaddr, 158 sos_size_t size, 159 sos_ui32_t new_prot); 160 161 /** 162 * Return the physical address of the given virtual address. Since page 163 * at physical addr 0 is not mapped, the NULL result means "page not 164 * mapped". 165 */ 166 sos_paddr_t sos_paging_get_paddr(sos_vaddr_t vaddr); 167 168 /** 169 * Tell whether the address is physically mapped 170 */ 171 #define sos_paging_check_present(vaddr) \ 172 (sos_paging_get_paddr(vaddr) != NULL) 173 174 175 /* ************************************************* 176 * Functions restricted to mm_context module 177 */ 178 179 180 /** 181 * Release the references to all the referenced pages (and PT on 182 * x86). On x86, this applies only to the USER pages and PT. 183 */ 184 sos_ret_t sos_paging_dispose(sos_vaddr_t vaddr_PD); 185 186 187 /** 188 * Copy the MMU configuration related to the kernel virtual area 189 */ 190 sos_ret_t sos_paging_copy_kernel_space(sos_vaddr_t dest_vaddr_PD, 191 sos_vaddr_t src_vaddr_PD); 192 193 194 /** 195 * Copy the MMU configuration related to the user virtual area 196 */ 197 sos_ret_t sos_paging_copy_user_space(sos_vaddr_t dest_vaddr_PD, 198 sos_vaddr_t src_vaddr_PD); 199 200 201 /** 202 * Prepare the *current* address space for COW on the given *private* 203 * mapping 204 */ 205 sos_ret_t sos_paging_prepare_COW(sos_uaddr_t base_address, 206 sos_size_t length); 207 208 209 /** 210 * Try to resolve the given page fault exception by a COW. 211 * 212 * @param uaddr The user-space address (of the current MMU context) of 213 * the faulting access 214 * 215 * @return TRUE if the page fault was a real COW and could be handled, 216 * FALSE if the page fault is not subject to COW (no physical mem 217 * mapped at this address). <0 in case the given address is subject to 218 * COW BUT could not be resolved due to runtime errors 219 */ 220 sos_ret_t sos_paging_try_resolve_COW(sos_uaddr_t uaddr); 221 222 223 /** 224 * Retrieve the current physical address of the PD 225 */ 226 sos_paddr_t sos_paging_get_current_PD_paddr(void); 227 228 229 /** 230 * Change the current MMU configuration. 231 * 232 * @note DANGEROUS. Don't use it unless you know exactly what you're 233 * doing ! 234 */ 235 sos_ret_t sos_paging_set_current_PD_paddr(sos_paddr_t paddr_PD); 236 237 #endif /* _SOS_PAGING_H_ */
[ source navigation ] | [ diff markup ] | [ identifier search ] | [ general search ] |