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)
noexcept
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)
noexcept
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)
noexcept {
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)
noexcept
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 &)
noexcept
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)
310 return _f(self, a1, a2,
313 return _P_dispatch<typename LIST::type>::f(self, proto, a1, a2);
318 template<
typename LIST>
323 template<
typename RPC>
struct Default_op;
330 typedef void opcode_type;
336 template<
typename O1,
typename O2,
typename RPCS>
337 struct _Rpc : _Rpc<typename RPCS::next::rpc, O2, typename RPCS::next>::type {};
340 template<
typename O1,
typename O2>
341 struct _Rpc<O1, O2, Rpcs_end> {};
343 template<
typename OP,
typename RPCS>
344 struct _Rpc<OP, OP, RPCS> : RPCS
349 template<
typename OP,
typename RPCS>
350 struct Rpc : _Rpc<typename RPCS::rpc, OP, RPCS> {};
352 template<
typename T,
unsigned CODE>
355 template<
bool,
typename>
struct Invalid_opcode {};
356 template<
typename X>
struct Invalid_opcode<true, X>;
359 template<
typename U, U>
struct _chk;
360 template<
typename U>
static long _opc(_chk<int, U::Opcode> *);
361 template<
typename U>
static char _opc(...);
363 template<
unsigned SZ,
typename U>
364 struct _Opc {
enum { value = CODE }; };
367 struct _Opc<sizeof(long), U> {
enum { value = U::Opcode }; };
370 enum { value = _Opc<sizeof(_opc<T>(0)), T>::value };
371 Invalid_opcode<(value < CODE), T> invalid_opcode;
375 template<
typename OPCODE,
unsigned O,
typename ...X>
379 template<
typename OPCODE,
unsigned O,
typename R,
typename ...X>
391 enum {
Opcode = _Get_opcode<R, O>::value };
393 template<
typename Y>
struct Rpc : Typeid::Detail::Rpc<Y, _Rpcs> {};
396 template<
typename OPCODE,
unsigned O,
typename R>
397 struct _Rpcs<OPCODE, O, Default_op<R> >
402 typedef void opcode_type;
410 template<
typename Y>
struct Rpc : Typeid::Detail::Rpc<Y, _Rpcs> {};
422 template<
typename CLASS>
427 typedef void opcode_type;
438 template<
typename ...RPCS>
449 template<
typename OPCODE_TYPE>
455 template<
typename ...RPCS>
464 template<
typename OPERATION>
475 template<
typename ...ARG>
478 template<
typename CLASS>
482 Rights(
unsigned rights) noexcept : rights(rights) {}
483 unsigned operator & (
unsigned rhs)
const noexcept {
return rights & rhs; }
521 static unsigned char max(
unsigned char a,
unsigned char b)
noexcept
522 {
return a > b ? a : b; }
538 Demand(
unsigned char caps = 0,
unsigned char flags = 0,
539 unsigned char mem = 0,
unsigned char ports = 0) noexcept
540 : caps(caps), flags(flags), mem(mem), ports(ports) {}
544 {
return caps == 0 && mem == 0 && ports == 0 && flags == 0; }
549 return Demand(max(caps, rhs.caps), flags | rhs.flags,
550 max(mem, rhs.mem), max(ports, rhs.ports));
562 template<
unsigned char CAPS = 0,
unsigned char FLAGS = 0,
563 unsigned char MEM = 0,
unsigned char PORTS = 0>
583 template<
typename D1,
typename D2>
585 D1::Flags | D2::Flags,
586 __I::Max<D1::Mem, D2::Mem>::Res,
587 __I::Max<D1::Ports, D2::Ports>::Res>
590 L4_std_type_info_ptr _type;
595 L4_std_type_info_ptr type() const noexcept {
return _type; }
596 Type_info const *base(
unsigned idx)
const noexcept {
return _bases[idx]; }
597 unsigned num_bases() const noexcept {
return _num_bases; }
598 long proto() const noexcept {
return _proto; }
599 char const *name() const noexcept {
return L4_kobject_type_name(type()); }
600 bool has_proto(
long proto)
const noexcept
602 if (_proto && _proto == proto)
608 for (
unsigned i = 0; i < _num_bases; ++i)
609 if (base(i)->has_proto(proto))
633 typedef typename T::__Kobject_typeid::Demand
Demand;
634 typedef typename T::__Iface::iface_type Iface;
635 typedef typename T::__Iface_list Iface_list;
641 static Type_info const *
id() noexcept {
return &T::__Kobject_typeid::_m; }
651 {
return T::__Kobject_typeid::Demand(); }
670 template<
typename THIS,
typename A1,
typename A2>
700#define L4____GEN_TI(t...) \
701Type_info const t::__Kobject_typeid::_m = \
703 L4_KOBJECT_META_RTTI(Derived), \
704 &t::__Kobject_typeid::_b[0], \
705 sizeof(t::__Kobject_typeid::_b) / sizeof(t::__Kobject_typeid::_b[0]), \
713#define L4____GEN_TI_MEMBERS(BASE_DEMAND...) \
715 template< typename T > friend struct Kobject_typeid; \
717 struct __Kobject_typeid { \
718 typedef Type_info::Demand_union_t<S_DEMAND, BASE_DEMAND> Demand; \
719 static Type_info const *const _b[]; \
720 static Type_info const _m; \
723 static long const Protocol = PROTO; \
724 typedef L4::Typeid::Rights<Class> Rights;
766 typedef Typeid::Iface<PROTO, Derived>
__Iface;
768 typedef Typeid::Merge_list<
769 Typeid::Iface_list<__Iface>,
typename Base::__Iface_list
775 typedef Typeid::Iface_conflict<__Iface, typename Base::__Iface_list> Base_conflict;
776 static_assert(!Base_conflict::value,
"ambiguous protocol ID: protocol also used by Base");
783 L4____GEN_TI_MEMBERS(
typename Base::__Kobject_typeid::Demand)
788template<
typename Derived,
typename Base,
long PROTO,
typename S_DEMAND>
791 __Kobject_typeid::_b[] = { &Base::__Kobject_typeid::_m };
798template<
typename Derived,
typename Base,
long PROTO,
typename S_DEMAND>
844 typedef Typeid::Iface<PROTO, Derived>
__Iface;
846 typedef Typeid::Merge_list<
847 Typeid::Iface_list<__Iface>,
849 typename Base1::__Iface_list,
850 typename Base2::__Iface_list
857 typedef typename Base1::__Iface_list Base1_proto_list;
858 typedef typename Base2::__Iface_list Base2_proto_list;
860 typedef Typeid::Iface_conflict<__Iface, Base1_proto_list> Base1_conflict;
861 typedef Typeid::Iface_conflict<__Iface, Base2_proto_list> Base2_conflict;
862 static_assert(!Base1_conflict::value,
"ambiguous protocol ID, also in Base1");
863 static_assert(!Base2_conflict::value,
"ambiguous protocol ID, also in Base2");
865 typedef Typeid::Conflict<Base1_proto_list, Base2_proto_list> Bases_conflict;
866 static_assert(!Bases_conflict::value,
"ambiguous protocol IDs in base classes");
871 {
return Base1::cap(); }
877 typename Base1::__Kobject_typeid::Demand,
878 typename Base2::__Kobject_typeid::Demand>
883 operator
Kobject const & () const noexcept
884 {
return *
static_cast<Base1
const *
>(
this); }
888 noexcept(noexcept(static_cast<Base1*>(
nullptr)->dec_refcnt(diff, utcb)))
889 {
return Base1::dec_refcnt(diff, utcb); }
894template<
typename Derived,
typename Base1,
typename Base2,
895 long PROTO,
typename S_DEMAND >
899 &Base1::__Kobject_typeid::_m,
900 &Base2::__Kobject_typeid::_m
908template<
typename Derived,
typename Base1,
typename Base2,
909 long PROTO,
typename S_DEMAND >
947 typedef Typeid::Iface<PROTO, Derived>
__Iface;
949 typedef Typeid::Merge_list<
950 Typeid::Iface_list<__Iface>,
952 typename Base1::__Iface_list,
954 typename Base2::__Iface_list,
955 typename Base3::__Iface_list
963 typedef typename Base1::__Iface_list Base1_proto_list;
964 typedef typename Base2::__Iface_list Base2_proto_list;
965 typedef typename Base3::__Iface_list Base3_proto_list;
967 typedef Typeid::Iface_conflict<__Iface, Base1_proto_list> Base1_conflict;
968 typedef Typeid::Iface_conflict<__Iface, Base2_proto_list> Base2_conflict;
969 typedef Typeid::Iface_conflict<__Iface, Base3_proto_list> Base3_conflict;
971 static_assert(!Base1_conflict::value,
"ambiguous protocol ID, also in Base1");
972 static_assert(!Base2_conflict::value,
"ambiguous protocol ID, also in Base2");
973 static_assert(!Base3_conflict::value,
"ambiguous protocol ID, also in Base3");
975 typedef Typeid::Conflict<Base1_proto_list, Base2_proto_list> Conflict_bases12;
976 typedef Typeid::Conflict<Base1_proto_list, Base3_proto_list> Conflict_bases13;
977 typedef Typeid::Conflict<Base2_proto_list, Base3_proto_list> Conflict_bases23;
979 static_assert(!Conflict_bases12::value,
"ambiguous protocol IDs in base classes: Base1 and Base2");
980 static_assert(!Conflict_bases13::value,
"ambiguous protocol IDs in base classes: Base1 and Base3");
981 static_assert(!Conflict_bases23::value,
"ambiguous protocol IDs in base classes: Base2 and Base3");
986 {
return Base1::cap(); }
992 typename Base1::__Kobject_typeid::Demand,
993 typename Base2::__Kobject_typeid::Demand>,
994 typename Base3::__Kobject_typeid::Demand>
999 operator
Kobject const & () const noexcept
1000 {
return *
static_cast<Base1
const *
>(
this); }
1004 noexcept(noexcept(static_cast<Base1*>(
nullptr)->dec_refcnt(diff, utcb)))
1005 {
return Base1::dec_refcnt(diff, utcb); }
1010template<
typename Derived,
typename Base1,
typename Base2,
typename Base3,
1011 long PROTO,
typename S_DEMAND >
1015 &Base1::__Kobject_typeid::_m,
1016 &Base2::__Kobject_typeid::_m,
1017 &Base3::__Kobject_typeid::_m
1025template<
typename Derived,
typename Base1,
typename Base2,
typename Base3,
1026 long PROTO,
typename S_DEMAND >
1031#if __cplusplus >= 201103L
1041template<
typename ...T >
1050template<
typename T1,
typename ...T2>
1053 Kobject_demand<T2...> >
1056namespace Typeid_xx {
1058 template<
typename ...LISTS>
1061 template<
typename L>
1062 struct Merge_list<L> : L {};
1064 template<
typename L1,
typename L2>
1065 struct Merge_list<L1, L2> : Typeid::Merge_list<L1, L2> {};
1067 template<
typename L1,
typename L2,
typename ...LISTS>
1068 struct Merge_list<L1, L2, LISTS...> :
1069 Merge_list<typename Typeid::Merge_list<L1, L2>::type, LISTS...> {};
1071 template<
typename I,
typename ...LIST >
1072 struct Iface_conflict;
1074 template<
typename I >
1077 template<
typename I,
typename L,
typename ...LIST >
1078 struct Iface_conflict<I, L, LIST...> :
1079 Typeid::Bool<Typeid::Iface_conflict<typename I::type, typename L::type>::value
1080 || Iface_conflict<I, LIST...>::value>
1083 template<
typename ...LIST >
1086 template<
typename L >
1089 template<
typename L1,
typename L2,
typename ...LIST >
1090 struct Conflict<L1, L2, LIST...> :
1091 Typeid::Bool<Typeid::Conflict<typename L1::type, typename L2::type>::value
1092 || Conflict<L1, LIST...>::value
1093 || Conflict<L2, LIST...>::value>
1096 template<
typename T >
1100 static char test(...);
1101 enum { value =
sizeof(test(
static_cast<T*
>(
nullptr))) ==
sizeof(
long) };
1104 template<
typename T,
typename ... >
1105 struct First : T {
typedef T type; };
1113template<
typename Derived,
long PROTO,
typename S_DEMAND,
typename ...BASES>
1114struct __Kobject_base : BASES...
1117 typedef Derived Class;
1118 typedef Typeid::Iface<PROTO, Derived> __Iface;
1119 typedef Typeid_xx::Merge_list<
1120 Typeid::Iface_list<__Iface>,
1121 typename BASES::__Iface_list...
1124 static void __check_protocols__() noexcept
1126 typedef Typeid_xx::Iface_conflict<__Iface,
typename BASES::__Iface_list...> Conflict;
1127 static_assert(!Conflict::value,
"ambiguous protocol ID, protocol also used in base class");
1129 typedef Typeid_xx::Conflict<
typename BASES::__Iface_list...> Base_conflict;
1130 static_assert(!Base_conflict::value,
"ambiguous protocol IDs in base classes");
1135 {
return Typeid_xx::First<BASES...>::type::cap(); }
1143 template<
typename B1,
typename ...>
struct Base1 {
typedef B1 type; };
1147 operator Kobject const & ()
const noexcept
1148 {
return *
static_cast<typename Base1<BASES...
>::type
const *>(
this); }
1152 noexcept(noexcept(static_cast<typename Base1<BASES...>::type *>(
nullptr)
1153 ->dec_refcnt(diff, utcb)))
1154 {
return Base1<BASES...>::type::dec_refcnt(diff, utcb); }
1158template<
typename Derived,
long PROTO,
typename S_DEMAND,
typename ...BASES>
1160__Kobject_base<Derived, PROTO, S_DEMAND, BASES...>::__Kobject_typeid::_b[] =
1162 (&BASES::__Kobject_typeid::_m)...
1166template<
typename Derived,
long PROTO,
typename S_DEMAND,
typename ...BASES>
1167L4____GEN_TI(__Kobject_base<Derived, PROTO, S_DEMAND, BASES...>);
1171template<
typename Derived,
long PROTO,
bool HAS_DEMAND,
typename DEMAND,
typename ...ARGS >
1172struct __Kobject_x_proto;
1175template<
typename Derived,
long PROTO,
typename DEMAND,
typename ...BASES>
1176struct __Kobject_x_proto<Derived, PROTO, true, DEMAND, BASES...> :
1177 __Kobject_base<Derived, PROTO, DEMAND, BASES...> {};
1180template<
typename Derived,
long PROTO,
typename B1,
typename ...BASES>
1181struct __Kobject_x_proto<Derived, PROTO, false, B1, BASES...> :
1182 __Kobject_base<Derived, PROTO, Type_info::Demand_t<>, B1, BASES...> {};
1191template<
long P = PROTO_EMPTY >
1207template<
typename Derived,
typename ...ARGS >
1210template<
typename Derived,
typename A,
typename ...ARGS >
1212 __Kobject_x_proto<Derived, PROTO_ANY, Typeid_xx::Is_demand<A>::value, A, ARGS...>
1215template<
typename Derived,
long PROTO,
typename A,
typename ...ARGS >
1217 __Kobject_x_proto<Derived, PROTO, Typeid_xx::Is_demand<A>::value, A, ARGS...>
1224#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.