Changeset 37e7d2b9 in mainline
- Timestamp:
- 2006-03-16T14:46:06Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- dabe6333
- Parents:
- e898a8d7
- Location:
- generic
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
generic/include/mm/as.h
re898a8d7 r37e7d2b9 63 63 link_t link; 64 64 int flags; 65 size_t size; /**< Size of this area in multiples of PAGE_SIZE. */65 count_t pages; /**< Size of this area in multiples of PAGE_SIZE. */ 66 66 __address base; /**< Base address of this area. */ 67 67 }; -
generic/src/lib/elf.c
re898a8d7 r37e7d2b9 194 194 segment = ((void *) elf) + entry->p_offset; 195 195 196 a = as_area_create(as, flags, SIZE2FRAMES(entry->p_memsz), entry->p_vaddr);196 a = as_area_create(as, flags, entry->p_memsz, entry->p_vaddr); 197 197 if (!a) 198 198 return EE_IRRECOVERABLE; -
generic/src/mm/as.c
re898a8d7 r37e7d2b9 71 71 static int get_area_flags(as_area_t *a); 72 72 static as_area_t *find_area_and_lock(as_t *as, __address va); 73 static bool check_area_conflicts(as_t *as, __address va, size_t size, as_area_t *avoid_area); 73 74 74 75 /** Initialize address space subsystem. */ … … 121 122 * @param as Target address space. 122 123 * @param flags Flags of the area. 123 * @param size Size of area in multiples of PAGE_SIZE.124 * @param size Size of area. 124 125 * @param base Base address of area. 125 126 * … … 132 133 133 134 if (base % PAGE_SIZE) 134 panic("addr not aligned to a page boundary"); 135 return NULL; 136 137 /* Writeable executable areas are not supported. */ 138 if ((flags & AS_AREA_EXEC) && (flags & AS_AREA_WRITE)) 139 return NULL; 135 140 136 141 ipl = interrupts_disable(); 137 142 spinlock_lock(&as->lock); 138 143 139 /* 140 * TODO: test as_area which is to be created doesn't overlap with an existing one. 141 */ 144 if (!check_area_conflicts(as, base, size, NULL)) { 145 spinlock_unlock(&as->lock); 146 interrupts_restore(ipl); 147 return NULL; 148 } 142 149 143 150 a = (as_area_t *) malloc(sizeof(as_area_t), 0); … … 147 154 link_initialize(&a->link); 148 155 a->flags = flags; 149 a-> size = size;156 a->pages = SIZE2FRAMES(size); 150 157 a->base = base; 151 158 … … 432 439 if (!area) { 433 440 spinlock_unlock(&as->lock); 441 interrupts_restore(ipl); 434 442 return (__address) -1; 435 443 } 436 444 437 445 pages = SIZE2FRAMES((address - area->base) + size); 438 if (pages < area->size) { 446 if (!check_area_conflicts(as, address, pages * PAGE_SIZE, area)) { 447 spinlock_unlock(&as->lock); 448 interrupts_restore(ipl); 449 return (__address) -1; 450 } 451 452 if (pages < area->pages) { 439 453 int i; 440 454 … … 442 456 * Shrinking the area. 443 457 */ 444 for (i = pages; i < area-> size; i++) {458 for (i = pages; i < area->pages; i++) { 445 459 pte_t *pte; 446 460 … … 467 481 * Invalidate TLB's. 468 482 */ 469 tlb_shootdown_start(TLB_INVL_PAGES, AS->asid, area->base + pages*PAGE_SIZE, area-> size- pages);470 tlb_invalidate_pages(AS->asid, area->base + pages*PAGE_SIZE, area-> size- pages);483 tlb_shootdown_start(TLB_INVL_PAGES, AS->asid, area->base + pages*PAGE_SIZE, area->pages - pages); 484 tlb_invalidate_pages(AS->asid, area->base + pages*PAGE_SIZE, area->pages - pages); 471 485 tlb_shootdown_finalize(); 472 486 } 473 487 474 area-> size= pages;488 area->pages = pages; 475 489 476 490 spinlock_unlock(&area->lock); … … 499 513 spinlock_lock(&a->lock); 500 514 501 if ((va >= a->base) && (va < a->base + a-> size* PAGE_SIZE))502 515 if ((va >= a->base) && (va < a->base + a->pages * PAGE_SIZE)) 516 return a; 503 517 504 518 spinlock_unlock(&a->lock); … … 507 521 return NULL; 508 522 } 523 524 /** Check area conflicts with other areas. 525 * 526 * The address space must be locked and interrupts must be disabled. 527 * 528 * @param as Address space. 529 * @param va Starting virtual address of the area being tested. 530 * @param size Size of the area being tested. 531 * @param avoid_area Do not touch this area. 532 * 533 * @return True if there is no conflict, false otherwise. 534 */ 535 bool check_area_conflicts(as_t *as, __address va, size_t size, as_area_t *avoid_area) 536 { 537 link_t *cur; 538 as_area_t *a; 539 540 for (cur = as->as_area_head.next; cur != &as->as_area_head; cur = cur->next) { 541 __address start; 542 __address end; 543 544 a = list_get_instance(cur, as_area_t, link); 545 if (a == avoid_area) 546 continue; 547 548 spinlock_lock(&a->lock); 549 550 start = a->base; 551 end = a->base + a->pages * PAGE_SIZE - 1; 552 553 spinlock_unlock(&a->lock); 554 555 if ((va >= start) && (va <= end)) { 556 /* 557 * Tested area is inside another area. 558 */ 559 return false; 560 } 561 562 if ((start >= va) && (start < va + size)) { 563 /* 564 * Another area starts in tested area. 565 */ 566 return false; 567 } 568 569 if ((end >= va) && (end < va + size)) { 570 /* 571 * Another area ends in tested area. 572 */ 573 return false; 574 } 575 576 } 577 578 return true; 579 } -
generic/src/proc/task.c
re898a8d7 r37e7d2b9 126 126 * Create the data as_area. 127 127 */ 128 a = as_area_create(as, AS_AREA_READ | AS_AREA_WRITE, 1, USTACK_ADDRESS);128 a = as_area_create(as, AS_AREA_READ | AS_AREA_WRITE, PAGE_SIZE, USTACK_ADDRESS); 129 129 130 130 thread_ready(t);
Note:
See TracChangeset
for help on using the changeset viewer.