Changes in kernel/genarch/src/mm/page_pt.c [235e6c7:caed0279] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/genarch/src/mm/page_pt.c
r235e6c7 rcaed0279 39 39 #include <mm/page.h> 40 40 #include <mm/frame.h> 41 #include <mm/km.h> 41 42 #include <mm/as.h> 42 43 #include <arch/mm/page.h> … … 45 46 #include <arch/asm.h> 46 47 #include <memstr.h> 48 #include <align.h> 49 #include <macros.h> 50 #include <bitops.h> 47 51 48 52 static void pt_mapping_insert(as_t *, uintptr_t, uintptr_t, unsigned int); 49 53 static void pt_mapping_remove(as_t *, uintptr_t); 50 54 static pte_t *pt_mapping_find(as_t *, uintptr_t, bool); 55 static void pt_mapping_make_global(uintptr_t, size_t); 51 56 52 57 page_mapping_operations_t pt_mapping_operations = { 53 58 .mapping_insert = pt_mapping_insert, 54 59 .mapping_remove = pt_mapping_remove, 55 .mapping_find = pt_mapping_find 60 .mapping_find = pt_mapping_find, 61 .mapping_make_global = pt_mapping_make_global 56 62 }; 57 63 … … 75 81 76 82 if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT) { 77 pte_t *newpt = (pte_t *) frame_alloc(PTL1_SIZE, FRAME_KA); 83 pte_t *newpt = (pte_t *) frame_alloc(PTL1_SIZE, 84 FRAME_LOWMEM | FRAME_KA); 78 85 memsetb(newpt, FRAME_SIZE << PTL1_SIZE, 0); 79 86 SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page), KA2PA(newpt)); 80 SET_PTL1_FLAGS(ptl0, PTL0_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE); 87 SET_PTL1_FLAGS(ptl0, PTL0_INDEX(page), 88 PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | 89 PAGE_WRITE); 81 90 } 82 91 … … 84 93 85 94 if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT) { 86 pte_t *newpt = (pte_t *) frame_alloc(PTL2_SIZE, FRAME_KA); 95 pte_t *newpt = (pte_t *) frame_alloc(PTL2_SIZE, 96 FRAME_LOWMEM | FRAME_KA); 87 97 memsetb(newpt, FRAME_SIZE << PTL2_SIZE, 0); 88 98 SET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page), KA2PA(newpt)); 89 SET_PTL2_FLAGS(ptl1, PTL1_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE); 99 SET_PTL2_FLAGS(ptl1, PTL1_INDEX(page), 100 PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | 101 PAGE_WRITE); 90 102 } 91 103 … … 93 105 94 106 if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT) { 95 pte_t *newpt = (pte_t *) frame_alloc(PTL3_SIZE, FRAME_KA); 107 pte_t *newpt = (pte_t *) frame_alloc(PTL3_SIZE, 108 FRAME_LOWMEM | FRAME_KA); 96 109 memsetb(newpt, FRAME_SIZE << PTL3_SIZE, 0); 97 110 SET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page), KA2PA(newpt)); 98 SET_PTL3_FLAGS(ptl2, PTL2_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE); 111 SET_PTL3_FLAGS(ptl2, PTL2_INDEX(page), 112 PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | 113 PAGE_WRITE); 99 114 } 100 115 … … 123 138 /* 124 139 * First, remove the mapping, if it exists. 125 *126 140 */ 127 141 … … 140 154 pte_t *ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page))); 141 155 142 /* Destroy the mapping. Setting to PAGE_NOT_PRESENT is not sufficient. */ 156 /* 157 * Destroy the mapping. 158 * Setting to PAGE_NOT_PRESENT is not sufficient. 159 */ 143 160 memsetb(&ptl3[PTL3_INDEX(page)], sizeof(pte_t), 0); 144 161 145 162 /* 146 * Second, free all empty tables along the way from PTL3 down to PTL0 .147 * 163 * Second, free all empty tables along the way from PTL3 down to PTL0 164 * except those needed for sharing the kernel non-identity mappings. 148 165 */ 149 166 … … 162 179 /* 163 180 * PTL3 is empty. 164 * Release the frame and remove PTL3 pointer from preceding table. 165 * 166 */ 167 frame_free(KA2PA((uintptr_t) ptl3)); 181 * Release the frame and remove PTL3 pointer from the parent 182 * table. 183 */ 168 184 #if (PTL2_ENTRIES != 0) 169 185 memsetb(&ptl2[PTL2_INDEX(page)], sizeof(pte_t), 0); … … 171 187 memsetb(&ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0); 172 188 #else 189 if (km_is_non_identity(page)) 190 return; 191 173 192 memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0); 174 193 #endif 194 frame_free(KA2PA((uintptr_t) ptl3)); 175 195 } else { 176 196 /* … … 195 215 /* 196 216 * PTL2 is empty. 197 * Release the frame and remove PTL2 pointer from preceding table. 198 * 199 */ 200 frame_free(KA2PA((uintptr_t) ptl2)); 217 * Release the frame and remove PTL2 pointer from the parent 218 * table. 219 */ 201 220 #if (PTL1_ENTRIES != 0) 202 221 memsetb(&ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0); 203 222 #else 223 if (km_is_non_identity(page)) 224 return; 225 204 226 memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0); 205 227 #endif 228 frame_free(KA2PA((uintptr_t) ptl2)); 206 229 } else { 207 230 /* … … 227 250 /* 228 251 * PTL1 is empty. 229 * Release the frame and remove PTL1 pointer from preceding table. 230 * 231 */ 252 * Release the frame and remove PTL1 pointer from the parent 253 * table. 254 */ 255 if (km_is_non_identity(page)) 256 return; 257 258 memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0); 232 259 frame_free(KA2PA((uintptr_t) ptl1)); 233 memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);234 260 } 235 261 #endif /* PTL1_ENTRIES != 0 */ … … 267 293 } 268 294 295 /** Return the size of the region mapped by a single PTL0 entry. 296 * 297 * @return Size of the region mapped by a single PTL0 entry. 298 */ 299 static uintptr_t ptl0_step_get(void) 300 { 301 size_t va_bits; 302 303 va_bits = fnzb(PTL0_ENTRIES) + fnzb(PTL1_ENTRIES) + fnzb(PTL2_ENTRIES) + 304 fnzb(PTL3_ENTRIES) + PAGE_WIDTH; 305 306 return 1UL << (va_bits - fnzb(PTL0_ENTRIES)); 307 } 308 309 /** Make the mappings in the given range global accross all address spaces. 310 * 311 * All PTL0 entries in the given range will be mapped to a next level page 312 * table. The next level page table will be allocated and cleared. 313 * 314 * pt_mapping_remove() will never deallocate these page tables even when there 315 * are no PTEs in them. 316 * 317 * @param as Address space. 318 * @param base Base address corresponding to the first PTL0 entry that will be 319 * altered by this function. 320 * @param size Size in bytes defining the range of PTL0 entries that will be 321 * altered by this function. 322 */ 323 void pt_mapping_make_global(uintptr_t base, size_t size) 324 { 325 uintptr_t ptl0 = PA2KA((uintptr_t) AS_KERNEL->genarch.page_table); 326 uintptr_t ptl0_step = ptl0_step_get(); 327 size_t order; 328 uintptr_t addr; 329 330 #if (PTL1_ENTRIES != 0) 331 order = PTL1_SIZE; 332 #elif (PTL2_ENTRIES != 0) 333 order = PTL2_SIZE; 334 #else 335 order = PTL3_SIZE; 336 #endif 337 338 ASSERT(size > 0); 339 340 for (addr = ALIGN_DOWN(base, ptl0_step); addr - 1 < base + size - 1; 341 addr += ptl0_step) { 342 uintptr_t l1; 343 344 l1 = (uintptr_t) frame_alloc(order, FRAME_KA | FRAME_LOWMEM); 345 memsetb((void *) l1, FRAME_SIZE << order, 0); 346 SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(addr), KA2PA(l1)); 347 SET_PTL1_FLAGS(ptl0, PTL0_INDEX(addr), 348 PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | 349 PAGE_WRITE); 350 } 351 } 352 269 353 /** @} 270 354 */
Note:
See TracChangeset
for help on using the changeset viewer.