Changeset 3fe58d3c in mainline
- Timestamp:
- 2012-01-20T22:35:26Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- e86b8f0
- Parents:
- 321052f7 (diff), 7943c43 (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. - Location:
- kernel
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/arm32/include/mm/km.h
r321052f7 r3fe58d3c 39 39 40 40 #define KM_ARM32_IDENTITY_START UINT32_C(0x80000000) 41 #define KM_ARM32_IDENTITY_SIZE UINT32_C(0x 40000000)41 #define KM_ARM32_IDENTITY_SIZE UINT32_C(0x70000000) 42 42 43 #define KM_ARM32_NON_IDENTITY_START UINT32_C(0xc0000000) 44 #define KM_ARM32_NON_IDENTITY_SIZE UINT32_C(0x40000000) 43 #define KM_ARM32_NON_IDENTITY_START UINT32_C(0xf0000000) 44 /* 45 * The last virtual megabyte contains the high exception vectors (0xFFFF0000). 46 * Do not include this range into kernel non-identity. 47 */ 48 #define KM_ARM32_NON_IDENTITY_SIZE UINT32_C(0x0ff00000) 45 49 46 50 extern void km_identity_arch_init(void); -
kernel/arch/arm32/src/mm/page.c
r321052f7 r3fe58d3c 65 65 page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags); 66 66 67 #ifdef HIGH_EXCEPTION_VECTORS 67 68 /* Create mapping for exception table at high offset */ 68 #ifdef HIGH_EXCEPTION_VECTORS 69 // XXX: fixme to use proper non-identity page 70 void *virtaddr = frame_alloc(ONE_FRAME, FRAME_KA); 71 page_mapping_insert(AS_KERNEL, EXC_BASE_ADDRESS, KA2PA(virtaddr), 72 flags); 69 uintptr_t ev_frame = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_NONE); 70 page_mapping_insert(AS_KERNEL, EXC_BASE_ADDRESS, ev_frame, flags); 73 71 #else 74 72 #error "Only high exception vector supported now" 75 73 #endif 76 cur = ALIGN_DOWN(0x50008010, FRAME_SIZE);77 page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags);78 74 79 75 page_table_unlock(AS_KERNEL, true); -
kernel/arch/ia32/src/mm/frame.c
r321052f7 r3fe58d3c 54 54 55 55 for (i = 0; i < e820counter; i++) { 56 uintptr_t base = (uintptr_t) e820table[i].base_address; 57 size_t size = (size_t) e820table[i].size; 56 uint64_t base64 = e820table[i].base_address; 57 uint64_t size64 = e820table[i].size; 58 59 #ifdef KARCH_ia32 60 /* 61 * Restrict the e820 table entries to 32-bits. 62 */ 63 if (base64 >= 0x100000000ULL) 64 continue; 65 if (base64 + size64 > 0x100000000ULL) 66 size64 -= base64 + size64 - 0x100000000ULL; 67 #endif 68 69 uintptr_t base = (uintptr_t) base64; 70 size_t size = (size_t) size64; 58 71 59 72 if (!frame_adjust_zone_bounds(low, &base, &size)) -
kernel/genarch/src/mm/page_pt.c
r321052f7 r3fe58d3c 322 322 323 323 ASSERT(ispwr2(ptl0step)); 324 325 for (addr = ALIGN_DOWN(base, ptl0step); addr < base + size; 324 ASSERT(size > 0); 325 326 for (addr = ALIGN_DOWN(base, ptl0step); addr - 1 < base + size - 1; 326 327 addr += ptl0step) { 327 328 uintptr_t l1; -
kernel/generic/include/mm/frame.h
r321052f7 r3fe58d3c 83 83 #define FRAME_TO_ZONE_FLAGS(ff) \ 84 84 ((((ff) & FRAME_LOWMEM) ? ZONE_LOWMEM : \ 85 (((ff) & FRAME_HIGHMEM) ? ZONE_HIGHMEM : ZONE_NONE)) | \ 86 (ZONE_AVAILABLE | ZONE_LOWMEM /* | ZONE_HIGHMEM */)) 85 (((ff) & FRAME_HIGHMEM) ? ZONE_HIGHMEM : \ 86 ZONE_LOWMEM /* | ZONE_HIGHMEM */)) | \ 87 ZONE_AVAILABLE) 87 88 88 89 #define ZONE_FLAGS_MATCH(zf, f) \ -
kernel/generic/include/mm/km.h
r321052f7 r3fe58d3c 37 37 38 38 #include <typedefs.h> 39 #include <mm/frame.h> 39 40 40 41 extern void km_identity_init(void); … … 48 49 extern bool km_is_non_identity(uintptr_t); 49 50 51 extern uintptr_t km_temporary_page_get(uintptr_t *, frame_flags_t); 52 extern void km_temporary_page_put(uintptr_t); 53 50 54 #endif 51 55 -
kernel/generic/src/mm/backend_anon.c
r321052f7 r3fe58d3c 44 44 #include <mm/frame.h> 45 45 #include <mm/slab.h> 46 #include <mm/km.h> 46 47 #include <synch/mutex.h> 47 48 #include <adt/list.h> … … 155 156 int anon_page_fault(as_area_t *area, uintptr_t addr, pf_access_t access) 156 157 { 158 uintptr_t upage = ALIGN_DOWN(addr, PAGE_SIZE); 159 uintptr_t kpage; 157 160 uintptr_t frame; 158 161 … … 175 178 mutex_lock(&area->sh_info->lock); 176 179 frame = (uintptr_t) btree_search(&area->sh_info->pagemap, 177 ALIGN_DOWN(addr, PAGE_SIZE)- area->base, &leaf);180 upage - area->base, &leaf); 178 181 if (!frame) { 179 182 bool allocate = true; … … 185 188 */ 186 189 for (i = 0; i < leaf->keys; i++) { 187 if (leaf->key[i] == 188 ALIGN_DOWN(addr, PAGE_SIZE) - area->base) { 190 if (leaf->key[i] == upage - area->base) { 189 191 allocate = false; 190 192 break; … … 192 194 } 193 195 if (allocate) { 194 frame = (uintptr_t) frame_alloc_noreserve( 195 ONE_FRAME, 0); 196 memsetb((void *) PA2KA(frame), FRAME_SIZE, 0); 196 kpage = km_temporary_page_get(&frame, 197 FRAME_NO_RESERVE); 198 memsetb((void *) kpage, PAGE_SIZE, 0); 199 km_temporary_page_put(kpage); 197 200 198 201 /* … … 201 204 */ 202 205 btree_insert(&area->sh_info->pagemap, 203 ALIGN_DOWN(addr, PAGE_SIZE) - area->base, 204 (void *) frame, leaf); 206 upage - area->base, (void *) frame, leaf); 205 207 } 206 208 } … … 223 225 * the different causes 224 226 */ 225 frame = (uintptr_t) frame_alloc_noreserve(ONE_FRAME, 0); 226 memsetb((void *) PA2KA(frame), FRAME_SIZE, 0); 227 kpage = km_temporary_page_get(&frame, FRAME_NO_RESERVE); 228 memsetb((void *) kpage, PAGE_SIZE, 0); 229 km_temporary_page_put(kpage); 227 230 } 228 231 229 232 /* 230 * Map ' page' to 'frame'.233 * Map 'upage' to 'frame'. 231 234 * Note that TLB shootdown is not attempted as only new information is 232 235 * being inserted into page tables. 233 236 */ 234 page_mapping_insert(AS, addr, frame, as_area_get_flags(area));235 if (!used_space_insert(area, ALIGN_DOWN(addr, PAGE_SIZE), 1))237 page_mapping_insert(AS, upage, frame, as_area_get_flags(area)); 238 if (!used_space_insert(area, upage, 1)) 236 239 panic("Cannot insert used space."); 237 240 -
kernel/generic/src/mm/backend_elf.c
r321052f7 r3fe58d3c 44 44 #include <mm/page.h> 45 45 #include <mm/reserve.h> 46 #include <mm/km.h> 46 47 #include <genarch/mm/page_pt.h> 47 48 #include <genarch/mm/page_ht.h> … … 229 230 elf_segment_header_t *entry = area->backend_data.segment; 230 231 btree_node_t *leaf; 231 uintptr_t base, frame, page, start_anon; 232 uintptr_t base; 233 uintptr_t frame; 234 uintptr_t kpage; 235 uintptr_t upage; 236 uintptr_t start_anon; 232 237 size_t i; 233 238 bool dirty = false; … … 249 254 (((void *) elf) + ALIGN_DOWN(entry->p_offset, PAGE_SIZE)); 250 255 251 /* Virtual address of faulting page */252 page = ALIGN_DOWN(addr, PAGE_SIZE);256 /* Virtual address of faulting page */ 257 upage = ALIGN_DOWN(addr, PAGE_SIZE); 253 258 254 259 /* Virtual address of the end of initialized part of segment */ … … 264 269 mutex_lock(&area->sh_info->lock); 265 270 frame = (uintptr_t) btree_search(&area->sh_info->pagemap, 266 page - area->base, &leaf);271 upage - area->base, &leaf); 267 272 if (!frame) { 268 273 unsigned int i; … … 273 278 274 279 for (i = 0; i < leaf->keys; i++) { 275 if (leaf->key[i] == page - area->base) {280 if (leaf->key[i] == upage - area->base) { 276 281 found = true; 277 282 break; … … 281 286 if (frame || found) { 282 287 frame_reference_add(ADDR2PFN(frame)); 283 page_mapping_insert(AS, addr, frame,288 page_mapping_insert(AS, upage, frame, 284 289 as_area_get_flags(area)); 285 if (!used_space_insert(area, page, 1))290 if (!used_space_insert(area, upage, 1)) 286 291 panic("Cannot insert used space."); 287 292 mutex_unlock(&area->sh_info->lock); … … 294 299 * mapping. 295 300 */ 296 if ( page >= entry->p_vaddr &&page + PAGE_SIZE <= start_anon) {301 if (upage >= entry->p_vaddr && upage + PAGE_SIZE <= start_anon) { 297 302 /* 298 303 * Initialized portion of the segment. The memory is backed … … 304 309 */ 305 310 if (entry->p_flags & PF_W) { 306 frame = (uintptr_t)frame_alloc_noreserve(ONE_FRAME, 0);307 memcpy((void *) PA2KA(frame),308 (void *) (base + i * FRAME_SIZE), FRAME_SIZE);311 kpage = km_temporary_page_get(&frame, FRAME_NO_RESERVE); 312 memcpy((void *) kpage, (void *) (base + i * PAGE_SIZE), 313 PAGE_SIZE); 309 314 if (entry->p_flags & PF_X) { 310 smc_coherence_block((void *) PA2KA(frame), 311 FRAME_SIZE); 315 smc_coherence_block((void *) kpage, PAGE_SIZE); 312 316 } 317 km_temporary_page_put(kpage); 313 318 dirty = true; 314 319 } else { 315 320 frame = KA2PA(base + i * FRAME_SIZE); 316 321 } 317 } else if ( page >= start_anon) {322 } else if (upage >= start_anon) { 318 323 /* 319 324 * This is the uninitialized portion of the segment. … … 322 327 * and cleared. 323 328 */ 324 frame = (uintptr_t) frame_alloc_noreserve(ONE_FRAME, 0); 325 memsetb((void *) PA2KA(frame), FRAME_SIZE, 0); 329 kpage = km_temporary_page_get(&frame, FRAME_NO_RESERVE); 330 memsetb((void *) kpage, PAGE_SIZE, 0); 331 km_temporary_page_put(kpage); 326 332 dirty = true; 327 333 } else { … … 334 340 * (The segment can be and often is shorter than 1 page). 335 341 */ 336 if ( page < entry->p_vaddr)337 pad_lo = entry->p_vaddr - page;342 if (upage < entry->p_vaddr) 343 pad_lo = entry->p_vaddr - upage; 338 344 else 339 345 pad_lo = 0; 340 346 341 if (start_anon < page + PAGE_SIZE)342 pad_hi = page + PAGE_SIZE - start_anon;347 if (start_anon < upage + PAGE_SIZE) 348 pad_hi = upage + PAGE_SIZE - start_anon; 343 349 else 344 350 pad_hi = 0; 345 351 346 frame = (uintptr_t) frame_alloc_noreserve(ONE_FRAME, 0);347 memcpy((void *) ( PA2KA(frame)+ pad_lo),348 (void *) (base + i * FRAME_SIZE + pad_lo),349 FRAME_SIZE - pad_lo - pad_hi);352 kpage = km_temporary_page_get(&frame, FRAME_NO_RESERVE); 353 memcpy((void *) (kpage + pad_lo), 354 (void *) (base + i * PAGE_SIZE + pad_lo), 355 PAGE_SIZE - pad_lo - pad_hi); 350 356 if (entry->p_flags & PF_X) { 351 smc_coherence_block((void *) ( PA2KA(frame)+ pad_lo),352 FRAME_SIZE - pad_lo - pad_hi);357 smc_coherence_block((void *) (kpage + pad_lo), 358 PAGE_SIZE - pad_lo - pad_hi); 353 359 } 354 memsetb((void *) PA2KA(frame), pad_lo, 0);355 memsetb((void *) ( PA2KA(frame) + FRAME_SIZE - pad_hi), pad_hi,356 0);360 memsetb((void *) kpage, pad_lo, 0); 361 memsetb((void *) (kpage + PAGE_SIZE - pad_hi), pad_hi, 0); 362 km_temporary_page_put(kpage); 357 363 dirty = true; 358 364 } … … 360 366 if (dirty && area->sh_info) { 361 367 frame_reference_add(ADDR2PFN(frame)); 362 btree_insert(&area->sh_info->pagemap, page - area->base,368 btree_insert(&area->sh_info->pagemap, upage - area->base, 363 369 (void *) frame, leaf); 364 370 } … … 367 373 mutex_unlock(&area->sh_info->lock); 368 374 369 page_mapping_insert(AS, addr, frame, as_area_get_flags(area));370 if (!used_space_insert(area, page, 1))375 page_mapping_insert(AS, upage, frame, as_area_get_flags(area)); 376 if (!used_space_insert(area, upage, 1)) 371 377 panic("Cannot insert used space."); 372 378 -
kernel/generic/src/mm/km.c
r321052f7 r3fe58d3c 39 39 #include <arch/mm/km.h> 40 40 #include <mm/page.h> 41 #include <mm/frame.h> 42 #include <mm/asid.h> 41 43 #include <config.h> 42 44 #include <typedefs.h> 43 45 #include <lib/ra.h> 44 46 #include <debug.h> 47 #include <arch.h> 45 48 46 49 static ra_arena_t *km_ni_arena; 50 51 #define DEFERRED_PAGES_MAX (PAGE_SIZE / sizeof(uintptr_t)) 52 53 /** Number of freed pages in the deferred buffer. */ 54 static volatile unsigned deferred_pages; 55 /** Buffer of deferred freed pages. */ 56 static uintptr_t deferred_page[DEFERRED_PAGES_MAX]; 57 58 /** Flush the buffer of deferred freed pages. 59 * 60 * @return Number of freed pages. 61 */ 62 static unsigned km_flush_deferred(void) 63 { 64 unsigned i = 0; 65 ipl_t ipl; 66 67 ipl = tlb_shootdown_start(TLB_INVL_ASID, ASID_KERNEL, 0, 0); 68 69 for (i = 0; i < deferred_pages; i++) { 70 page_mapping_remove(AS_KERNEL, deferred_page[i]); 71 km_page_free(deferred_page[i], PAGE_SIZE); 72 } 73 74 tlb_invalidate_asid(ASID_KERNEL); 75 76 as_invalidate_translation_cache(AS_KERNEL, 0, -1); 77 tlb_shootdown_finalize(ipl); 78 79 return i; 80 } 47 81 48 82 /** Architecture dependent setup of identity-mapped kernel memory. */ … … 87 121 } 88 122 123 /** Unmap kernen non-identity page. 124 * 125 * @param[in] page Non-identity page to be unmapped. 126 */ 127 static void km_unmap_deferred(uintptr_t page) 128 { 129 page_table_lock(AS_KERNEL, true); 130 131 if (deferred_pages == DEFERRED_PAGES_MAX) { 132 (void) km_flush_deferred(); 133 deferred_pages = 0; 134 } 135 136 deferred_page[deferred_pages++] = page; 137 138 page_table_unlock(AS_KERNEL, true); 139 } 140 141 /** Create a temporary page. 142 * 143 * The page is mapped read/write to a newly allocated frame of physical memory. 144 * The page must be returned back to the system by a call to 145 * km_temporary_page_put(). 146 * 147 * @param[inout] framep Pointer to a variable which will receive the physical 148 * address of the allocated frame. 149 * @param[in] flags Frame allocation flags. FRAME_NONE or FRAME_NO_RESERVE. 150 * @return Virtual address of the allocated frame. 151 */ 152 uintptr_t km_temporary_page_get(uintptr_t *framep, frame_flags_t flags) 153 { 154 uintptr_t frame; 155 uintptr_t page; 156 157 ASSERT(THREAD); 158 ASSERT(framep); 159 ASSERT(!(flags & ~FRAME_NO_RESERVE)); 160 161 /* 162 * Allocate a frame, preferably from high memory. 163 */ 164 frame = (uintptr_t) frame_alloc(ONE_FRAME, 165 FRAME_HIGHMEM | FRAME_ATOMIC | flags); 166 if (frame) { 167 page = km_page_alloc(PAGE_SIZE, PAGE_SIZE); 168 ASSERT(page); // FIXME 169 page_table_lock(AS_KERNEL, true); 170 page_mapping_insert(AS_KERNEL, page, frame, 171 PAGE_CACHEABLE | PAGE_READ | PAGE_WRITE); 172 page_table_unlock(AS_KERNEL, true); 173 } else { 174 frame = (uintptr_t) frame_alloc_noreserve(ONE_FRAME, 175 FRAME_LOWMEM); 176 page = PA2KA(frame); 177 } 178 179 *framep = frame; 180 return page; 181 } 182 183 /** Destroy a temporary page. 184 * 185 * This function destroys a temporary page previously created by 186 * km_temporary_page_get(). The page destruction may be immediate or deferred. 187 * The frame mapped by the destroyed page is not freed. 188 * 189 * @param[in] page Temporary page to be destroyed. 190 */ 191 void km_temporary_page_put(uintptr_t page) 192 { 193 ASSERT(THREAD); 194 195 if (km_is_non_identity(page)) 196 km_unmap_deferred(page); 197 } 89 198 90 199 /** @} -
kernel/generic/src/mm/page.c
r321052f7 r3fe58d3c 202 202 asize = ALIGN_UP(size, PAGE_SIZE); 203 203 align = ispwr2(size) ? size : (1U << (fnzb(size) + 1)); 204 virtaddr = km_page_alloc(asize, align);204 virtaddr = km_page_alloc(asize, max(PAGE_SIZE, align)); 205 205 206 206 page_table_lock(AS_KERNEL, true);
Note:
See TracChangeset
for help on using the changeset viewer.