27 #pragma GCC system_header 30 #include "cxx/ipc_basics" 31 #include "cxx/capability.h" 33 #if defined(__GXX_RTTI) && !defined(L4_NO_RTTI) 35 typedef std::type_info
const *L4_std_type_info_ptr;
36 # define L4_KOBJECT_META_RTTI(type) (&typeid(type)) 37 inline char const *L4_kobject_type_name(L4_std_type_info_ptr n)
38 {
return n ? n->name() : 0; }
40 typedef void const *L4_std_type_info_ptr;
41 # define L4_KOBJECT_META_RTTI(type) (0) 42 inline char const *L4_kobject_type_name(L4_std_type_info_ptr)
51 template<
unsigned char A,
unsigned char B>
52 struct Max {
enum { Res = A > B ? A : B }; };
93 template<
long P,
typename T>
108 struct Iface_list_end
110 typedef Iface_list_end type;
111 static bool contains(
long) {
return false; }
122 template<
typename I,
typename N = Iface_list_end>
125 typedef Iface_list<I, N> type;
127 typedef typename I::iface_type iface_type;
130 enum { Proto = I::Proto };
132 static bool contains(
long proto)
133 {
return (proto == Proto) || Next::contains(proto); }
137 template<
typename I,
typename N>
138 struct Iface_list<Iface<PROTO_EMPTY, I>, N> : N {};
141 template<
long P,
typename N>
142 struct Iface_list<Iface<P, void>, N> : N {};
152 template<
typename I,
typename L >
155 template<
typename I >
156 struct _In_list<I, Iface_list_end> :
False {};
158 template<
typename I,
typename N >
159 struct _In_list<I, Iface_list<I, N> > :
True {};
161 template<
typename I,
typename I2,
typename N >
162 struct _In_list<I, Iface_list<I2, N> > : _In_list<I, typename N::type> {};
164 template<
typename I,
typename L>
165 struct In_list : _In_list<typename I::type, typename L::type> {};
174 template<
bool ADD,
typename I,
typename L>
175 struct _Iface_list_add;
177 template<
typename I,
typename L>
178 struct _Iface_list_add<false, I, L> : L {};
180 template<
typename I,
typename L>
181 struct _Iface_list_add<true, I, L> : Iface_list<I, L> {};
188 template<
typename I,
typename L >
189 struct Iface_list_add :
191 !In_list<I, typename L::type>::value, I, typename L::type>
201 template<
typename I1,
typename I2 >
202 struct __Iface_conflict :
Bool<I1::Proto != PROTO_EMPTY && I1::Proto == I2::Proto> {};
204 template<
typename I >
205 struct __Iface_conflict<I, I> :
False {};
211 template<
typename I,
typename LIST >
212 struct _Iface_conflict;
214 template<
typename I >
215 struct _Iface_conflict<I, Iface_list_end> :
False {};
217 template<
typename I,
typename I2,
typename LIST >
218 struct _Iface_conflict<I, Iface_list<I2, LIST> > :
219 Bool<__Iface_conflict<I, I2>::value || _Iface_conflict<I, typename LIST::type>::value>
226 template<
typename I,
typename LIST >
227 struct Iface_conflict : _Iface_conflict<typename I::type, typename LIST::type> {};
234 template<
typename L1,
typename L2 >
237 template<
typename L >
238 struct _Merge_list<Iface_list_end, L> : L {};
240 template<
typename I,
typename L1,
typename L2 >
241 struct _Merge_list<Iface_list<I, L1>, L2> :
242 _Merge_list<typename L1::type, typename Iface_list_add<I, L2>::type> {};
244 template<
typename L1,
typename L2>
245 struct Merge_list : _Merge_list<typename L1::type, typename L2::type> {};
252 template<
typename L1,
typename L2 >
255 template<
typename L >
256 struct _Conflict<Iface_list_end, L> :
False {};
258 template<
typename I,
typename L1,
typename L2 >
259 struct _Conflict<Iface_list<I, L1>, L2> :
260 Bool<Iface_conflict<I, typename L2::type>::value
261 || _Conflict<typename L1::type, typename L2::type>::value> {};
263 template<
typename L1,
typename L2 >
264 struct Conflict : _Conflict<typename L1::type, typename L2::type> {};
273 template<
typename LIST>
278 struct _P_dispatch<Iface_list_end>
280 template<
typename THIS,
typename A1,
typename A2 >
281 static int f(THIS *,
long, A1, A2 &)
287 template<
typename I,
typename LIST >
288 struct _P_dispatch<Iface_list<I, LIST> >
291 template<
typename THIS,
typename A1,
typename A2 >
292 static int _f(THIS
self, A1, A2 &a2, True::type)
294 return self->dispatch_meta_request(a2);
298 template<
typename THIS,
typename A1,
typename A2 >
299 static int _f(THIS
self, A1 a1, A2 &a2, False::type)
301 return self->p_dispatch(reinterpret_cast<typename I::iface_type *>(0),
306 template<
typename THIS,
typename A1,
typename A2 >
307 static int f(THIS *
self,
long proto, A1 a1, A2 &a2)
309 if (I::Proto == proto)
312 return _P_dispatch<typename LIST::type>::f(
self, proto, a1, a2);
317 template<
typename LIST>
322 template<
typename RPC>
struct Default_op;
329 typedef void opcode_type;
335 template<
typename O1,
typename O2,
typename RPCS>
336 struct _Rpc : _Rpc<typename RPCS::next::rpc, O2, typename RPCS::next>
::type {};
339 template<
typename O1,
typename O2>
340 struct _Rpc<O1, O2, Rpcs_end> {};
342 template<
typename OP,
typename RPCS>
343 struct _Rpc<OP, OP, RPCS> : RPCS
348 template<
typename OP,
typename RPCS>
349 struct Rpc : _Rpc<typename RPCS::rpc, OP, RPCS> {};
351 template<
typename T,
unsigned CODE>
354 template<
bool,
typename>
struct Invalid_opcode {};
355 template<
typename X>
struct Invalid_opcode<true, X>;
358 template<
typename U, U>
struct _chk;
359 template<
typename U>
static long _opc(_chk<int, U::Opcode> *);
360 template<
typename U>
static char _opc(...);
362 template<
unsigned SZ,
typename U>
363 struct _Opc {
enum { value = CODE }; };
366 struct _Opc<sizeof(long), U> {
enum { value =
U::Opcode }; };
369 enum { value = _Opc<sizeof(_opc<T>(0)), T>::value };
370 Invalid_opcode<(value < CODE), T> invalid_opcode;
374 template<
typename OPCODE,
unsigned O,
typename ...X>
378 template<
typename OPCODE,
unsigned O,
typename R,
typename ...X>
390 enum { Opcode = _Get_opcode<R, O>::value };
392 template<
typename Y>
struct Rpc : Typeid::Detail::Rpc<Y, _Rpcs> {};
395 template<
typename OPCODE,
unsigned O,
typename R>
396 struct _Rpcs<OPCODE, O, Default_op<R> >
405 typedef Rpcs_end
next;
407 enum { Opcode = -99 };
409 template<
typename Y>
struct Rpc : Typeid::Detail::Rpc<Y, _Rpcs> {};
421 template<
typename CLASS>
426 typedef void opcode_type;
437 template<
typename ...RPCS>
448 template<
typename OPCODE_TYPE>
454 template<
typename ...RPCS>
463 template<
typename OPERATION>
474 template<
typename ...ARG>
477 template<
typename CLASS>
481 Rights(
unsigned rights) : rights(rights) {}
482 unsigned operator & (
unsigned rhs)
const {
return rights & rhs; }
520 static unsigned char max(
unsigned char a,
unsigned char b)
521 {
return a > b ? a : b; }
537 Demand(
unsigned char caps = 0,
unsigned char flags = 0,
538 unsigned char mem = 0,
unsigned char ports = 0)
539 : caps(caps), flags(flags), mem(mem), ports(ports) {}
543 {
return caps == 0 && mem == 0 && ports == 0 && flags == 0; }
561 template<
unsigned char CAPS = 0,
unsigned char FLAGS = 0,
562 unsigned char MEM = 0,
unsigned char PORTS = 0>
582 template<
typename D1,
typename D2>
584 D1::Flags | D2::Flags,
585 __I::Max<D1::Mem, D2::Mem>::Res,
586 __I::Max<D1::Ports, D2::Ports>::Res>
589 L4_std_type_info_ptr _type;
594 L4_std_type_info_ptr type()
const {
return _type; }
595 Type_info const *base(
unsigned idx)
const {
return _bases[idx]; }
596 unsigned num_bases()
const {
return _num_bases; }
597 long proto()
const {
return _proto; }
598 char const *name()
const {
return L4_kobject_type_name(type()); }
599 bool has_proto(
long proto)
const 601 if (_proto && _proto == proto)
607 for (
unsigned i = 0; i < _num_bases; ++i)
608 if (base(i)->has_proto(proto))
632 typedef typename T::__Kobject_typeid::Demand
Demand;
633 typedef typename T::__Iface::iface_type Iface;
634 typedef typename T::__Iface_list Iface_list;
650 {
return T::__Kobject_typeid::Demand(); }
669 template<
typename THIS,
typename A1,
typename A2>
699 #define L4____GEN_TI(t...) \ 700 Type_info const t::__Kobject_typeid::_m = \ 702 L4_KOBJECT_META_RTTI(Derived), \ 703 &t::__Kobject_typeid::_b[0], \ 704 sizeof(t::__Kobject_typeid::_b) / sizeof(t::__Kobject_typeid::_b[0]), \ 712 #define L4____GEN_TI_MEMBERS(BASE_DEMAND...) \ 714 template< typename T > friend struct Kobject_typeid; \ 716 struct __Kobject_typeid { \ 717 typedef Type_info::Demand_union_t<S_DEMAND, BASE_DEMAND> Demand; \ 718 static Type_info const *const _b[]; \ 719 static Type_info const _m; \ 722 static long const Protocol = PROTO; \ 723 typedef L4::Typeid::Rights<Class> Rights; 765 typedef Typeid::Iface<PROTO, Derived>
__Iface;
767 typedef Typeid::Merge_list<
768 Typeid::Iface_list<__Iface>,
typename Base::__Iface_list
774 typedef Typeid::Iface_conflict<__Iface, typename Base::__Iface_list> Base_conflict;
775 static_assert(!Base_conflict::value,
"ambiguous protocol ID: protocol also used by Base");
782 L4____GEN_TI_MEMBERS(
typename Base::__Kobject_typeid::Demand)
786 template<
typename Derived,
typename Base,
long PROTO,
typename S_DEMAND>
789 __Kobject_typeid::_b[] = { &Base::__Kobject_typeid::_m };
795 template<
typename Derived,
typename Base,
long PROTO,
typename S_DEMAND>
841 typedef Typeid::Iface<PROTO, Derived>
__Iface;
843 typedef Typeid::Merge_list<
844 Typeid::Iface_list<__Iface>,
846 typename Base1::__Iface_list,
847 typename Base2::__Iface_list
854 typedef typename Base1::__Iface_list Base1_proto_list;
855 typedef typename Base2::__Iface_list Base2_proto_list;
857 typedef Typeid::Iface_conflict<__Iface, Base1_proto_list> Base1_conflict;
858 typedef Typeid::Iface_conflict<__Iface, Base2_proto_list> Base2_conflict;
859 static_assert(!Base1_conflict::value,
"ambiguous protocol ID, also in Base1");
860 static_assert(!Base2_conflict::value,
"ambiguous protocol ID, also in Base2");
862 typedef Typeid::Conflict<Base1_proto_list, Base2_proto_list> Bases_conflict;
863 static_assert(!Bases_conflict::value,
"ambiguous protocol IDs in base classes");
868 {
return Base1::cap(); }
874 typename Base1::__Kobject_typeid::Demand,
875 typename Base2::__Kobject_typeid::Demand>
880 operator Kobject const & ()
const 881 {
return *
static_cast<Base1
const *
>(
this); }
885 {
return Base1::dec_refcnt(diff, utcb); }
889 template<
typename Derived,
typename Base1,
typename Base2,
890 long PROTO,
typename S_DEMAND >
894 &Base1::__Kobject_typeid::_m,
895 &Base2::__Kobject_typeid::_m
902 template<
typename Derived,
typename Base1,
typename Base2,
903 long PROTO,
typename S_DEMAND >
941 typedef Typeid::Iface<PROTO, Derived>
__Iface;
943 typedef Typeid::Merge_list<
944 Typeid::Iface_list<__Iface>,
946 typename Base1::__Iface_list,
948 typename Base2::__Iface_list,
949 typename Base3::__Iface_list
957 typedef typename Base1::__Iface_list Base1_proto_list;
958 typedef typename Base2::__Iface_list Base2_proto_list;
959 typedef typename Base3::__Iface_list Base3_proto_list;
961 typedef Typeid::Iface_conflict<__Iface, Base1_proto_list> Base1_conflict;
962 typedef Typeid::Iface_conflict<__Iface, Base2_proto_list> Base2_conflict;
963 typedef Typeid::Iface_conflict<__Iface, Base3_proto_list> Base3_conflict;
965 static_assert(!Base1_conflict::value,
"ambiguous protocol ID, also in Base1");
966 static_assert(!Base2_conflict::value,
"ambiguous protocol ID, also in Base2");
967 static_assert(!Base3_conflict::value,
"ambiguous protocol ID, also in Base3");
969 typedef Typeid::Conflict<Base1_proto_list, Base2_proto_list> Conflict_bases12;
970 typedef Typeid::Conflict<Base1_proto_list, Base3_proto_list> Conflict_bases13;
971 typedef Typeid::Conflict<Base2_proto_list, Base3_proto_list> Conflict_bases23;
973 static_assert(!Conflict_bases12::value,
"ambiguous protocol IDs in base classes: Base1 and Base2");
974 static_assert(!Conflict_bases13::value,
"ambiguous protocol IDs in base classes: Base1 and Base3");
975 static_assert(!Conflict_bases23::value,
"ambiguous protocol IDs in base classes: Base2 and Base3");
980 {
return Base1::cap(); }
986 typename Base1::__Kobject_typeid::Demand,
987 typename Base2::__Kobject_typeid::Demand>,
988 typename Base3::__Kobject_typeid::Demand>
993 operator Kobject const & ()
const 994 {
return *
static_cast<Base1
const *
>(
this); }
998 {
return Base1::dec_refcnt(diff, utcb); }
1002 template<
typename Derived,
typename Base1,
typename Base2,
typename Base3,
1003 long PROTO,
typename S_DEMAND >
1007 &Base1::__Kobject_typeid::_m,
1008 &Base2::__Kobject_typeid::_m,
1009 &Base3::__Kobject_typeid::_m
1016 template<
typename Derived,
typename Base1,
typename Base2,
typename Base3,
1017 long PROTO,
typename S_DEMAND >
1022 #if __cplusplus >= 201103L 1032 template<
typename ...T >
1038 template<
typename T>
1041 template<
typename T1,
typename ...T2>
1044 Kobject_demand<T2...> >
1047 namespace Typeid_xx {
1049 template<
typename ...LISTS>
1052 template<
typename L>
1053 struct Merge_list<L> : L {};
1055 template<
typename L1,
typename L2>
1056 struct Merge_list<L1, L2> : Typeid::Merge_list<L1, L2> {};
1058 template<
typename L1,
typename L2,
typename ...LISTS>
1059 struct Merge_list<L1, L2, LISTS...> :
1060 Merge_list<typename Typeid::Merge_list<L1, L2>::type, LISTS...> {};
1062 template<
typename I,
typename ...LIST >
1063 struct Iface_conflict;
1065 template<
typename I >
1068 template<
typename I,
typename L,
typename ...LIST >
1069 struct Iface_conflict<I, L, LIST...> :
1070 Typeid::Bool<Typeid::Iface_conflict<typename I::type, typename L::type>::value
1071 || Iface_conflict<I, LIST...>::value>
1074 template<
typename ...LIST >
1077 template<
typename L >
1080 template<
typename L1,
typename L2,
typename ...LIST >
1081 struct Conflict<L1, L2, LIST...> :
1082 Typeid::Bool<Typeid::Conflict<typename L1::type, typename L2::type>::value
1083 || Conflict<L1, LIST...>::value
1084 || Conflict<L2, LIST...>::value>
1087 template<
typename T >
1091 static char test(...);
1092 enum { value =
sizeof(test((T*)0)) ==
sizeof(
long) };
1095 template<
typename T,
typename ... >
1096 struct First : T {
typedef T type; };
1104 template<
typename Derived,
long PROTO,
typename S_DEMAND,
typename ...BASES>
1105 struct __Kobject_base : BASES...
1108 typedef Derived Class;
1109 typedef Typeid::Iface<PROTO, Derived> __Iface;
1110 typedef Typeid_xx::Merge_list<
1111 Typeid::Iface_list<__Iface>,
1112 typename BASES::__Iface_list...
1115 static void __check_protocols__()
1117 typedef Typeid_xx::Iface_conflict<__Iface,
typename BASES::__Iface_list...> Conflict;
1118 static_assert(!Conflict::value,
"ambiguous protocol ID, protocol also used in base class");
1120 typedef Typeid_xx::Conflict<
typename BASES::__Iface_list...> Base_conflict;
1121 static_assert(!Base_conflict::value,
"ambiguous protocol IDs in base classes");
1126 {
return Typeid_xx::First<BASES...>::type::cap(); }
1134 template<
typename B1,
typename ...>
struct Base1 {
typedef B1 type; };
1138 operator Kobject const & ()
const 1139 {
return *
static_cast<typename Base1<BASES...
>::type
const *>(
this); }
1143 {
return Base1<BASES...>::type::dec_refcnt(diff, utcb); }
1146 template<
typename Derived,
long PROTO,
typename S_DEMAND,
typename ...BASES>
1148 __Kobject_base<Derived, PROTO, S_DEMAND, BASES...>::__Kobject_typeid::_b[] =
1150 (&BASES::__Kobject_typeid::_m)...
1153 template<
typename Derived,
long PROTO,
typename S_DEMAND,
typename ...BASES>
1154 L4____GEN_TI(__Kobject_base<Derived, PROTO, S_DEMAND, BASES...>);
1158 template<
typename Derived,
long PROTO,
bool HAS_DEMAND,
typename DEMAND,
typename ...ARGS >
1159 struct __Kobject_x_proto;
1162 template<
typename Derived,
long PROTO,
typename DEMAND,
typename ...BASES>
1163 struct __Kobject_x_proto<Derived, PROTO, true, DEMAND, BASES...> :
1164 __Kobject_base<Derived, PROTO, DEMAND, BASES...> {};
1167 template<
typename Derived,
long PROTO,
typename B1,
typename ...BASES>
1168 struct __Kobject_x_proto<Derived, PROTO, false, B1, BASES...> :
1169 __Kobject_base<Derived, PROTO, Type_info::Demand_t<>, B1, BASES...> {};
1178 template<
long P = PROTO_EMPTY >
1194 template<
typename Derived,
typename ...ARGS >
1197 template<
typename Derived,
typename A,
typename ...ARGS >
1199 __Kobject_x_proto<Derived, PROTO_ANY, Typeid_xx::Is_demand<A>::value, A, ARGS...>
1202 template<
typename Derived,
long PROTO,
typename A,
typename ...ARGS >
1204 __Kobject_x_proto<Derived, PROTO, Typeid_xx::Is_demand<A>::value, A, ARGS...>
1211 #undef L4____GEN_TI_MEMBERS Default protocol used by Kobject_t and Kobject_x.
static Type_info const * id()
Get a pointer to teh Kobject type information of T.
static Type_info::Demand demand()
Get the receive-buffer demand for the server providing the interface T.
Data type for expressing the needed receive buffers at the server-side of an interface.
unsigned char ports
number of IO-port receive buffers.
Type_info const * kobject_typeid()
Get the L4::Type_info for the L4Re interface given in T.
Helper class to create an L4Re interface class that is derived from three base classes (see L4::Kobje...
Template for defining typical Flags bitmaps.
Derived Class
The target interface type (inheriting from Kobject_t)
Standard list of RPCs of an interface.
Get the combined server-side resource requirements for all type T...
Template type statically describing demand of receive buffers.
static void __check_protocols__()
signed long l4_mword_t
Signed machine word.
L4 low-level kernel interface.
static void __check_protocols__()
Template type statically describing the combination of two Demand object.
_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.
unsigned long l4_cap_idx_t
L4 Capability selector Type.
Typeid::Iface< PROTO, Derived > __Iface
The interface description for the derived class.
L4::Cap< Class > c() const
Get the capability to ourselves.
struct l4_utcb_t l4_utcb_t
Opaque type for the UTCB.
RPCs list for passing raw incoming IPC to the server object.
Use for protocol based dispatch stage.
T1 max(T1 a, T1 b)
Get the maximum of a and b.
Derived Class
The target interface type (inheriting from Kobject_t)
List of RPCs of an interface using a single operation without an opcode.
R rpc
The RPC type L4::Ipc::Msg::Rpc_call or L4::Ipc::Msg::Rpc_inline_call.
Generic Kobject inheritance template.
int Opcode
Data type for RPC opcodes.
unsigned char flags
flags, such as the need for timeouts (TBD).
unsigned char caps
number of capability receive buffers.
static void __check_protocols__()
Helper to check for protocol conflicts.
L4::Cap< Class > c() const
Get the capability to ourselves.
List of RPCs typically used for kernel interfaces.
T::__Kobject_typeid::Demand Demand
Data type expressing the static demand of receive buffers in a server.
Base class for all kinds of kernel objects and remote objects, referenced by capabilities.
_Rpcs type
The list element itself.
List of RPCs of an interface using a special opcode type.
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.
Typeid::Iface< PROTO, Derived > __Iface
The interface description for the derived class.
Demand(unsigned char caps=0, unsigned char flags=0, unsigned char mem=0, unsigned char ports=0)
Make Demand object.
Helper class to create an L4Re interface class that is derived from two base classes (see L4::Kobject...
unsigned char mem
number of memory receive buffers.
Dynamic Type Information for L4Re Interfaces.
Typeid::Merge_list< Typeid::Iface_list< __Iface >, typename Base::__Iface_list > __Iface_list
The list of all RPC interfaces provided directly or through inheritance.
Data type for defining protocol numbers.
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.
l4_utcb_t * l4_utcb(void) L4_NOTHROW L4_PURE
Get the UTCB address.
L4 basic type helpers for C++.
L4::Cap< Class > c() const
Get the capability to ourselves.
Internal end-of-list marker.
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.
Meta information protocol.
C++ interface for capabilities.
OPCODE opcode_type
The data type for the opcode.
Message tag data structure.
Derived Class
The target interface type (inheriting from Kobject_t)
Meta object for handling access to type information of Kobjects.
Empty protocol for empty APIs.
static int proto_dispatch(THIS *self, long proto, A1 a1, A2 &a2)
Protocol based server-side dispatch function.