L4Re Operating System Framework
Interface and Usage Documentation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
object_registry
1// vi:set ft=cpp: -*- Mode: C++ -*-
2/*
3 * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
4 * Alexander Warg <warg@os.inf.tu-dresden.de>
5 * economic rights: Technische Universität Dresden (Germany)
6 *
7 * License: see LICENSE.spdx (in this directory or the directories above)
8 */
9
10#pragma once
11
12#include <l4/re/util/cap_alloc>
13#include <l4/re/util/unique_cap>
14#include <l4/re/consts>
15#include <l4/re/env>
16
17#include <l4/sys/cxx/ipc_server_loop>
18#include <l4/sys/factory>
19#include <l4/sys/task>
20#include <l4/sys/thread>
21#include <l4/sys/ipc_gate>
22
23#include <l4/cxx/exceptions>
24
25namespace L4Re { namespace Util {
26
42 public L4::Basic_registry,
44{
49 struct Null_handler : L4::Epiface_t<Null_handler, L4::Kobject>
50 {};
51
52protected:
53 L4::Cap<L4::Thread> _server;
54 L4::Cap<L4::Factory> _factory;
56
57private:
58 Null_handler _null_handler;
59
60public:
66 explicit
68 : _server(L4Re::Env::env()->main_thread()),
69 _factory(L4Re::Env::env()->factory()),
70 _sif(sif)
71 {}
72
84 : _server(server), _factory(factory), _sif(sif)
85 {}
86
87private:
88 typedef L4::Ipc_svr::Server_iface Server_iface;
89 typedef Server_iface::Demand Demand;
90
92 _register_ep(L4::Epiface *o, L4::Cap<L4::Rcv_endpoint> ep,
93 Demand const &demand)
94 {
95 int err = _sif->alloc_buffer_demand(demand);
96 if (err < 0)
97 return L4::Cap<L4::Rcv_endpoint>(err | L4_INVALID_CAP_BIT);
98
99 err = o->set_server(_sif, ep);
100 if (err < 0)
101 return L4::Cap<L4::Rcv_endpoint>(err | L4_INVALID_CAP_BIT);
102
103 l4_umword_t id = l4_umword_t(o);
104 err = l4_error(ep->bind_thread(_server, id));
105 if (err < 0)
106 return L4::Cap<L4::Rcv_endpoint>(err | L4_INVALID_CAP_BIT);
107
108 return ep;
109 }
110
111 L4::Cap<void> _register_ep(L4::Epiface *o, char const *service,
112 Demand const &demand)
113 {
115 if (!cap.is_valid())
116 return cap;
117
118 return _register_ep(o, cap, demand);
119 }
120
121 L4::Cap<void> _register_gate(L4::Epiface *o, Demand const &demand)
122 {
123 int err = _sif->alloc_buffer_demand(demand);
124 if (err < 0)
125 return L4::Cap<void>(err | L4_INVALID_CAP_BIT);
126
127 auto cap = L4Re::Util::make_unique_cap<L4::Kobject>();
128
129 if (!cap.is_valid())
130 return cap.get();
131
132 l4_umword_t id = l4_umword_t(o);
133 err = l4_error(_factory->create_gate(cap.get(), _server, id));
134 if (err < 0)
135 return L4::Cap<void>(err | L4_INVALID_CAP_BIT);
136
137 err = o->set_server(_sif, cap.get(), true);
138 if (err < 0)
139 return L4::Cap<void>(err | L4_INVALID_CAP_BIT);
140
141 return cap.release();
142 }
143
144 L4::Cap<L4::Irq> _register_irq(L4::Epiface *o,
145 Demand const &demand)
146 {
147 int err = _sif->alloc_buffer_demand(demand);
148 if (err < 0)
149 return L4::Cap<L4::Irq>(err | L4_INVALID_CAP_BIT);
150
151 auto cap = L4Re::Util::make_unique_cap<L4::Irq>();
152
153 if (!cap.is_valid())
154 return cap.get();
155
156 l4_umword_t id = l4_umword_t(o);
157 err = l4_error(_factory->create(cap.get()));
158 if (err < 0)
159 return L4::Cap<L4::Irq>(err | L4_INVALID_CAP_BIT);
160
161 err = o->set_server(_sif, cap.get(), true);
162 if (err < 0)
163 return L4::Cap<L4::Irq>(err | L4_INVALID_CAP_BIT);
164
165 err = l4_error(cap->bind_thread(_server, id));
166 if (err < 0)
167 return L4::Cap<L4::Irq>(err | L4_INVALID_CAP_BIT);
168
169 return cap.release();
170 }
171
172 static Demand _get_buffer_demand(L4::Epiface *o)
173 { return o->get_buffer_demand(); }
174
175 template<typename T>
176 static Demand _get_buffer_demand(T *,
179 { return d; }
180
181public:
194 L4::Cap<void> register_obj(L4::Epiface *o, char const *service) override
195 {
196 return _register_ep(o, service, _get_buffer_demand(o));
197 }
198
212 {
213 return _register_gate(o, _get_buffer_demand(o));
214 }
215
228 {
229 return _register_irq(o, _get_buffer_demand(o));
230 }
231
232 // pass access to deprecated register_irq_obj
234
250 {
251 return _register_ep(o, ep, _get_buffer_demand(o));
252 }
253
254
265 void unregister_obj(L4::Epiface *o, bool unmap = true) override
266 {
267 L4::Epiface::Stored_cap c;
268
269 if (!o || !o->obj_cap().is_valid())
270 return;
271
272 c = o->obj_cap();
273
274 if (unmap)
275 L4::Cap<L4::Task>(L4Re::This_task)->unmap(c.fpage(), L4_FP_ALL_SPACES);
276
277 // make sure unhandled ipc ends up with the null handler
279 todo.add(~3UL, reinterpret_cast<l4_umword_t>(o),
280 ~0UL, reinterpret_cast<l4_umword_t>
281 (static_cast<L4::Epiface *>(&_null_handler)));
282 _server->modify_senders(todo);
283
284 // we use bit 4 to indicated an internally allocated cap
285 if (c.managed())
286 cap_alloc.free(c);
287
289 }
290};
291
295template< typename LOOP_HOOKS = L4::Ipc_svr::Default_loop_hooks >
296class Registry_server : public L4::Server<LOOP_HOOKS>
297{
298private:
300 Object_registry _registry;
301
302public:
308 Registry_server() : _registry(this)
309 {}
310
321 L4::Cap<L4::Factory> factory) L4_DEPRECATED("Omit UTCB pointer argument")
322 : _registry(this, server, factory)
323 {}
324
332 L4::Cap<L4::Factory> factory)
333 : _registry(this, server, factory)
334 {}
335
337 Object_registry const *registry() const { return &_registry; }
339 Object_registry *registry() { return &_registry; }
340
348 { Base::template loop<L4::Runtime_error, Object_registry &>(_registry, utcb); }
349
358 template <typename Printer>
359 void L4_NORETURN loop_dbg(Printer printer, l4_utcb_t *utcb = l4_utcb())
360 {
361 Base::template loop_dbg<L4::Runtime_error, Object_registry &, Printer>
362 (_registry, printer, utcb);
363 }
364};
365}}
C++ interface of the initial environment that is provided to an L4 task.
Definition env:78
static Env const * env() noexcept
Returns the initial environment for the current task.
Definition env:95
L4::Cap< T > get_cap(char const *name, unsigned l) const noexcept
Get the capability selector for the object named name.
Definition env:196
A registry that manages server objects and their attached IPC gates for a single server loop for a sp...
L4::Cap< L4::Rcv_endpoint > register_obj(L4::Epiface *o, L4::Cap< L4::Rcv_endpoint > ep) override
Register a handler for an already existing interrupt.
L4::Cap< L4::Irq > register_irq_obj(L4::Epiface *o) override
Register a handler for an interrupt.
L4::Cap< void > register_obj(L4::Epiface *o, char const *service) override
Register a new server object to a pre-allocated receive endpoint.
L4::Cap< void > register_obj(L4::Epiface *o) override
Register a new server object on a newly allocated capability.
Object_registry(L4::Ipc_svr::Server_iface *sif, L4::Cap< L4::Thread > server, L4::Cap< L4::Factory > factory)
Create a registry for arbitrary threads.
Object_registry(L4::Ipc_svr::Server_iface *sif)
Create a registry for the main thread of the task using the default factory.
void unregister_obj(L4::Epiface *o, bool unmap=true) override
Remove a server object from the handler list.
A server loop object which has a Object_registry included.
Object_registry const * registry() const
Return registry of this server loop.
void L4_NORETURN loop(l4_utcb_t *utcb=l4_utcb())
Start the server loop.
Registry_server(L4::Cap< L4::Thread > server, L4::Cap< L4::Factory > factory)
Create a new server loop object for an arbitrary thread and factory.
Registry_server(l4_utcb_t *, L4::Cap< L4::Thread > server, L4::Cap< L4::Factory > factory)
Create a new server loop object for an arbitrary thread and factory.
Registry_server()
Create a new server loop object for the main thread of the task.
Object_registry * registry()
Return registry of this server loop.
void L4_NORETURN loop_dbg(Printer printer, l4_utcb_t *utcb=l4_utcb())
Start the server loop with error printing.
void free(L4::Cap< void > cap, l4_cap_idx_t task=L4_INVALID_CAP, unsigned unmap_flags=L4_FP_ALL_SPACES) noexcept override
Free a capability.
This registry returns the corresponding server object based on the label of an Ipc_gate.
Definition ipc_epiface:530
bool is_valid() const noexcept
Test whether the capability is a valid capability index (i.e., not L4_INVALID_CAP).
Definition capability.h:57
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 alloc_buffer_demand(Demand const &demand)=0
Tells the server to allocate buffers for the given demand.
Interface for kernel objects that allow to receive IPC from them.
Definition rcv_endpoint:32
Abstract interface for object registries.
Definition ipc_epiface:323
virtual L4::Cap< L4::Irq > register_irq_obj(L4::Epiface *o)=0
Register o as server-side object for asynchronous IRQs.
Basic server loop for handling client requests.
Class wrapping a list of rules which modify the sender label of IPC messages inbound to this thread.
Definition thread:439
int add(l4_umword_t match_mask, l4_umword_t match, l4_umword_t del_bits, l4_umword_t add_bits) noexcept
Add a rule.
Definition thread:471
Environment interface.
Base exceptions.
Common factory related definitions.
unsigned long l4_umword_t
Unsigned machine word.
Definition l4int.h:40
long l4_error(l4_msgtag_t tag) L4_NOTHROW
Get IPC error code if any or message tag label otherwise for an IPC call.
Definition ipc.h:646
@ L4_FP_ALL_SPACES
Flag to tell the unmap operation to revoke permissions from all child mappings including the mapping ...
Definition consts.h:187
struct l4_utcb_t l4_utcb_t
Opaque type for the UTCB.
Definition utcb.h:56
l4_utcb_t * l4_utcb(void) L4_NOTHROW L4_PURE
Get the UTCB address.
Definition utcb.h:346
_Cap_alloc & cap_alloc
Capability allocator.
#define L4_NORETURN
Noreturn function attribute.
Definition compiler.h:197
#define L4_DEPRECATED(s)
Mark symbol deprecated.
Definition compiler.h:280
The C++ IPC gate interface.
L4Re C++ Interfaces.
Definition cmd_control:14
Constants.
Epiface implementation for Kobject-based interface implementations.
Definition ipc_epiface:504
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
virtual Demand get_buffer_demand() const =0
Get the server-side receive buffer demand for this object.
int set_server(Server_iface *srv, Cap< void > cap, bool managed=false)
Set server registration info for the object.
Definition ipc_epiface:224
T::__Kobject_typeid::Demand Demand
Data type expressing the static demand of receive buffers in a server.
Definition __typeinfo.h:622
Common thread related definitions.
Common task related definitions.
Capability allocator.
Unique_cap / Unique_del_cap.