19#pragma GCC system_header
21#include <l4/sys/cxx/ipc_basics>
31template<
typename T>
struct Sizeof {
enum { size =
sizeof(T) }; };
32template<>
struct Sizeof<void> {
enum { size = 0 }; };
37template<
typename ...>
struct Arg_pack
39 template<
typename DIR>
40 unsigned get(
char *,
unsigned offset,
unsigned)
43 template<
typename DIR>
44 unsigned set(
char *,
unsigned offset,
unsigned,
long)
47 template<
typename F,
typename ...ARGS>
48 long call(F f, ARGS ...args)
49 {
return f(args...); }
51 template<
typename O,
typename FUNC,
typename ...ARGS>
52 long obj_call(O *o, ARGS ...args)
54 typedef typename FUNC::template fwd<O> Fwd;
55 return Fwd(o).template call<ARGS...>(args...);
63template<
typename T,
typename SVR_TYPE,
typename ...M>
64struct Svr_arg : Svr_xmit<T>, Arg_pack<M...>
66 typedef Arg_pack<M...> Base;
68 typedef SVR_TYPE svr_type;
69 typedef typename _Elem<T>::svr_arg_type svr_arg_type;
73 template<
typename DIR>
74 int get(
char *msg,
unsigned offset,
unsigned limit)
76 typedef Svr_xmit<T> ct;
77 int r = ct::to_svr(msg, offset, limit, this->v,
78 typename DIR::dir(),
typename DIR::cls());
80 return Base::template get<DIR>(msg, r, limit);
82 if (_Elem<T>::Is_optional)
85 return Base::template get<DIR>(msg, offset, limit);
90 template<
typename DIR>
91 int set(
char *msg,
unsigned offset,
unsigned limit,
long ret)
93 typedef Svr_xmit<T> ct;
94 int r = ct::from_svr(msg, offset, limit, ret, this->v,
95 typename DIR::dir(),
typename DIR::cls());
98 return Base::template set<DIR>(msg, r, limit, ret);
101 template<
typename F,
typename ...ARGS>
102 long call(F f, ARGS ...args)
105 return Base::template
106 call<F, ARGS..., svr_arg_type>(f, args..., this->v);
109 template<
typename O,
typename FUNC,
typename ...ARGS>
110 long obj_call(O *o, ARGS ...args)
113 return Base::template
114 obj_call<O,FUNC, ARGS..., svr_arg_type>(o, args..., this->v);
118template<
typename T,
typename ...M>
119struct Svr_arg<T, void, M...> : Arg_pack<M...>
121 typedef Arg_pack<M...> Base;
123 template<
typename DIR>
124 int get(
char *msg,
unsigned offset,
unsigned limit)
125 {
return Base::template get<DIR>(msg, offset, limit); }
127 template<
typename DIR>
128 int set(
char *msg,
unsigned offset,
unsigned limit,
long ret)
129 {
return Base::template set<DIR>(msg, offset, limit, ret); }
131 template<
typename F,
typename ...ARGS>
132 long call(F f, ARGS ...args)
134 return Base::template call<F, ARGS...>(f, args...);
137 template<
typename O,
typename FUNC,
typename ...ARGS>
138 long obj_call(O *o, ARGS ...args)
140 return Base::template obj_call<O, FUNC, ARGS...>(o, args...);
144template<
typename A,
typename ...M>
145struct Arg_pack<A, M...> : Svr_arg<A, typename _Elem<A>::svr_type, M...>
157template<
typename R,
typename ...ARGS>
158struct Svr_arg_pack<R (ARGS...)> : Detail::Arg_pack<ARGS...>
160 typedef Detail::Arg_pack<ARGS...> Base;
161 template<
typename DIR>
162 int get(
void *msg,
unsigned offset,
unsigned limit)
164 char *buf =
static_cast<char *
>(msg);
165 return Base::template get<DIR>(buf, offset, limit);
168 template<
typename DIR>
169 int set(
void *msg,
unsigned offset,
unsigned limit,
long ret)
171 char *buf =
static_cast<char *
>(msg);
172 return Base::template set<DIR>(buf, offset, limit, ret);
179template<
typename IPC_TYPE,
typename O,
typename ...ARGS>
183 typedef Svr_arg_pack<typename IPC_TYPE::rpc::ipc_type> Pack;
186 Do_reply = IPC_TYPE::rpc::flags_type::Is_call,
198 int in_pos = Detail::Sizeof<typename IPC_TYPE::opcode_type>::size;
202 in_pos = pack.template get<Do_in_data>(&mrs->
mr[0], in_pos, in_bytes);
211 in_pos = pack.template get<Do_in_items>(&mrs->
mr[tag.
words()], 0,
217 asm volatile (
"" :
"=m" (mrs->
mr));
220 long ret = pack.template obj_call<O,
typename IPC_TYPE::rpc, ARGS...>(o, args...);
231 int bytes = pack.template set<Do_out_data>(mrs->
mr, 0,
Mr_bytes, ret);
236 bytes = pack.template set<Do_out_items>(&mrs->
mr[words], 0,
248template<
typename RPCS,
typename OPCODE_TYPE>
251template<
typename CLASS>
252struct Dispatch_call<
L4::Typeid::Raw_ipc<CLASS>, void>
254 template<
typename OBJ,
typename ...ARGS>
258 return o->op_dispatch(utcb, tag, a...);
262template<
typename RPCS>
263struct Dispatch_call<RPCS, void>
265 constexpr static unsigned rmask()
266 {
return RPCS::rpc::flags_type::Rights & 3UL; }
268 template<
typename OBJ,
typename ...ARGS>
272 if ((rights & rmask()) != rmask())
275 typedef L4::Typeid::Rights<typename RPCS::rpc::class_type> Rights;
276 return handle_svr_obj_call<RPCS>(o, utcb, tag,
277 Rights(rights), a...);
282template<
typename RPCS,
typename OPCODE_TYPE>
285 constexpr static unsigned rmask()
286 {
return RPCS::rpc::flags_type::Rights & 3UL; }
288 template<
typename OBJ,
typename ...ARGS>
293 || RPCS::Opcode == op)
295 if ((rights & rmask()) != rmask())
298 typedef L4::Typeid::Rights<typename RPCS::rpc::class_type> Rights;
299 return handle_svr_obj_call<RPCS>(o, utcb, tag,
300 Rights(rights), a...);
302 return Dispatch_call<typename RPCS::next, OPCODE_TYPE>::template
303 _call<OBJ, ARGS...>(o, utcb, tag, rights, op, a...);
306 template<
typename OBJ,
typename ...ARGS>
312 typedef Svr_xmit<OPCODE_TYPE> S;
313 int err = S::to_svr(
reinterpret_cast<char *
>(l4_utcb_mr_u(utcb)->mr), 0,
314 limit, op, Dir_in(), Cls_data());
318 return _call<OBJ, ARGS...>(o, utcb, tag, rights, op, a...);
323struct Dispatch_call<Typeid::Detail::Rpcs_end, void>
325 template<
typename OBJ,
typename ...ARGS>
330 template<
typename OBJ,
typename ...ARGS>
336template<
typename OPCODE_TYPE>
337struct Dispatch_call<Typeid::Detail::Rpcs_end, OPCODE_TYPE> :
338 Dispatch_call<Typeid::Detail::Rpcs_end, void> {};
340template<
typename RPCS,
typename OBJ,
typename ...ARGS>
344 return Dispatch_call<typename RPCS::type, typename RPCS::opcode_type>::template
345 call<OBJ, ARGS...>(o, utcb, tag, rights, a...);
Type information handling.
@ L4_EMSGTOOLONG
Message too long.
@ L4_EMSGTOOSHORT
Message too short.
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.
#define L4_UNLIKELY(x)
Expression is unlikely to execute.
#define L4_LIKELY(x)
Expression is likely to execute.
Interface Definition Language.
@ 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
L4 low-level kernel interface.
Server-side RPC arguments data structure used to provide arguments to the server-side implementation ...
Compare two data types for equality.
Message tag data structure.
unsigned words() const L4_NOTHROW
Get the number of untyped words.
unsigned items() const L4_NOTHROW
Get the number of typed items.
Encapsulation of the message-register block in the UTCB.
l4_umword_t mr[L4_UTCB_GENERIC_DATA_SIZE]
Message registers.