mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-09 04:15:52 +00:00
parent
e6ca122fe3
commit
19398159e1
@ -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
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user