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)
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> >
401 typedef void opcode_type;
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) noexcept : rights(rights) {}
482 unsigned operator & (
unsigned rhs)
const noexcept {
return rights & rhs; }
520 static unsigned char max(
unsigned char a,
unsigned char b)
noexcept
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) noexcept
539 : caps(caps), flags(flags), mem(mem), ports(ports) {}
543 {
return caps == 0 && mem == 0 && ports == 0 && flags == 0; }
548 return Demand(max(caps, rhs.caps), flags | rhs.flags,
549 max(mem, rhs.mem), max(ports, rhs.ports));
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 noexcept {
return _type; }
595 Type_info const *base(
unsigned idx)
const noexcept {
return _bases[idx]; }
596 unsigned num_bases() const noexcept {
return _num_bases; }
597 long proto() const noexcept {
return _proto; }
598 char const *name() const noexcept {
return L4_kobject_type_name(type()); }
599 bool has_proto(
long proto)
const noexcept
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;
640 static Type_info const *
id() noexcept {
return &T::__Kobject_typeid::_m; }
650 {
return T::__Kobject_typeid::Demand(); }
669 template<
typename THIS,
typename A1,
typename A2>
699#define L4____GEN_TI(t...) \
700Type_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)
787template<
typename Derived,
typename Base,
long PROTO,
typename S_DEMAND>
790 __Kobject_typeid::_b[] = { &Base::__Kobject_typeid::_m };
797template<
typename Derived,
typename Base,
long PROTO,
typename S_DEMAND>
843 typedef Typeid::Iface<PROTO, Derived>
__Iface;
845 typedef Typeid::Merge_list<
846 Typeid::Iface_list<__Iface>,
848 typename Base1::__Iface_list,
849 typename Base2::__Iface_list
856 typedef typename Base1::__Iface_list Base1_proto_list;
857 typedef typename Base2::__Iface_list Base2_proto_list;
859 typedef Typeid::Iface_conflict<__Iface, Base1_proto_list> Base1_conflict;
860 typedef Typeid::Iface_conflict<__Iface, Base2_proto_list> Base2_conflict;
861 static_assert(!Base1_conflict::value,
"ambiguous protocol ID, also in Base1");
862 static_assert(!Base2_conflict::value,
"ambiguous protocol ID, also in Base2");
864 typedef Typeid::Conflict<Base1_proto_list, Base2_proto_list> Bases_conflict;
865 static_assert(!Bases_conflict::value,
"ambiguous protocol IDs in base classes");
870 {
return Base1::cap(); }
876 typename Base1::__Kobject_typeid::Demand,
877 typename Base2::__Kobject_typeid::Demand>
882 operator
Kobject const & () const noexcept
883 {
return *
static_cast<Base1
const *
>(
this); }
887 noexcept(noexcept(((Base1*)0)->dec_refcnt(diff, utcb)))
888 {
return Base1::dec_refcnt(diff, utcb); }
893template<
typename Derived,
typename Base1,
typename Base2,
894 long PROTO,
typename S_DEMAND >
898 &Base1::__Kobject_typeid::_m,
899 &Base2::__Kobject_typeid::_m
907template<
typename Derived,
typename Base1,
typename Base2,
908 long PROTO,
typename S_DEMAND >
946 typedef Typeid::Iface<PROTO, Derived>
__Iface;
948 typedef Typeid::Merge_list<
949 Typeid::Iface_list<__Iface>,
951 typename Base1::__Iface_list,
953 typename Base2::__Iface_list,
954 typename Base3::__Iface_list
962 typedef typename Base1::__Iface_list Base1_proto_list;
963 typedef typename Base2::__Iface_list Base2_proto_list;
964 typedef typename Base3::__Iface_list Base3_proto_list;
966 typedef Typeid::Iface_conflict<__Iface, Base1_proto_list> Base1_conflict;
967 typedef Typeid::Iface_conflict<__Iface, Base2_proto_list> Base2_conflict;
968 typedef Typeid::Iface_conflict<__Iface, Base3_proto_list> Base3_conflict;
970 static_assert(!Base1_conflict::value,
"ambiguous protocol ID, also in Base1");
971 static_assert(!Base2_conflict::value,
"ambiguous protocol ID, also in Base2");
972 static_assert(!Base3_conflict::value,
"ambiguous protocol ID, also in Base3");
974 typedef Typeid::Conflict<Base1_proto_list, Base2_proto_list> Conflict_bases12;
975 typedef Typeid::Conflict<Base1_proto_list, Base3_proto_list> Conflict_bases13;
976 typedef Typeid::Conflict<Base2_proto_list, Base3_proto_list> Conflict_bases23;
978 static_assert(!Conflict_bases12::value,
"ambiguous protocol IDs in base classes: Base1 and Base2");
979 static_assert(!Conflict_bases13::value,
"ambiguous protocol IDs in base classes: Base1 and Base3");
980 static_assert(!Conflict_bases23::value,
"ambiguous protocol IDs in base classes: Base2 and Base3");
985 {
return Base1::cap(); }
991 typename Base1::__Kobject_typeid::Demand,
992 typename Base2::__Kobject_typeid::Demand>,
993 typename Base3::__Kobject_typeid::Demand>
998 operator
Kobject const & () const noexcept
999 {
return *
static_cast<Base1
const *
>(
this); }
1003 noexcept(noexcept(((Base1*)0)->dec_refcnt(diff, utcb)))
1004 {
return Base1::dec_refcnt(diff, utcb); }
1009template<
typename Derived,
typename Base1,
typename Base2,
typename Base3,
1010 long PROTO,
typename S_DEMAND >
1014 &Base1::__Kobject_typeid::_m,
1015 &Base2::__Kobject_typeid::_m,
1016 &Base3::__Kobject_typeid::_m
1024template<
typename Derived,
typename Base1,
typename Base2,
typename Base3,
1025 long PROTO,
typename S_DEMAND >
1030#if __cplusplus >= 201103L
1040template<
typename ...T >
1049template<
typename T1,
typename ...T2>
1052 Kobject_demand<T2...> >
1055namespace Typeid_xx {
1057 template<
typename ...LISTS>
1060 template<
typename L>
1061 struct Merge_list<L> : L {};
1063 template<
typename L1,
typename L2>
1064 struct Merge_list<L1, L2> : Typeid::Merge_list<L1, L2> {};
1066 template<
typename L1,
typename L2,
typename ...LISTS>
1067 struct Merge_list<L1, L2, LISTS...> :
1068 Merge_list<typename Typeid::Merge_list<L1, L2>::type, LISTS...> {};
1070 template<
typename I,
typename ...LIST >
1071 struct Iface_conflict;
1073 template<
typename I >
1076 template<
typename I,
typename L,
typename ...LIST >
1077 struct Iface_conflict<I, L, LIST...> :
1078 Typeid::Bool<Typeid::Iface_conflict<typename I::type, typename L::type>::value
1079 || Iface_conflict<I, LIST...>::value>
1082 template<
typename ...LIST >
1085 template<
typename L >
1088 template<
typename L1,
typename L2,
typename ...LIST >
1089 struct Conflict<L1, L2, LIST...> :
1090 Typeid::Bool<Typeid::Conflict<typename L1::type, typename L2::type>::value
1091 || Conflict<L1, LIST...>::value
1092 || Conflict<L2, LIST...>::value>
1095 template<
typename T >
1099 static char test(...);
1100 enum { value =
sizeof(test((T*)0)) ==
sizeof(
long) };
1103 template<
typename T,
typename ... >
1104 struct First : T {
typedef T type; };
1112template<
typename Derived,
long PROTO,
typename S_DEMAND,
typename ...BASES>
1113struct __Kobject_base : BASES...
1116 typedef Derived Class;
1117 typedef Typeid::Iface<PROTO, Derived> __Iface;
1118 typedef Typeid_xx::Merge_list<
1119 Typeid::Iface_list<__Iface>,
1120 typename BASES::__Iface_list...
1123 static void __check_protocols__() noexcept
1125 typedef Typeid_xx::Iface_conflict<__Iface,
typename BASES::__Iface_list...> Conflict;
1126 static_assert(!Conflict::value,
"ambiguous protocol ID, protocol also used in base class");
1128 typedef Typeid_xx::Conflict<
typename BASES::__Iface_list...> Base_conflict;
1129 static_assert(!Base_conflict::value,
"ambiguous protocol IDs in base classes");
1134 {
return Typeid_xx::First<BASES...>::type::cap(); }
1142 template<
typename B1,
typename ...>
struct Base1 {
typedef B1 type; };
1146 operator Kobject const & ()
const noexcept
1147 {
return *
static_cast<typename Base1<BASES...
>::type
const *>(
this); }
1151 noexcept(noexcept(((typename Base1<BASES...>::type *)0)->dec_refcnt(diff, utcb)))
1152 {
return Base1<BASES...>::type::dec_refcnt(diff, utcb); }
1156template<
typename Derived,
long PROTO,
typename S_DEMAND,
typename ...BASES>
1158__Kobject_base<Derived, PROTO, S_DEMAND, BASES...>::__Kobject_typeid::_b[] =
1160 (&BASES::__Kobject_typeid::_m)...
1164template<
typename Derived,
long PROTO,
typename S_DEMAND,
typename ...BASES>
1165L4____GEN_TI(__Kobject_base<Derived, PROTO, S_DEMAND, BASES...>);
1169template<
typename Derived,
long PROTO,
bool HAS_DEMAND,
typename DEMAND,
typename ...ARGS >
1170struct __Kobject_x_proto;
1173template<
typename Derived,
long PROTO,
typename DEMAND,
typename ...BASES>
1174struct __Kobject_x_proto<Derived, PROTO, true, DEMAND, BASES...> :
1175 __Kobject_base<Derived, PROTO, DEMAND, BASES...> {};
1178template<
typename Derived,
long PROTO,
typename B1,
typename ...BASES>
1179struct __Kobject_x_proto<Derived, PROTO, false, B1, BASES...> :
1180 __Kobject_base<Derived, PROTO, Type_info::Demand_t<>, B1, BASES...> {};
1189template<
long P = PROTO_EMPTY >
1205template<
typename Derived,
typename ...ARGS >
1208template<
typename Derived,
typename A,
typename ...ARGS >
1210 __Kobject_x_proto<Derived, PROTO_ANY, Typeid_xx::Is_demand<A>::value, A, ARGS...>
1213template<
typename Derived,
long PROTO,
typename A,
typename ...ARGS >
1215 __Kobject_x_proto<Derived, PROTO, Typeid_xx::Is_demand<A>::value, A, ARGS...>
1222#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.