28 #include <l4/sys/ipc.h> 31 #include <l4/sys/cxx/ipc_varg> 32 #include <l4/cxx/type_traits> 33 #include <l4/cxx/minmax> 35 #define L4_CXX_IPC_BACKWARD_COMPAT 61 template<
typename T >
71 Buf_cp_out(T
const *v,
unsigned long size) : _v(v), _s(size) {}
80 unsigned long size()
const {
return _s; }
89 T
const *buf()
const {
return _v; }
113 template<
typename T >
114 Internal::Buf_cp_out<T>
buf_cp_out(T
const *v,
unsigned long size)
115 {
return Internal::Buf_cp_out<T>(v, size); }
131 template<
typename T >
143 Buf_cp_in(T *v,
unsigned long &size) : _v(v), _s(&size) {}
145 unsigned long &size()
const {
return *_s; }
146 T *buf()
const {
return _v; }
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; }
224 template<
typename T >
240 template<
typename T >
253 void set(T *p)
const { *_p = p; }
263 template<
typename T >
282 template<
typename T >
292 Buf_in(T *&v,
unsigned long &size) : _v(&v), _s(&size) {}
294 void set_size(
unsigned long s)
const { *_s = s; }
295 T *&buf()
const {
return *_v; }
320 template<
typename T >
321 Internal::Buf_in<T>
buf_in(T *&v,
unsigned long &size)
322 {
return Internal::Buf_in<T>(v, size); }
324 namespace Utcb_stream_check
326 static bool check_utcb_data_offset(
unsigned sz)
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 >
383 unsigned apos = cxx::Type_traits<T>::align(_pos);
384 return (count <= max_bytes /
sizeof(T))
385 && (apos + (
sizeof(T) * count)
402 template<
typename T >
403 unsigned long get(T *buf,
unsigned long elems)
408 unsigned long size = elems *
sizeof(T);
409 _pos = cxx::Type_traits<T>::align(_pos);
411 __builtin_memcpy(buf, _current_msg + _pos, size);
421 template<
typename T >
427 unsigned long size = elems *
sizeof(T);
428 _pos = cxx::Type_traits<T>::align(_pos);
444 template<
typename T >
445 unsigned long get(
Msg_ptr<T> const &buf,
unsigned long elems = 1)
450 unsigned long size = elems *
sizeof(T);
451 _pos = cxx::Type_traits<T>::align(_pos);
453 buf.set(reinterpret_cast<T*>(_current_msg + _pos));
466 template<
typename T >
475 _pos = cxx::Type_traits<T>::align(_pos);
476 v = *(
reinterpret_cast<T*
>(_current_msg + _pos));
485 if (!has_more<Ipc::Varg::Tag>())
591 unsigned char _current_buf;
594 class Istream_copy :
public Istream 604 _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);
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;
689 int put(
Varg const &va)
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_item const &);
750 unsigned long tell()
const 753 w -= _current_item * 2;
754 _tag =
l4_msgtag(0, w, _current_item, 0);
758 l4_msgtag_t prepare_ipc(
long proto = 0,
unsigned flags = 0)
761 w -= _current_item * 2;
762 return l4_msgtag(proto, w, _current_item, flags);
769 _current_item = tag.
items();
776 unsigned char _current_item;
912 Ostream::put_snd_item(
Snd_item const &v)
915 _pos = cxx::Type_traits<Snd_item>::align(_pos);
916 if (Utcb_stream_check::check_utcb_data_offset(_pos +
sizeof(T)))
919 *(
reinterpret_cast<T*
>(_current_msg + _pos)) = v;
932 l4_utcb_br_u(_utcb)->
bdr &= ~L4_BDR_OFFSET_MASK;
934 reinterpret_cast<Buf_item&
>(l4_utcb_br_u(_utcb)->
br[_current_buf]) = item;
946 l4_utcb_br_u(_utcb)->
bdr &= ~L4_BDR_OFFSET_MASK;
948 reinterpret_cast<Small_buf&
>(l4_utcb_br_u(_utcb)->
br[_current_buf]) = item;
965 tag =
l4_ipc_call(dst, Ostream::_utcb, tag, timeout);
1062 { s.
get(&v);
return s; }
1097 template<
typename T >
1100 L4::Ipc::Internal::Buf_in<T>
const &v)
1124 template<
typename T >
1145 template<
typename T >
1148 L4::Ipc::Internal::Buf_cp_in<T>
const &v)
1152 v.size() = s.
get(v.buf(),
cxx::min(v.size(), sz));
1166 template<
typename T >
1173 unsigned long rsz = s.
get(v.buf(),
cxx::min(v.size(), sz));
1174 if (rsz < v.size() && v.buf()[rsz - 1])
1178 v.buf()[rsz - 1] = 0;
1206 template<
typename T >
1207 inline L4::Ipc::Ostream &operator << (L4::Ipc::Ostream &s, L4::Cap<T>
const &v)
1211 { s.
put(v);
return s; }
1212 template<
typename T >
1213 inline L4::Ipc::Ostream &operator << (L4::Ipc::Ostream &s, L4::Ipc::Varg_t<T>
const &v)
1214 { s.
put(v);
return s; }
1242 template<
typename T >
1245 L4::Ipc::Internal::Buf_cp_out<T>
const &v)
1248 s.
put(v.buf(), v.size());
1267 unsigned long l = __builtin_strlen(v) + 1;
1274 #ifdef L4_CXX_IPC_BACKWARD_COMPAT 1278 template<
typename T >
class Ipc_buf_cp_out :
public Ipc::Buf_cp_out<T> {};
1279 template<
typename T >
class Ipc_buf_cp_in :
public Ipc::Buf_cp_in<T> {};
1280 template<
typename T >
class Ipc_buf_in :
public Ipc::Buf_in<T> {};
1281 template<
typename T >
class Msg_ptr :
public Ipc::Msg_ptr<T> {};
1284 template<
typename T >
1285 Ipc::Internal::Buf_cp_out<T> ipc_buf_cp_out(T *v,
unsigned long size)
1288 template<
typename T >
1289 Ipc::Internal::Buf_cp_out<T> ipc_buf_cp_out(T *v,
unsigned long size)
1290 {
return Ipc::Internal::Buf_cp_out<T>(v, size); }
1293 template<
typename T >
1294 Ipc::Internal::Buf_cp_in<T> ipc_buf_cp_in(T *v,
unsigned long &size)
1297 template<
typename T >
1298 Ipc::Internal::Buf_cp_in<T> ipc_buf_cp_in(T *v,
unsigned long &size)
1299 {
return Ipc::Internal::Buf_cp_in<T>(v, size); }
1302 template<
typename T >
1303 Ipc::Internal::Buf_in<T> ipc_buf_in(T *&v,
unsigned long &size)
1306 template<
typename T >
1307 Ipc::Internal::Buf_in<T> ipc_buf_in(T *&v,
unsigned long &size)
1308 {
return Ipc::Internal::Buf_in<T>(v, size); }
1311 template<
typename T >
1312 Ipc::Msg_ptr<T>
msg_ptr(T *&p)
1315 template<
typename T >
1316 Ipc::Msg_ptr<T>
msg_ptr(T *&p)
1317 {
return Ipc::Msg_ptr<T>(p); }
1319 typedef Ipc::Istream Ipc_istream
L4_DEPRECATED(
"Use L4::Ipc::Istream now");
1320 typedef Ipc::Ostream Ipc_ostream
L4_DEPRECATED(
"Use L4::Ipc::Ostream now");;
1321 typedef Ipc::Iostream Ipc_iostream
L4_DEPRECATED(
"Use L4::Ipc::Iostream now");;
1324 typedef Ipc::Small_buf Small_buf
L4_DEPRECATED(
"Use L4::Ipc::Small_buf now");;
1328 template<
typename T >
class Buf_cp_in :
public Internal::Buf_cp_in<T>
1331 Buf_cp_in(T *v,
unsigned long &size) : Internal::Buf_cp_in<T>(v, size) {}
1334 template<
typename T >
1335 class Buf_cp_out :
public Internal::Buf_cp_out<T>
1338 Buf_cp_out(T
const *v,
unsigned long size) : Internal::Buf_cp_out<T>(v, size) {}
1341 template<
typename T >
1342 class Buf_in :
public Internal::Buf_in<T>
1345 Buf_in(T *&v,
unsigned long &size) : Internal::Buf_in<T>(v, size) {}
1350 template<
typename T >
1355 template<
typename T >
1358 {
return operator>>(s,
static_cast<L4::Ipc::Internal::Buf_cp_in<T>
>(v)); }
1360 template<
typename T >
1365 template<
typename T >
1368 {
return operator>>(s,
static_cast<L4::Ipc::Internal::Buf_in<T>
>(v)); }
1370 template<
typename T >
1372 L4::Ipc::Ostream &operator << (L4::Ipc::Ostream &s, L4::Ipc::Buf_cp_out<T>
const &v)
1375 template<
typename T >
1377 L4::Ipc::Ostream &operator << (L4::Ipc::Ostream &s, L4::Ipc::Buf_cp_out<T>
const &v)
1378 {
return operator<<(s, static_cast<L4::Ipc::Internal::Buf_cp_out<T> >(v)); }
1381 namespace L4 {
namespace Ipc {
1390 template<
typename T >
Encapsulation of the message-register block in the UTCB.
l4_msgtag_t tag() const
Get the message tag of a received IPC.
Msg_ptr(T *&p)
Create a Msg_ptr object that set pointer p to point into the message buffer.
Iostream(l4_utcb_t *utcb)
Create an IPC IO stream with a single message buffer.
Total number of message register (MRs) available.
Invalid capability selector.
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 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 receiving to the input stream.
Input stream for IPC unmarshalling.
Input/Output stream for IPC [un]marshalling.
l4_umword_t mr[L4_UTCB_GENERIC_DATA_SIZE]
Message registers.
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).
Variably sized RPC argument.
T read(Istream &s)
Read a value out of a stream.
L4 low-level kernel interface.
Istream(l4_utcb_t *utcb)
Create an input stream for the given message buffer.
l4_msgtag_t tag() const
Extract the L4 message tag from the stream.
A receive item for receiving a single capability.
unsigned words() const
Get the number of untyped words.
Abstraction for extracting a zero-terminated string from an Ipc::Istream.
void data(char const *d)
Set Varg to indirect data value (usually in UTCB)
unsigned long l4_cap_idx_t
L4 Capability selector Type.
void reset()
Reset the stream to empty, and ready for receive()/wait().
struct l4_utcb_t l4_utcb_t
Opaque type for the UTCB.
l4_msgtag_t & tag()
Extract a reference to the L4 message tag from the stream.
RPC wrapper for a send item.
Internal::Buf_in< T > buf_in(T *&v, unsigned long &size)
Return a pointer to stream array data.
#define L4_IPC_NEVER
never timeout
L4::Cap related definitions.
l4_msgtag_t wait(l4_umword_t *src)
Wait for an incoming message from any sender.
Internal::Buf_cp_in< T > buf_cp_in(T *v, unsigned long &size)
Extract an array from an Ipc::Istream.
l4_msgtag_t send(l4_cap_idx_t dst, long proto=0, unsigned flags=0)
Send the message via IPC to the given receiver.
RPC warpper for a receive item.
l4_msgtag_t reply_and_wait(l4_umword_t *src_dst, long proto=0)
Do an IPC reply and wait.
bool has_more(unsigned long count=1)
Check whether a value of type T can be obtained from the stream.
l4_umword_t bdr
Buffer descriptor.
Total number of buffer registers (BRs) available.
l4_umword_t Tag
The data type for the tag.
bool put(T const &v)
Insert an element of type T into the stream.
void skip(unsigned long elems)
Skip size elements of type T in the stream.
#define L4_UNLIKELY(x)
Expression is unlikely to execute.
Str_cp_in(T *v, unsigned long &size)
Create a buffer for extracting an array from an Ipc::Istream.
unsigned long l4_umword_t
Unsigned machine word.
void reset()
Reset the stream to its initial state.
l4_utcb_t * utcb() const
Return utcb pointer.
unsigned items() const
Get the number of typed items.
l4_utcb_t * utcb() const
Return utcb pointer.
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).
Gen_fpage< Snd_item > Snd_fpage
Send flex-page.
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_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).
unsigned long get(T *buf, unsigned long elems)
Copy out an array of type T with size elements.
unsigned length() const
Get the size of the RPC argument.
Internal::Buf_cp_out< T > buf_cp_out(T const *v, unsigned long size)
Insert an array into an Ipc::Ostream.
Gen_fpage< Buf_item > Rcv_fpage
Rcv flex-page.
Str_cp_in< T > str_cp_in(T *v, unsigned long &size)
Create a Str_cp_in for the given values.
#define L4_IPC_SEND_TIMEOUT_0
0 send timeout
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.
Ostream(l4_utcb_t *utcb)
Create an IPC output stream using the given message buffer utcb.
bool put(T *buf, unsigned long size)
Put an array with size elements of type T into the stream.
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::Ipc::Ostream & operator<<(L4::Ipc::Ostream &s, bool v)
Insert an element to type T into the stream s.
l4_msgtag_t & tag()
Get the message tag of a received IPC.
Pointer to an element of type T in an Ipc::Istream.
Output stream for IPC marshalling.
Message tag data structure.
L4::Ipc::Istream & operator>>(L4::Ipc::Istream &s, bool &v)
Extract one element of type T from the stream s.
unsigned long l4_addr_t
Address type.
l4_msgtag_t receive(l4_cap_idx_t src)
Wait for a message from the specified sender.
l4_umword_t br[L4_UTCB_GENERIC_BUFFERS_SIZE]
Buffer registers.
void reset()
Reset the stream to empty, same state as a newly created stream.
Msg_ptr< T > msg_ptr(T *&p)
Create an Msg_ptr to adjust the given pointer.
#define L4_DEPRECATED(s)
Mark symbol deprecated.
T1 min(T1 a, T1 b)
Get the minimum of a and b.