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
{
/* UTCB payload */
union {
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]; }
char payload[1<<MIN_MAPPING_SIZE_LOG2];
/**
* Get the base of the UTCB
*/
void * base() { return (void *)bytes; }
void * base() { return payload; }
/**
* Get the UTCB size
*/
size_t size() { return sizeof(bytes); }
size_t size() { return sizeof(payload); }
};
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) {
return (s + sizeof(size_t) - 1) / sizeof(size_t); }
void limit_msg_size(Msgbuf_base * const msgbuf, Native_utcb * const utcb,
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
*/
static void copy_utcb_to_msgbuf(Msgbuf_base * const receive_buffer,
size_t const message_size)
static void utcb_to_msgbuf(Msgbuf_base * const msgbuf, size_t size)
{
/* log data that is received via IPC */
enum { VERBOSE = 0 };
/* get pointers and message attributes */
Native_utcb * const utcb = Thread_base::myself()->utcb();
unsigned * const msgbuf = (unsigned *)receive_buffer->buf;
size_t const message_wsize = size_in_words(message_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);
Native_utcb * const utcb = Thread_base::myself()->utcb();
limit_msg_size(msgbuf, utcb, size);
memcpy(msgbuf->buf, utcb->base(), size);
}
/**
* Copy message payload to the UTCB
*/
static void copy_msgbuf_to_utcb(Msgbuf_base * const send_buffer,
size_t const message_size,
unsigned const local_name)
static void msgbuf_to_utcb(Msgbuf_base * const msgbuf, size_t size,
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();
unsigned * const msgbuf = (unsigned *)send_buffer->buf;
size_t const message_wsize = size_in_words(message_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) ;
}
/* 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];
Native_utcb * const utcb = Thread_base::myself()->utcb();
*(unsigned *)utcb->base() = local_name;
size += sizeof(local_name);
limit_msg_size(msgbuf, utcb, size);
memcpy((unsigned *)utcb->base() + 1, (unsigned *)msgbuf->buf + 1, size);
}
@ -144,10 +119,9 @@ void Ipc_client::_call()
using namespace Kernel;
/* send request and receive reply */
copy_msgbuf_to_utcb(_snd_msg, _write_offset,
Ipc_ostream::_dst.local_name());
msgbuf_to_utcb(_snd_msg, _write_offset, Ipc_ostream::_dst.local_name());
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 */
_write_offset = _read_offset = RPC_OBJECT_ID_SIZE;
@ -187,7 +161,7 @@ void Ipc_server::_prepare_next_reply_wait()
void Ipc_server::_wait()
{
/* 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 */
_prepare_next_reply_wait();
@ -206,9 +180,8 @@ void Ipc_server::_reply_wait()
return;
}
/* send reply and receive next request */
copy_msgbuf_to_utcb(_snd_msg, _write_offset,
Ipc_ostream::_dst.local_name());
copy_utcb_to_msgbuf(_rcv_msg, Kernel::reply(_write_offset, 1));
msgbuf_to_utcb(_snd_msg, _write_offset, Ipc_ostream::_dst.local_name());
utcb_to_msgbuf(_rcv_msg, Kernel::reply(_write_offset, 1));
/* update server state */
_prepare_next_reply_wait();