Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2676 → Rev 2677

/trunk/kernel/generic/include/ipc/ipc.h
159,7 → 159,7
* on answer, the recipient must set:
* - ARG1 - dst as_area base adress
*/
#define IPC_M_AS_AREA_SEND 4
#define IPC_M_SHARE_OUT 4
 
/** Receive as_area over IPC.
* - ARG1 - destination as_area base address
171,7 → 171,7
* - ARG1 - source as_area base address
* - ARG2 - flags that will be used for sharing
*/
#define IPC_M_AS_AREA_RECV 5
#define IPC_M_SHARE_IN 5
 
/** Send data to another address space over IPC.
* - ARG1 - source address space virtual address
/trunk/kernel/generic/src/ipc/sysipc.c
112,8 → 112,8
static inline int method_is_immutable(unative_t method)
{
switch (method) {
case IPC_M_AS_AREA_SEND:
case IPC_M_AS_AREA_RECV:
case IPC_M_SHARE_OUT:
case IPC_M_SHARE_IN:
case IPC_M_DATA_WRITE:
case IPC_M_DATA_READ:
return 1;
141,8 → 141,8
switch (IPC_GET_METHOD(call->data)) {
case IPC_M_CONNECT_TO_ME:
case IPC_M_CONNECT_ME_TO:
case IPC_M_AS_AREA_SEND:
case IPC_M_AS_AREA_RECV:
case IPC_M_SHARE_OUT:
case IPC_M_SHARE_IN:
case IPC_M_DATA_WRITE:
case IPC_M_DATA_READ:
return 1;
199,7 → 199,7
ipc_phone_connect((phone_t *) IPC_GET_ARG5(*olddata),
&TASK->answerbox);
}
} else if (IPC_GET_METHOD(*olddata) == IPC_M_AS_AREA_SEND) {
} else if (IPC_GET_METHOD(*olddata) == IPC_M_SHARE_OUT) {
if (!IPC_GET_RETVAL(answer->data)) {
/* Accepted, handle as_area receipt */
ipl_t ipl;
218,7 → 218,7
IPC_SET_RETVAL(answer->data, rc);
return rc;
}
} else if (IPC_GET_METHOD(*olddata) == IPC_M_AS_AREA_RECV) {
} else if (IPC_GET_METHOD(*olddata) == IPC_M_SHARE_IN) {
if (!IPC_GET_RETVAL(answer->data)) {
ipl_t ipl;
as_t *as;
313,7 → 313,7
call->flags |= IPC_CALL_CONN_ME_TO;
call->priv = newphid;
break;
case IPC_M_AS_AREA_SEND:
case IPC_M_SHARE_OUT:
size = as_area_get_size(IPC_GET_ARG1(call->data));
if (!size)
return EPERM;
/trunk/uspace/app/klog/klog.c
63,8 → 63,8
printf("Kernel console output.\n");
mapping = as_get_mappable_page(PAGE_SIZE);
res = ipc_call_sync_3_0(PHONE_NS, IPC_M_AS_AREA_RECV,
(sysarg_t) mapping, PAGE_SIZE, SERVICE_MEM_KLOG);
res = ipc_share_in_send_1_0(PHONE_NS, mapping, PAGE_SIZE,
SERVICE_MEM_KLOG);
if (res) {
printf("Failed to initialize klog memarea\n");
_exit(1);
/trunk/uspace/lib/libfs/libfs.c
94,8 → 94,7
/*
* Request sharing the Path Lookup Buffer with VFS.
*/
rc = ipc_call_sync_2_0(vfs_phone, IPC_M_AS_AREA_RECV,
(ipcarg_t) reg->plb_ro, PLB_SIZE);
rc = ipc_share_in_send_0_0(vfs_phone, reg->plb_ro, PLB_SIZE);
if (rc) {
async_wait_for(req, NULL);
return rc;
/trunk/uspace/lib/libc/include/ipc/ipc.h
262,6 → 262,25
ipcarg_t arg1, ipcarg_t arg2, int mode);
 
 
/*
* User-friendly wrappers for ipc_share_in_send().
*/
#define ipc_share_in_send_0_0(phoneid, dst, size) \
ipc_share_in_send((phoneid), (dst), (size), 0, NULL)
#define ipc_share_in_send_0_1(phoneid, dst, size, flags) \
ipc_share_in_send((phoneid), (dst), (size), 0, (flags))
#define ipc_share_in_send_1_0(phoneid, dst, size, arg) \
ipc_share_in_send((phoneid), (dst), (size), (arg), NULL)
#define ipc_share_in_send_1_1(phoneid, dst, size, arg, flags) \
ipc_share_in_send((phoneid), (dst), (size), (arg), (flags))
 
extern int ipc_share_in_send(int phoneid, void *dst, size_t size, ipcarg_t arg,
int *flags);
extern int ipc_share_in_receive(ipc_callid_t *callid, size_t *size);
extern int ipc_share_in_deliver(ipc_callid_t callid, void *src, int flags);
extern int ipc_share_out_send(int phoneid, void *src, int flags);
extern int ipc_share_out_receive(ipc_callid_t *callid, size_t *size, int *flags);
extern int ipc_share_out_deliver(ipc_callid_t callid, void *dst);
extern int ipc_data_read_send(int phoneid, void *dst, size_t size);
extern int ipc_data_read_receive(ipc_callid_t *callid, size_t *size);
extern int ipc_data_read_deliver(ipc_callid_t callid, void *src, size_t size);
/trunk/uspace/lib/libc/generic/time.c
135,15 → 135,14
{
void *mapping;
sysarg_t s1, s2;
sysarg_t rights;
int rights;
int res;
 
if (!ktime) {
mapping = as_get_mappable_page(PAGE_SIZE);
/* Get the mapping of kernel clock */
res = ipc_call_sync_3_2(PHONE_NS, IPC_M_AS_AREA_RECV,
(sysarg_t) mapping, PAGE_SIZE, SERVICE_MEM_REALTIME, NULL,
&rights);
res = ipc_share_in_send_1_1(PHONE_NS, mapping, PAGE_SIZE,
SERVICE_MEM_REALTIME, &rights);
if (res) {
printf("Failed to initialize timeofday memarea\n");
_exit(1);
/trunk/uspace/lib/libc/generic/ipc.c
666,6 → 666,133
arg2, mode);
}
 
/** Wrapper for making IPC_M_SHARE_IN calls.
*
* @param phoneid Phone that will be used to contact the receiving side.
* @param dst Destination address space area base.
* @param size Size of the destination address space area.
* @param arg User defined argument.
* @param flags Storage where the received flags will be stored. Can be
* NULL.
*
* @return Zero on success or a negative error code from errno.h.
*/
int ipc_share_in_send(int phoneid, void *dst, size_t size, ipcarg_t arg,
int *flags)
{
int res;
sysarg_t tmp_flags;
res = ipc_call_sync_3_2(phoneid, IPC_M_SHARE_IN, (ipcarg_t) dst,
(ipcarg_t) size, arg, NULL, &tmp_flags);
if (flags)
*flags = tmp_flags;
return res;
}
 
/** Wrapper for receiving the IPC_M_SHARE_IN calls.
*
* This wrapper only makes it more comfortable to receive IPC_M_SHARE_IN calls
* so that the user doesn't have to remember the meaning of each IPC argument.
*
* So far, this wrapper is to be used from within a connection fibril.
*
* @param callid Storage where the hash of the IPC_M_SHARE_IN call will
* be stored.
* @param size Destination address space area size.
*
* @return Non-zero on success, zero on failure.
*/
int ipc_share_in_receive(ipc_callid_t *callid, size_t *size)
{
ipc_call_t data;
assert(callid);
assert(size);
 
*callid = async_get_call(&data);
if (IPC_GET_METHOD(data) != IPC_M_SHARE_IN)
return 0;
*size = (size_t) IPC_GET_ARG2(data);
return 1;
}
 
/** Wrapper for answering the IPC_M_SHARE_IN calls.
*
* This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls
* so that the user doesn't have to remember the meaning of each IPC argument.
*
* @param callid Hash of the IPC_M_DATA_READ call to answer.
* @param src Source address space base.
* @param flags Flags to be used for sharing. Bits can be only cleared.
*
* @return Zero on success or a value from @ref errno.h on failure.
*/
int ipc_share_in_deliver(ipc_callid_t callid, void *src, int flags)
{
return ipc_answer_2(callid, EOK, (ipcarg_t) src, (ipcarg_t) flags);
}
 
/** Wrapper for making IPC_M_SHARE_OUT calls.
*
* @param phoneid Phone that will be used to contact the receiving side.
* @param src Source address space area base address.
* @param flags Flags to be used for sharing. Bits can be only cleared.
*
* @return Zero on success or a negative error code from errno.h.
*/
int ipc_share_out_send(int phoneid, void *src, int flags)
{
return ipc_call_sync_3_0(phoneid, IPC_M_SHARE_OUT, (ipcarg_t) src, 0,
(ipcarg_t) flags);
}
 
/** Wrapper for receiving the IPC_M_SHARE_OUT calls.
*
* This wrapper only makes it more comfortable to receive IPC_M_SHARE_OUT calls
* so that the user doesn't have to remember the meaning of each IPC argument.
*
* So far, this wrapper is to be used from within a connection fibril.
*
* @param callid Storage where the hash of the IPC_M_SHARE_OUT call will
* be stored.
* @param size Storage where the source address space area size will be
* stored.
* @param flags Storage where the sharing flags will be stored.
*
* @return Non-zero on success, zero on failure.
*/
int ipc_share_out_receive(ipc_callid_t *callid, size_t *size, int *flags)
{
ipc_call_t data;
assert(callid);
assert(size);
assert(flags);
 
*callid = async_get_call(&data);
if (IPC_GET_METHOD(data) != IPC_M_DATA_WRITE)
return 0;
*size = (size_t) IPC_GET_ARG2(data);
*flags = (int) IPC_GET_ARG3(data);
return 1;
}
 
/** Wrapper for answering the IPC_M_SHARE_OUT calls.
*
* This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT calls
* so that the user doesn't have to remember the meaning of each IPC argument.
*
* @param callid Hash of the IPC_M_DATA_WRITE call to answer.
* @param dst Destination address space area base address.
*
* @return Zero on success or a value from @ref errno.h on failure.
*/
int ipc_share_out_deliver(ipc_callid_t callid, void *dst)
{
return ipc_answer_1(callid, EOK, (ipcarg_t) dst);
}
 
 
/** Wrapper for making IPC_M_DATA_READ calls.
*
* @param phoneid Phone that will be used to contact the receiving side.
/trunk/uspace/srv/ns/ns.c
117,7 → 117,7
while (1) {
callid = ipc_wait_for_call(&call);
switch (IPC_GET_METHOD(call)) {
case IPC_M_AS_AREA_RECV:
case IPC_M_SHARE_IN:
switch (IPC_GET_ARG3(call)) {
case SERVICE_MEM_REALTIME:
get_as_area(callid, &call, "clock.faddr",
/trunk/uspace/srv/console/console.c
537,8 → 537,8
sizeof(keyfield_t) * fb_info.cols * fb_info.rows,
PROTO_READ | PROTO_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
if (!interbuffer) {
if (async_req_3_0(fb_info.phone, IPC_M_AS_AREA_SEND,
(ipcarg_t) interbuffer, 0, AS_AREA_READ) != 0) {
if (ipc_share_out_send(fb_info.phone, interbuffer,
AS_AREA_READ) != EOK) {
munmap(interbuffer,
sizeof(keyfield_t) * fb_info.cols * fb_info.rows);
interbuffer = NULL;
/trunk/uspace/srv/console/gcons.c
325,8 → 325,7
rc = async_req_1_0(fbphone, FB_PREPARE_SHM, (ipcarg_t) shm);
if (rc)
goto exit;
rc = async_req_3_0(fbphone, IPC_M_AS_AREA_SEND, (ipcarg_t) shm, 0,
PROTO_READ);
rc = ipc_share_out_send(fbphone, shm, PROTO_READ);
if (rc)
goto drop;
/* Draw logo */
387,8 → 386,7
rc = async_req_1_0(fbphone, FB_PREPARE_SHM, (ipcarg_t) shm);
if (rc)
goto exit;
rc = async_req_3_0(fbphone, IPC_M_AS_AREA_SEND, (ipcarg_t) shm, 0,
PROTO_READ);
rc = ipc_share_out_send(fbphone, shm, PROTO_READ);
if (rc)
goto drop;
 
/trunk/uspace/srv/rd/rd.c
103,14 → 103,14
/*
* Now we wait for the client to send us its communication as_area.
*/
callid = async_get_call(&call);
if (IPC_GET_METHOD(call) == IPC_M_AS_AREA_SEND) {
if (IPC_GET_ARG1(call) >= (ipcarg_t) BLOCK_SIZE) {
size_t size;
if (ipc_share_out_receive(&callid, &size, NULL)) {
if (size >= BLOCK_SIZE) {
/*
* The client sends an as_area that can absorb the whole
* block.
*/
ipc_answer_1(callid, EOK, (uintptr_t) fs_va);
(void) ipc_share_out_deliver(callid, fs_va);
} else {
/*
* The client offered as_area too small.
/trunk/uspace/srv/fb/fb.c
747,7 → 747,7
unsigned int x, y;
 
switch (IPC_GET_METHOD(*call)) {
case IPC_M_AS_AREA_SEND:
case IPC_M_SHARE_OUT:
/* We accept one area for data interchange */
if (IPC_GET_ARG1(*call) == shm_id) {
void *dest = as_get_mappable_page(IPC_GET_ARG2(*call));
/trunk/uspace/srv/fb/ega.c
208,7 → 208,7
client_connected = 0;
ipc_answer_0(callid, EOK);
return; /* Exit thread */
case IPC_M_AS_AREA_SEND:
case IPC_M_SHARE_OUT:
/* We accept one area for data interchange */
intersize = IPC_GET_ARG2(call);
if (intersize >= scr_width * scr_height *
/trunk/uspace/srv/vfs/vfs_register.c
270,8 → 270,8
/*
* The client will want us to send him the address space area with PLB.
*/
callid = async_get_call(&call);
if (IPC_GET_METHOD(call) != IPC_M_AS_AREA_RECV) {
 
if (!ipc_share_in_receive(&callid, &size)) {
dprintf("Unexpected call, method = %d\n", IPC_GET_METHOD(call));
list_remove(&fs_info->fs_link);
futex_up(&fs_head_futex);
285,7 → 285,6
/*
* We can only send the client address space area PLB_SIZE bytes long.
*/
size = IPC_GET_ARG2(call);
if (size != PLB_SIZE) {
dprintf("Client suggests wrong size of PFB, size = %d\n", size);
list_remove(&fs_info->fs_link);
300,8 → 299,8
/*
* Commit to read-only sharing the PLB with the client.
*/
ipc_answer_2(callid, EOK, (ipcarg_t) plb,
(ipcarg_t) (AS_AREA_READ | AS_AREA_CACHEABLE));
(void) ipc_share_in_deliver(callid, plb,
AS_AREA_READ | AS_AREA_CACHEABLE);
 
dprintf("Sharing PLB.\n");