16#pragma GCC system_header
19#include "cxx/ipc_basics"
20#include "cxx/capability.h"
22#if defined(__GXX_RTTI) && !defined(L4_NO_RTTI)
24 typedef std::type_info
const *L4_std_type_info_ptr;
25# define L4_KOBJECT_META_RTTI(type) (&typeid(type))
26 inline char const *L4_kobject_type_name(L4_std_type_info_ptr n)
noexcept
27 {
return n ? n->name() : 0; }
29 typedef void const *L4_std_type_info_ptr;
30# define L4_KOBJECT_META_RTTI(type) (0)
31 inline char const *L4_kobject_type_name(L4_std_type_info_ptr)
noexcept
40 template<
unsigned char A,
unsigned char B>
41 struct Max {
enum { Res = A > B ? A : B }; };
82 template<
long P,
typename T>
99 typedef Iface_list_end type;
100 static bool contains(
long)
noexcept {
return false; }
111 template<
typename I,
typename N = Iface_list_end>
114 typedef Iface_list<I, N> type;
116 typedef typename I::iface_type iface_type;
119 enum { Proto = I::Proto };
121 static bool contains(
long proto)
noexcept
122 {
return (proto == Proto) || Next::contains(proto); }
126 template<
typename I,
typename N>
127 struct Iface_list<Iface<
PROTO_EMPTY, I>, N> : N {};
130 template<
long P,
typename N>
131 struct Iface_list<Iface<P, void>, N> : N {};
141 template<
typename I,
typename L >
144 template<
typename I >
145 struct _In_list<I, Iface_list_end> :
False {};
147 template<
typename I,
typename N >
148 struct _In_list<I, Iface_list<I, N> > :
True {};
150 template<
typename I,
typename I2,
typename N >
151 struct _In_list<I, Iface_list<I2, N> > : _In_list<I, typename N::type> {};
153 template<
typename I,
typename L>
154 struct In_list : _In_list<typename I::type, typename L::type> {};
163 template<
bool ADD,
typename I,
typename L>
164 struct _Iface_list_add;
166 template<
typename I,
typename L>
167 struct _Iface_list_add<false, I, L> : L {};
169 template<
typename I,
typename L>
170 struct _Iface_list_add<true, I, L> : Iface_list<I, L> {};
177 template<
typename I,
typename L >
178 struct Iface_list_add :
180 !In_list<I, typename L::type>::value, I, typename L::type>
190 template<
typename I1,
typename I2 >
191 struct __Iface_conflict :
Bool<I1::Proto != PROTO_EMPTY && I1::Proto == I2::Proto> {};
193 template<
typename I >
194 struct __Iface_conflict<I, I> :
False {};
200 template<
typename I,
typename LIST >
201 struct _Iface_conflict;
203 template<
typename I >
204 struct _Iface_conflict<I, Iface_list_end> :
False {};
206 template<
typename I,
typename I2,
typename LIST >
207 struct _Iface_conflict<I, Iface_list<I2, LIST> > :
208 Bool<__Iface_conflict<I, I2>::value || _Iface_conflict<I, typename LIST::type>::value>
215 template<
typename I,
typename LIST >
216 struct Iface_conflict : _Iface_conflict<typename I::type, typename LIST::type> {};
223 template<
typename L1,
typename L2 >
226 template<
typename L >
227 struct _Merge_list<Iface_list_end, L> : L {};
229 template<
typename I,
typename L1,
typename L2 >
230 struct _Merge_list<Iface_list<I, L1>, L2> :
231 _Merge_list<typename L1::type, typename Iface_list_add<I, L2>::type> {};
233 template<
typename L1,
typename L2>
234 struct Merge_list : _Merge_list<typename L1::type, typename L2::type> {};
241 template<
typename L1,
typename L2 >
244 template<
typename L >
245 struct _Conflict<Iface_list_end, L> :
False {};
247 template<
typename I,
typename L1,
typename L2 >
248 struct _Conflict<Iface_list<I, L1>, L2> :
249 Bool<Iface_conflict<I, typename L2::type>::value
250 || _Conflict<typename L1::type, typename L2::type>::value> {};
252 template<
typename L1,
typename L2 >
253 struct Conflict : _Conflict<typename L1::type, typename L2::type> {};
262 template<
typename LIST>
267 struct _P_dispatch<Iface_list_end>
269 template<
typename THIS,
typename A1,
typename A2 >
270 static int f(THIS *,
long, A1, A2 &)
noexcept
276 template<
typename I,
typename LIST >
277 struct _P_dispatch<Iface_list<I, LIST> >
280 template<
typename THIS,
typename A1,
typename A2 >
281 static int _f(THIS self, A1, A2 &a2,
True::type)
283 return self->dispatch_meta_request(a2);
287 template<
typename THIS,
typename A1,
typename A2 >
288 static int _f(THIS self, A1 a1, A2 &a2,
False::type)
290 return self->p_dispatch(
reinterpret_cast<typename I::iface_type *
>(0),
295 template<
typename THIS,
typename A1,
typename A2 >
296 static int f(THIS *self,
long proto, A1 a1, A2 &a2)
298 if (I::Proto == proto)
299 return _f(self, a1, a2,
302 return _P_dispatch<typename LIST::type>::f(self, proto, a1, a2);
307 template<
typename LIST>
312 template<
typename RPC>
struct Default_op;
319 typedef void opcode_type;
325 template<
typename O1,
typename O2,
typename RPCS>
326 struct _Rpc : _Rpc<typename RPCS::next::rpc, O2, typename RPCS::next>::type {};
329 template<
typename O1,
typename O2>
330 struct _Rpc<O1, O2, Rpcs_end> {};
332 template<
typename OP,
typename RPCS>
333 struct _Rpc<OP, OP, RPCS> : RPCS
338 template<
typename OP,
typename RPCS>
339 struct Rpc : _Rpc<typename RPCS::rpc, OP, RPCS> {};
341 template<
typename T,
unsigned CODE>
344 template<
bool,
typename>
struct Invalid_opcode {};
345 template<
typename X>
struct Invalid_opcode<true, X>;
348 template<
typename U, U>
struct _chk;
349 template<
typename U>
static long _opc(_chk<int, U::Opcode> *);
350 template<
typename U>
static char _opc(...);
352 template<
unsigned SZ,
typename U>
353 struct _Opc {
enum { value = CODE }; };
356 struct _Opc<sizeof(long), U> {
enum { value = U::Opcode }; };
359 enum { value = _Opc<sizeof(_opc<T>(0)), T>::value };
360 Invalid_opcode<(value < CODE), T> invalid_opcode;
364 template<
typename OPCODE,
unsigned O,
typename ...X>
368 template<
typename OPCODE,
unsigned O,
typename R,
typename ...X>
380 enum {
Opcode = _Get_opcode<R, O>::value };
382 template<
typename Y>
struct Rpc : Typeid::Detail::Rpc<Y, _Rpcs> {};
385 template<
typename OPCODE,
unsigned O,
typename R>
386 struct _Rpcs<OPCODE, O, Default_op<R> >
391 typedef void opcode_type;
399 template<
typename Y>
struct Rpc : Typeid::Detail::Rpc<Y, _Rpcs> {};
411 template<
typename CLASS>
416 typedef void opcode_type;
427 template<
typename ...RPCS>
438 template<
typename OPCODE_TYPE>
444 template<
typename ...RPCS>
453 template<
typename OPERATION>
464 template<
typename ...ARG>
467 template<
typename CLASS>
471 Rights(
unsigned rights) noexcept : rights(rights) {}
472 unsigned operator & (
unsigned rhs)
const noexcept {
return rights & rhs; }
510 static unsigned char max(
unsigned char a,
unsigned char b)
noexcept
511 {
return a > b ? a : b; }
527 Demand(
unsigned char caps = 0,
unsigned char flags = 0,
528 unsigned char mem = 0,
unsigned char ports = 0) noexcept
529 : caps(caps), flags(flags), mem(mem), ports(ports) {}
527 Demand(
unsigned char caps = 0,
unsigned char flags = 0, {
…}
533 {
return caps == 0 && mem == 0 && ports == 0 && flags == 0; }
538 return Demand(max(caps, rhs.caps), flags | rhs.flags,
539 max(mem, rhs.mem), max(ports, rhs.ports));
551 template<
unsigned char CAPS = 0,
unsigned char FLAGS = 0,
552 unsigned char MEM = 0,
unsigned char PORTS = 0>
572 template<
typename D1,
typename D2>
574 D1::Flags | D2::Flags,
575 __I::Max<D1::Mem, D2::Mem>::Res,
576 __I::Max<D1::Ports, D2::Ports>::Res>
579 L4_std_type_info_ptr _type;
584 L4_std_type_info_ptr type() const noexcept {
return _type; }
585 Type_info const *base(
unsigned idx)
const noexcept {
return _bases[idx]; }
586 unsigned num_bases() const noexcept {
return _num_bases; }
587 long proto() const noexcept {
return _proto; }
588 char const *name() const noexcept {
return L4_kobject_type_name(type()); }
589 bool has_proto(
long proto)
const noexcept
591 if (_proto && _proto == proto)
597 for (
unsigned i = 0; i < _num_bases; ++i)
598 if (base(i)->has_proto(proto))
622 typedef typename T::__Kobject_typeid::Demand
Demand;
623 typedef typename T::__Iface::iface_type Iface;
624 typedef typename T::__Iface_list Iface_list;
630 static Type_info const *
id() noexcept {
return &T::__Kobject_typeid::_m; }
640 {
return T::__Kobject_typeid::Demand(); }
659 template<
typename THIS,
typename A1,
typename A2>
689#define L4____GEN_TI(t...) \
690Type_info const t::__Kobject_typeid::_m = \
692 L4_KOBJECT_META_RTTI(Derived), \
693 &t::__Kobject_typeid::_b[0], \
694 sizeof(t::__Kobject_typeid::_b) / sizeof(t::__Kobject_typeid::_b[0]), \
702#define L4____GEN_TI_MEMBERS(BASE_DEMAND...) \
704 template< typename T > friend struct Kobject_typeid; \
706 struct __Kobject_typeid { \
707 typedef Type_info::Demand_union_t<S_DEMAND, BASE_DEMAND> Demand; \
708 static Type_info const *const _b[]; \
709 static Type_info const _m; \
712 static long const Protocol = PROTO; \
713 typedef L4::Typeid::Rights<Class> Rights;
755 typedef Typeid::Iface<PROTO, Derived>
__Iface;
757 typedef Typeid::Merge_list<
758 Typeid::Iface_list<__Iface>,
typename Base::__Iface_list
764 typedef Typeid::Iface_conflict<__Iface, typename Base::__Iface_list> Base_conflict;
765 static_assert(!Base_conflict::value,
"ambiguous protocol ID: protocol also used by Base");
772 L4____GEN_TI_MEMBERS(
typename Base::__Kobject_typeid::Demand)
777template<
typename Derived,
typename Base,
long PROTO,
typename S_DEMAND>
780 __Kobject_typeid::_b[] = { &Base::__Kobject_typeid::_m };
787template<
typename Derived,
typename Base,
long PROTO,
typename S_DEMAND>
833 typedef Typeid::Iface<PROTO, Derived>
__Iface;
835 typedef Typeid::Merge_list<
836 Typeid::Iface_list<__Iface>,
838 typename Base1::__Iface_list,
839 typename Base2::__Iface_list
846 typedef typename Base1::__Iface_list Base1_proto_list;
847 typedef typename Base2::__Iface_list Base2_proto_list;
849 typedef Typeid::Iface_conflict<__Iface, Base1_proto_list> Base1_conflict;
850 typedef Typeid::Iface_conflict<__Iface, Base2_proto_list> Base2_conflict;
851 static_assert(!Base1_conflict::value,
"ambiguous protocol ID, also in Base1");
852 static_assert(!Base2_conflict::value,
"ambiguous protocol ID, also in Base2");
854 typedef Typeid::Conflict<Base1_proto_list, Base2_proto_list> Bases_conflict;
855 static_assert(!Bases_conflict::value,
"ambiguous protocol IDs in base classes");
860 {
return Base1::cap(); }
866 typename Base1::__Kobject_typeid::Demand,
867 typename Base2::__Kobject_typeid::Demand>
872 operator
Kobject const & () const noexcept
873 {
return *
static_cast<Base1
const *
>(
this); }
877 noexcept(noexcept(static_cast<Base1*>(
nullptr)->dec_refcnt(diff, utcb)))
878 {
return Base1::dec_refcnt(diff, utcb); }
883template<
typename Derived,
typename Base1,
typename Base2,
884 long PROTO,
typename S_DEMAND >
888 &Base1::__Kobject_typeid::_m,
889 &Base2::__Kobject_typeid::_m
897template<
typename Derived,
typename Base1,
typename Base2,
898 long PROTO,
typename S_DEMAND >
936 typedef Typeid::Iface<PROTO, Derived>
__Iface;
938 typedef Typeid::Merge_list<
939 Typeid::Iface_list<__Iface>,
941 typename Base1::__Iface_list,
943 typename Base2::__Iface_list,
944 typename Base3::__Iface_list
952 typedef typename Base1::__Iface_list Base1_proto_list;
953 typedef typename Base2::__Iface_list Base2_proto_list;
954 typedef typename Base3::__Iface_list Base3_proto_list;
956 typedef Typeid::Iface_conflict<__Iface, Base1_proto_list> Base1_conflict;
957 typedef Typeid::Iface_conflict<__Iface, Base2_proto_list> Base2_conflict;
958 typedef Typeid::Iface_conflict<__Iface, Base3_proto_list> Base3_conflict;
960 static_assert(!Base1_conflict::value,
"ambiguous protocol ID, also in Base1");
961 static_assert(!Base2_conflict::value,
"ambiguous protocol ID, also in Base2");
962 static_assert(!Base3_conflict::value,
"ambiguous protocol ID, also in Base3");
964 typedef Typeid::Conflict<Base1_proto_list, Base2_proto_list> Conflict_bases12;
965 typedef Typeid::Conflict<Base1_proto_list, Base3_proto_list> Conflict_bases13;
966 typedef Typeid::Conflict<Base2_proto_list, Base3_proto_list> Conflict_bases23;
968 static_assert(!Conflict_bases12::value,
"ambiguous protocol IDs in base classes: Base1 and Base2");
969 static_assert(!Conflict_bases13::value,
"ambiguous protocol IDs in base classes: Base1 and Base3");
970 static_assert(!Conflict_bases23::value,
"ambiguous protocol IDs in base classes: Base2 and Base3");
975 {
return Base1::cap(); }
981 typename Base1::__Kobject_typeid::Demand,
982 typename Base2::__Kobject_typeid::Demand>,
983 typename Base3::__Kobject_typeid::Demand>
988 operator
Kobject const & () const noexcept
989 {
return *
static_cast<Base1
const *
>(
this); }
993 noexcept(noexcept(static_cast<Base1*>(
nullptr)->dec_refcnt(diff, utcb)))
994 {
return Base1::dec_refcnt(diff, utcb); }
999template<
typename Derived,
typename Base1,
typename Base2,
typename Base3,
1000 long PROTO,
typename S_DEMAND >
1004 &Base1::__Kobject_typeid::_m,
1005 &Base2::__Kobject_typeid::_m,
1006 &Base3::__Kobject_typeid::_m
1014template<
typename Derived,
typename Base1,
typename Base2,
typename Base3,
1015 long PROTO,
typename S_DEMAND >
1020#if __cplusplus >= 201103L
1030template<
typename ...T >
1039template<
typename T1,
typename ...T2>
1042 Kobject_demand<T2...> >
1045namespace Typeid_xx {
1047 template<
typename ...LISTS>
1050 template<
typename L>
1051 struct Merge_list<L> : L {};
1053 template<
typename L1,
typename L2>
1054 struct Merge_list<L1, L2> : Typeid::Merge_list<L1, L2> {};
1056 template<
typename L1,
typename L2,
typename ...LISTS>
1057 struct Merge_list<L1, L2, LISTS...> :
1058 Merge_list<typename Typeid::Merge_list<L1, L2>::type, LISTS...> {};
1060 template<
typename I,
typename ...LIST >
1061 struct Iface_conflict;
1063 template<
typename I >
1066 template<
typename I,
typename L,
typename ...LIST >
1067 struct Iface_conflict<I, L, LIST...> :
1068 Typeid::Bool<Typeid::Iface_conflict<typename I::type, typename L::type>::value
1069 || Iface_conflict<I, LIST...>::value>
1072 template<
typename ...LIST >
1075 template<
typename L >
1078 template<
typename L1,
typename L2,
typename ...LIST >
1079 struct Conflict<L1, L2, LIST...> :
1080 Typeid::Bool<Typeid::Conflict<typename L1::type, typename L2::type>::value
1081 || Conflict<L1, LIST...>::value
1082 || Conflict<L2, LIST...>::value>
1085 template<
typename T >
1089 static char test(...);
1090 enum { value =
sizeof(test(
static_cast<T*
>(
nullptr))) ==
sizeof(
long) };
1093 template<
typename T,
typename ... >
1094 struct First : T {
typedef T type; };
1102template<
typename Derived,
long PROTO,
typename S_DEMAND,
typename ...BASES>
1103struct __Kobject_base : BASES...
1106 typedef Derived Class;
1107 typedef Typeid::Iface<PROTO, Derived> __Iface;
1108 typedef Typeid_xx::Merge_list<
1109 Typeid::Iface_list<__Iface>,
1110 typename BASES::__Iface_list...
1113 static void __check_protocols__() noexcept
1115 typedef Typeid_xx::Iface_conflict<__Iface,
typename BASES::__Iface_list...> Conflict;
1116 static_assert(!Conflict::value,
"ambiguous protocol ID, protocol also used in base class");
1118 typedef Typeid_xx::Conflict<
typename BASES::__Iface_list...> Base_conflict;
1119 static_assert(!Base_conflict::value,
"ambiguous protocol IDs in base classes");
1124 {
return Typeid_xx::First<BASES...>::type::cap(); }
1132 template<
typename B1,
typename ...>
struct Base1 {
typedef B1 type; };
1136 operator Kobject const & ()
const noexcept
1137 {
return *
static_cast<typename Base1<BASES...
>::type
const *>(
this); }
1141 noexcept(noexcept(static_cast<typename Base1<BASES...>::type *>(
nullptr)
1142 ->dec_refcnt(diff, utcb)))
1143 {
return Base1<BASES...>::type::dec_refcnt(diff, utcb); }
1147template<
typename Derived,
long PROTO,
typename S_DEMAND,
typename ...BASES>
1149__Kobject_base<Derived, PROTO, S_DEMAND, BASES...>::__Kobject_typeid::_b[] =
1151 (&BASES::__Kobject_typeid::_m)...
1155template<
typename Derived,
long PROTO,
typename S_DEMAND,
typename ...BASES>
1156L4____GEN_TI(__Kobject_base<Derived, PROTO, S_DEMAND, BASES...>);
1160template<
typename Derived,
long PROTO,
bool HAS_DEMAND,
typename DEMAND,
typename ...ARGS >
1161struct __Kobject_x_proto;
1164template<
typename Derived,
long PROTO,
typename DEMAND,
typename ...BASES>
1165struct __Kobject_x_proto<Derived, PROTO, true, DEMAND, BASES...> :
1166 __Kobject_base<Derived, PROTO, DEMAND, BASES...> {};
1169template<
typename Derived,
long PROTO,
typename B1,
typename ...BASES>
1170struct __Kobject_x_proto<Derived, PROTO, false, B1, BASES...> :
1171 __Kobject_base<Derived, PROTO, Type_info::Demand_t<>, B1, BASES...> {};
1180template<
long P = PROTO_EMPTY >
1196template<
typename Derived,
typename ...ARGS >
1199template<
typename Derived,
typename A,
typename ...ARGS >
1201 __Kobject_x_proto<Derived, PROTO_ANY, Typeid_xx::Is_demand<A>::value, A, ARGS...>
1204template<
typename Derived,
long PROTO,
typename A,
typename ...ARGS >
1206 __Kobject_x_proto<Derived, PROTO, Typeid_xx::Is_demand<A>::value, A, ARGS...>
1213#undef L4____GEN_TI_MEMBERS
C++ interface for capabilities.
Helper class to create an L4Re interface class that is derived from two base classes (see L4::Kobject...
Derived Class
The target interface type (inheriting from Kobject_t)
L4::Cap< Class > c() const noexcept
Get the capability to ourselves.
static void __check_protocols__() noexcept
Helper to check for protocol conflicts.
Typeid::Iface< PROTO, Derived > __Iface
The interface description for the derived class.
Typeid::Merge_list< Typeid::Iface_list< __Iface >, Typeid::Merge_list< typename Base1::__Iface_list, typename Base2::__Iface_list > > __Iface_list
The list of all RPC interfaces provided directly or through inheritance.
Helper class to create an L4Re interface class that is derived from a single base class.
Typeid::Iface< PROTO, Derived > __Iface
The interface description for the derived class.
L4::Cap< Class > c() const noexcept
Get the capability to ourselves.
static void __check_protocols__() noexcept
Helper to check for protocol conflicts.
Derived Class
The target interface type (inheriting from Kobject_t)
Typeid::Merge_list< Typeid::Iface_list< __Iface >, typename Base::__Iface_list > __Iface_list
The list of all RPC interfaces provided directly or through inheritance.
Base class for all kinds of kernel objects and remote objects, referenced by capabilities.
Data type for expressing the needed receive buffers at the server-side of an interface.
unsigned char mem
number of memory receive buffers.
Demand(unsigned char caps=0, unsigned char flags=0, unsigned char mem=0, unsigned char ports=0) noexcept
Make Demand object.
unsigned char flags
flags, such as the need for timeouts (TBD).
bool no_demand() const noexcept
unsigned char caps
number of capability receive buffers.
unsigned char ports
number of IO-port receive buffers.
Template for defining typical Flags bitmaps.
signed long l4_mword_t
Signed machine word.
unsigned long l4_cap_idx_t
Capability selector type.
@ L4_EBADPROTO
Unsupported protocol.
Type_info const * kobject_typeid() noexcept
Get the L4::Type_info for the L4Re interface given in T.
@ L4_PROTO_META
Meta information protocol.
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.
#define L4_EXPORT
Attribute to mark functions, variables, and data types as being exported from a library.
L4 basic type helpers for C++.
L4 low-level kernel interface.
int Opcode
Data type for RPC opcodes.
@ PROTO_EMPTY
Empty protocol for empty APIs.
@ PROTO_ANY
Default protocol used by Kobject_t and Kobject_x.
Helper class to create an L4Re interface class that is derived from three base classes (see L4::Kobje...
Typeid::Merge_list< Typeid::Iface_list< __Iface >, Typeid::Merge_list< typename Base1::__Iface_list, Typeid::Merge_list< typename Base2::__Iface_list, typename Base3::__Iface_list > > > __Iface_list
The list of all RPC interfaces provided directly or through inheritance.
Derived Class
The target interface type (inheriting from Kobject_t)
static void __check_protocols__() noexcept
Helper to check for protocol conflicts.
Typeid::Iface< PROTO, Derived > __Iface
The interface description for the derived class.
L4::Cap< Class > c() const noexcept
Get the capability to ourselves.
Get the combined server-side resource requirements for all type T...
Meta object for handling access to type information of Kobjects.
static Type_info const * id() noexcept
Get a pointer to teh Kobject type information of T.
static int proto_dispatch(THIS *self, long proto, A1 a1, A2 &a2)
Protocol based server-side dispatch function.
T::__Kobject_typeid::Demand Demand
Data type expressing the static demand of receive buffers in a server.
static Type_info::Demand demand() noexcept
Get the receive-buffer demand for the server providing the interface T.
Generic Kobject inheritance template.
Data type for defining protocol numbers.
Template type statically describing demand of receive buffers.
Template type statically describing the combination of two Demand object.
Dynamic Type Information for L4Re Interfaces.
Internal end-of-list marker.
R rpc
The RPC type L4::Ipc::Msg::Rpc_call or L4::Ipc::Msg::Rpc_inline_call.
_Rpcs type
The list element itself.
_Rpcs< OPCODE, _Get_opcode< R, O >::value+1, X... >::type next
The next RPC in the list or Rpcs_end if this is the last.
OPCODE opcode_type
The data type for the opcode.
Use for protocol based dispatch stage.
RPCs list for passing raw incoming IPC to the server object.
List of RPCs of an interface using a single operation without an opcode.
List of RPCs of an interface using a special opcode type.
List of RPCs typically used for kernel interfaces.
Standard list of RPCs of an interface.
Bool< V > type
The meta type itself.
Message tag data structure.