Changes in kernel/genarch/src/mm/page_pt.c [a2789d2:de73242] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/genarch/src/mm/page_pt.c
ra2789d2 rde73242 43 43 #include <arch/mm/page.h> 44 44 #include <arch/mm/as.h> 45 #include <arch/barrier.h> 45 46 #include <typedefs.h> 46 47 #include <arch/asm.h> … … 48 49 #include <align.h> 49 50 #include <macros.h> 51 #include <bitops.h> 50 52 51 53 static void pt_mapping_insert(as_t *, uintptr_t, uintptr_t, unsigned int); … … 85 87 SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page), KA2PA(newpt)); 86 88 SET_PTL1_FLAGS(ptl0, PTL0_INDEX(page), 87 PAGE_ PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE |89 PAGE_NOT_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | 88 90 PAGE_WRITE); 91 /* 92 * Make sure that a concurrent hardware page table walk or 93 * pt_mapping_find() will see the new PTL1 only after it is 94 * fully initialized. 95 */ 96 write_barrier(); 97 SET_PTL1_PRESENT(ptl0, PTL0_INDEX(page)); 89 98 } 90 99 … … 97 106 SET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page), KA2PA(newpt)); 98 107 SET_PTL2_FLAGS(ptl1, PTL1_INDEX(page), 99 PAGE_ PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE |108 PAGE_NOT_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | 100 109 PAGE_WRITE); 110 /* 111 * Make the new PTL2 visible only after it is fully initialized. 112 */ 113 write_barrier(); 114 SET_PTL2_PRESENT(ptl1, PTL1_INDEX(page)); 101 115 } 102 116 … … 109 123 SET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page), KA2PA(newpt)); 110 124 SET_PTL3_FLAGS(ptl2, PTL2_INDEX(page), 111 PAGE_ PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE |125 PAGE_NOT_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | 112 126 PAGE_WRITE); 127 /* 128 * Make the new PTL3 visible only after it is fully initialized. 129 */ 130 write_barrier(); 131 SET_PTL3_PRESENT(ptl2, PTL2_INDEX(page)); 113 132 } 114 133 … … 116 135 117 136 SET_FRAME_ADDRESS(ptl3, PTL3_INDEX(page), frame); 118 SET_FRAME_FLAGS(ptl3, PTL3_INDEX(page), flags); 137 SET_FRAME_FLAGS(ptl3, PTL3_INDEX(page), flags | PAGE_NOT_PRESENT); 138 /* 139 * Make the new mapping visible only after it is fully initialized. 140 */ 141 write_barrier(); 142 SET_FRAME_PRESENT(ptl3, PTL3_INDEX(page)); 119 143 } 120 144 … … 278 302 if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT) 279 303 return NULL; 304 305 read_barrier(); 280 306 281 307 pte_t *ptl1 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page))); 282 308 if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT) 283 309 return NULL; 310 311 #if (PTL1_ENTRIES != 0) 312 /* 313 * Always read ptl2 only after we are sure it is present. 314 */ 315 read_barrier(); 316 #endif 284 317 285 318 pte_t *ptl2 = (pte_t *) PA2KA(GET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page))); 286 319 if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT) 287 320 return NULL; 321 322 #if (PTL2_ENTRIES != 0) 323 /* 324 * Always read ptl3 only after we are sure it is present. 325 */ 326 read_barrier(); 327 #endif 288 328 289 329 pte_t *ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page))); 290 330 291 331 return &ptl3[PTL3_INDEX(page)]; 332 } 333 334 /** Return the size of the region mapped by a single PTL0 entry. 335 * 336 * @return Size of the region mapped by a single PTL0 entry. 337 */ 338 static uintptr_t ptl0_step_get(void) 339 { 340 size_t va_bits; 341 342 va_bits = fnzb(PTL0_ENTRIES) + fnzb(PTL1_ENTRIES) + fnzb(PTL2_ENTRIES) + 343 fnzb(PTL3_ENTRIES) + PAGE_WIDTH; 344 345 return 1UL << (va_bits - fnzb(PTL0_ENTRIES)); 292 346 } 293 347 … … 309 363 { 310 364 uintptr_t ptl0 = PA2KA((uintptr_t) AS_KERNEL->genarch.page_table); 311 uintptr_t ptl0 step = (((uintptr_t) -1) / PTL0_ENTRIES) + 1;365 uintptr_t ptl0_step = ptl0_step_get(); 312 366 size_t order; 313 367 uintptr_t addr; … … 321 375 #endif 322 376 323 ASSERT(ispwr2(ptl0step));324 377 ASSERT(size > 0); 325 378 326 for (addr = ALIGN_DOWN(base, ptl0 step); addr - 1 < base + size - 1;327 addr += ptl0 step) {379 for (addr = ALIGN_DOWN(base, ptl0_step); addr - 1 < base + size - 1; 380 addr += ptl0_step) { 328 381 uintptr_t l1; 329 382 … … 332 385 SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(addr), KA2PA(l1)); 333 386 SET_PTL1_FLAGS(ptl0, PTL0_INDEX(addr), 334 PAGE_PRESENT | PAGE_USER | PAGE_ EXEC | PAGE_CACHEABLE |335 PAGE_ WRITE);387 PAGE_PRESENT | PAGE_USER | PAGE_CACHEABLE | 388 PAGE_EXEC | PAGE_WRITE | PAGE_READ); 336 389 } 337 390 }
Note:
See TracChangeset
for help on using the changeset viewer.