21#include <l4/sys/utcb.h>
41constexpr unsigned long align_to(
unsigned long bytes,
unsigned long align)
noexcept
42{
return (bytes + align - 1) & ~(align - 1); }
51constexpr unsigned long align_to(
unsigned long bytes)
noexcept
52{
return align_to(bytes, __alignof(T)); }
64constexpr bool check_size(
unsigned offset,
unsigned limit)
noexcept
66 return offset +
sizeof(T) <= limit;
81template<
typename T,
typename CTYPE>
82inline bool check_size(
unsigned offset,
unsigned limit, CTYPE cnt)
noexcept
84 if (
L4_UNLIKELY(
sizeof(CTYPE) <=
sizeof(
unsigned) &&
85 ~0U /
sizeof(T) <=
static_cast<unsigned>(cnt)))
89 static_cast<CTYPE
>(~0U /
sizeof(T)) <= cnt))
92 return sizeof(T) * cnt <= limit - offset;
125inline int msg_add(
char *msg,
unsigned offs,
unsigned limit, T v)
noexcept
127 offs = align_to<T>(offs);
130 *
reinterpret_cast<typename L4::Types::Remove_const<T>::type *
>(msg + offs) = v;
131 return offs +
sizeof(T);
146inline int msg_get(
char *msg,
unsigned offs,
unsigned limit, T &v)
noexcept
148 offs = align_to<T>(offs);
151 v = *
reinterpret_cast<T *
>(msg + offs);
152 return offs +
sizeof(T);
182template<
typename T>
struct _Plain
185 static T deref(T v)
noexcept {
return v; }
188template<
typename T>
struct _Plain<T *>
191 static T &deref(T *v)
noexcept {
return *v; }
194template<
typename T>
struct _Plain<T &>
197 static T &deref(T &v)
noexcept {
return v; }
201template<
typename T>
struct _Plain<T const &>
204 static T
const &deref(T
const &v)
noexcept {
return v; }
207template<
typename T>
struct _Plain<T const *>
210 static T
const &deref(T
const *v)
noexcept {
return *v; }
221template<
typename MTYPE,
typename DIR,
typename CLASS>
struct Clnt_val_ops;
223template<
typename T>
struct Clnt_noops
225 template<
typename A,
typename B>
226 static constexpr int to_msg(
char *,
unsigned offset,
unsigned, T, A, B)
noexcept
230 template<
typename A,
typename B>
231 static constexpr int from_msg(
char *,
unsigned offset,
unsigned,
long, T
const &, A, B)
noexcept
235template<
typename T>
struct Svr_noops
237 template<
typename A,
typename B>
238 static constexpr int from_svr(
char *,
unsigned offset,
unsigned,
long, T, A, B)
noexcept
242 template<
typename A,
typename B>
243 static constexpr int to_svr(
char *,
unsigned offset,
unsigned, T, A, B)
noexcept
247template<
typename MTYPE,
typename CLASS>
248struct Clnt_val_ops<MTYPE, Dir_in, CLASS> : Clnt_noops<MTYPE>
250 using Clnt_noops<MTYPE>::to_msg;
252 static int to_msg(
char *msg,
unsigned offset,
unsigned limit,
253 MTYPE arg, Dir_in, CLASS)
noexcept
254 {
return msg_add<MTYPE>(msg, offset, limit, arg); }
258template<
typename MTYPE,
typename CLASS>
259struct Clnt_val_ops<MTYPE, Dir_out, CLASS> : Clnt_noops<MTYPE>
261 using Clnt_noops<MTYPE>::from_msg;
263 static int from_msg(
char *msg,
unsigned offset,
unsigned limit,
long,
264 MTYPE &arg, Dir_out, CLASS)
noexcept
265 {
return msg_get<MTYPE>(msg, offset, limit, arg); }
275template<
typename MTYPE,
typename DIR,
typename CLASS>
struct Svr_val_ops;
277template<
typename MTYPE,
typename CLASS>
280 using Svr_noops<MTYPE>::to_svr;
282 static int to_svr(
char *msg,
unsigned offset,
unsigned limit,
283 MTYPE &arg,
Dir_in, CLASS)
noexcept
284 {
return msg_get<MTYPE>(msg, offset, limit, arg); }
287template<
typename MTYPE,
typename CLASS>
288struct Svr_val_ops<MTYPE, Dir_out, CLASS> : Svr_noops<MTYPE>
290 using Svr_noops<MTYPE>::to_svr;
291 static int to_svr(
char *,
unsigned offs,
unsigned limit,
292 MTYPE &, Dir_out, CLASS)
noexcept
294 offs = align_to<MTYPE>(offs);
297 return offs +
sizeof(MTYPE);
300 using Svr_noops<MTYPE>::from_svr;
302 static int from_svr(
char *msg,
unsigned offset,
unsigned limit,
long,
303 MTYPE arg, Dir_out, CLASS)
noexcept
304 {
return msg_add<MTYPE>(msg, offset, limit, arg); }
307template<
typename T>
struct Elem
314 typedef T svr_arg_type;
316 enum { Is_optional =
false };
320template<
typename T>
struct Elem<T &>
325 typedef T &svr_arg_type;
326 enum { Is_optional =
false };
329template<
typename T>
struct Elem<T const &>
331 typedef T
const &arg_type;
335 typedef T
const &svr_arg_type;
336 enum { Is_optional =
false };
339template<
typename T>
struct Elem<T *> : Elem<T &>
344template<
typename T>
struct Elem<T const *> : Elem<T const &>
346 typedef T
const *arg_type;
355template<
typename T,
bool B>
struct Error_invalid_rpc_parameter_used;
356template<
typename T>
struct Error_invalid_rpc_parameter_used<T, true> {};
358#if __cplusplus >= 201103L
360struct _Elem : Elem<T>
362 static_assert(Is_valid_rpc_type<T>::value,
363 "L4::Ipc::Msg::_Elem<T>: type T is not a valid RPC parameter type.");
367struct _Elem : Elem<T>,
368 Error_invalid_rpc_parameter_used<T, Is_valid_rpc_type<T>::value>
373template<
typename T>
struct Class : Cls_data {};
374template<
typename T>
struct Direction : Dir_in {};
375template<
typename T>
struct Direction<T const &> : Dir_in {};
376template<
typename T>
struct Direction<T const *> : Dir_in {};
377template<
typename T>
struct Direction<T &> : Dir_out {};
378template<
typename T>
struct Direction<T *> : Dir_out {};
380template<
typename T>
struct _Clnt_noops :
381 Clnt_noops<typename Detail::_Plain<typename _Elem<T>::arg_type>::type>
386template<
typename T,
typename DIR,
typename CLASS>
387struct _Clnt_val_ops :
388 Clnt_val_ops<typename Detail::_Plain<T>::type, DIR, CLASS> {};
391 typename ELEM = _Elem<T>,
392 typename CLNT_OPS = _Clnt_val_ops<
typename ELEM::arg_type,
393 typename Direction<T>::type,
394 typename Class<typename Detail::_Plain<T>::type>::type>
396struct _Clnt_xmit : CLNT_OPS {};
399 typename ELEM = _Elem<T>,
400 typename SVR_OPS = Svr_val_ops<
typename ELEM::svr_type,
401 typename Direction<T>::type,
402 typename Class<typename Detail::_Plain<T>::type>::type>
404struct _Svr_xmit : SVR_OPS {};
407template<
typename T>
struct Clnt_xmit : Detail::_Clnt_xmit<T> {};
408template<
typename T>
struct Svr_xmit : Detail::_Svr_xmit<T> {};
unsigned long l4_umword_t
Unsigned machine word.
@ L4_EMSGTOOLONG
Message too long.
@ L4_EMSGTOOSHORT
Message too short.
#define L4_UNLIKELY(x)
Expression is unlikely to execute.
constexpr bool check_size(unsigned offset, unsigned limit) noexcept
Check if there is enough space for T from offset to limit.
constexpr unsigned long align_to(unsigned long bytes, unsigned long align) noexcept
Pad bytes to the given alignment align (in bytes)
@ Br_bytes
number of bytes available in the UTCB buffer registers
@ Item_words
number of message words for one message item
@ Mr_bytes
number of bytes available in the UTCB message registers
@ Item_bytes
number of bytes for one message item
@ Word_bytes
number of bytes for one message word
@ Mr_words
number of message words available in the UTCB
int msg_add(char *msg, unsigned offs, unsigned limit, T v) noexcept
Add some data to a message at offs.
int msg_get(char *msg, unsigned offs, unsigned limit, T &v) noexcept
Get some data from a message at offs.
L4 low-level kernel interface.
Defines client-side handling of ‘MTYPE’ as RPC argument.
Marker type for receive buffer values.
Marker type for data values.
Marker type for item values.
Marker type for input values.
Marker type for output values.
Marker for receive buffers.
Type trait defining a valid RPC parameter type.
Defines server-side handling for MTYPE server arguments.