19 #pragma GCC system_header 21 #include <l4/sys/cxx/ipc_basics> 31 template<
typename T>
struct Sizeof {
enum { size =
sizeof(T) }; };
32 template<>
struct Sizeof<void> {
enum { size = 0 }; };
37 template<
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...);
63 template<
typename T,
typename SVR_TYPE,
typename ...M>
64 struct 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);
118 template<
typename T,
typename ...M>
119 struct 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...);
144 template<
typename A,
typename ...M>
145 struct Arg_pack<A, M...> : Svr_arg<A, typename _Elem<A>::svr_type, M...>
157 template<
typename R,
typename ...ARGS>
158 struct 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 return Base::template get<DIR>((
char *)msg, offset, limit);
167 template<
typename DIR>
168 int set(
void *msg,
unsigned offset,
unsigned limit,
long ret)
170 return Base::template set<DIR>((
char *)msg, offset, limit, ret);
177 template<
typename IPC_TYPE,
typename O,
typename ...ARGS>
184 Do_reply = IPC_TYPE::rpc::flags_type::Is_call,
196 int in_pos = Detail::Sizeof<typename IPC_TYPE::opcode_type>::size;
200 in_pos = pack.template get<Do_in_data>(&mrs->
mr[0], in_pos, in_bytes);
209 in_pos = pack.template get<Do_in_items>(&mrs->
mr[tag.
words()], 0,
215 asm volatile (
"" :
"=m" (mrs->
mr));
218 long ret = pack.template obj_call<O,
typename IPC_TYPE::rpc, ARGS...>(o, args...);
229 int bytes = pack.template set<Do_out_data>(mrs->
mr, 0,
Mr_bytes, ret);
234 bytes = pack.template set<Do_out_items>(&mrs->
mr[words], 0,
246 template<
typename RPCS,
typename OPCODE_TYPE>
247 struct Dispatch_call;
249 template<
typename CLASS>
252 template<
typename OBJ,
typename ...ARGS>
256 return o->op_dispatch(utcb, tag, a...);
260 template<
typename RPCS>
261 struct Dispatch_call<RPCS, void>
263 constexpr
static unsigned rmask()
264 {
return RPCS::rpc::flags_type::Rights & 3UL; }
266 template<
typename OBJ,
typename ...ARGS>
270 if ((rights & rmask()) != rmask())
273 typedef L4::Typeid::Rights<typename RPCS::rpc::class_type> Rights;
274 return handle_svr_obj_call<RPCS>(o, utcb, tag,
275 Rights(rights), a...);
280 template<
typename RPCS,
typename OPCODE_TYPE>
283 constexpr
static unsigned rmask()
284 {
return RPCS::rpc::flags_type::Rights & 3UL; }
286 template<
typename OBJ,
typename ...ARGS>
293 if ((rights & rmask()) != rmask())
296 typedef L4::Typeid::Rights<typename RPCS::rpc::class_type> Rights;
297 return handle_svr_obj_call<RPCS>(o, utcb, tag,
298 Rights(rights), a...);
300 return Dispatch_call<typename RPCS::next, OPCODE_TYPE>::template
301 _call<OBJ, ARGS...>(o, utcb, tag, rights, op, a...);
304 template<
typename OBJ,
typename ...ARGS>
310 typedef Svr_xmit<OPCODE_TYPE> S;
311 int err = S::to_svr((
char *)l4_utcb_mr_u(utcb)->mr, 0, limit, op,
316 return _call<OBJ, ARGS...>(o, utcb, tag, rights, op, a...);
321 struct Dispatch_call<Typeid::Detail::Rpcs_end, void>
323 template<
typename OBJ,
typename ...ARGS>
328 template<
typename OBJ,
typename ...ARGS>
334 template<
typename OPCODE_TYPE>
335 struct Dispatch_call<Typeid::Detail::Rpcs_end, OPCODE_TYPE> :
336 Dispatch_call<Typeid::Detail::Rpcs_end, void> {};
338 template<
typename RPCS,
typename OBJ,
typename ...ARGS>
342 return Dispatch_call<typename RPCS::type, typename RPCS::opcode_type>::template
343 call<OBJ, ARGS...>(o, utcb, tag, rights, a...);
Encapsulation of the message-register block in the UTCB.
Compare two data types for equality.
Server-side RPC arguments data structure used to provide arguments to the server-side implementation ...
number of bytes for one message item
number of message words for one message item
l4_umword_t mr[L4_UTCB_GENERIC_DATA_SIZE]
Message registers.
L4 low-level kernel interface.
unsigned words() const
Get the number of untyped words.
struct l4_utcb_t l4_utcb_t
Opaque type for the UTCB.
RPCs list for passing raw incoming IPC to the server object.
Type information handling.
number of bytes for one message word
int Opcode
Data type for RPC opcodes.
#define L4_UNLIKELY(x)
Expression is unlikely to execute.
number of message words available in the UTCB
Interface Definition Language.
unsigned items() const
Get the number of typed items.
Marker type for input values.
#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.
Marker type for data values.
number of bytes available in the UTCB message registers
Message tag data structure.