L4Re Operating System Framework – Interface and Usage Documentation
Loading...
Searching...
No Matches
ipc_epiface
1// vi:set ft=cpp: -*- Mode: C++ -*-
2/*
3 * (c) 2014-2015 Alexander Warg <alexander.warg@kernkonzept.com>
4 *
5 * This file is part of TUD:OS and distributed under the terms of the
6 * GNU General Public License 2.
7 * Please see the COPYING-GPL-2 file for details.
8 *
9 * As a special exception, you may use this file as part of a free software
10 * library without restriction. Specifically, if other files instantiate
11 * templates or use macros or inline functions from this file, or you compile
12 * this file and link it with other files to produce an executable, this
13 * file does not by itself cause the resulting executable to be covered by
14 * the GNU General Public License. This exception does not however
15 * invalidate any other reasons why the executable file might be covered by
16 * the GNU General Public License.
17 */
18#pragma once
19#pragma GCC system_header
20
21#include "capability.h"
22#include "ipc_server"
23#include "ipc_string"
24#include <l4/sys/types.h>
25#include <l4/sys/utcb.h>
26#include <l4/sys/__typeinfo.h>
27#include <l4/sys/meta>
28#include <l4/cxx/type_traits>
29
30namespace L4 {
31
32// forward for Irqep_t
33class Irq;
34class Rcv_endpoint;
35
36namespace Ipc_svr {
37
38class Timeout;
39
48{
49private:
51 Server_iface const &operator = (Server_iface const &);
52
53public:
56
57 Server_iface(Server_iface &&) = delete;
58 Server_iface &operator = (Server_iface &&) = delete;
59
62
63 // Destroy the server interface
64 virtual ~Server_iface() = 0;
65
75 virtual int alloc_buffer_demand(Demand const &demand) = 0;
76
85 virtual L4::Cap<void> get_rcv_cap(int index) const = 0;
86
95 virtual int realloc_rcv_cap(int index) = 0;
96
104 virtual int add_timeout(Timeout *timeout, l4_kernel_clock_t time) = 0;
105
111 virtual int remove_timeout(Timeout *timeout) = 0;
112
124 template<typename T>
125 L4::Cap<T> rcv_cap(int index) const
126 { return L4::cap_cast<T>(get_rcv_cap(index)); }
127
137 L4::Cap<void> rcv_cap(int index) const
138 { return get_rcv_cap(index); }
139};
140
141inline Server_iface::~Server_iface() {}
142
143} // namespace Ipc_svr
144
157{
158 Epiface(Epiface const &) = delete;
159 Epiface &operator = (Epiface const &) = delete;
160
165
166 class Stored_cap : public Cap<void>
167 {
168 private:
169 enum { Managed = 0x10 };
170
171 public:
172 Stored_cap() = default;
173 Stored_cap(Cap<void> const &c, bool managed = false)
174 : Cap<void>((c.cap() & L4_CAP_MASK) | (managed ? Managed : 0))
175 {
176 static_assert (!(L4_CAP_MASK & Managed), "conflicting bits used...");
177 }
178
179 bool managed() const { return cap() & Managed; }
180 };
181
183 Epiface() : _data(0) {}
184
197 virtual l4_msgtag_t dispatch(l4_msgtag_t tag, unsigned rights,
198 l4_utcb_t *utcb) = 0;
199
206 virtual Demand get_buffer_demand() const = 0; //{ return Demand(0); }
207
209 virtual ~Epiface() = 0;
210
217 Stored_cap obj_cap() const { return _cap; }
218
224 Server_iface *server_iface() const { return _data; }
225
235 int set_server(Server_iface *srv, Cap<void> cap, bool managed = false)
236 {
237 if ((srv && cap) || (!srv && !cap))
238 {
239 _data = srv;
240 _cap = Stored_cap(cap, managed);
241 return 0;
242 }
243
244 return -L4_EINVAL;
245 }
246
250 void set_obj_cap(Cap<void> const &cap) { _cap = cap; }
251
252private:
253 Server_iface *_data;
254 Stored_cap _cap;
255};
256
258
266template<typename RPC_IFACE, typename BASE = Epiface>
267struct Epiface_t0 : BASE
268{
270 typedef RPC_IFACE Interface;
271
274 { return typename Kobject_typeid<RPC_IFACE>::Demand(); }
275
281 { return L4::cap_cast<RPC_IFACE>(BASE::obj_cap()); }
282};
283
291template<typename Derived, typename BASE = Epiface,
292 bool = cxx::is_polymorphic<BASE>::value>
293struct Irqep_t : Epiface_t0<void, BASE>
294{
296 {
297 static_cast<Derived*>(this)->handle_irq();
298 return l4_msgtag(-L4_ENOREPLY, 0, 0, 0);
299 }
300
306 { return L4::cap_cast<L4::Irq>(BASE::obj_cap()); }
307};
308
309template<typename Derived, typename BASE>
310struct Irqep_t<Derived, BASE, false> : Epiface_t0<void, BASE>
311{
313 {
314 static_cast<Derived*>(this)->handle_irq();
315 return l4_msgtag(-L4_ENOREPLY, 0, 0, 0);
316 }
317
322 Cap<L4::Irq> obj_cap() const
323 { return L4::cap_cast<L4::Irq>(BASE::obj_cap()); }
324};
325
334{
335public:
336 virtual ~Registry_iface() = 0;
337
350 virtual L4::Cap<void>
351 register_obj(L4::Epiface *o, char const *service) = 0;
352
367 virtual L4::Cap<void>
369
384
399
412 virtual void
413 unregister_obj(L4::Epiface *o, bool unmap = true) = 0;
414};
415
416inline Registry_iface::~Registry_iface() {}
417
418namespace Ipc {
419namespace Detail {
420
421using namespace L4::Typeid;
422
423template<typename IFACE>
424struct Meta_svr
425{
426 long op_num_interfaces(L4::Meta::Rights)
427 { return 1; }
428
429 long op_interface(L4::Meta::Rights, l4_umword_t ifx, long &proto, L4::Ipc::String<char> &name)
430 {
431 if (ifx > 0)
432 return -L4_ERANGE;
433 proto = L4::kobject_typeid<IFACE>()->proto();
434 if (auto *n = L4::kobject_typeid<IFACE>()->name())
435 name.copy_in(n);
436
437 return 0;
438 }
439
440 long op_supports(L4::Meta::Rights, l4_mword_t proto)
441 { return L4::kobject_typeid<IFACE>()->has_proto(proto); }
442};
443
444template<typename IFACE, typename LIST>
445struct _Dispatch;
446
447// No match dispatcher found
448template<typename IFACE>
449struct _Dispatch<IFACE, Iface_list_end>
450{
451 template< typename THIS, typename A1, typename A2 >
452 static l4_msgtag_t f(THIS *, l4_msgtag_t, A1, A2 &)
453 { return l4_msgtag(-L4_EBADPROTO, 0, 0, 0); }
454};
455
456// call matching p_dispatch() function
457template<typename IFACE, typename I, typename LIST >
458struct _Dispatch<IFACE, Iface_list<I, LIST> >
459{
460 // special handling for the meta protocol, to avoid 'using' murx
461 template< typename THIS >
462 static l4_msgtag_t _f(THIS *, l4_msgtag_t tag, unsigned r,
463 l4_utcb_t *utcb, True::type)
464 {
465 using L4::Ipc::Msg::dispatch_call;
466 typedef L4::Meta::Rpcs Meta;
467 typedef Meta_svr<IFACE> Msvr;
468 return dispatch_call<Meta>((Msvr *)0, utcb, tag, r);
469 }
470
471 // normal dispatch to the op_<func> methods of \a self.
472 template< typename THIS >
473 static l4_msgtag_t _f(THIS *self, l4_msgtag_t t, unsigned r,
474 l4_utcb_t *utcb, False::type)
475 {
476 using L4::Ipc::Msg::dispatch_call;
477 return dispatch_call<typename I::iface_type::Rpcs>(self, utcb, t, r);
478 }
479
480 // dispatch function with switch for meta protocol
481 template< typename THIS >
482 static l4_msgtag_t f(THIS *self, l4_msgtag_t tag, unsigned r,
483 l4_utcb_t *utcb)
484 {
485 if (I::Proto == tag.label())
486 return _f(self, tag, r, utcb, Bool<I::Proto == (long)L4_PROTO_META>());
487
488 return _Dispatch<IFACE, typename LIST::type>::f(self, tag, r, utcb);
489 }
490};
491
492template<typename IFACE>
493struct Dispatch :
494 _Dispatch<IFACE, typename L4::Kobject_typeid<IFACE>::Iface_list::type>
495{};
496
497} // namespace Detail
498
499template<typename EPIFACE>
500struct Dispatch : Detail::Dispatch<typename EPIFACE::Interface>
501{};
502
503} // namespace Ipc
504
511template<typename Derived, typename IFACE, typename BASE = L4::Epiface,
512 bool = cxx::is_polymorphic<BASE>::value>
513struct Epiface_t : Epiface_t0<IFACE, BASE>
514{
516 dispatch(l4_msgtag_t tag, unsigned rights, l4_utcb_t *utcb) final
517 {
518 typedef Ipc::Dispatch<Derived> Dispatch;
519 return Dispatch::f(static_cast<Derived*>(this), tag, rights, utcb);
520 }
521};
522
523template<typename Derived, typename IFACE, typename BASE>
524struct Epiface_t<Derived, IFACE, BASE, false> : Epiface_t0<IFACE, BASE>
525{
527 dispatch(l4_msgtag_t tag, unsigned rights, l4_utcb_t *utcb)
528 {
529 typedef Ipc::Dispatch<Derived> Dispatch;
530 return Dispatch::f(static_cast<Derived*>(this), tag, rights, utcb);
531 }
532};
533
540{
541public:
542 typedef Epiface Value;
548 static Value *find(l4_umword_t label)
549 { return reinterpret_cast<Value*>(label & ~3UL); }
550
565 l4_utcb_t *utcb)
566 {
567 return find(label)->dispatch(tag, label, utcb);
568 }
569};
570
571
572} // namespace L4
573
Type information handling.
This registry returns the corresponding server object based on the label of an Ipc_gate.
Definition ipc_epiface:540
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:564
static Value * find(l4_umword_t label)
Get the server object for an Ipc_gate label.
Definition ipc_epiface:548
l4_cap_idx_t cap() const noexcept
Return capability selector.
Definition capability.h:52
C++ interface for capabilities.
Definition capability.h:222
Interface for server-loop related functions.
Definition ipc_epiface:48
L4::Type_info::Demand Demand
Data type expressing server-side demand for receive buffers.
Definition ipc_epiface:55
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:61
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:137
L4::Cap< T > rcv_cap(int index) const
Get given receive buffer as typed capability.
Definition ipc_epiface:125
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:38
Abstract interface for object registries.
Definition ipc_epiface:334
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:517
unsigned long l4_umword_t
Unsigned machine word.
Definition l4int.h:51
signed long l4_mword_t
Signed machine word.
Definition l4int.h:48
l4_uint64_t l4_kernel_clock_t
Kernel clock type.
Definition l4int.h:64
@ L4_CAP_MASK
Mask to get only the relevant bits of an l4_cap_idx_t.
Definition consts.h:166
@ L4_ERANGE
Range error.
Definition err.h:58
@ L4_EINVAL
Invalid argument.
Definition err.h:56
@ L4_ENOREPLY
No reply.
Definition err.h:65
@ L4_EBADPROTO
Unsupported protocol.
Definition err.h:61
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:427
@ L4_PROTO_META
Meta information protocol.
Definition types.h:73
struct l4_utcb_t l4_utcb_t
Opaque type for the UTCB.
Definition utcb.h:67
Common L4 ABI Data Types.
Definition of interface data-type helpers.
Definition __typeinfo.h:77
L4 low-level kernel interface.
Epiface mixin for generic Kobject-based interfaces.
Definition ipc_epiface:268
Type_info::Demand get_buffer_demand() const
Get the server-side buffer demand based in IFACE.
Definition ipc_epiface:273
Cap< RPC_IFACE > obj_cap() const
Get the (typed) capability to this object.
Definition ipc_epiface:280
RPC_IFACE Interface
Data type of the IPC interface definition.
Definition ipc_epiface:270
Epiface implementation for Kobject-based interface implementations.
Definition ipc_epiface:514
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:516
Base class for interface implementations.
Definition ipc_epiface:157
Stored_cap obj_cap() const
Get the capability to the kernel object belonging to this object.
Definition ipc_epiface:217
Ipc_svr::Server_iface::Demand Demand
Type for server-side receive buffer demand.
Definition ipc_epiface:164
virtual ~Epiface()=0
Destroy the object.
Definition ipc_epiface:257
Server_iface * server_iface() const
Get pointer to server interface at which the object is currently registered.
Definition ipc_epiface:224
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:250
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:162
int set_server(Server_iface *srv, Cap< void > cap, bool managed=false)
Set server registration info for the object.
Definition ipc_epiface:235
Epiface()
Make a server object.
Definition ipc_epiface:183
Epiface implementation for interrupt handlers.
Definition ipc_epiface:294
Cap< L4::Irq > obj_cap() const
Get the (typed) capability to this object.
Definition ipc_epiface:305
l4_msgtag_t dispatch(l4_msgtag_t, unsigned, l4_utcb_t *) final
The abstract handler for client requests to the object.
Definition ipc_epiface:295
T::__Kobject_typeid::Demand Demand
Data type expressing the static demand of receive buffers in a server.
Definition __typeinfo.h:632
Standard list of RPCs of an interface.
Definition __typeinfo.h:438
Boolean meta type.
Definition types:301
Message tag data structure.
Definition types.h:163
long label() const L4_NOTHROW
Get the protocol value.
Definition types.h:167
Meta interface for getting dynamic type information about objects behind capabilities.