2016-03-18 22:53:25 +01:00
|
|
|
/*
|
|
|
|
* \brief IPC utility functions
|
|
|
|
* \author Norman Feske
|
|
|
|
* \date 2016-03-08
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2017-02-20 13:23:52 +01:00
|
|
|
* Copyright (C) 2016-2017 Genode Labs GmbH
|
2016-03-18 22:53:25 +01:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
2017-02-20 13:23:52 +01:00
|
|
|
* under the terms of the GNU Affero General Public License version 3.
|
2016-03-18 22:53:25 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _INCLUDE__BASE__INTERNAL__IPC_H_
|
|
|
|
#define _INCLUDE__BASE__INTERNAL__IPC_H_
|
|
|
|
|
|
|
|
/* NOVA includes */
|
|
|
|
#include <nova/syscalls.h>
|
|
|
|
#include <nova/native_thread.h>
|
2016-06-15 15:04:54 +02:00
|
|
|
#include <nova/capability_space.h>
|
2016-03-18 22:53:25 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Copy message registers from UTCB to destination message buffer
|
|
|
|
*
|
|
|
|
* \return protocol word delivered via the first UTCB message register
|
|
|
|
*
|
|
|
|
* The caller of this function must ensure that utcb.msg_words is greater
|
|
|
|
* than 0.
|
|
|
|
*/
|
|
|
|
static inline Nova::mword_t copy_utcb_to_msgbuf(Nova::Utcb &utcb,
|
|
|
|
Genode::Receive_window &rcv_window,
|
|
|
|
Genode::Msgbuf_base &rcv_msg)
|
|
|
|
{
|
|
|
|
using namespace Genode;
|
|
|
|
using namespace Nova;
|
|
|
|
|
|
|
|
size_t num_msg_words = utcb.msg_words();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Handle the reception of a malformed message. This should never happen
|
|
|
|
* because the utcb.msg_words is checked by the caller of this function.
|
|
|
|
*/
|
|
|
|
if (num_msg_words < 1)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* the UTCB contains the protocol word followed by the message data */
|
2017-04-12 11:55:08 +02:00
|
|
|
mword_t const protocol_word = utcb.msg()[0];
|
2016-03-18 22:53:25 +01:00
|
|
|
size_t num_data_words = num_msg_words - 1;
|
|
|
|
|
|
|
|
if (num_data_words*sizeof(mword_t) > rcv_msg.capacity()) {
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
error("receive message buffer too small msg "
|
|
|
|
"size=", num_data_words*sizeof(mword_t), " "
|
|
|
|
"buf size=", rcv_msg.capacity());
|
2016-03-18 22:53:25 +01:00
|
|
|
num_data_words = rcv_msg.capacity()/sizeof(mword_t);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* read message payload into destination message buffer */
|
2017-04-12 11:55:08 +02:00
|
|
|
mword_t *src = (mword_t *)(void *)(&utcb.msg()[1]);
|
2016-03-18 22:53:25 +01:00
|
|
|
mword_t *dst = (mword_t *)rcv_msg.data();
|
|
|
|
for (unsigned i = 0; i < num_data_words; i++)
|
|
|
|
*dst++ = *src++;
|
|
|
|
|
|
|
|
/* extract caps from UTCB */
|
|
|
|
for (unsigned i = 0; i < rcv_window.num_received_caps(); i++) {
|
|
|
|
Native_capability cap;
|
|
|
|
rcv_window.rcv_pt_sel(cap);
|
|
|
|
rcv_msg.insert(cap);
|
|
|
|
}
|
|
|
|
|
|
|
|
return protocol_word;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Copy message payload to UTCB message registers
|
|
|
|
*/
|
|
|
|
static inline bool copy_msgbuf_to_utcb(Nova::Utcb &utcb,
|
|
|
|
Genode::Msgbuf_base const &snd_msg,
|
|
|
|
Nova::mword_t protocol_value)
|
|
|
|
{
|
|
|
|
using namespace Genode;
|
|
|
|
using namespace Nova;
|
|
|
|
|
|
|
|
/* look up address and size of message payload */
|
|
|
|
mword_t *msg_buf = (mword_t *)snd_msg.data();
|
|
|
|
|
|
|
|
/* size of message payload in machine words */
|
|
|
|
size_t const num_data_words = snd_msg.data_size()/sizeof(mword_t);
|
|
|
|
|
|
|
|
/* account for protocol value in front of the message */
|
|
|
|
size_t num_msg_words = 1 + num_data_words;
|
|
|
|
|
|
|
|
enum { NUM_MSG_REGS = 256 };
|
|
|
|
if (num_msg_words > NUM_MSG_REGS) {
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
error("message does not fit into UTCB message registers");
|
2016-03-18 22:53:25 +01:00
|
|
|
num_msg_words = NUM_MSG_REGS;
|
|
|
|
}
|
|
|
|
|
2017-04-12 11:55:08 +02:00
|
|
|
utcb.msg()[0] = protocol_value;
|
2016-03-18 22:53:25 +01:00
|
|
|
|
|
|
|
/* store message into UTCB message registers */
|
|
|
|
mword_t *src = (mword_t *)&msg_buf[0];
|
2017-04-12 11:55:08 +02:00
|
|
|
mword_t *dst = (mword_t *)(void *)&utcb.msg()[1];
|
2016-03-18 22:53:25 +01:00
|
|
|
for (unsigned i = 0; i < num_data_words; i++)
|
|
|
|
*dst++ = *src++;
|
|
|
|
|
|
|
|
utcb.set_msg_word(num_msg_words);
|
|
|
|
|
|
|
|
/* append portal capability selectors */
|
|
|
|
for (unsigned i = 0; i < snd_msg.used_caps(); i++) {
|
|
|
|
|
|
|
|
Native_capability const &cap = snd_msg.cap(i);
|
2016-06-15 15:04:54 +02:00
|
|
|
Nova::Crd const crd = Capability_space::crd(cap);
|
2016-03-18 22:53:25 +01:00
|
|
|
|
|
|
|
if (crd.base() == ~0UL) continue;
|
|
|
|
|
|
|
|
if (!utcb.append_item(crd, i, false, false, true))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endif /* _INCLUDE__BASE__INTERNAL__IPC_H_ */
|