Changes in kernel/genarch/src/mm/page_pt.c [caed0279:235e6c7] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/genarch/src/mm/page_pt.c
rcaed0279 r235e6c7 39 39 #include <mm/page.h> 40 40 #include <mm/frame.h> 41 #include <mm/km.h>42 41 #include <mm/as.h> 43 42 #include <arch/mm/page.h> … … 46 45 #include <arch/asm.h> 47 46 #include <memstr.h> 48 #include <align.h>49 #include <macros.h>50 #include <bitops.h>51 47 52 48 static void pt_mapping_insert(as_t *, uintptr_t, uintptr_t, unsigned int); 53 49 static void pt_mapping_remove(as_t *, uintptr_t); 54 50 static pte_t *pt_mapping_find(as_t *, uintptr_t, bool); 55 static void pt_mapping_make_global(uintptr_t, size_t);56 51 57 52 page_mapping_operations_t pt_mapping_operations = { 58 53 .mapping_insert = pt_mapping_insert, 59 54 .mapping_remove = pt_mapping_remove, 60 .mapping_find = pt_mapping_find, 61 .mapping_make_global = pt_mapping_make_global 55 .mapping_find = pt_mapping_find 62 56 }; 63 57 … … 81 75 82 76 if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT) { 83 pte_t *newpt = (pte_t *) frame_alloc(PTL1_SIZE, 84 FRAME_LOWMEM | FRAME_KA); 77 pte_t *newpt = (pte_t *) frame_alloc(PTL1_SIZE, FRAME_KA); 85 78 memsetb(newpt, FRAME_SIZE << PTL1_SIZE, 0); 86 79 SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page), KA2PA(newpt)); 87 SET_PTL1_FLAGS(ptl0, PTL0_INDEX(page), 88 PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | 89 PAGE_WRITE); 80 SET_PTL1_FLAGS(ptl0, PTL0_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE); 90 81 } 91 82 … … 93 84 94 85 if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT) { 95 pte_t *newpt = (pte_t *) frame_alloc(PTL2_SIZE, 96 FRAME_LOWMEM | FRAME_KA); 86 pte_t *newpt = (pte_t *) frame_alloc(PTL2_SIZE, FRAME_KA); 97 87 memsetb(newpt, FRAME_SIZE << PTL2_SIZE, 0); 98 88 SET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page), KA2PA(newpt)); 99 SET_PTL2_FLAGS(ptl1, PTL1_INDEX(page), 100 PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | 101 PAGE_WRITE); 89 SET_PTL2_FLAGS(ptl1, PTL1_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE); 102 90 } 103 91 … … 105 93 106 94 if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT) { 107 pte_t *newpt = (pte_t *) frame_alloc(PTL3_SIZE, 108 FRAME_LOWMEM | FRAME_KA); 95 pte_t *newpt = (pte_t *) frame_alloc(PTL3_SIZE, FRAME_KA); 109 96 memsetb(newpt, FRAME_SIZE << PTL3_SIZE, 0); 110 97 SET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page), KA2PA(newpt)); 111 SET_PTL3_FLAGS(ptl2, PTL2_INDEX(page), 112 PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | 113 PAGE_WRITE); 98 SET_PTL3_FLAGS(ptl2, PTL2_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE); 114 99 } 115 100 … … 138 123 /* 139 124 * First, remove the mapping, if it exists. 125 * 140 126 */ 141 127 … … 154 140 pte_t *ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page))); 155 141 142 /* Destroy the mapping. Setting to PAGE_NOT_PRESENT is not sufficient. */ 143 memsetb(&ptl3[PTL3_INDEX(page)], sizeof(pte_t), 0); 144 156 145 /* 157 * Destroy the mapping. 158 * Setting to PAGE_NOT_PRESENT is not sufficient. 159 */ 160 memsetb(&ptl3[PTL3_INDEX(page)], sizeof(pte_t), 0); 161 162 /* 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. 146 * Second, free all empty tables along the way from PTL3 down to PTL0. 147 * 165 148 */ 166 149 … … 179 162 /* 180 163 * PTL3 is empty. 181 * Release the frame and remove PTL3 pointer from the parent 182 * table. 183 */ 164 * Release the frame and remove PTL3 pointer from preceding table. 165 * 166 */ 167 frame_free(KA2PA((uintptr_t) ptl3)); 184 168 #if (PTL2_ENTRIES != 0) 185 169 memsetb(&ptl2[PTL2_INDEX(page)], sizeof(pte_t), 0); … … 187 171 memsetb(&ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0); 188 172 #else 189 if (km_is_non_identity(page))190 return;191 192 173 memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0); 193 174 #endif 194 frame_free(KA2PA((uintptr_t) ptl3));195 175 } else { 196 176 /* … … 215 195 /* 216 196 * PTL2 is empty. 217 * Release the frame and remove PTL2 pointer from the parent 218 * table. 219 */ 197 * Release the frame and remove PTL2 pointer from preceding table. 198 * 199 */ 200 frame_free(KA2PA((uintptr_t) ptl2)); 220 201 #if (PTL1_ENTRIES != 0) 221 202 memsetb(&ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0); 222 203 #else 223 if (km_is_non_identity(page))224 return;225 226 204 memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0); 227 205 #endif 228 frame_free(KA2PA((uintptr_t) ptl2));229 206 } else { 230 207 /* … … 250 227 /* 251 228 * PTL1 is empty. 252 * Release the frame and remove PTL1 pointer from the parent 253 * table. 254 */ 255 if (km_is_non_identity(page)) 256 return; 257 229 * Release the frame and remove PTL1 pointer from preceding table. 230 * 231 */ 232 frame_free(KA2PA((uintptr_t) ptl1)); 258 233 memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0); 259 frame_free(KA2PA((uintptr_t) ptl1));260 234 } 261 235 #endif /* PTL1_ENTRIES != 0 */ … … 293 267 } 294 268 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 page312 * table. The next level page table will be allocated and cleared.313 *314 * pt_mapping_remove() will never deallocate these page tables even when there315 * are no PTEs in them.316 *317 * @param as Address space.318 * @param base Base address corresponding to the first PTL0 entry that will be319 * altered by this function.320 * @param size Size in bytes defining the range of PTL0 entries that will be321 * 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 #else335 order = PTL3_SIZE;336 #endif337 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 353 269 /** @} 354 270 */
Note:
See TracChangeset
for help on using the changeset viewer.