19 #pragma GCC system_header 21 #include <l4/sys/cxx/ipc_basics> 197 namespace L4 {
namespace Ipc {
217 enum { Is_call =
true };
245 template<
unsigned RIGHTS>
248 enum { Rights = RIGHTS };
265 enum { Is_call =
false };
282 template<
typename OP,
typename CLASS,
typename SIG,
typename FLAGS = Call>
283 struct L4_EXPORT Rpc_inline_call;
289 template<
typename OP,
typename CLASS,
typename FLAGS,
typename R,
291 struct L4_EXPORT Rpc_inline_call<OP, CLASS, R (ARGS...), FLAGS>
293 template<
typename T>
struct Result {
typedef T result_type; };
300 typedef Rpc_inline_call type;
304 typedef CLASS class_type;
306 typedef typename Result<R>::result_type result_type;
308 typedef R ipc_type (ARGS...);
310 typedef result_type func_type (
typename _Elem<ARGS>::arg_type...);
313 typedef FLAGS flags_type;
315 template<
typename RES>
316 static typename L4::Types::Enable_if< Return_tag, RES >::type
317 return_err(
long err) {
return l4_msgtag(err, 0, 0, 0); }
319 template<
typename RES>
320 static typename L4::Types::Enable_if< Return_tag, RES >::type
323 template<
typename RES>
324 static typename L4::Types::Enable_if< Return_tag, RES >::type
327 template<
typename RES>
328 static typename L4::Types::Enable_if< !Return_tag, RES >::type
329 return_err(
long err) {
return err; }
331 template<
typename RES>
332 static typename L4::Types::Enable_if< !Return_tag, RES >::type
336 template<
typename RES>
337 static typename L4::Types::Enable_if< !Return_tag, RES >::type
341 typename _Elem<ARGS>::arg_type ...a,
349 template<
typename OP,
typename CLASS,
typename SIG,
typename FLAGS = Call>
350 struct L4_EXPORT Rpc_call;
359 template<
typename IPC,
typename SIG>
struct _Call;
362 template<
typename IPC,
typename R,
typename ...ARGS>
363 struct _Call<IPC, R (ARGS...)>
366 typedef typename IPC::class_type class_type;
367 typedef typename IPC::result_type result_type;
378 result_type operator () (ARGS ...a,
l4_utcb_t *utcb =
l4_utcb())
const throw()
379 {
return IPC::call(cap(), a..., utcb); }
388 template<
typename IPC>
struct Call : _Call<IPC, typename IPC::func_type> {};
394 template<
typename OP,
399 struct L4_EXPORT Rpc_call<OP, CLASS, R (ARGS...), FLAGS> :
400 Rpc_inline_call<OP, CLASS, R (ARGS...), FLAGS>
403 typename _Elem<ARGS>::arg_type ...a,
407 #define L4_INLINE_RPC_SRV_FORWARD(name) \ 408 template<typename OBJ> struct fwd \ 411 fwd(OBJ *o) : o(o) {} \ 412 template<typename ...ARGS> long call(ARGS ...a) \ 413 { return o->op_##name(a...); } \ 429 #define L4_INLINE_RPC_NF(res, name, args...) \ 430 struct name##_t : L4::Ipc::Msg::Rpc_inline_call<name##_t, Class, res args> \ 432 typedef L4::Ipc::Msg::Rpc_inline_call<name##_t, Class, res args> type; \ 433 L4_INLINE_RPC_SRV_FORWARD(name); \ 442 #define L4_INLINE_RPC_NF_OP(op, res, name, args...) \ 443 struct name##_t : L4::Ipc::Msg::Rpc_inline_call<name##_t, Class, res args> \ 445 typedef L4::Ipc::Msg::Rpc_inline_call<name##_t, Class, res args> type; \ 446 enum { Opcode = (op) }; \ 447 L4_INLINE_RPC_SRV_FORWARD(name); \ 458 #define L4_INLINE_RPC(res, name, args, attr...) res name args 460 #define L4_INLINE_RPC(res, name, args...) \ 461 L4_INLINE_RPC_NF(res, name, args); L4::Ipc::Msg::Call<name##_t> name 473 #define L4_INLINE_RPC_OP(op, res, name, args, attr...) res name args 475 #define L4_INLINE_RPC_OP(op, res, name, args...) \ 476 L4_INLINE_RPC_NF_OP(op, res, name, args); L4::Ipc::Msg::Call<name##_t> name 486 #define L4_RPC_NF(res, name, args...) \ 487 struct name##_t : L4::Ipc::Msg::Rpc_call<name##_t, Class, res args> \ 489 typedef L4::Ipc::Msg::Rpc_call<name##_t, Class, res args> type; \ 490 L4_INLINE_RPC_SRV_FORWARD(name); \ 501 #define L4_RPC_NF_OP(op, res, name, args...) \ 502 struct name##_t : L4::Ipc::Msg::Rpc_call<name##_t, Class, res args> \ 504 typedef L4::Ipc::Msg::Rpc_call<name##_t, Class, res args> type; \ 505 enum { Opcode = (op) }; \ 506 L4_INLINE_RPC_SRV_FORWARD(name); \ 517 #define L4_RPC(res, name, args, attr...) res name args 519 #define L4_RPC(res, name, args...) \ 520 L4_RPC_NF(res, name, args); L4::Ipc::Msg::Call<name##_t> name 532 #define L4_RPC_OP(op, res, name, args, attr...) res name args 534 #define L4_RPC_OP(op, res, name, args...) \ 535 L4_RPC_NF_OP(op, res, name, args); L4::Ipc::Msg::Call<name##_t> name 548 template<
typename ...ARGS>
552 template<
typename DIR>
553 static int write(
char *,
int offset,
int)
556 template<
typename DIR>
557 static int read(
char *,
int offset,
int,
long)
563 template<
typename A,
typename ...M>
564 struct Buf<A, M...> : Buf<M...>
566 typedef Buf<M...> Base;
568 typedef Clnt_xmit<A> xmit;
569 typedef typename _Elem<A>::arg_type arg_type;
570 typedef Detail::_Plain<arg_type> plain;
572 template<
typename DIR>
574 write(
char *base,
int offset,
int limit,
575 arg_type a,
typename _Elem<M>::arg_type ...m)
577 offset = xmit::to_msg(base, offset, limit, plain::deref(a),
578 typename DIR::dir(),
typename DIR::cls());
579 return Base::template write<DIR>(base, offset, limit, m...);
582 template<
typename DIR>
584 read(
char *base,
int offset,
int limit,
long ret,
585 arg_type a,
typename _Elem<M>::arg_type ...m)
587 int r = xmit::from_msg(base, offset, limit, ret, plain::deref(a),
588 typename DIR::dir(),
typename DIR::cls());
590 return Base::template read<DIR>(base, r, limit, ret, m...);
592 if (_Elem<A>::Is_optional)
593 return Base::template read<DIR>(base, offset, limit, ret, m...);
599 template <
typename ...ARGS>
struct _Part
602 typedef Buf<ARGS...> Data;
604 template<
typename DIR>
605 static int write(
void *b,
int offset,
int limit,
606 typename _Elem<ARGS>::arg_type ...m)
608 int r = Data::template write<DIR>((
char *)b, offset, limit, m...);
614 template<
typename DIR>
615 static int read(
void *b,
int offset,
int limit,
long ret,
616 typename _Elem<ARGS>::arg_type ...m)
618 int r = Data::template read<DIR>((
char *)b, offset, limit, ret, m...);
631 template<
typename IPC_TYPE,
typename OPCODE =
void>
635 template<
typename R,
typename ...ARGS>
636 struct Part<R (ARGS...), void> : _Part<ARGS...>
639 typedef Buf<ARGS...> Data;
642 template<
typename DIR>
643 static int write_op(
void *b,
int offset,
int limit,
645 typename _Elem<ARGS>::arg_type ...m)
647 int r = Data::template write<DIR>((
char *)b, offset, limit, m...);
655 template<
typename OPCODE,
typename R,
typename ...ARGS>
656 struct Part<R (ARGS...), OPCODE> : _Part<ARGS...>
658 typedef OPCODE opcode_type;
660 typedef Buf<opcode_type, ARGS...> Data;
663 template<
typename DIR>
664 static int write_op(
void *b,
int offset,
int limit,
665 opcode_type op,
typename _Elem<ARGS>::arg_type ...m)
667 int r = Data::template write<DIR>((
char *)b, offset, limit, op, m...);
682 template<
typename OP,
typename CLASS,
typename FLAGS,
typename R,
685 Rpc_inline_call<OP, CLASS, R (ARGS...), FLAGS>::
687 typename _Elem<ARGS>::arg_type ...a,
690 using namespace Ipc::Msg;
692 typedef typename Kobject_typeid<CLASS>::Iface::Rpcs Rpcs;
693 typedef typename Rpcs::template Rpc<OP> Opt;
694 typedef Detail::Part<ipc_type, typename Rpcs::opcode_type> Args;
700 Args::template write_op<Do_in_data>(mrs->
mr, 0, Mr_bytes,
704 return return_err<R>(send_bytes);
706 send_bytes = align_to<l4_umword_t>(send_bytes);
707 int const send_words = send_bytes / Word_bytes;
710 Args::template write<Do_in_items>(&mrs->
mr[send_words], 0,
711 Mr_bytes - send_bytes, a...);
714 return return_err<R>(item_bytes);
716 int send_items = item_bytes / Item_bytes;
727 Args::template write<Do_rcv_buffers>(brs->
br, 0, Br_bytes - Word_bytes,
731 return return_err<R>(bytes);
733 brs->
br[bytes / Word_bytes] = 0;
739 t =
l4_msgtag(CLASS::Protocol, send_words, send_items, 0);
741 if (flags_type::Is_call)
747 return return_ipc_err<R>(t, utcb);
749 return return_code<R>(
l4_msgtag(0, 0, 0, t.flags()));
756 return return_ipc_err<R>(t, utcb);
763 return return_err<R>(r);
765 int const rcv_bytes = t.words() * Word_bytes;
768 int err = Args::template read<Do_out_data>(mrs->
mr, 0, rcv_bytes, r, a...);
770 int const item_limit = t.items() * Item_bytes;
776 err = Args::template read<Do_out_items>(&mrs->
mr[t.words()], 0, item_limit,
782 return return_code<R>(t);
Encapsulation of the message-register block in the UTCB.
Compare two data types for equality.
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).
T read(Istream &s)
Read a value out of a stream.
L4 low-level kernel interface.
long l4_ipc_to_errno(unsigned long ipc_error_code) L4_NOTHROW
Get a negative error code for the given IPC error code.
unsigned long l4_cap_idx_t
L4 Capability selector Type.
RPC attribute for a send-only RPC.
struct l4_utcb_t l4_utcb_t
Opaque type for the UTCB.
#define L4_IPC_NEVER
never timeout
Encapsulation of the buffer-registers block in the UTCB.
Type information handling.
long label() const
Get the protocol value.
l4_umword_t bdr
Buffer descriptor.
int l4_ipc_error_code(l4_utcb_t *utcb) L4_NOTHROW
Get the error condition of the last invocation from the TCR.
int Opcode
Data type for RPC opcodes.
#define L4_UNLIKELY(x)
Expression is unlikely to execute.
l4_cap_idx_t cap() const
Return capability selector.
Mask to get only the relevant bits of an l4_cap_idx_t.
RPC attribute for an RPC call, with zero send timeout.
l4_utcb_t * l4_utcb(void) L4_NOTHROW L4_PURE
Get the UTCB address.
#define L4_LIKELY(x)
Expression is likely to execute.
l4_msgtag_t l4_msgtag(long label, unsigned words, unsigned items, unsigned flags) L4_NOTHROW
Create a message tag from the specified values.
RPC attribute for an RPC call with required rights.
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).
#define L4_IPC_SEND_TIMEOUT_0
0 send timeout
C++ interface for capabilities.
Message tag data structure.
RPC attribute for a standard RPC call.
l4_umword_t br[L4_UTCB_GENERIC_BUFFERS_SIZE]
Buffer registers.