Changeset d3e7ff4 in mainline for generic/src/mm/as.c
- Timestamp:
- 2006-03-14T14:10:25Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 5581c45e
- Parents:
- 5be1923
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
generic/src/mm/as.c
r5be1923 rd3e7ff4 70 70 71 71 static int get_area_flags(as_area_t *a); 72 static as_area_t *find_area_and_lock(as_t *as, __address va); 72 73 73 74 /** Initialize address space subsystem. */ … … 169 170 void as_set_mapping(as_t *as, __address page, __address frame) 170 171 { 171 as_area_t *a, *area = NULL; 172 link_t *cur; 172 as_area_t *area; 173 173 ipl_t ipl; 174 174 … … 176 176 spinlock_lock(&as->lock); 177 177 178 /* 179 * First, try locate an area. 180 */ 181 for (cur = as->as_area_head.next; cur != &as->as_area_head; cur = cur->next) { 182 a = list_get_instance(cur, as_area_t, link); 183 spinlock_lock(&a->lock); 184 185 if ((page >= a->base) && (page < a->base + a->size * PAGE_SIZE)) { 186 area = a; 187 break; 188 } 189 190 spinlock_unlock(&a->lock); 191 } 192 178 area = find_area_and_lock(as, page); 193 179 if (!area) { 194 180 panic("page not part of any as_area\n"); 195 181 } 196 182 197 /*198 * Note: area->lock is held.199 */200 201 183 page_mapping_insert(as, page, frame, get_area_flags(area)); 202 184 … … 217 199 int as_page_fault(__address page) 218 200 { 219 link_t *cur; 220 as_area_t *a, *area = NULL; 201 as_area_t *area; 221 202 __address frame; 222 203 … … 224 205 spinlock_lock(&AS->lock); 225 206 226 /* 227 * Search this areas of this address space for presence of 'page'. 228 */ 229 for (cur = AS->as_area_head.next; cur != &AS->as_area_head; cur = cur->next) { 230 a = list_get_instance(cur, as_area_t, link); 231 spinlock_lock(&a->lock); 232 233 if ((page >= a->base) && (page < a->base + a->size * PAGE_SIZE)) { 234 235 /* 236 * We found the area containing 'page'. 237 * TODO: access checking 238 */ 239 area = a; 240 break; 241 } 242 243 spinlock_unlock(&a->lock); 244 } 245 207 area = find_area_and_lock(AS, page); 246 208 if (!area) { 247 209 /* … … 253 215 } 254 216 255 /*256 * Note: area->lock is held.257 */258 259 217 /* 260 218 * In general, there can be several reasons that … … 400 358 return as_operations->page_table_create(flags); 401 359 } 360 361 /** Find address space area and change it. 362 * 363 * @param as Address space. 364 * @param address Virtual address belonging to the area to be changed. Must be page-aligned. 365 * @param size New size of the virtual memory block starting at address. 366 * @param flags Flags influencing the remap operation. Currently unused. 367 * 368 * @return address on success, (__address) -1 otherwise. 369 */ 370 __address as_remap(as_t *as, __address address, size_t size, int flags) 371 { 372 as_area_t *area = NULL; 373 ipl_t ipl; 374 size_t pages; 375 376 ipl = interrupts_disable(); 377 spinlock_lock(&as->lock); 378 379 /* 380 * Locate the area. 381 */ 382 area = find_area_and_lock(as, address); 383 if (!area) { 384 spinlock_unlock(&as->lock); 385 return (__address) -1; 386 } 387 388 pages = SIZE2FRAMES((address - area->base) + size); 389 if (pages < area->size) { 390 int i; 391 392 /* 393 * Shrinking the area. 394 */ 395 for (i = pages; i < area->size; i++) { 396 pte_t *pte; 397 398 /* 399 * Releasing physical memory. 400 * This depends on the fact that the memory was allocated using frame_alloc(). 401 */ 402 pte = page_mapping_find(as, area->base + i*PAGE_SIZE); 403 if (pte) { 404 ASSERT(PTE_PRESENT(pte)); 405 frame_free(ADDR2PFN(PTE_GET_FRAME(pte))); 406 } 407 page_mapping_remove(as, area->base + i*PAGE_SIZE); 408 } 409 /* 410 * Invalidate TLB's. 411 */ 412 tlb_shootdown_start(TLB_INVL_PAGES, AS->asid, area->base + pages*PAGE_SIZE, area->size - pages); 413 tlb_invalidate_pages(AS->asid, area->base + pages*PAGE_SIZE, area->size - pages); 414 tlb_shootdown_finalize(); 415 } else { 416 /* 417 * Growing the area. 418 */ 419 area->size = size; 420 } 421 422 spinlock_unlock(&area->lock); 423 spinlock_unlock(&as->lock); 424 interrupts_restore(ipl); 425 426 return address; 427 } 428 429 /** Find address space area and lock it. 430 * 431 * The address space must be locked and interrupts must be disabled. 432 * 433 * @param as Address space. 434 * @param va Virtual address. 435 * 436 * @return Locked address space area containing va on success or NULL on failure. 437 */ 438 as_area_t *find_area_and_lock(as_t *as, __address va) 439 { 440 link_t *cur; 441 as_area_t *a; 442 443 for (cur = as->as_area_head.next; cur != &as->as_area_head; cur = cur->next) { 444 a = list_get_instance(cur, as_area_t, link); 445 spinlock_lock(&a->lock); 446 447 if ((va >= a->base) && (va < a->base + a->size * PAGE_SIZE)) 448 return a; 449 450 spinlock_unlock(&a->lock); 451 } 452 453 return NULL; 454 }
Note:
See TracChangeset
for help on using the changeset viewer.