Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 1305 → Rev 1306

//kernel/trunk/generic/include/mm/as.h
122,7 → 122,8
extern void as_init(void);
extern as_t *as_create(int flags);
extern as_area_t *as_area_create(as_t *as, int flags, size_t size, __address base, int attrs);
extern __address as_area_resize(as_t *as, __address address, size_t size, int flags);
extern int as_area_resize(as_t *as, __address address, size_t size, int flags);
extern int as_area_destroy(as_t *as, __address address);
int as_area_send(task_id_t dst_id, __address base);
extern void as_set_mapping(as_t *as, __address page, __address frame);
extern int as_page_fault(__address page, istate_t *istate);
137,6 → 138,7
/* Address space area related syscalls. */
extern __native sys_as_area_create(__address address, size_t size, int flags);
extern __native sys_as_area_resize(__address address, size_t size, int flags);
extern __native sys_as_area_destroy(__address address);
extern __native sys_as_area_accept(as_area_acptsnd_arg_t *uspace_accept_arg);
extern __native sys_as_area_send(as_area_acptsnd_arg_t *uspace_send_arg);
 
//kernel/trunk/generic/include/syscall/syscall.h
39,6 → 39,7
SYS_FUTEX_WAKEUP,
SYS_AS_AREA_CREATE,
SYS_AS_AREA_RESIZE,
SYS_AS_AREA_DESTROY,
SYS_AS_AREA_ACCEPT,
SYS_AS_AREA_SEND,
SYS_IPC_CALL_SYNC_FAST,
//kernel/trunk/generic/include/errno.h
31,16 → 31,18
 
/* 1-255 are kernel error codes, 256-512 are user error codes */
 
#define ENOENT -1 /* No such entry */
#define ENOMEM -2 /* Not enough memory */
#define ELIMIT -3 /* Limit exceeded */
#define EREFUSED -4 /* Connection refused */
#define EFORWARD -5 /* Forward error */
#define EPERM -6 /* Permission denied */
#define EHANGUP -7 /* Answerbox closed connection, call sys_ipc_hangup
* to close the connection. Used by answerbox
* to close the connection. */
#define EEXISTS -8 /* Entry already exists */
#define EBADMEM -9 /* Bad memory pointer */
#define ENOENT -1 /* No such entry */
#define ENOMEM -2 /* Not enough memory */
#define ELIMIT -3 /* Limit exceeded */
#define EREFUSED -4 /* Connection refused */
#define EFORWARD -5 /* Forward error */
#define EPERM -6 /* Permission denied */
#define EHANGUP -7 /* Answerbox closed connection, call sys_ipc_hangup
* to close the connection. Used by answerbox
* to close the connection. */
#define EEXISTS -8 /* Entry already exists */
#define EBADMEM -9 /* Bad memory pointer */
#define ENOTSUP -10 /* Not supported */
#define EADDRNOTAVAIL -11 /* Address not available. */
 
#endif
//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.
//kernel/trunk/generic/src/syscall/syscall.c
84,6 → 84,7
/* Address space related syscalls. */
sys_as_area_create,
sys_as_area_resize,
sys_as_area_destroy,
sys_as_area_accept,
sys_as_area_send,