Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 1305 → Rev 1306

/kernel/trunk/generic/src/mm/as.c
194,11 → 194,11
* @param size New size of the virtual memory block starting at address.
* @param flags Flags influencing the remap operation. Currently unused.
*
* @return address on success, (__address) -1 otherwise.
* @return Zero on success or a value from @ref errno.h otherwise.
*/
__address as_area_resize(as_t *as, __address address, size_t size, int flags)
int as_area_resize(as_t *as, __address address, size_t size, int flags)
{
as_area_t *area = NULL;
as_area_t *area;
ipl_t ipl;
size_t pages;
212,7 → 212,7
if (!area) {
spinlock_unlock(&as->lock);
interrupts_restore(ipl);
return (__address) -1;
return ENOENT;
}
 
if (area->flags & AS_AREA_DEVICE) {
223,7 → 223,7
spinlock_unlock(&area->lock);
spinlock_unlock(&as->lock);
interrupts_restore(ipl);
return (__address) -1;
return ENOTSUP;
}
 
pages = SIZE2FRAMES((address - area->base) + size);
234,7 → 234,7
spinlock_unlock(&area->lock);
spinlock_unlock(&as->lock);
interrupts_restore(ipl);
return (__address) -1;
return EPERM;
}
if (pages < area->pages) {
281,7 → 281,7
spinlock_unlock(&area->lock);
spinlock_unlock(&as->lock);
interrupts_restore(ipl);
return (__address) -1;
return EADDRNOTAVAIL;
}
}
 
291,9 → 291,76
spinlock_unlock(&as->lock);
interrupts_restore(ipl);
 
return address;
return 0;
}
 
/** Destroy address space area.
*
* @param as Address space.
* @param address Address withing the area to be deleted.
*
* @return Zero on success or a value from @ref errno.h on failure.
*/
int as_area_destroy(as_t *as, __address address)
{
as_area_t *area;
__address base;
ipl_t ipl;
int i;
 
ipl = interrupts_disable();
spinlock_lock(&as->lock);
 
area = find_area_and_lock(as, address);
if (!area) {
spinlock_unlock(&as->lock);
interrupts_restore(ipl);
return ENOENT;
}
 
base = area->base;
for (i = 0; i < area->pages; i++) {
pte_t *pte;
 
/*
* Releasing physical memory.
* Areas mapping memory-mapped devices are treated differently than
* areas backing frame_alloc()'ed memory.
*/
page_table_lock(as, false);
pte = page_mapping_find(as, area->base + i*PAGE_SIZE);
if (pte && PTE_VALID(pte)) {
ASSERT(PTE_PRESENT(pte));
page_mapping_remove(as, area->base + i*PAGE_SIZE);
if (area->flags & AS_AREA_DEVICE) {
__address frame;
frame = PTE_GET_FRAME(pte);
frame_free(ADDR2PFN(frame));
}
page_table_unlock(as, false);
} else {
page_table_unlock(as, false);
}
}
/*
* Invalidate TLB's.
*/
tlb_shootdown_start(TLB_INVL_PAGES, AS->asid, area->base, area->pages);
tlb_invalidate_pages(AS->asid, area->base, area->pages);
tlb_shootdown_finalize();
 
spinlock_unlock(&area->lock);
 
/*
* Remove the empty area from address space.
*/
btree_remove(&AS->as_area_btree, base, NULL);
spinlock_unlock(&AS->lock);
interrupts_restore(ipl);
return 0;
}
 
/** Send address space area to another task.
*
* Address space area is sent to the specified task.
307,7 → 374,7
* @param dst_id Task ID of the accepting task.
* @param src_base Base address of the source address space area.
*
* @return 0 on success or ENOENT if there is no such task or
* @return Zero on success or ENOENT if there is no such task or
* if there is no such address space area,
* EPERM if there was a problem in accepting the area or
* ENOMEM if there was a problem in allocating destination
891,9 → 958,15
/** Wrapper for as_area_resize. */
__native sys_as_area_resize(__address address, size_t size, int flags)
{
return as_area_resize(AS, address, size, 0);
return (__native) as_area_resize(AS, address, size, 0);
}
 
/** Wrapper for as_area_destroy. */
__native sys_as_area_destroy(__address address)
{
return (__native) as_area_destroy(AS, address);
}
 
/** Prepare task for accepting address space area from another task.
*
* @param uspace_accept_arg Accept structure passed from userspace.