16#include <l4/sys/ipc.h>
19#include <l4/sys/cxx/ipc_varg>
20#include <l4/cxx/type_traits>
21#include <l4/cxx/minmax>
57 Buf_cp_out(T
const *v,
unsigned long size) : _v(v), _s(size) {}
66 unsigned long size()
const {
return _s; }
75 T
const *buf()
const {
return _v; }
100Internal::Buf_cp_out<T>
buf_cp_out(T
const *v,
unsigned long size)
101{
return Internal::Buf_cp_out<T>(v, size); }
100Internal::Buf_cp_out<T>
buf_cp_out(T
const *v,
unsigned long size) {
…}
117template<
typename T >
129 Buf_cp_in(T *v,
unsigned long &size) : _v(v), _s(&size) {}
131 unsigned long &size()
const {
return *_s; }
132 T *buf()
const {
return _v; }
135 friend class Istream;
158template<
typename T >
159Internal::Buf_cp_in<T>
buf_cp_in(T *v,
unsigned long &size)
160{
return Internal::Buf_cp_in<T>(v, size); }
159Internal::Buf_cp_in<T>
buf_cp_in(T *v,
unsigned long &size) {
…}
177template<
typename T >
189 Str_cp_in(T *v,
unsigned long &size) : _v(v), _s(&size) {}
191 unsigned long &size()
const {
return *_s; }
192 T *buf()
const {
return _v; }
195 friend class Istream;
212template<
typename T >
228template<
typename T >
241 void set(T *p)
const { *_p = p; }
251template<
typename T >
270template<
typename T >
280 Buf_in(T *&v,
unsigned long &size) : _v(&v), _s(&size) {}
282 void set_size(
unsigned long s)
const { *_s = s; }
283 T *&buf()
const {
return *_v; }
286 friend class Istream;
309template<
typename T >
310Internal::Buf_in<T>
buf_in(T *&v,
unsigned long &size)
311{
return Internal::Buf_in<T>(v, size); }
310Internal::Buf_in<T>
buf_in(T *&v,
unsigned long &size) {
…}
313namespace Utcb_stream_check
315 static bool check_utcb_data_offset(
unsigned sz)
316 {
return sz >
sizeof(
l4_umword_t) * L4_UTCB_GENERIC_DATA_SIZE; }
349 : _tag(), _utcb(
utcb),
350 _current_msg(reinterpret_cast<char*>(l4_utcb_mr_u(
utcb)->mr)),
351 _pos(0), _current_buf(0)
362 _current_msg =
reinterpret_cast<char*
>(l4_utcb_mr_u(_utcb)->
mr);
368 template<
typename T >
371 auto const max_bytes = L4_UTCB_GENERIC_DATA_SIZE *
sizeof(
l4_umword_t);
372 unsigned apos = cxx::Type_traits<T>::align(_pos);
373 return (count <= max_bytes /
sizeof(T))
374 && (apos + (
sizeof(T) * count)
393 template<
typename T >
394 unsigned long get(T *buf,
unsigned long elems)
399 unsigned long size = elems *
sizeof(T);
400 _pos = cxx::Type_traits<T>::align(_pos);
402 __builtin_memcpy(buf, _current_msg + _pos, size);
394 unsigned long get(T *buf,
unsigned long elems) {
…}
413 template<
typename T >
419 unsigned long size = elems *
sizeof(T);
420 _pos = cxx::Type_traits<T>::align(_pos);
438 template<
typename T >
444 unsigned long size = elems *
sizeof(T);
445 _pos = cxx::Type_traits<T>::align(_pos);
447 buf.set(
reinterpret_cast<T*
>(_current_msg + _pos));
463 template<
typename T >
472 _pos = cxx::Type_traits<T>::align(_pos);
473 v = *(
reinterpret_cast<T*
>(_current_msg + _pos));
482 if (!has_more<Ipc::Varg::Tag>())
588 unsigned char _current_buf;
591class Istream_copy :
public Istream
597 Istream_copy(Istream
const &o) : Istream(o), _mrs(*l4_utcb_mr_u(o.
utcb()))
602 -
reinterpret_cast<l4_addr_t>(l4_utcb_mr_u(
nullptr)));
603 _current_msg =
reinterpret_cast<char*
>(l4_utcb_mr_u(_utcb)->
mr);
630 : _tag(), _utcb(
utcb),
631 _current_msg(reinterpret_cast<char *>(l4_utcb_mr_u(_utcb)->mr)),
632 _pos(0), _current_item(0)
642 _current_msg =
reinterpret_cast<char*
>(l4_utcb_mr_u(_utcb)->
mr);
659 template<
typename T >
660 bool put(T *buf,
unsigned long size)
663 _pos = cxx::Type_traits<T>::align(_pos);
664 if (Utcb_stream_check::check_utcb_data_offset(_pos + size))
667 __builtin_memcpy(_current_msg + _pos, buf, size);
660 bool put(T *buf,
unsigned long size) {
…}
677 template<
typename T >
680 _pos = cxx::Type_traits<T>::align(_pos);
681 if (Utcb_stream_check::check_utcb_data_offset(_pos +
sizeof(T)))
684 *(
reinterpret_cast<T*
>(_current_msg + _pos)) = v;
697 template<
typename T >
698 int put(Varg_t<T>
const &va)
699 {
return put(
static_cast<Varg
const &
>(va)); }
721 inline bool put_snd_item(
Snd_fpage const &);
750 unsigned long tell()
const
753 _tag =
l4_msgtag(0, w, _current_item, 0);
757 l4_msgtag_t prepare_ipc(
long proto = 0,
unsigned flags = 0)
760 return l4_msgtag(proto, w, _current_item, flags);
774 unsigned char _current_item;
910Ostream::put_snd_item(Snd_fpage
const &v)
913 _pos = cxx::Type_traits<Snd_fpage>::align(_pos);
914 if (Utcb_stream_check::check_utcb_data_offset(_pos +
sizeof(T)))
917 *(
reinterpret_cast<T*
>(_current_msg + _pos)) = v;
925Istream::put(Rcv_fpage
const &item)
927 unsigned words = item.forward_mappings() ? 3 : 2;
928 if (_current_buf >= L4_UTCB_GENERIC_BUFFERS_SIZE - words - 1)
931 l4_utcb_br_u(_utcb)->
bdr &= ~L4_BDR_OFFSET_MASK;
934 =
reinterpret_cast<l4_umword_t *
>(&l4_utcb_br_u(_utcb)->
br[_current_buf]);
935 *buf++ = item.base_x();
936 *buf++ = item.data();
937 if (item.forward_mappings())
938 *buf++ = item.rcv_task();
939 _current_buf += words;
945Istream::put(Small_buf
const &item)
947 if (_current_buf >= L4_UTCB_GENERIC_BUFFERS_SIZE - 2)
950 l4_utcb_br_u(_utcb)->
bdr &= ~L4_BDR_OFFSET_MASK;
952 reinterpret_cast<Small_buf&
>(l4_utcb_br_u(_utcb)->
br[_current_buf]) = item;
969 tag =
l4_ipc_call(dst, Ostream::_utcb, tag, timeout);
1066{ s.
get(&v);
return s; }
1101template<
typename T >
1104 L4::Ipc::Internal::Buf_in<T>
const &v)
1128template<
typename T >
1149template<
typename T >
1152 L4::Ipc::Internal::Buf_cp_in<T>
const &v)
1156 v.size() = s.
get(v.buf(), cxx::min(v.size(), sz));
1170template<
typename T >
1177 unsigned long rsz = s.
get(v.buf(), cxx::min(v.size(), sz));
1178 if (rsz < v.size() && v.buf()[rsz - 1])
1182 v.buf()[rsz - 1] = 0;
1210template<
typename T >
1215{ s.
put(v);
return s; }
1216template<
typename T >
1218{ s.
put(v);
return s; }
1246template<
typename T >
1249 L4::Ipc::Internal::Buf_cp_out<T>
const &v)
1252 s.
put(v.buf(), v.size());
1271 unsigned long l = __builtin_strlen(v) + 1;
1277namespace L4 {
namespace Ipc {
1287template<
typename T >
L4::Cap related definitions.
l4_fpage_t fpage(unsigned rights=L4_CAP_FPAGE_RWS) const noexcept
Return flexpage 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.
Send item or return 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)
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.