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; }
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; }
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; }
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)
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);
423 template<
typename T >
429 unsigned long size = elems *
sizeof(T);
430 _pos = cxx::Type_traits<T>::align(_pos);
446 template<
typename T >
447 unsigned long get(
Msg_ptr<T> const &buf,
unsigned long elems = 1)
452 unsigned long size = elems *
sizeof(T);
453 _pos = cxx::Type_traits<T>::align(_pos);
455 buf.set(reinterpret_cast<T*>(_current_msg + _pos));
468 template<
typename T >
477 _pos = cxx::Type_traits<T>::align(_pos);
478 v = *(
reinterpret_cast<T*
>(_current_msg + _pos));
487 if (!has_more<Ipc::Varg::Tag>())
593 unsigned char _current_buf;
596 class Istream_copy :
public Istream 606 _current_msg =
reinterpret_cast<char*
>(l4_utcb_mr_u(_utcb)->
mr);
632 : _tag(), _utcb(utcb),
633 _current_msg(reinterpret_cast<char *>(l4_utcb_mr_u(_utcb)->mr)),
634 _pos(0), _current_item(0)
644 _current_msg =
reinterpret_cast<char*
>(l4_utcb_mr_u(_utcb)->
mr);
661 template<
typename T >
662 bool put(T *buf,
unsigned long size)
665 _pos = cxx::Type_traits<T>::align(_pos);
666 if (Utcb_stream_check::check_utcb_data_offset(_pos + size))
669 __builtin_memcpy(_current_msg + _pos, buf, size);
679 template<
typename T >
682 _pos = cxx::Type_traits<T>::align(_pos);
683 if (Utcb_stream_check::check_utcb_data_offset(_pos +
sizeof(T)))
686 *(
reinterpret_cast<T*
>(_current_msg + _pos)) = v;
691 int put(
Varg const &va)
699 template<
typename T >
700 int put(Varg_t<T>
const &va)
701 {
return put(static_cast<Varg const &>(va)); }
723 inline bool put_snd_item(
Snd_item const &);
752 unsigned long tell()
const 755 w -= _current_item * 2;
756 _tag =
l4_msgtag(0, w, _current_item, 0);
760 l4_msgtag_t prepare_ipc(
long proto = 0,
unsigned flags = 0)
763 w -= _current_item * 2;
764 return l4_msgtag(proto, w, _current_item, flags);
771 _current_item = tag.
items();
778 unsigned char _current_item;
914 Ostream::put_snd_item(
Snd_item const &v)
917 _pos = cxx::Type_traits<Snd_item>::align(_pos);
918 if (Utcb_stream_check::check_utcb_data_offset(_pos +
sizeof(T)))
921 *(
reinterpret_cast<T*
>(_current_msg + _pos)) = v;
934 l4_utcb_br_u(_utcb)->
bdr &= ~L4_BDR_OFFSET_MASK;
936 reinterpret_cast<Buf_item&
>(l4_utcb_br_u(_utcb)->
br[_current_buf]) = item;
948 l4_utcb_br_u(_utcb)->
bdr &= ~L4_BDR_OFFSET_MASK;
950 reinterpret_cast<Small_buf&
>(l4_utcb_br_u(_utcb)->
br[_current_buf]) = item;
967 tag =
l4_ipc_call(dst, Ostream::_utcb, tag, timeout);
1064 { s.
get(&v);
return s; }
1099 template<
typename T >
1102 L4::Ipc::Internal::Buf_in<T>
const &v)
1126 template<
typename T >
1147 template<
typename T >
1150 L4::Ipc::Internal::Buf_cp_in<T>
const &v)
1154 v.size() = s.
get(v.buf(),
cxx::min(v.size(), sz));
1168 template<
typename T >
1175 unsigned long rsz = s.
get(v.buf(),
cxx::min(v.size(), sz));
1176 if (rsz < v.size() && v.buf()[rsz - 1])
1180 v.buf()[rsz - 1] = 0;
1208 template<
typename T >
1209 inline L4::Ipc::Ostream &operator << (L4::Ipc::Ostream &s, L4::Cap<T>
const &v)
1213 { s.
put(v);
return s; }
1214 template<
typename T >
1215 inline L4::Ipc::Ostream &operator << (L4::Ipc::Ostream &s, L4::Ipc::Varg_t<T>
const &v)
1216 { s.
put(v);
return s; }
1244 template<
typename T >
1247 L4::Ipc::Internal::Buf_cp_out<T>
const &v)
1250 s.
put(v.buf(), v.size());
1269 unsigned long l = __builtin_strlen(v) + 1;
1276 #ifdef L4_CXX_IPC_BACKWARD_COMPAT 1280 template<
typename T >
class Ipc_buf_cp_out :
public Ipc::Buf_cp_out<T> {};
1281 template<
typename T >
class Ipc_buf_cp_in :
public Ipc::Buf_cp_in<T> {};
1282 template<
typename T >
class Ipc_buf_in :
public Ipc::Buf_in<T> {};
1283 template<
typename T >
class Msg_ptr :
public Ipc::Msg_ptr<T> {};
1286 template<
typename T >
1287 Ipc::Internal::Buf_cp_out<T> ipc_buf_cp_out(T *v,
unsigned long size)
1290 template<
typename T >
1291 Ipc::Internal::Buf_cp_out<T> ipc_buf_cp_out(T *v,
unsigned long size)
1292 {
return Ipc::Internal::Buf_cp_out<T>(v, size); }
1295 template<
typename T >
1296 Ipc::Internal::Buf_cp_in<T> ipc_buf_cp_in(T *v,
unsigned long &size)
1299 template<
typename T >
1300 Ipc::Internal::Buf_cp_in<T> ipc_buf_cp_in(T *v,
unsigned long &size)
1301 {
return Ipc::Internal::Buf_cp_in<T>(v, size); }
1304 template<
typename T >
1305 Ipc::Internal::Buf_in<T> ipc_buf_in(T *&v,
unsigned long &size)
1308 template<
typename T >
1309 Ipc::Internal::Buf_in<T> ipc_buf_in(T *&v,
unsigned long &size)
1310 {
return Ipc::Internal::Buf_in<T>(v, size); }
1313 template<
typename T >
1314 Ipc::Msg_ptr<T>
msg_ptr(T *&p)
1317 template<
typename T >
1318 Ipc::Msg_ptr<T>
msg_ptr(T *&p)
1319 {
return Ipc::Msg_ptr<T>(p); }
1321 typedef Ipc::Istream Ipc_istream
L4_DEPRECATED(
"Use L4::Ipc::Istream now");
1322 typedef Ipc::Ostream Ipc_ostream
L4_DEPRECATED(
"Use L4::Ipc::Ostream now");;
1323 typedef Ipc::Iostream Ipc_iostream
L4_DEPRECATED(
"Use L4::Ipc::Iostream now");;
1326 typedef Ipc::Small_buf Small_buf
L4_DEPRECATED(
"Use L4::Ipc::Small_buf now");;
1330 template<
typename T >
class Buf_cp_in :
public Internal::Buf_cp_in<T>
1333 Buf_cp_in(T *v,
unsigned long &size) : Internal::Buf_cp_in<T>(v, size) {}
1336 template<
typename T >
1337 class Buf_cp_out :
public Internal::Buf_cp_out<T>
1340 Buf_cp_out(T
const *v,
unsigned long size) : Internal::Buf_cp_out<T>(v, size) {}
1343 template<
typename T >
1344 class Buf_in :
public Internal::Buf_in<T>
1347 Buf_in(T *&v,
unsigned long &size) : Internal::Buf_in<T>(v, size) {}
1352 template<
typename T >
1357 template<
typename T >
1360 {
return operator>>(s,
static_cast<L4::Ipc::Internal::Buf_cp_in<T>
>(v)); }
1362 template<
typename T >
1367 template<
typename T >
1370 {
return operator>>(s,
static_cast<L4::Ipc::Internal::Buf_in<T>
>(v)); }
1372 template<
typename T >
1374 L4::Ipc::Ostream &operator << (L4::Ipc::Ostream &s, L4::Ipc::Buf_cp_out<T>
const &v)
1377 template<
typename T >
1379 L4::Ipc::Ostream &operator << (L4::Ipc::Ostream &s, L4::Ipc::Buf_cp_out<T>
const &v)
1380 {
return operator<<(s, static_cast<L4::Ipc::Internal::Buf_cp_out<T> >(v)); }
1383 namespace L4 {
namespace Ipc {
1392 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.