19 #pragma GCC system_header
21 #include <l4/sys/cxx/ipc_basics>
208 namespace L4 {
namespace Ipc {
228 enum { Is_call =
true };
238 static l4_timeout_t timeout() {
return L4_IPC_SEND_TIMEOUT_0; }
256 template<
unsigned RIGHTS>
259 enum { Rights = RIGHTS };
276 enum { Is_call =
false };
293 template<
typename OP,
typename CLASS,
typename SIG,
typename FLAGS = Call>
294 struct L4_EXPORT Rpc_inline_call;
300 template<
typename OP,
typename CLASS,
typename FLAGS,
typename R,
302 struct L4_EXPORT Rpc_inline_call<OP, CLASS, R (ARGS...), FLAGS>
304 template<
typename T>
struct Result {
typedef T result_type; };
311 typedef Rpc_inline_call type;
315 typedef CLASS class_type;
317 typedef typename Result<R>::result_type result_type;
319 typedef R ipc_type (ARGS...);
321 typedef result_type func_type (
typename _Elem<ARGS>::arg_type...);
324 typedef FLAGS flags_type;
326 template<
typename RES>
327 static typename L4::Types::Enable_if< Return_tag, RES >::type
328 return_err(
long err) noexcept {
return l4_msgtag(err, 0, 0, 0); }
330 template<
typename RES>
331 static typename L4::Types::Enable_if< Return_tag, RES >::type
334 template<
typename RES>
335 static typename L4::Types::Enable_if< Return_tag, RES >::type
336 return_code(
l4_msgtag_t tag) noexcept {
return tag; }
338 template<
typename RES>
339 static typename L4::Types::Enable_if< !Return_tag, RES >::type
340 return_err(
long err) noexcept {
return err; }
342 template<
typename RES>
343 static typename L4::Types::Enable_if< !Return_tag, RES >::type
347 template<
typename RES>
348 static typename L4::Types::Enable_if< !Return_tag, RES >::type
349 return_code(
l4_msgtag_t tag) noexcept {
return tag.label(); }
352 typename _Elem<ARGS>::arg_type ...a,
360 template<typename OP, typename CLASS, typename SIG, typename FLAGS = Call>
361 struct L4_EXPORT Rpc_call;
370 template<typename IPC, typename SIG> struct _Call;
373 template<typename IPC, typename R, typename ...ARGS>
374 struct _Call<IPC, R (ARGS...)>
377 typedef typename IPC::class_type class_type;
378 typedef typename IPC::result_type result_type;
389 result_type operator () (ARGS ...a,
l4_utcb_t *utcb =
l4_utcb()) const noexcept
390 {
return IPC::call(cap(), a..., utcb); }
399 template<
typename IPC>
struct Call : _Call<IPC, typename IPC::func_type> {};
405 template<
typename OP,
410 struct L4_EXPORT Rpc_call<OP, CLASS, R (ARGS...), FLAGS> :
411 Rpc_inline_call<OP, CLASS, R (ARGS...), FLAGS>
414 typename _Elem<ARGS>::arg_type ...a,
418 #define L4_INLINE_RPC_SRV_FORWARD(name) \
419 template<typename OBJ> struct fwd \
422 fwd(OBJ *o) noexcept : o(o) {} \
423 template<typename ...ARGS> long call(ARGS ...a) noexcept(noexcept(o->op_##name(a...))) \
424 { return o->op_##name(a...); } \
440 #define L4_INLINE_RPC_NF(res, name, args...) \
441 struct name##_t : L4::Ipc::Msg::Rpc_inline_call<name##_t, Class, res args> \
443 typedef L4::Ipc::Msg::Rpc_inline_call<name##_t, Class, res args> type; \
444 L4_INLINE_RPC_SRV_FORWARD(name); \
453 #define L4_INLINE_RPC_NF_OP(op, res, name, args...) \
454 struct name##_t : L4::Ipc::Msg::Rpc_inline_call<name##_t, Class, res args> \
456 typedef L4::Ipc::Msg::Rpc_inline_call<name##_t, Class, res args> type; \
457 enum { Opcode = (op) }; \
458 L4_INLINE_RPC_SRV_FORWARD(name); \
469 #define L4_INLINE_RPC(res, name, args, attr...) res name args
471 #define L4_INLINE_RPC(res, name, args...) \
472 L4_INLINE_RPC_NF(res, name, args); L4::Ipc::Msg::Call<name##_t> name
484 #define L4_INLINE_RPC_OP(op, res, name, args, attr...) res name args
486 #define L4_INLINE_RPC_OP(op, res, name, args...) \
487 L4_INLINE_RPC_NF_OP(op, res, name, args); L4::Ipc::Msg::Call<name##_t> name
497 #define L4_RPC_NF(res, name, args...) \
498 struct name##_t : L4::Ipc::Msg::Rpc_call<name##_t, Class, res args> \
500 typedef L4::Ipc::Msg::Rpc_call<name##_t, Class, res args> type; \
501 L4_INLINE_RPC_SRV_FORWARD(name); \
512 #define L4_RPC_NF_OP(op, res, name, args...) \
513 struct name##_t : L4::Ipc::Msg::Rpc_call<name##_t, Class, res args> \
515 typedef L4::Ipc::Msg::Rpc_call<name##_t, Class, res args> type; \
516 enum { Opcode = (op) }; \
517 L4_INLINE_RPC_SRV_FORWARD(name); \
528 #define L4_RPC(res, name, args, attr...) res name args
530 #define L4_RPC(res, name, args...) \
531 L4_RPC_NF(res, name, args); L4::Ipc::Msg::Call<name##_t> name
543 #define L4_RPC_OP(op, res, name, args, attr...) res name args
545 #define L4_RPC_OP(op, res, name, args...) \
546 L4_RPC_NF_OP(op, res, name, args); L4::Ipc::Msg::Call<name##_t> name
559 template<
typename ...ARGS>
563 template<
typename DIR>
564 static constexpr
int write(
char *,
int offset,
int) noexcept
567 template<
typename DIR>
568 static constexpr
int read(
char *,
int offset,
int,
long) noexcept
574 template<
typename A,
typename ...M>
575 struct Buf<A, M...> : Buf<M...>
577 typedef Buf<M...> Base;
579 typedef Clnt_xmit<A> xmit;
580 typedef typename _Elem<A>::arg_type arg_type;
581 typedef Detail::_Plain<arg_type> plain;
583 template<
typename DIR>
585 write(
char *base,
int offset,
int limit,
586 arg_type a,
typename _Elem<M>::arg_type ...m) noexcept
588 offset = xmit::to_msg(base, offset, limit, plain::deref(a),
589 typename DIR::dir(),
typename DIR::cls());
590 return Base::template write<DIR>(base, offset, limit, m...);
593 template<
typename DIR>
595 read(
char *base,
int offset,
int limit,
long ret,
596 arg_type a,
typename _Elem<M>::arg_type ...m) noexcept
598 int r = xmit::from_msg(base, offset, limit, ret, plain::deref(a),
599 typename DIR::dir(),
typename DIR::cls());
601 return Base::template read<DIR>(base, r, limit, ret, m...);
603 if (_Elem<A>::Is_optional)
604 return Base::template read<DIR>(base, offset, limit, ret, m...);
610 template <
typename ...ARGS>
struct _Part
613 typedef Buf<ARGS...> Data;
615 template<
typename DIR>
616 static int write(
void *b,
int offset,
int limit,
617 typename _Elem<ARGS>::arg_type ...m) noexcept
619 int r = Data::template write<DIR>((
char *)b, offset, limit, m...);
625 template<
typename DIR>
626 static int read(
void *b,
int offset,
int limit,
long ret,
627 typename _Elem<ARGS>::arg_type ...m) noexcept
629 int r = Data::template read<DIR>((
char *)b, offset, limit, ret, m...);
642 template<
typename IPC_TYPE,
typename OPCODE =
void>
646 template<
typename R,
typename ...ARGS>
647 struct Part<R (ARGS...), void> : _Part<ARGS...>
650 typedef Buf<ARGS...> Data;
653 template<
typename DIR>
654 static int write_op(
void *b,
int offset,
int limit,
656 typename _Elem<ARGS>::arg_type ...m) noexcept
658 int r = Data::template write<DIR>((
char *)b, offset, limit, m...);
666 template<
typename OPCODE,
typename R,
typename ...ARGS>
667 struct Part<R (ARGS...), OPCODE> : _Part<ARGS...>
669 typedef OPCODE opcode_type;
671 typedef Buf<opcode_type, ARGS...> Data;
674 template<
typename DIR>
675 static int write_op(
void *b,
int offset,
int limit,
676 opcode_type op,
typename _Elem<ARGS>::arg_type ...m) noexcept
678 int r = Data::template write<DIR>((
char *)b, offset, limit, op, m...);
693 template<
typename OP,
typename CLASS,
typename FLAGS,
typename R,
696 Rpc_inline_call<OP, CLASS, R (ARGS...), FLAGS>::
698 typename _Elem<ARGS>::arg_type ...a,
701 using namespace Ipc::Msg;
703 typedef typename Kobject_typeid<CLASS>::Iface::Rpcs Rpcs;
704 typedef typename Rpcs::template Rpc<OP> Opt;
705 typedef Detail::Part<ipc_type, typename Rpcs::opcode_type> Args;
711 Args::template write_op<Do_in_data>(mrs->
mr, 0,
Mr_bytes,
715 return return_err<R>(send_bytes);
717 send_bytes = align_to<l4_umword_t>(send_bytes);
718 int const send_words = send_bytes /
Word_bytes;
721 Args::template write<Do_in_items>(&mrs->
mr[send_words], 0,
725 return return_err<R>(item_bytes);
742 return return_err<R>(bytes);
750 t =
l4_msgtag(CLASS::Protocol, send_words, send_items, 0);
752 if (flags_type::Is_call)
758 return return_ipc_err<R>(t, utcb);
767 return return_ipc_err<R>(t, utcb);
774 return return_err<R>(r);
779 int err = Args::template read<Do_out_data>(mrs->
mr, 0, rcv_bytes, r, a...);
787 err = Args::template read<Do_out_items>(&mrs->
mr[t.
words()], 0, item_limit,
793 return return_code<R>(t);
Type information handling.
l4_cap_idx_t cap() const noexcept
Return capability selector.
C++ interface for capabilities.
#define L4_UNLIKELY(x)
Expression is unlikely to execute.
#define L4_LIKELY(x)
Expression is likely to execute.
unsigned long l4_cap_idx_t
L4 Capability selector Type.
@ L4_CAP_MASK
Mask to get only the relevant bits of an l4_cap_idx_t.
@ L4_EMSGTOOSHORT
Message too short.
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).
int l4_ipc_error_code(l4_utcb_t *utcb) L4_NOTHROW
Get the error condition of the last invocation from the TCR.
l4_msgtag_t l4_msgtag(long label, unsigned words, unsigned items, unsigned flags) L4_NOTHROW
Create a message tag from the specified values.
struct l4_utcb_t l4_utcb_t
Opaque type for the UTCB.
l4_utcb_t * l4_utcb(void) L4_NOTHROW L4_PURE
Get the UTCB address.
long l4_ipc_to_errno(unsigned long ipc_error_code) L4_NOTHROW
Get a negative error code for the given IPC error code.
@ Br_bytes
number of bytes available in the UTCB buffer registers
@ 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
T read(Istream &s)
Read a value out of a stream.
L4 low-level kernel interface.
int Opcode
Data type for RPC opcodes.
RPC attribute for an RPC call with required rights.
RPC attribute for an RPC call, with zero send timeout.
RPC attribute for a standard RPC call.
RPC attribute for a send-only RPC.
Compare two data types for equality.
Encapsulation of the buffer-registers block in the UTCB.
l4_umword_t br[L4_UTCB_GENERIC_BUFFERS_SIZE]
Buffer registers.
l4_umword_t bdr
Buffer descriptor.
Message tag data structure.
long label() const L4_NOTHROW
Get the protocol value.
unsigned has_error() const L4_NOTHROW
Test if flags indicate an error.
unsigned words() const L4_NOTHROW
Get the number of untyped words.
unsigned items() const L4_NOTHROW
Get the number of typed items.
unsigned flags() const L4_NOTHROW
Get the flags value.
Encapsulation of the message-register block in the UTCB.
l4_umword_t mr[L4_UTCB_GENERIC_DATA_SIZE]
Message registers.