Changeset c520034 in mainline for kernel/genarch/src/mm/page_pt.c
- Timestamp:
- 2011-12-31T18:19:35Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 295f658, 77c2b02, 96cd5b4
- Parents:
- 852052d (diff), 22f0561 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/genarch/src/mm/page_pt.c
r852052d rc520034 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> 47 50 48 51 static void pt_mapping_insert(as_t *, uintptr_t, uintptr_t, unsigned int); 49 52 static void pt_mapping_remove(as_t *, uintptr_t); 50 53 static pte_t *pt_mapping_find(as_t *, uintptr_t, bool); 54 static void pt_mapping_make_global(uintptr_t, size_t); 51 55 52 56 page_mapping_operations_t pt_mapping_operations = { 53 57 .mapping_insert = pt_mapping_insert, 54 58 .mapping_remove = pt_mapping_remove, 55 .mapping_find = pt_mapping_find 59 .mapping_find = pt_mapping_find, 60 .mapping_make_global = pt_mapping_make_global 56 61 }; 57 62 … … 75 80 76 81 if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT) { 77 pte_t *newpt = (pte_t *) frame_alloc(PTL1_SIZE, FRAME_KA); 82 pte_t *newpt = (pte_t *) frame_alloc(PTL1_SIZE, 83 FRAME_LOWMEM | FRAME_KA); 78 84 memsetb(newpt, FRAME_SIZE << PTL1_SIZE, 0); 79 85 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); 86 SET_PTL1_FLAGS(ptl0, PTL0_INDEX(page), 87 PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | 88 PAGE_WRITE); 81 89 } 82 90 … … 84 92 85 93 if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT) { 86 pte_t *newpt = (pte_t *) frame_alloc(PTL2_SIZE, FRAME_KA); 94 pte_t *newpt = (pte_t *) frame_alloc(PTL2_SIZE, 95 FRAME_LOWMEM | FRAME_KA); 87 96 memsetb(newpt, FRAME_SIZE << PTL2_SIZE, 0); 88 97 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); 98 SET_PTL2_FLAGS(ptl1, PTL1_INDEX(page), 99 PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | 100 PAGE_WRITE); 90 101 } 91 102 … … 93 104 94 105 if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT) { 95 pte_t *newpt = (pte_t *) frame_alloc(PTL3_SIZE, FRAME_KA); 106 pte_t *newpt = (pte_t *) frame_alloc(PTL3_SIZE, 107 FRAME_LOWMEM | FRAME_KA); 96 108 memsetb(newpt, FRAME_SIZE << PTL3_SIZE, 0); 97 109 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); 110 SET_PTL3_FLAGS(ptl2, PTL2_INDEX(page), 111 PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | 112 PAGE_WRITE); 99 113 } 100 114 … … 123 137 /* 124 138 * First, remove the mapping, if it exists. 125 *126 139 */ 127 140 … … 140 153 pte_t *ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page))); 141 154 142 /* Destroy the mapping. Setting to PAGE_NOT_PRESENT is not sufficient. */ 155 /* 156 * Destroy the mapping. 157 * Setting to PAGE_NOT_PRESENT is not sufficient. 158 */ 143 159 memsetb(&ptl3[PTL3_INDEX(page)], sizeof(pte_t), 0); 144 160 145 161 /* 146 * Second, free all empty tables along the way from PTL3 down to PTL0 .147 * 162 * Second, free all empty tables along the way from PTL3 down to PTL0 163 * except those needed for sharing the kernel non-identity mappings. 148 164 */ 149 165 … … 162 178 /* 163 179 * PTL3 is empty. 164 * Release the frame and remove PTL3 pointer from preceding table. 165 * 166 */ 167 frame_free(KA2PA((uintptr_t) ptl3)); 180 * Release the frame and remove PTL3 pointer from the parent 181 * table. 182 */ 168 183 #if (PTL2_ENTRIES != 0) 169 184 memsetb(&ptl2[PTL2_INDEX(page)], sizeof(pte_t), 0); … … 171 186 memsetb(&ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0); 172 187 #else 188 if (km_is_non_identity(page)) 189 return; 190 173 191 memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0); 174 192 #endif 193 frame_free(KA2PA((uintptr_t) ptl3)); 175 194 } else { 176 195 /* … … 195 214 /* 196 215 * PTL2 is empty. 197 * Release the frame and remove PTL2 pointer from preceding table. 198 * 199 */ 200 frame_free(KA2PA((uintptr_t) ptl2)); 216 * Release the frame and remove PTL2 pointer from the parent 217 * table. 218 */ 201 219 #if (PTL1_ENTRIES != 0) 202 220 memsetb(&ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0); 203 221 #else 222 if (km_is_non_identity(page)) 223 return; 224 204 225 memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0); 205 226 #endif 227 frame_free(KA2PA((uintptr_t) ptl2)); 206 228 } else { 207 229 /* … … 227 249 /* 228 250 * PTL1 is empty. 229 * Release the frame and remove PTL1 pointer from preceding table. 230 * 231 */ 251 * Release the frame and remove PTL1 pointer from the parent 252 * table. 253 */ 254 if (km_is_non_identity(page)) 255 return; 256 257 memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0); 232 258 frame_free(KA2PA((uintptr_t) ptl1)); 233 memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);234 259 } 235 260 #endif /* PTL1_ENTRIES != 0 */ … … 267 292 } 268 293 294 /** Make the mappings in the given range global accross all address spaces. 295 * 296 * All PTL0 entries in the given range will be mapped to a next level page 297 * table. The next level page table will be allocated and cleared. 298 * 299 * pt_mapping_remove() will never deallocate these page tables even when there 300 * are no PTEs in them. 301 * 302 * @param as Address space. 303 * @param base Base address corresponding to the first PTL0 entry that will be 304 * altered by this function. 305 * @param size Size in bytes defining the range of PTL0 entries that will be 306 * altered by this function. 307 */ 308 void pt_mapping_make_global(uintptr_t base, size_t size) 309 { 310 uintptr_t ptl0 = PA2KA((uintptr_t) AS_KERNEL->genarch.page_table); 311 uintptr_t ptl0step = (((uintptr_t) -1) / PTL0_ENTRIES) + 1; 312 size_t order; 313 uintptr_t addr; 314 315 #if (PTL1_ENTRIES != 0) 316 order = PTL1_SIZE; 317 #elif (PTL2_ENTRIES != 0) 318 order = PTL2_SIZE; 319 #else 320 order = PTL3_SIZE; 321 #endif 322 323 ASSERT(ispwr2(ptl0step)); 324 325 for (addr = ALIGN_DOWN(base, ptl0step); addr < base + size; 326 addr += ptl0step) { 327 uintptr_t l1; 328 329 l1 = (uintptr_t) frame_alloc(order, FRAME_KA | FRAME_LOWMEM); 330 memsetb((void *) l1, FRAME_SIZE << order, 0); 331 SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(addr), KA2PA(l1)); 332 SET_PTL1_FLAGS(ptl0, PTL0_INDEX(addr), 333 PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | 334 PAGE_WRITE); 335 } 336 } 337 269 338 /** @} 270 339 */
Note:
See TracChangeset
for help on using the changeset viewer.