27#include <l4/sys/ipc.h>
30#include <l4/sys/cxx/ipc_varg>
31#include <l4/cxx/type_traits>
32#include <l4/cxx/minmax>
68 Buf_cp_out(T
const *v,
unsigned long size) : _v(v), _s(size) {}
77 unsigned long size()
const {
return _s; }
86 T
const *buf()
const {
return _v; }
110template<
typename T >
111Internal::Buf_cp_out<T>
buf_cp_out(T
const *v,
unsigned long size)
112{
return Internal::Buf_cp_out<T>(v, size); }
128template<
typename T >
140 Buf_cp_in(T *v,
unsigned long &size) : _v(v), _s(&size) {}
142 unsigned long &size()
const {
return *_s; }
143 T *buf()
const {
return _v; }
146 friend class Istream;
169template<
typename T >
170Internal::Buf_cp_in<T>
buf_cp_in(T *v,
unsigned long &size)
171{
return Internal::Buf_cp_in<T>(v, size); }
188template<
typename T >
200 Str_cp_in(T *v,
unsigned long &size) : _v(v), _s(&size) {}
202 unsigned long &size()
const {
return *_s; }
203 T *buf()
const {
return _v; }
206 friend class Istream;
223template<
typename T >
239template<
typename T >
252 void set(T *p)
const { *_p = p; }
262template<
typename T >
281template<
typename T >
291 Buf_in(T *&v,
unsigned long &size) : _v(&v), _s(&size) {}
293 void set_size(
unsigned long s)
const { *_s = s; }
294 T *&buf()
const {
return *_v; }
297 friend class Istream;
320template<
typename T >
321Internal::Buf_in<T>
buf_in(T *&v,
unsigned long &size)
322{
return Internal::Buf_in<T>(v, size); }
324namespace Utcb_stream_check
326 static bool check_utcb_data_offset(
unsigned sz)
327 {
return sz >
sizeof(
l4_umword_t) * L4_UTCB_GENERIC_DATA_SIZE; }
360 : _tag(), _utcb(
utcb),
361 _current_msg(reinterpret_cast<char*>(l4_utcb_mr_u(
utcb)->mr)),
362 _pos(0), _current_buf(0)
373 _current_msg =
reinterpret_cast<char*
>(l4_utcb_mr_u(_utcb)->
mr);
379 template<
typename T >
382 auto const max_bytes = L4_UTCB_GENERIC_DATA_SIZE *
sizeof(
l4_umword_t);
383 unsigned apos = cxx::Type_traits<T>::align(_pos);
384 return (count <= max_bytes /
sizeof(T))
385 && (apos + (
sizeof(T) * count)
404 template<
typename T >
405 unsigned long get(T *buf,
unsigned long elems)
410 unsigned long size = elems *
sizeof(T);
411 _pos = cxx::Type_traits<T>::align(_pos);
413 __builtin_memcpy(buf, _current_msg + _pos, size);
424 template<
typename T >
430 unsigned long size = elems *
sizeof(T);
431 _pos = cxx::Type_traits<T>::align(_pos);
449 template<
typename T >
455 unsigned long size = elems *
sizeof(T);
456 _pos = cxx::Type_traits<T>::align(_pos);
458 buf.set(
reinterpret_cast<T*
>(_current_msg + _pos));
474 template<
typename T >
483 _pos = cxx::Type_traits<T>::align(_pos);
484 v = *(
reinterpret_cast<T*
>(_current_msg + _pos));
493 if (!has_more<Ipc::Varg::Tag>())
599 unsigned char _current_buf;
602class Istream_copy :
public Istream
608 Istream_copy(Istream
const &o) : Istream(o), _mrs(*l4_utcb_mr_u(o.
utcb()))
613 -
reinterpret_cast<l4_addr_t>(l4_utcb_mr_u(
nullptr)));
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_fpage const &);
761 unsigned long tell()
const
764 _tag =
l4_msgtag(0, w, _current_item, 0);
768 l4_msgtag_t prepare_ipc(
long proto = 0,
unsigned flags = 0)
771 return l4_msgtag(proto, w, _current_item, flags);
785 unsigned char _current_item;
921Ostream::put_snd_item(Snd_fpage
const &v)
924 _pos = cxx::Type_traits<Snd_fpage>::align(_pos);
925 if (Utcb_stream_check::check_utcb_data_offset(_pos +
sizeof(T)))
928 *(
reinterpret_cast<T*
>(_current_msg + _pos)) = v;
936Istream::put(Rcv_fpage
const &item)
938 unsigned words = item.is_compound() ? 3 : 2;
939 if (_current_buf >= L4_UTCB_GENERIC_BUFFERS_SIZE - words - 1)
942 l4_utcb_br_u(_utcb)->
bdr &= ~L4_BDR_OFFSET_MASK;
945 =
reinterpret_cast<l4_umword_t *
>(&l4_utcb_br_u(_utcb)->
br[_current_buf]);
946 *buf++ = item.base_x();
947 *buf++ = item.data();
948 if (item.is_compound())
949 *buf++ = item.rcv_task();
950 _current_buf += words;
956Istream::put(Small_buf
const &item)
958 if (_current_buf >= L4_UTCB_GENERIC_BUFFERS_SIZE - 2)
961 l4_utcb_br_u(_utcb)->
bdr &= ~L4_BDR_OFFSET_MASK;
963 reinterpret_cast<Small_buf&
>(l4_utcb_br_u(_utcb)->
br[_current_buf]) = item;
980 tag =
l4_ipc_call(dst, Ostream::_utcb, tag, timeout);
1077{ s.
get(&v);
return s; }
1112template<
typename T >
1115 L4::Ipc::Internal::Buf_in<T>
const &v)
1139template<
typename T >
1160template<
typename T >
1163 L4::Ipc::Internal::Buf_cp_in<T>
const &v)
1167 v.size() = s.
get(v.buf(), cxx::min(v.size(), sz));
1181template<
typename T >
1188 unsigned long rsz = s.
get(v.buf(), cxx::min(v.size(), sz));
1189 if (rsz < v.size() && v.buf()[rsz - 1])
1193 v.buf()[rsz - 1] = 0;
1221template<
typename T >
1226{ s.
put(v);
return s; }
1227template<
typename T >
1229{ s.
put(v);
return s; }
1257template<
typename T >
1260 L4::Ipc::Internal::Buf_cp_out<T>
const &v)
1263 s.
put(v.buf(), v.size());
1282 unsigned long l = __builtin_strlen(v) + 1;
1288namespace L4 {
namespace Ipc {
1298template<
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.
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_utcb_t * utcb() const
Return utcb pointer.
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.
l4_msgtag_t & tag()
Get the message tag of a received IPC.
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.
bool has_more(unsigned long count=1)
Check whether a value of type T can be obtained from the stream.
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_utcb_t * utcb() const
Return utcb pointer.
l4_msgtag_t & tag()
Extract a reference to the L4 message tag from the stream.
void reset()
Reset the stream to empty, same state as a newly created stream.
A receive item for receiving a single object capability.
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)
unsigned long l4_umword_t
Unsigned machine word.
unsigned long l4_addr_t
Address type.
unsigned long l4_cap_idx_t
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.
unsigned l4_bytes_to_mwords(unsigned size) L4_NOTHROW
Determine how many machine words (l4_umword_t) are required to store a buffer of 'size' bytes.
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.
#define L4_IPC_SEND_TIMEOUT_0
0 send timeout
#define L4_IPC_NEVER
never timeout
struct l4_utcb_t l4_utcb_t
Opaque type for the UTCB.
#define L4_UNLIKELY(x)
Expression is unlikely to execute.
L4::Ipc::Istream & operator>>(L4::Ipc::Istream &s, bool &v)
Extract one element of type T from the stream s.
Str_cp_in< T > str_cp_in(T *v, unsigned long &size)
Create a Str_cp_in for the given values.
Internal::Buf_in< T > buf_in(T *&v, unsigned long &size)
Return a pointer to stream array data.
Internal::Buf_cp_out< T > buf_cp_out(T const *v, unsigned long size)
Insert an array into an Ipc::Ostream.
Internal::Buf_cp_in< T > buf_cp_in(T *v, unsigned long &size)
Extract an array from an Ipc::Istream.
Msg_ptr< T > msg_ptr(T *&p)
Create an Msg_ptr to adjust the given pointer.
T read(Istream &s)
Read a value out of a stream.
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.