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