21 #include <l4/sys/utcb.h>
41 constexpr
unsigned long align_to(
unsigned long bytes,
unsigned long align) noexcept
42 {
return (bytes + align - 1) & ~(align - 1); }
51 constexpr
unsigned long align_to(
unsigned long bytes) noexcept
52 {
return align_to(bytes, __alignof(T)); }
64 constexpr
bool check_size(
unsigned offset,
unsigned limit) noexcept
66 return offset +
sizeof(T) <= limit;
81 template<
typename T,
typename CTYPE>
82 inline 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;
125 inline 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);
146 inline 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);
182 template<
typename T>
struct _Plain
185 static T deref(T v) noexcept {
return v; }
188 template<
typename T>
struct _Plain<T *>
191 static T &deref(T *v) noexcept {
return *v; }
194 template<
typename T>
struct _Plain<T &>
197 static T &deref(T &v) noexcept {
return v; }
201 template<
typename T>
struct _Plain<T const &>
204 static T
const &deref(T
const &v) noexcept {
return v; }
207 template<
typename T>
struct _Plain<T const *>
210 static T
const &deref(T
const *v) noexcept {
return *v; }
221 template<
typename MTYPE,
typename DIR,
typename CLASS>
struct Clnt_val_ops;
223 template<
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
235 template<
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
247 template<
typename MTYPE,
typename CLASS>
248 struct 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); }
258 template<
typename MTYPE,
typename CLASS>
259 struct 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); }
275 template<
typename MTYPE,
typename DIR,
typename CLASS>
struct Svr_val_ops;
277 template<
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); }
287 template<
typename MTYPE,
typename CLASS>
288 struct 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); }
307 template<
typename T>
struct Elem
314 typedef T svr_arg_type;
316 enum { Is_optional =
false };
320 template<
typename T>
struct Elem<T &>
325 typedef T &svr_arg_type;
326 enum { Is_optional =
false };
329 template<
typename T>
struct Elem<T const &>
331 typedef T
const &arg_type;
335 typedef T
const &svr_arg_type;
336 enum { Is_optional =
false };
339 template<
typename T>
struct Elem<T *> : Elem<T &>
344 template<
typename T>
struct Elem<T const *> : Elem<T const &>
346 typedef T
const *arg_type;
355 template<
typename T,
bool B>
struct Error_invalid_rpc_parameter_used;
356 template<
typename T>
struct Error_invalid_rpc_parameter_used<T, true> {};
358 #if __cplusplus >= 201103L
360 struct _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.");
367 struct _Elem : Elem<T>,
368 Error_invalid_rpc_parameter_used<T, Is_valid_rpc_type<T>::value>
373 template<
typename T>
struct Class : Cls_data {};
374 template<
typename T>
struct Direction : Dir_in {};
375 template<
typename T>
struct Direction<T const &> : Dir_in {};
376 template<
typename T>
struct Direction<T const *> : Dir_in {};
377 template<
typename T>
struct Direction<T &> : Dir_out {};
378 template<
typename T>
struct Direction<T *> : Dir_out {};
380 template<
typename T>
struct _Clnt_noops :
381 Clnt_noops<typename Detail::_Plain<typename _Elem<T>::arg_type>::type>
386 template<
typename T,
typename DIR,
typename CLASS>
387 struct _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>
396 struct _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>
404 struct _Svr_xmit : SVR_OPS {};
407 template<
typename T>
struct Clnt_xmit : Detail::_Clnt_xmit<T> {};
408 template<
typename T>
struct Svr_xmit : Detail::_Svr_xmit<T> {};
#define L4_UNLIKELY(x)
Expression is unlikely to execute.
unsigned long l4_umword_t
Unsigned machine word.
@ L4_EMSGTOOLONG
Message too long.
@ L4_EMSGTOOSHORT
Message too short.
@ L4_UTCB_GENERIC_DATA_SIZE
Total number of message register (MRs) available.
@ L4_UTCB_GENERIC_BUFFERS_SIZE
Total number of buffer registers (BRs) available.
@ 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
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)
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.