L4Re Operating System Framework
Interface and Usage Documentation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ipc_epiface
1// vi:set ft=cpp: -*- Mode: C++ -*-
2/*
3 * (c) 2014-2015 Alexander Warg <alexander.warg@kernkonzept.com>
4 *
5 * License: see LICENSE.spdx (in this directory or the directories above)
6 */
7#pragma once
8#pragma GCC system_header
9
10#include "capability.h"
11#include "ipc_server"
12#include "ipc_string"
13#include <l4/sys/types.h>
14#include <l4/sys/utcb.h>
15#include <l4/sys/__typeinfo.h>
16#include <l4/sys/meta>
17#include <l4/cxx/type_traits>
18
19namespace L4 {
20
21// forward for Irqep_t
22class Irq;
23class Rcv_endpoint;
24
25namespace Ipc_svr {
26
27class Timeout;
28
37{
38private:
40 Server_iface const &operator = (Server_iface const &);
41
42public:
45
46 Server_iface(Server_iface &&) = delete;
47 Server_iface &operator = (Server_iface &&) = delete;
48
51
52 // Destroy the server interface
53 virtual ~Server_iface() = 0;
54
64 virtual int alloc_buffer_demand(Demand const &demand) = 0;
65
74 virtual L4::Cap<void> get_rcv_cap(int index) const = 0;
75
84 virtual int realloc_rcv_cap(int index) = 0;
85
93 virtual int add_timeout(Timeout *timeout, l4_kernel_clock_t time) = 0;
94
100 virtual int remove_timeout(Timeout *timeout) = 0;
101
113 template<typename T>
114 L4::Cap<T> rcv_cap(int index) const
115 { return L4::cap_cast<T>(get_rcv_cap(index)); }
116
126 L4::Cap<void> rcv_cap(int index) const
127 { return get_rcv_cap(index); }
128};
129
130inline Server_iface::~Server_iface() {}
131
132} // namespace Ipc_svr
133
146{
147 Epiface(Epiface const &) = delete;
148 Epiface &operator = (Epiface const &) = delete;
149
154
155 class Stored_cap : public Cap<void>
156 {
157 private:
158 enum { Managed = 0x10 };
159
160 public:
161 Stored_cap() = default;
162 Stored_cap(Cap<void> const &c, bool managed = false)
163 : Cap<void>((c.cap() & L4_CAP_MASK) | (managed ? Managed : 0))
164 {
165 static_assert (!(L4_CAP_MASK & Managed), "conflicting bits used...");
166 }
167
168 bool managed() const { return cap() & Managed; }
169 };
170
172 Epiface() : _data(0) {}
173
186 virtual l4_msgtag_t dispatch(l4_msgtag_t tag, unsigned rights,
187 l4_utcb_t *utcb) = 0;
188
195 virtual Demand get_buffer_demand() const = 0; //{ return Demand(0); }
196
198 virtual ~Epiface() = 0;
199
206 Stored_cap obj_cap() const { return _cap; }
207
213 Server_iface *server_iface() const { return _data; }
214
224 int set_server(Server_iface *srv, Cap<void> cap, bool managed = false)
225 {
226 if ((srv && cap) || (!srv && !cap))
227 {
228 _data = srv;
229 _cap = Stored_cap(cap, managed);
230 return 0;
231 }
232
233 return -L4_EINVAL;
234 }
235
239 void set_obj_cap(Cap<void> const &cap) { _cap = cap; }
240
241private:
242 Server_iface *_data;
243 Stored_cap _cap;
244};
245
247
255template<typename RPC_IFACE, typename BASE = Epiface>
256struct Epiface_t0 : BASE
257{
259 typedef RPC_IFACE Interface;
260
263 { return typename Kobject_typeid<RPC_IFACE>::Demand(); }
264
270 { return L4::cap_cast<RPC_IFACE>(BASE::obj_cap()); }
271};
272
280template<typename Derived, typename BASE = Epiface,
281 bool = cxx::is_polymorphic<BASE>::value>
282struct Irqep_t : Epiface_t0<void, BASE>
283{
285 {
286 static_cast<Derived*>(this)->handle_irq();
287 return l4_msgtag(-L4_ENOREPLY, 0, 0, 0);
288 }
289
295 { return L4::cap_cast<L4::Irq>(BASE::obj_cap()); }
296};
297
298template<typename Derived, typename BASE>
299struct Irqep_t<Derived, BASE, false> : Epiface_t0<void, BASE>
300{
302 {
303 static_cast<Derived*>(this)->handle_irq();
304 return l4_msgtag(-L4_ENOREPLY, 0, 0, 0);
305 }
306
311 Cap<L4::Irq> obj_cap() const
312 { return L4::cap_cast<L4::Irq>(BASE::obj_cap()); }
313};
314
323{
324public:
325 virtual ~Registry_iface() = 0;
326
339 virtual L4::Cap<void>
340 register_obj(L4::Epiface *o, char const *service) = 0;
341
356 virtual L4::Cap<void>
358
373
388
401 virtual void
402 unregister_obj(L4::Epiface *o, bool unmap = true) = 0;
403};
404
405inline Registry_iface::~Registry_iface() {}
406
407namespace Ipc {
408namespace Detail {
409
410using namespace L4::Typeid;
411
412template<typename IFACE>
413struct Meta_svr
414{
415 long op_num_interfaces(L4::Meta::Rights)
416 { return 1; }
417
418 long op_interface(L4::Meta::Rights, l4_umword_t ifx, long &proto, L4::Ipc::String<char> &name)
419 {
420 if (ifx > 0)
421 return -L4_ERANGE;
422 proto = L4::kobject_typeid<IFACE>()->proto();
423 if (auto *n = L4::kobject_typeid<IFACE>()->name())
424 name.copy_in(n);
425
426 return 0;
427 }
428
429 long op_supports(L4::Meta::Rights, l4_mword_t proto)
430 { return L4::kobject_typeid<IFACE>()->has_proto(proto); }
431};
432
433template<typename IFACE, typename LIST>
434struct _Dispatch;
435
436// No match dispatcher found
437template<typename IFACE>
438struct _Dispatch<IFACE, Iface_list_end>
439{
440 template< typename THIS, typename A1, typename A2 >
441 static l4_msgtag_t f(THIS *, l4_msgtag_t, A1, A2 &)
442 { return l4_msgtag(-L4_EBADPROTO, 0, 0, 0); }
443};
444
445// call matching p_dispatch() function
446template<typename IFACE, typename I, typename LIST >
447struct _Dispatch<IFACE, Iface_list<I, LIST> >
448{
449 // special handling for the meta protocol, to avoid 'using' murx
450 template< typename THIS >
451 static l4_msgtag_t _f(THIS *, l4_msgtag_t tag, unsigned r,
452 l4_utcb_t *utcb, True::type)
453 {
454 using L4::Ipc::Msg::dispatch_call;
455 typedef L4::Meta::Rpcs Meta;
456 typedef Meta_svr<IFACE> Msvr;
457 return dispatch_call<Meta>(static_cast<Msvr *>(nullptr), utcb, tag, r);
458 }
459
460 // normal dispatch to the op_<func> methods of \a self.
461 template< typename THIS >
462 static l4_msgtag_t _f(THIS *self, l4_msgtag_t t, unsigned r,
463 l4_utcb_t *utcb, False::type)
464 {
465 using L4::Ipc::Msg::dispatch_call;
466 return dispatch_call<typename I::iface_type::Rpcs>(self, utcb, t, r);
467 }
468
469 // dispatch function with switch for meta protocol
470 template< typename THIS >
471 static l4_msgtag_t f(THIS *self, l4_msgtag_t tag, unsigned r,
472 l4_utcb_t *utcb)
473 {
474 if (I::Proto == tag.label())
475 return _f(self, tag, r, utcb,
476 Bool<I::Proto == static_cast<long>(L4_PROTO_META)>());
477
478 return _Dispatch<IFACE, typename LIST::type>::f(self, tag, r, utcb);
479 }
480};
481
482template<typename IFACE>
483struct Dispatch :
484 _Dispatch<IFACE, typename L4::Kobject_typeid<IFACE>::Iface_list::type>
485{};
486
487} // namespace Detail
488
489template<typename EPIFACE>
490struct Dispatch : Detail::Dispatch<typename EPIFACE::Interface>
491{};
492
493} // namespace Ipc
494
501template<typename Derived, typename IFACE, typename BASE = L4::Epiface,
502 bool = cxx::is_polymorphic<BASE>::value>
503struct Epiface_t : Epiface_t0<IFACE, BASE>
504{
506 dispatch(l4_msgtag_t tag, unsigned rights, l4_utcb_t *utcb) final
507 {
508 typedef Ipc::Dispatch<Derived> Dispatch;
509 return Dispatch::f(static_cast<Derived*>(this), tag, rights, utcb);
510 }
511};
512
513template<typename Derived, typename IFACE, typename BASE>
514struct Epiface_t<Derived, IFACE, BASE, false> : Epiface_t0<IFACE, BASE>
515{
517 dispatch(l4_msgtag_t tag, unsigned rights, l4_utcb_t *utcb)
518 {
519 typedef Ipc::Dispatch<Derived> Dispatch;
520 return Dispatch::f(static_cast<Derived*>(this), tag, rights, utcb);
521 }
522};
523
530{
531public:
532 typedef Epiface Value;
538 static Value *find(l4_umword_t label)
539 { return reinterpret_cast<Value*>(label & ~3UL); }
540
555 l4_utcb_t *utcb)
556 {
557 return find(label)->dispatch(tag, label, utcb);
558 }
559};
560
561
562} // namespace L4
Type information handling.
This registry returns the corresponding server object based on the label of an Ipc_gate.
Definition ipc_epiface:530
static l4_msgtag_t dispatch(l4_msgtag_t tag, l4_umword_t label, l4_utcb_t *utcb)
The dispatch function called by the server loop.
Definition ipc_epiface:554
static Value * find(l4_umword_t label)
Get the server object for an Ipc_gate label.
Definition ipc_epiface:538
l4_cap_idx_t cap() const noexcept
Return capability selector.
Definition capability.h:49
C++ interface for capabilities.
Definition capability.h:219
Interface for server-loop related functions.
Definition ipc_epiface:37
L4::Type_info::Demand Demand
Data type expressing server-side demand for receive buffers.
Definition ipc_epiface:44
virtual int realloc_rcv_cap(int index)=0
Allocate a new capability for the given receive buffer.
virtual int add_timeout(Timeout *timeout, l4_kernel_clock_t time)=0
Add a timeout to the server internal timeout queue.
virtual int remove_timeout(Timeout *timeout)=0
Remove the given timeout from the timer queue.
Server_iface()
Make a server interface.
Definition ipc_epiface:50
virtual L4::Cap< void > get_rcv_cap(int index) const =0
Get capability slot allocated to the given receive buffer.
L4::Cap< void > rcv_cap(int index) const
Get receive cap with the given index as generic (void) type.
Definition ipc_epiface:126
L4::Cap< T > rcv_cap(int index) const
Get given receive buffer as typed capability.
Definition ipc_epiface:114
virtual int alloc_buffer_demand(Demand const &demand)=0
Tells the server to allocate buffers for the given demand.
Callback interface for Timeout_queue.
Meta interface that shall be implemented by each L4Re object and gives access to the dynamic type inf...
Definition meta:27
Abstract interface for object registries.
Definition ipc_epiface:323
virtual void unregister_obj(L4::Epiface *o, bool unmap=true)=0
Unregister the given object o from the server.
virtual L4::Cap< L4::Irq > register_irq_obj(L4::Epiface *o)=0
Register o as server-side object for asynchronous IRQs.
virtual L4::Cap< void > register_obj(L4::Epiface *o, char const *service)=0
Register an L4::Epiface for an IPC gate available in the applications environment under the name serv...
virtual L4::Cap< L4::Rcv_endpoint > register_obj(L4::Epiface *o, L4::Cap< L4::Rcv_endpoint > ep)=0
Register o as server-side object for a pre-allocated capability.
virtual L4::Cap< void > register_obj(L4::Epiface *o)=0
Register o as server-side object for synchronous RPC.
Data type for expressing the needed receive buffers at the server-side of an interface.
Definition __typeinfo.h:507
unsigned long l4_umword_t
Unsigned machine word.
Definition l4int.h:40
signed long l4_mword_t
Signed machine word.
Definition l4int.h:37
l4_uint64_t l4_kernel_clock_t
Kernel clock type.
Definition l4int.h:53
@ L4_CAP_MASK
Mask to get only the relevant bits of an l4_cap_idx_t.
Definition consts.h:155
@ L4_ERANGE
Range error.
Definition err.h:48
@ L4_EINVAL
Invalid argument.
Definition err.h:46
@ L4_ENOREPLY
No reply.
Definition err.h:55
@ L4_EBADPROTO
Unsupported protocol.
Definition err.h:51
l4_msgtag_t l4_msgtag(long label, unsigned words, unsigned items, unsigned flags) L4_NOTHROW
Create a message tag from the specified values.
Definition types.h:404
@ L4_PROTO_META
Meta information protocol.
Definition types.h:62
struct l4_utcb_t l4_utcb_t
Opaque type for the UTCB.
Definition utcb.h:56
Common L4 ABI Data Types.
Definition of interface data-type helpers.
Definition __typeinfo.h:66
L4 low-level kernel interface.
Epiface mixin for generic Kobject-based interfaces.
Definition ipc_epiface:257
Type_info::Demand get_buffer_demand() const
Get the server-side buffer demand based in IFACE.
Definition ipc_epiface:262
Cap< RPC_IFACE > obj_cap() const
Get the (typed) capability to this object.
Definition ipc_epiface:269
RPC_IFACE Interface
Data type of the IPC interface definition.
Definition ipc_epiface:259
Epiface implementation for Kobject-based interface implementations.
Definition ipc_epiface:504
l4_msgtag_t dispatch(l4_msgtag_t tag, unsigned rights, l4_utcb_t *utcb) final
The abstract handler for client requests to the object.
Definition ipc_epiface:506
Base class for interface implementations.
Definition ipc_epiface:146
Stored_cap obj_cap() const
Get the capability to the kernel object belonging to this object.
Definition ipc_epiface:206
Ipc_svr::Server_iface::Demand Demand
Type for server-side receive buffer demand.
Definition ipc_epiface:153
virtual ~Epiface()=0
Destroy the object.
Definition ipc_epiface:246
Server_iface * server_iface() const
Get pointer to server interface at which the object is currently registered.
Definition ipc_epiface:213
virtual l4_msgtag_t dispatch(l4_msgtag_t tag, unsigned rights, l4_utcb_t *utcb)=0
The abstract handler for client requests to the object.
void set_obj_cap(Cap< void > const &cap)
Deprecated server registration function.
Definition ipc_epiface:239
virtual Demand get_buffer_demand() const =0
Get the server-side receive buffer demand for this object.
Ipc_svr::Server_iface Server_iface
Type for abstract server interface.
Definition ipc_epiface:151
int set_server(Server_iface *srv, Cap< void > cap, bool managed=false)
Set server registration info for the object.
Definition ipc_epiface:224
Epiface()
Make a server object.
Definition ipc_epiface:172
Epiface implementation for interrupt handlers.
Definition ipc_epiface:283
Cap< L4::Irq > obj_cap() const
Get the (typed) capability to this object.
Definition ipc_epiface:294
l4_msgtag_t dispatch(l4_msgtag_t, unsigned, l4_utcb_t *) final
The abstract handler for client requests to the object.
Definition ipc_epiface:284
T::__Kobject_typeid::Demand Demand
Data type expressing the static demand of receive buffers in a server.
Definition __typeinfo.h:622
Standard list of RPCs of an interface.
Definition __typeinfo.h:428
Boolean meta type.
Definition types:289
Message tag data structure.
Definition types.h:153
long label() const L4_NOTHROW
Get the protocol value.
Definition types.h:157
Meta interface for getting dynamic type information about objects behind capabilities.