L4Re Operating System Framework
Interface and Usage Documentation
Loading...
Searching...
No Matches
br_manager
1// vi:set ft=cpp: -*- Mode: C++ -*-
2/*
3 * (c) 2014 Alexander Warg <alexander.warg@kernkonzept.com>
4 *
5 * License: see LICENSE.spdx (in this directory or the directories above)
6 */
7
8#pragma once
9
10#include <l4/re/env>
11#include <l4/re/util/cap_alloc>
12#include <l4/sys/cxx/ipc_server_loop>
13#include <l4/cxx/ipc_timeout_queue>
14#include <l4/cxx/minmax>
15#include <l4/sys/assert.h>
16
17namespace L4Re { namespace Util {
18
28 private L4::Ipc_svr::Server_iface::Mem_window::Allocator
29{
30private:
31 enum { _ports = 0 };
32 enum { Brs_per_timeout = sizeof(l4_kernel_clock_t) / sizeof(l4_umword_t) };
33
34 void dispose(l4_fpage_t fp) noexcept override
35 {
36 auto *env = L4Re::Env::env();
37
38 env->task()->unmap(fp, L4_FP_ALL_SPACES);
39 env->rm()->free_area(l4_fpage_memaddr(fp));
40 }
41
42public:
45 {
46 _brs[0] = 0; // obj caps terminating entry
47 _brs[1] = 0; // mem terminating entry
48 }
49
50 Br_manager(Br_manager const &) = delete;
51 Br_manager &operator = (Br_manager const &) = delete;
52
53 Br_manager(Br_manager &&) = delete;
54 Br_manager &operator = (Br_manager &&) = delete;
55
57 {
58 // Slots for received capabilities are placed at the beginning of the
59 // (shadowed) buffer registers. Free those.
60 for (unsigned i = 0; i < _caps; ++i)
61 cap_alloc.free(L4::Cap<void>(_brs[i] & L4_CAP_MASK));
62
63 if (l4_is_fpage_valid(_mem_fp))
64 dispose(_mem_fp);
65 }
66
67 /*
68 * This implementation dynamically manages assignment of buffer registers for
69 * the necessary amount of receive buffers allocated by all calls to this
70 * function.
71 */
72 int alloc_buffer_demand(Demand const &d) override
73 {
75
76 // IO port receive windows currently not supported
77 if (d.ports)
78 return -L4_EINVAL;
79
80 // Take extra buffers for a possible timeout and for two zero terminators
81 // (caps + mem).
82 if ( cxx::max(d.caps, _caps) + 1 // obj BRs + terminator
83 + (cxx::max(d.mem, _mem_order) ? 2 : 0) + 1 // mem BRs + terminator
84 + Brs_per_timeout // timeout BR(s)
85 > L4_UTCB_GENERIC_BUFFERS_SIZE)
86 return -L4_ERANGE;
87
88 if (d.caps > _caps)
89 {
90 while (_caps < d.caps)
91 {
92 L4::Cap<void> cap = cap_alloc.alloc();
93 if (!cap)
94 return -L4_ENOMEM;
95
96 reinterpret_cast<Small_buf&>(_brs[_caps])
97 = Small_buf(cap.cap(), _cap_flags);
98 ++_caps;
99 }
100 _brs[_caps] = 0;
101 }
102
103 if (d.mem > _mem_order)
104 {
105 l4_addr_t start = 0;
106 int err = L4Re::Env::env()->rm()
107 ->reserve_area(&start, 1UL << d.mem,
109 d.mem);
110 if (err < 0)
111 return -L4_ENOMEM;
112
113 if (l4_is_fpage_valid(_mem_fp))
114 dispose(_mem_fp);
115
116 _mem_order = d.mem;
117 _mem_fp = l4_fpage(start, _mem_order, L4_FPAGE_RWX);
118 }
119
120 // Memory receive window is in BRs after object caps...
121 if (l4_is_fpage_valid(_mem_fp))
122 {
123 L4::Ipc::Rcv_fpage rcv_fpage(_mem_fp);
124 _brs[_caps + 1] = rcv_fpage.base_x();
125 _brs[_caps + 2] = rcv_fpage.data();
126 _brs[_caps + 3] = 0;
127 _used_brs = _caps + 4;
128 }
129 else
130 {
131 _brs[_caps + 1] = 0;
132 _used_brs = _caps + 2;
133 }
134
135 return L4_EOK;
136 }
137
138
139 L4::Cap<void> get_rcv_cap(int i) const override
140 {
141 if (i < 0 || i >= _caps)
143
144 return L4::Cap<void>(_brs[i] & L4_CAP_MASK);
145 }
146
147 int realloc_rcv_cap(int i) override
148 {
149 using L4::Ipc::Small_buf;
150
151 if (i < 0 || i >= _caps)
152 return -L4_EINVAL;
153
154 L4::Cap<void> cap = cap_alloc.alloc();
155 if (!cap)
156 return -L4_ENOMEM;
157
158 reinterpret_cast<Small_buf&>(_brs[i])
159 = Small_buf(cap.cap(), _cap_flags);
160
161 return L4_EOK;
162 }
163
165 get_rcv_mem() noexcept override
166 {
167 if (!_mem_order)
168 return cxx::Error(-L4_EINVAL);
169
170 l4_addr_t start = 0;
171 int err = L4Re::Env::env()->rm()
172 ->reserve_area(&start, 1UL << _mem_order,
174 _mem_order);
175 if (err < 0)
176 {
177 // There might be pages mapped there already. Unmap them because the
178 // caller cannot get hold of them any more.
179 L4Re::Env::env()->task()->unmap(_mem_fp, L4_FP_ALL_SPACES);
180 return cxx::Error(-L4_ENOMEM);
181 }
182
183 l4_fpage_t ret = _mem_fp;
184
185 _mem_fp = l4_fpage(start, _mem_order, L4_FPAGE_RWX);
186 L4::Ipc::Rcv_fpage rcv_fpage(_mem_fp);
187 _brs[_caps + 1] = rcv_fpage.base_x();
188 _brs[_caps + 2] = rcv_fpage.data();
189
191 }
192
200 void set_rcv_cap_flags(unsigned long flags)
201 {
202 l4_assert(_caps == 0);
203
204 _cap_flags = flags;
205 }
206
210
213 { return -L4_ENOSYS; }
214
217 {
218 l4_buf_regs_t *br = l4_utcb_br_u(utcb);
219 br->bdr = l4_bdr(_caps + 1, 0, 0, 0);
220 for (unsigned i = 0; i < _used_brs; ++i)
221 br->br[i] = _brs[i];
222 }
223
224protected:
226 unsigned first_free_br() const
227 {
228 // The last BR (64-bit) or the last two BRs (32-bit); this is constant.
229 return L4_UTCB_GENERIC_BUFFERS_SIZE - Brs_per_timeout;
230 // We could also do the following dynamic approach:
231 // return _caps + _mem + _ports + 1
232 }
233
234private:
235 unsigned char _caps = 0;
236 unsigned char _mem_order = 0;
237 unsigned char _used_brs = 2; // always at least two terminating entries
238 unsigned long _cap_flags = L4_RCV_ITEM_LOCAL_ID;
239 l4_fpage_t _mem_fp = l4_fpage_invalid();
240
241 l4_umword_t _brs[L4_UTCB_GENERIC_BUFFERS_SIZE];
242};
243
256
265 public L4::Ipc_svr::Timeout_queue_hooks<Br_manager_timeout_hooks, Br_manager>,
267{
268public:
269 static l4_kernel_clock_t now()
270 { return l4_kip_clock(l4re_kip()); }
271};
272
273}}
274
static Env const * env() noexcept
Returns the initial environment for the current task.
Definition env:96
L4::Cap< Rm > rm() const noexcept
Object-capability to the region map.
Definition env:120
L4::Cap< L4::Task > task() const noexcept
Object-capability of the user task.
Definition env:142
Buffer-register (BR) manager for L4::Server.
Definition br_manager:29
int realloc_rcv_cap(int i) override
Allocate a new capability for the given receive buffer.
Definition br_manager:147
unsigned first_free_br() const
Used for assigning BRs for a timeout.
Definition br_manager:226
cxx::Result< L4::Ipc_svr::Server_iface::Mem_window > get_rcv_mem() noexcept override
Take the current memory receive window.
Definition br_manager:165
int add_timeout(L4::Ipc_svr::Timeout *, l4_kernel_clock_t) override
No timeouts handled by us.
Definition br_manager:208
void set_rcv_cap_flags(unsigned long flags)
Set the receive flags for the buffers.
Definition br_manager:200
void setup_wait(l4_utcb_t *utcb, L4::Ipc_svr::Reply_mode)
setup_wait() used the server loop (L4::Server)
Definition br_manager:216
Br_manager()
Make a buffer-register (BR) manager.
Definition br_manager:44
L4::Cap< void > get_rcv_cap(int i) const override
Get capability slot allocated to the given receive buffer.
Definition br_manager:139
int remove_timeout(L4::Ipc_svr::Timeout *) override
No timeouts handled by us.
Definition br_manager:212
int alloc_buffer_demand(Demand const &d) override
Tells the server to allocate buffers for the given demand.
Definition br_manager:72
l4_cap_idx_t cap() const noexcept
Return capability selector.
Definition capability.h:49
@ Invalid
Invalid capability selector.
Definition capability.h:42
C++ interface for capabilities.
Definition capability.h:224
l4_umword_t base_x() const noexcept
Return the raw base descriptor.
Definition ipc_types:306
l4_umword_t data() const noexcept
Return the raw flexpage descriptor.
Definition ipc_types:304
Non-small receive item.
Definition ipc_types:545
A receive item for receiving a single object capability.
Definition ipc_types:258
Interface for server-loop related functions.
Definition ipc_epiface:38
L4::Type_info::Demand Demand
Data type expressing server-side demand for receive buffers.
Definition ipc_epiface:133
Loop hooks mixin for integrating a timeout queue into the server loop.
Callback interface for Timeout_queue.
unsigned char mem
size (2^mem bytes) of memory receive buffer.
Definition __typeinfo.h:516
unsigned char caps
number of capability receive buffers.
Definition __typeinfo.h:514
unsigned char ports
number of IO-port receive buffers.
Definition __typeinfo.h:517
Error value.
Definition result:20
A result of a function call.
Definition result:40
Environment interface.
l4_kernel_info_t const * l4re_kip(void) L4_NOTHROW
Get Kernel Info Page.
Definition env.h:199
Reply_mode
Reply mode for server loop.
unsigned long l4_umword_t
Unsigned machine word.
Definition l4int.h:40
unsigned long l4_addr_t
Address type.
Definition l4int.h:34
l4_uint64_t l4_kernel_clock_t
Kernel clock type.
Definition l4int.h:53
#define L4_CAP_MASK
Mask to get only the relevant bits of an l4_cap_idx_t.
Definition consts.h:150
@ L4_ERANGE
Range error.
Definition err.h:49
@ L4_ENOSYS
No sys.
Definition err.h:51
@ L4_EINVAL
Invalid argument.
Definition err.h:47
@ L4_EOK
Ok.
Definition err.h:33
@ L4_ENOMEM
No memory.
Definition err.h:40
L4_CONSTEXPR int l4_is_fpage_valid(l4_fpage_t fp) L4_NOTHROW
Test if the flexpage is valid.
Definition __l4_fpage.h:803
L4_CONSTEXPR l4_addr_t l4_fpage_memaddr(l4_fpage_t f) L4_NOTHROW
Return the memory address from the memory flexpage.
Definition __l4_fpage.h:677
L4_CONSTEXPR l4_fpage_t l4_fpage(l4_addr_t address, unsigned int order, unsigned char rights) L4_NOTHROW
Create a memory flexpage.
Definition __l4_fpage.h:719
L4_CONSTEXPR l4_fpage_t l4_fpage_invalid(void) L4_NOTHROW
Get an invalid flexpage.
Definition __l4_fpage.h:745
@ L4_FPAGE_RWX
Read-write-execute flexpage.
Definition __l4_fpage.h:125
l4_cpu_time_t l4_kip_clock(l4_kernel_info_t const *kip) L4_NOTHROW
Return clock value from the KIP.
Definition kip.h:242
@ L4_RCV_ITEM_LOCAL_ID
The receiver requests to receive a local ID instead of a mapping whenever possible.
Definition consts.h:315
struct l4_utcb_t l4_utcb_t
Opaque type for the UTCB.
Definition utcb.h:56
l4_umword_t l4_bdr(l4_umword_t mem, l4_umword_t io, l4_umword_t obj, l4_umword_t flags) L4_NOTHROW
Create a buffer descriptor.
Definition utcb.h:362
_Cap_alloc cap_alloc
Capability allocator.
Documentation of the L4 Runtime Environment utility functionality in C++.
Definition l4re.dox:21
@ L4_FP_ALL_SPACES
Flag to tell the unmap operation to revoke permissions from all child mappings including the mapping ...
Definition consts.h:202
L4Re C++ Interfaces.
Definition cmd_control:14
@ Reserved
Region is reserved (blocked).
Definition rm:153
@ Search_addr
Search for a suitable address range.
Definition rm:113
Predefined server-loop hooks for a server loop using the Br_manager.
Definition br_manager:255
Predefined server-loop hooks for a server with using the Br_manager and a timeout queue.
Definition br_manager:267
Mix in for LOOP_HOOKS to always use compound reply and wait.
Mix in for LOOP_HOOKS to use a 0 send and an infinite receive timeout.
Mix in for LOOP_HOOKS to ignore IPC errors.
Encapsulation of the buffer-registers block in the UTCB.
Definition utcb.h:148
l4_umword_t br[L4_UTCB_GENERIC_BUFFERS_SIZE]
Buffer registers.
Definition utcb.h:153
l4_umword_t bdr
Buffer descriptor.
Definition utcb.h:150
Low-level assert implementation.
#define l4_assert(expr)
Low-level assert.
Definition assert.h:32
L4 flexpage type.
Definition __l4_fpage.h:76
Capability allocator.