27 #include <l4/sys/ipc.h>
30 #include <l4/sys/cxx/ipc_varg>
31 #include <l4/cxx/type_traits>
32 #include <l4/cxx/minmax>
34 #define L4_CXX_IPC_BACKWARD_COMPAT
60 template<
typename T >
70 Buf_cp_out(T
const *v,
unsigned long size) : _v(v), _s(size) {}
79 unsigned long size()
const {
return _s; }
88 T
const *buf()
const {
return _v; }
112 template<
typename T >
113 Internal::Buf_cp_out<T>
buf_cp_out(T
const *v,
unsigned long size)
114 {
return Internal::Buf_cp_out<T>(v, size); }
130 template<
typename T >
142 Buf_cp_in(T *v,
unsigned long &size) : _v(v), _s(&size) {}
144 unsigned long &size()
const {
return *_s; }
145 T *buf()
const {
return _v; }
148 friend class Istream;
171 template<
typename T >
172 Internal::Buf_cp_in<T>
buf_cp_in(T *v,
unsigned long &size)
173 {
return Internal::Buf_cp_in<T>(v, size); }
190 template<
typename T >
202 Str_cp_in(T *v,
unsigned long &size) : _v(v), _s(&size) {}
204 unsigned long &size()
const {
return *_s; }
205 T *buf()
const {
return _v; }
208 friend class Istream;
225 template<
typename T >
241 template<
typename T >
254 void set(T *p)
const { *_p = p; }
264 template<
typename T >
283 template<
typename T >
293 Buf_in(T *&v,
unsigned long &size) : _v(&v), _s(&size) {}
295 void set_size(
unsigned long s)
const { *_s = s; }
296 T *&buf()
const {
return *_v; }
299 friend class Istream;
322 template<
typename T >
323 Internal::Buf_in<T>
buf_in(T *&v,
unsigned long &size)
324 {
return Internal::Buf_in<T>(v, size); }
326 namespace Utcb_stream_check
328 static bool check_utcb_data_offset(
unsigned sz)
362 : _tag(), _utcb(
utcb),
363 _current_msg(reinterpret_cast<char*>(l4_utcb_mr_u(
utcb)->mr)),
364 _pos(0), _current_buf(0)
375 _current_msg =
reinterpret_cast<char*
>(l4_utcb_mr_u(_utcb)->
mr);
381 template<
typename T >
385 unsigned apos = cxx::Type_traits<T>::align(_pos);
386 return (count <= max_bytes /
sizeof(T))
387 && (apos + (
sizeof(T) * count)
406 template<
typename T >
407 unsigned long get(T *buf,
unsigned long elems)
412 unsigned long size = elems *
sizeof(T);
413 _pos = cxx::Type_traits<T>::align(_pos);
415 __builtin_memcpy(buf, _current_msg + _pos, size);
426 template<
typename T >
432 unsigned long size = elems *
sizeof(T);
433 _pos = cxx::Type_traits<T>::align(_pos);
451 template<
typename T >
457 unsigned long size = elems *
sizeof(T);
458 _pos = cxx::Type_traits<T>::align(_pos);
460 buf.set(
reinterpret_cast<T*
>(_current_msg + _pos));
476 template<
typename T >
485 _pos = cxx::Type_traits<T>::align(_pos);
486 v = *(
reinterpret_cast<T*
>(_current_msg + _pos));
495 if (!has_more<Ipc::Varg::Tag>())
562 {
return wait(src, L4_IPC_NEVER); }
586 {
return receive(src, L4_IPC_NEVER); }
601 unsigned char _current_buf;
604 class Istream_copy :
public Istream
610 Istream_copy(Istream
const &o) : Istream(o), _mrs(*l4_utcb_mr_u(o.utcb()))
614 _current_msg =
reinterpret_cast<char*
>(l4_utcb_mr_u(_utcb)->
mr);
641 : _tag(), _utcb(
utcb),
642 _current_msg(reinterpret_cast<char *>(l4_utcb_mr_u(_utcb)->mr)),
643 _pos(0), _current_item(0)
653 _current_msg =
reinterpret_cast<char*
>(l4_utcb_mr_u(_utcb)->
mr);
670 template<
typename T >
671 bool put(T *buf,
unsigned long size)
674 _pos = cxx::Type_traits<T>::align(_pos);
675 if (Utcb_stream_check::check_utcb_data_offset(_pos + size))
678 __builtin_memcpy(_current_msg + _pos, buf, size);
688 template<
typename T >
691 _pos = cxx::Type_traits<T>::align(_pos);
692 if (Utcb_stream_check::check_utcb_data_offset(_pos +
sizeof(T)))
695 *(
reinterpret_cast<T*
>(_current_msg + _pos)) = v;
708 template<
typename T >
709 int put(Varg_t<T>
const &va)
710 {
return put(
static_cast<Varg
const &
>(va)); }
732 inline bool put_snd_item(
Snd_item const &);
761 unsigned long tell()
const
764 w -= _current_item * 2;
765 _tag =
l4_msgtag(0, w, _current_item, 0);
769 l4_msgtag_t prepare_ipc(
long proto = 0,
unsigned flags = 0)
772 w -= _current_item * 2;
773 return l4_msgtag(proto, w, _current_item, flags);
787 unsigned char _current_item;
892 {
return send_and_wait(dest, src, L4_IPC_SEND_TIMEOUT_0, proto); }
916 {
return reply(L4_IPC_SEND_TIMEOUT_0, proto); }
923 Ostream::put_snd_item(Snd_item
const &v)
926 _pos = cxx::Type_traits<Snd_item>::align(_pos);
927 if (Utcb_stream_check::check_utcb_data_offset(_pos +
sizeof(T)))
930 *(
reinterpret_cast<T*
>(_current_msg + _pos)) = v;
938 Istream::put(Buf_item
const &item)
943 l4_utcb_br_u(_utcb)->
bdr &= ~L4_BDR_OFFSET_MASK;
945 reinterpret_cast<Buf_item&
>(l4_utcb_br_u(_utcb)->
br[_current_buf]) = item;
952 Istream::put(Small_buf
const &item)
957 l4_utcb_br_u(_utcb)->
bdr &= ~L4_BDR_OFFSET_MASK;
959 reinterpret_cast<Small_buf&
>(l4_utcb_br_u(_utcb)->
br[_current_buf]) = item;
976 tag =
l4_ipc_call(dst, Ostream::_utcb, tag, timeout);
984 {
return call(dst, L4_IPC_NEVER, label); }
1073 { s.
get(&v);
return s; }
1108 template<
typename T >
1111 L4::Ipc::Internal::Buf_in<T>
const &v)
1135 template<
typename T >
1156 template<
typename T >
1159 L4::Ipc::Internal::Buf_cp_in<T>
const &v)
1163 v.size() = s.
get(v.buf(),
cxx::min(v.size(), sz));
1177 template<
typename T >
1184 unsigned long rsz = s.
get(v.buf(),
cxx::min(v.size(), sz));
1185 if (rsz < v.size() && v.buf()[rsz - 1])
1189 v.buf()[rsz - 1] = 0;
1217 template<
typename T >
1222 { s.
put(v);
return s; }
1223 template<
typename T >
1225 { s.
put(v);
return s; }
1253 template<
typename T >
1256 L4::Ipc::Internal::Buf_cp_out<T>
const &v)
1259 s.
put(v.buf(), v.size());
1278 unsigned long l = __builtin_strlen(v) + 1;
1285 #ifdef L4_CXX_IPC_BACKWARD_COMPAT
1289 template<
typename T >
class Ipc_buf_cp_out :
public Ipc::Buf_cp_out<T> {};
1290 template<
typename T >
class Ipc_buf_cp_in :
public Ipc::Buf_cp_in<T> {};
1291 template<
typename T >
class Ipc_buf_in :
public Ipc::Buf_in<T> {};
1292 template<
typename T >
class Msg_ptr :
public Ipc::Msg_ptr<T> {};
1295 template<
typename T >
1296 Ipc::Internal::Buf_cp_out<T> ipc_buf_cp_out(T *v,
unsigned long size)
1299 template<
typename T >
1300 Ipc::Internal::Buf_cp_out<T> ipc_buf_cp_out(T *v,
unsigned long size)
1301 {
return Ipc::Internal::Buf_cp_out<T>(v, size); }
1304 template<
typename T >
1305 Ipc::Internal::Buf_cp_in<T> ipc_buf_cp_in(T *v,
unsigned long &size)
1308 template<
typename T >
1309 Ipc::Internal::Buf_cp_in<T> ipc_buf_cp_in(T *v,
unsigned long &size)
1310 {
return Ipc::Internal::Buf_cp_in<T>(v, size); }
1313 template<
typename T >
1314 Ipc::Internal::Buf_in<T> ipc_buf_in(T *&v,
unsigned long &size)
1317 template<
typename T >
1318 Ipc::Internal::Buf_in<T> ipc_buf_in(T *&v,
unsigned long &size)
1319 {
return Ipc::Internal::Buf_in<T>(v, size); }
1322 template<
typename T >
1323 Ipc::Msg_ptr<T>
msg_ptr(T *&p)
1326 template<
typename T >
1327 Ipc::Msg_ptr<T>
msg_ptr(T *&p)
1328 {
return Ipc::Msg_ptr<T>(p); }
1330 typedef Ipc::Istream Ipc_istream
L4_DEPRECATED(
"Use L4::Ipc::Istream now");
1331 typedef Ipc::Ostream Ipc_ostream
L4_DEPRECATED(
"Use L4::Ipc::Ostream now");;
1332 typedef Ipc::Iostream Ipc_iostream
L4_DEPRECATED(
"Use L4::Ipc::Iostream now");;
1335 typedef Ipc::Small_buf Small_buf
L4_DEPRECATED(
"Use L4::Ipc::Small_buf now");;
1339 template<
typename T >
class Buf_cp_in :
public Internal::Buf_cp_in<T>
1342 Buf_cp_in(T *v,
unsigned long &size) : Internal::Buf_cp_in<T>(v, size) {}
1345 template<
typename T >
1346 class Buf_cp_out :
public Internal::Buf_cp_out<T>
1349 Buf_cp_out(T
const *v,
unsigned long size) : Internal::Buf_cp_out<T>(v, size) {}
1352 template<
typename T >
1353 class Buf_in :
public Internal::Buf_in<T>
1356 Buf_in(T *&v,
unsigned long &size) : Internal::Buf_in<T>(v, size) {}
1361 template<
typename T >
1366 template<
typename T >
1369 {
return operator>>(s,
static_cast<L4::Ipc::Internal::Buf_cp_in<T>
>(v)); }
1371 template<
typename T >
1376 template<
typename T >
1379 {
return operator>>(s,
static_cast<L4::Ipc::Internal::Buf_in<T>
>(v)); }
1381 template<
typename T >
1386 template<
typename T >
1389 {
return operator<<(s,
static_cast<L4::Ipc::Internal::Buf_cp_out<T>
>(v)); }
1392 namespace L4 {
namespace Ipc {
1402 template<
typename T >
L4::Cap related definitions.
l4_fpage_t fpage(unsigned rights=L4_CAP_FPAGE_RWS) const noexcept
Return flex-page for the capability.
C++ interface for capabilities.
RPC warpper for a receive item.
Input/Output stream for IPC [un]marshalling.
void reset()
Reset the stream to its initial state.
l4_msgtag_t call(l4_cap_idx_t dst, l4_timeout_t timeout, long proto=0)
Do an IPC call using the message in the output stream and receive the reply in the input stream.
l4_msgtag_t reply_and_wait(l4_umword_t *src_dst, long proto=0)
Do an IPC reply and wait.
Iostream(l4_utcb_t *utcb)
Create an IPC IO stream with a single message buffer.
Input stream for IPC unmarshalling.
l4_msgtag_t receive(l4_cap_idx_t src)
Wait for a message from the specified sender.
void skip(unsigned long elems)
Skip size elements of type T in the stream.
void reset()
Reset the stream to empty, and ready for receive()/wait().
bool get(T &v)
Extract a single element of type T from the stream.
l4_msgtag_t tag() const
Get the message tag of a received IPC.
l4_msgtag_t & tag()
Get the message tag of a received IPC.
bool has_more(unsigned long count=1)
Check whether a value of type T can be obtained from the stream.
l4_utcb_t * utcb() const
Return utcb pointer.
Istream(l4_utcb_t *utcb)
Create an input stream for the given message buffer.
unsigned long get(Msg_ptr< T > const &buf, unsigned long elems=1)
Read one size elements of type T from the stream and return a pointer.
l4_msgtag_t wait(l4_umword_t *src)
Wait for an incoming message from any sender.
unsigned long get(T *buf, unsigned long elems)
Copy out an array of type T with size elements.
Pointer to an element of type T in an Ipc::Istream.
Msg_ptr(T *&p)
Create a Msg_ptr object that set pointer p to point into the message buffer.
Output stream for IPC marshalling.
Ostream(l4_utcb_t *utcb)
Create an IPC output stream using the given message buffer utcb.
l4_msgtag_t send(l4_cap_idx_t dst, long proto=0, unsigned flags=0)
Send the message via IPC to the given receiver.
bool put(T const &v)
Insert an element of type T into the stream.
bool put(T *buf, unsigned long size)
Put an array with size elements of type T into the stream.
l4_msgtag_t tag() const
Extract the L4 message tag from the stream.
l4_msgtag_t & tag()
Extract a reference to the L4 message tag from the stream.
l4_utcb_t * utcb() const
Return utcb pointer.
void reset()
Reset the stream to empty, same state as a newly created stream.
A receive item for receiving a single capability.
RPC wrapper for a send item.
Abstraction for extracting a zero-terminated string from an Ipc::Istream.
Str_cp_in(T *v, unsigned long &size)
Create a buffer for extracting an array from an Ipc::Istream.
Variably sized RPC argument.
l4_umword_t Tag
The data type for the tag.
unsigned length() const
Get the size of the RPC argument.
void data(char const *d)
Set Varg to indirect data value (usually in UTCB)
#define L4_UNLIKELY(x)
Expression is unlikely to execute.
#define L4_DEPRECATED(s)
Mark symbol deprecated.
T1 min(T1 a, T1 b)
Get the minimum of a and b.
unsigned long l4_umword_t
Unsigned machine word.
unsigned long l4_addr_t
Address type.
unsigned long l4_cap_idx_t
L4 Capability selector Type.
@ L4_INVALID_CAP
Invalid capability selector.
l4_msgtag_t l4_ipc_reply_and_wait(l4_utcb_t *utcb, l4_msgtag_t tag, l4_umword_t *label, l4_timeout_t timeout) L4_NOTHROW
Reply and wait operation (uses the reply capability).
l4_msgtag_t l4_ipc_receive(l4_cap_idx_t object, l4_utcb_t *utcb, l4_timeout_t timeout) L4_NOTHROW
Wait for a message from a specific source.
l4_msgtag_t l4_ipc_send_and_wait(l4_cap_idx_t dest, l4_utcb_t *utcb, l4_msgtag_t tag, l4_umword_t *label, l4_timeout_t timeout) L4_NOTHROW
Send a message and do an open wait.
l4_msgtag_t l4_ipc_send(l4_cap_idx_t dest, l4_utcb_t *utcb, l4_msgtag_t tag, l4_timeout_t timeout) L4_NOTHROW
Send a message to an object (do not wait for a reply).
l4_msgtag_t l4_ipc_call(l4_cap_idx_t object, l4_utcb_t *utcb, l4_msgtag_t tag, l4_timeout_t timeout) L4_NOTHROW
Object call (usual invocation).
l4_msgtag_t l4_ipc_wait(l4_utcb_t *utcb, l4_umword_t *label, l4_timeout_t timeout) L4_NOTHROW
Wait for an incoming message from any possible sender.
@ L4_SYSF_REPLY
Reply flag.
l4_msgtag_t l4_msgtag(long label, unsigned words, unsigned items, unsigned flags) L4_NOTHROW
Create a message tag from the specified values.
@ L4_MSGTAG_FLAGS
Mask for all flags.
@ L4_UTCB_GENERIC_DATA_SIZE
Total number of message register (MRs) available.
@ L4_UTCB_GENERIC_BUFFERS_SIZE
Total number of buffer registers (BRs) available.
struct l4_utcb_t l4_utcb_t
Opaque type for the UTCB.
L4::Ipc::Istream & operator>>(L4::Ipc::Istream &s, bool &v)
Extract one element of type T from the stream s.
L4::Ipc::Ostream & operator<<(L4::Ipc::Ostream &s, bool v)
Insert an element to type T into the stream s.
Str_cp_in< T > str_cp_in(T *v, unsigned long &size)
Create a Str_cp_in for the given values.
Msg_ptr< T > msg_ptr(T *&p)
Create an Msg_ptr to adjust the given pointer.
Internal::Buf_cp_out< T > buf_cp_out(T const *v, unsigned long size)
Insert an array into an Ipc::Ostream.
Gen_fpage< Snd_item > Snd_fpage
Send flex-page.
Gen_fpage< Buf_item > Rcv_fpage
Rcv flex-page.
T read(Istream &s)
Read a value out of a stream.
Internal::Buf_in< T > buf_in(T *&v, unsigned long &size)
Return a pointer to stream array data.
Internal::Buf_cp_in< T > buf_cp_in(T *v, unsigned long &size)
Extract an array from an Ipc::Istream.
L4 low-level kernel interface.
l4_umword_t br[L4_UTCB_GENERIC_BUFFERS_SIZE]
Buffer registers.
l4_umword_t bdr
Buffer descriptor.
Message tag data structure.
unsigned words() const L4_NOTHROW
Get the number of untyped words.
unsigned items() const L4_NOTHROW
Get the number of typed items.
Encapsulation of the message-register block in the UTCB.
l4_umword_t mr[L4_UTCB_GENERIC_DATA_SIZE]
Message registers.