base-hw: use Genode::memcpy in base/ipc.cc

Ref #583
This commit is contained in:
Martin Stein
2012-12-19 15:49:44 +01:00
committed by Norman Feske
parent e6ca122fe3
commit 19398159e1
2 changed files with 28 additions and 63 deletions

View File

@ -86,25 +86,17 @@ namespace Genode
struct Native_utcb struct Native_utcb
{ {
/* UTCB payload */ /* UTCB payload */
union { char payload[1<<MIN_MAPPING_SIZE_LOG2];
char bytes[1<<MIN_MAPPING_SIZE_LOG2];
umword_t words[sizeof(bytes)/sizeof(umword_t)];
};
/**
* Get pointer to a specific word within the UTCB
*/
umword_t * word(unsigned const index) { return &words[index]; }
/** /**
* Get the base of the UTCB * Get the base of the UTCB
*/ */
void * base() { return (void *)bytes; } void * base() { return payload; }
/** /**
* Get the UTCB size * Get the UTCB size
*/ */
size_t size() { return sizeof(bytes); } size_t size() { return sizeof(payload); }
}; };
struct Cap_dst_policy struct Cap_dst_policy

View File

@ -38,65 +38,40 @@ enum
***************/ ***************/
/** /**
* Translate byte size 's' to size in words * Limit message size to the size of UTCB and message buffer
*/ */
static size_t size_in_words(size_t const s) { void limit_msg_size(Msgbuf_base * const msgbuf, Native_utcb * const utcb,
return (s + sizeof(size_t) - 1) / sizeof(size_t); } size_t & size)
{
if (size > utcb->size() || size > msgbuf->size()) {
kernel_log() << __PRETTY_FUNCTION__ << ": truncate message\n";
size = utcb->size() < msgbuf->size() ? utcb->size() : msgbuf->size();
}
}
/** /**
* Copy message payload to message buffer * Copy message payload to message buffer
*/ */
static void copy_utcb_to_msgbuf(Msgbuf_base * const receive_buffer, static void utcb_to_msgbuf(Msgbuf_base * const msgbuf, size_t size)
size_t const message_size)
{ {
/* log data that is received via IPC */
enum { VERBOSE = 0 };
/* get pointers and message attributes */
Native_utcb * const utcb = Thread_base::myself()->utcb(); Native_utcb * const utcb = Thread_base::myself()->utcb();
unsigned * const msgbuf = (unsigned *)receive_buffer->buf; limit_msg_size(msgbuf, utcb, size);
size_t const message_wsize = size_in_words(message_size); memcpy(msgbuf->buf, utcb->base(), size);
/* assertions, avoid 'printf' in here, it may lead to infinite recursion */
if (message_wsize > size_in_words(utcb->size()))
{
kernel_log() << __PRETTY_FUNCTION__ << ": Oversized message\n";
while (1) ;
}
/* fill message buffer with message */
for (unsigned i=0; i < message_wsize; i++)
msgbuf[i] = *utcb->word(i);
} }
/** /**
* Copy message payload to the UTCB * Copy message payload to the UTCB
*/ */
static void copy_msgbuf_to_utcb(Msgbuf_base * const send_buffer, static void msgbuf_to_utcb(Msgbuf_base * const msgbuf, size_t size,
size_t const message_size,
unsigned const local_name) unsigned const local_name)
{ {
/* log data that is send via IPC */
enum { VERBOSE = 0 };
/* get pointers and message attributes */
Native_utcb * const utcb = Thread_base::myself()->utcb(); Native_utcb * const utcb = Thread_base::myself()->utcb();
unsigned * const msgbuf = (unsigned *)send_buffer->buf; *(unsigned *)utcb->base() = local_name;
size_t const message_wsize = size_in_words(message_size); size += sizeof(local_name);
limit_msg_size(msgbuf, utcb, size);
/* assertions, avoid 'printf' in here, it may lead to infinite recursion */ memcpy((unsigned *)utcb->base() + 1, (unsigned *)msgbuf->buf + 1, size);
if (message_wsize > size_in_words(utcb->size()))
{
kernel_log() << __PRETTY_FUNCTION__ << ": Oversized message\n";
while (1) ;
}
/* address message to an object that the targeted thread knows */
*utcb->word(0) = local_name;
/* write message payload */
for (unsigned i = 1; i < message_wsize; i++)
*utcb->word(i) = msgbuf[i];
} }
@ -144,10 +119,9 @@ void Ipc_client::_call()
using namespace Kernel; using namespace Kernel;
/* send request and receive reply */ /* send request and receive reply */
copy_msgbuf_to_utcb(_snd_msg, _write_offset, msgbuf_to_utcb(_snd_msg, _write_offset, Ipc_ostream::_dst.local_name());
Ipc_ostream::_dst.local_name());
size_t const s = request_and_wait(Ipc_ostream::_dst.dst(), _write_offset); size_t const s = request_and_wait(Ipc_ostream::_dst.dst(), _write_offset);
copy_utcb_to_msgbuf(_rcv_msg, s); utcb_to_msgbuf(_rcv_msg, s);
/* reset unmarshaller */ /* reset unmarshaller */
_write_offset = _read_offset = RPC_OBJECT_ID_SIZE; _write_offset = _read_offset = RPC_OBJECT_ID_SIZE;
@ -187,7 +161,7 @@ void Ipc_server::_prepare_next_reply_wait()
void Ipc_server::_wait() void Ipc_server::_wait()
{ {
/* receive next request */ /* receive next request */
copy_utcb_to_msgbuf(_rcv_msg, Kernel::wait_for_request()); utcb_to_msgbuf(_rcv_msg, Kernel::wait_for_request());
/* update server state */ /* update server state */
_prepare_next_reply_wait(); _prepare_next_reply_wait();
@ -206,9 +180,8 @@ void Ipc_server::_reply_wait()
return; return;
} }
/* send reply and receive next request */ /* send reply and receive next request */
copy_msgbuf_to_utcb(_snd_msg, _write_offset, msgbuf_to_utcb(_snd_msg, _write_offset, Ipc_ostream::_dst.local_name());
Ipc_ostream::_dst.local_name()); utcb_to_msgbuf(_rcv_msg, Kernel::reply(_write_offset, 1));
copy_utcb_to_msgbuf(_rcv_msg, Kernel::reply(_write_offset, 1));
/* update server state */ /* update server state */
_prepare_next_reply_wait(); _prepare_next_reply_wait();