L4Re Operating System Framework
Interface and Usage Documentation
Loading...
Searching...
No Matches
dataspace_svr
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 * Torsten Frenzel <frenzel@os.inf.tu-dresden.de>
6 * economic rights: Technische Universität Dresden (Germany)
7 *
8 * License: see LICENSE.spdx (in this directory or the directories above)
9 */
10#pragma once
11
12#include <string.h>
13#include <stddef.h>
14#include <l4/bid_config.h>
15#include <l4/sys/types.h>
16#include <l4/cxx/minmax>
17#include <l4/re/dataspace>
18#include <l4/re/dataspace-sys.h>
19#include <l4/sys/cxx/ipc_legacy>
20
21namespace L4Re { namespace Util {
22
29class Dataspace_svr
30{
31public:
32 L4_RPC_LEGACY_DISPATCH(L4Re::Dataspace);
33
34 typedef L4::Ipc::Snd_fpage::Map_type Map_type;
35 typedef L4::Ipc::Snd_fpage::Cacheopt Cache_type;
36
37 Dataspace_svr() noexcept
38 : _ds_start(0), _ds_size(0), _map_flags(L4::Ipc::Snd_fpage::Map),
39 _cache_flags(L4::Ipc::Snd_fpage::Cached)
40 {}
41
42 virtual ~Dataspace_svr() noexcept {}
43
57 int map(Dataspace::Offset offset,
58 Dataspace::Map_addr local_addr,
59 Dataspace::Flags flags,
60 Dataspace::Map_addr min_addr,
61 Dataspace::Map_addr max_addr,
62 L4::Ipc::Snd_fpage &memory)
63 {
64 memory = L4::Ipc::Snd_fpage();
65
66 offset = l4_trunc_page(offset);
67 local_addr = l4_trunc_page(local_addr);
68
69 if (!check_limit(offset))
70 {
71#if 0
72 printf("limit failed: off=%lx sz=%lx\n", offset, size());
73#endif
74 return -L4_ERANGE;
75 }
76
77 min_addr = l4_trunc_page(min_addr);
78 max_addr = l4_round_page(max_addr);
79
80 l4_addr_t addr = _ds_start + offset;
81 unsigned char order = L4_PAGESHIFT;
82
83 while (order < 30 /* limit to 1GB flexpage */)
84 {
85 l4_addr_t map_base = l4_trunc_size(addr, order + 1);
86 if (map_base < _ds_start)
87 break;
88
89 if (map_base + (1UL << (order + 1)) -1 > (_ds_start + round_size() - 1))
90 break;
91
92 map_base = l4_trunc_size(local_addr, order + 1);
93 if (map_base < min_addr)
94 break;
95
96 if (map_base + (1UL << (order + 1)) -1 > max_addr -1)
97 break;
98
99 l4_addr_t mask = ~(~0UL << (order + 1));
100 if (local_addr == ~0UL || ((addr ^ local_addr) & mask))
101 break;
102
103 ++order;
104 }
105
106 l4_addr_t map_base = l4_trunc_size(addr, order);
107
108 Dataspace::Map_addr b = map_base;
109 unsigned send_order = order;
110 int err = map_hook(offset /*map_base - _ds_start*/, order, flags,
111 &b, &send_order);
112 if (err < 0)
113 return err;
114
115 l4_fpage_t fpage = l4_fpage(b, send_order, flags.fpage_rights());
116
117 memory = L4::Ipc::Snd_fpage(fpage, local_addr, _map_flags, _cache_flags);
118
119 return L4_EOK;
120 }
121
136 virtual int map_hook([[maybe_unused]] Dataspace::Offset offs,
137 [[maybe_unused]] unsigned order,
138 [[maybe_unused]] Dataspace::Flags flags,
139 [[maybe_unused]] Dataspace::Map_addr *base,
140 [[maybe_unused]] unsigned *send_order)
141 {
142 return 0;
143 }
144
150 virtual void take() noexcept
151 {}
152
160 virtual unsigned long release() noexcept
161 { return 0; }
162
175 virtual long copy([[maybe_unused]] l4_addr_t dst_offs,
176 [[maybe_unused]] l4_umword_t src_id,
177 [[maybe_unused]] l4_addr_t src_offs,
178 [[maybe_unused]] unsigned long size) noexcept
179 {
180 return -L4_ENODEV;
181 }
182
192 virtual long clear(unsigned long offs, unsigned long size) const noexcept
193 {
194 if (!check_limit(offs))
195 return -L4_ERANGE;
196
197 unsigned long sz = size = cxx::min(size, round_size() - offs);
198
199 while (sz)
200 {
201 unsigned long b_addr = _ds_start + offs;
202 unsigned long b_sz = cxx::min(size - offs, sz);
203
204 memset(reinterpret_cast<void *>(b_addr), 0, b_sz);
205
206 offs += b_sz;
207 sz -= b_sz;
208 }
209
210 return 0;
211 }
212
224 virtual long allocate([[maybe_unused]] l4_addr_t offset,
225 [[maybe_unused]] l4_size_t size,
226 [[maybe_unused]] unsigned access) noexcept
227 {
228 return -L4_ENODEV;
229 }
230
236 virtual unsigned long page_shift() const noexcept
237 { return L4_LOG2_PAGESIZE; }
238
244 virtual bool is_static() const noexcept
245 { return true; }
246
259 virtual long map_info([[maybe_unused]] l4_addr_t &start_addr,
260 [[maybe_unused]] l4_addr_t &end_addr) noexcept
261 { return -L4_EPERM; }
262
263
264 long op_map(L4Re::Dataspace::Rights rights,
265 L4Re::Dataspace::Offset offset,
266 L4Re::Dataspace::Map_addr spot,
267 L4Re::Dataspace::Flags flags,
269 {
270 auto rf = map_flags(rights);
271 if (!rf.w() && flags.w())
272 return -L4_EPERM;
273
274 return map(offset, spot, flags & rf, 0, ~0, fp);
275 }
276
277 long op_allocate(L4Re::Dataspace::Rights rights,
278 L4Re::Dataspace::Offset offset,
279 L4Re::Dataspace::Size size)
280 { return allocate(offset, size, rights & 3); }
281
282 long op_copy_in(L4Re::Dataspace::Rights rights,
283 L4Re::Dataspace::Offset dst_offs,
284 L4::Ipc::Snd_fpage const &src_cap,
285 L4Re::Dataspace::Offset src_offs,
286 L4Re::Dataspace::Size sz)
287 {
288 if (!src_cap.id_received())
289 return -L4_EINVAL;
290
291 if (!(rights & L4_CAP_FPAGE_W))
292 return -L4_EACCESS;
293
294 if (sz == 0)
295 return L4_EOK;
296
297 return copy(dst_offs, src_cap.data(), src_offs, sz);
298 }
299
300 long op_info(L4Re::Dataspace::Rights rights, L4Re::Dataspace::Stats &s)
301 {
302 s.size = size();
303 // only return writable if really writable
304 s.flags = Dataspace::Flags(0);
305 if (map_flags(rights).w())
307 return L4_EOK;
308 }
309
310 long op_clear(L4Re::Dataspace::Rights rights,
311 L4Re::Dataspace::Offset offset,
312 L4Re::Dataspace::Size size)
313 {
314 if (!map_flags(rights).w())
315 return -L4_EACCESS;
316
317 return clear(offset, size);
318 }
319
320 long op_map_info(L4Re::Dataspace::Rights,
321 [[maybe_unused]] l4_addr_t &start_addr,
322 [[maybe_unused]] l4_addr_t &end_addr)
323 {
324#ifdef CONFIG_MMU
325 return 0;
326#else
327 return map_info(start_addr, end_addr);
328#endif
329 }
330
331protected:
332 unsigned long size() const noexcept
333 { return _ds_size; }
334 unsigned long map_flags() const noexcept
335 { return _map_flags; }
336 unsigned long page_size() const noexcept
337 { return 1UL << page_shift(); }
338 unsigned long round_size() const noexcept
339 { return l4_round_size(size(), page_shift()); }
340 bool check_limit(l4_addr_t offset) const noexcept
341 { return offset < round_size(); }
342
343 L4Re::Dataspace::Flags
344 map_flags(L4Re::Dataspace::Rights rights = L4_CAP_FPAGE_W) const noexcept
345 {
346 auto f = (_rw_flags & L4Re::Dataspace::Flags(0x0f)) | L4Re::Dataspace::F::Caching_mask;
347 if (!(rights & L4_CAP_FPAGE_W))
349
350 return f;
351 }
352
353protected:
354 void size(unsigned long size) noexcept { _ds_size = size; }
355
356 l4_addr_t _ds_start;
357 l4_size_t _ds_size;
358 Map_type _map_flags;
359 Cache_type _cache_flags;
360 L4Re::Dataspace::Flags _rw_flags;
361};
362
363}}
Interface for memory-like objects.
Definition dataspace:53
virtual long map_info(l4_addr_t &start_addr, l4_addr_t &end_addr) noexcept
Return mapping information for no-MMU systems.
virtual unsigned long page_shift() const noexcept
Define the size of the flexpage to map.
virtual void take() noexcept
Take a reference to this dataspace.
int map(Dataspace::Offset offset, Dataspace::Map_addr local_addr, Dataspace::Flags flags, Dataspace::Map_addr min_addr, Dataspace::Map_addr max_addr, L4::Ipc::Snd_fpage &memory)
Map a region of the dataspace.
Definition dataspace_svr:57
virtual long allocate(l4_addr_t offset, l4_size_t size, unsigned access) noexcept
Allocate a region within a dataspace.
virtual int map_hook(Dataspace::Offset offs, unsigned order, Dataspace::Flags flags, Dataspace::Map_addr *base, unsigned *send_order)
A hook that is called for acquiring the data to be mapped.
virtual long clear(unsigned long offs, unsigned long size) const noexcept
Clear a region in the dataspace.
virtual unsigned long release() noexcept
Release a reference to this dataspace.
virtual long copy(l4_addr_t dst_offs, l4_umword_t src_id, l4_addr_t src_offs, unsigned long size) noexcept
Copy from src dataspace to this destination dataspace.
virtual bool is_static() const noexcept
Return whether the dataspace is static.
l4_umword_t data() const noexcept
Return the raw flexpage descriptor.
Definition ipc_types:304
Send item or return item.
Definition ipc_types:324
bool id_received() const noexcept
(Defined for return items only.) Check if an IPC gate label has been received instead of a mapping.
Definition ipc_types:512
Map_type
(Defined for send items only.) Kind of mapping.
Definition ipc_types:329
@ Map
Flag as usual map operation.
Definition ipc_types:330
Cacheopt
(Defined for memory send items only.) Caching options, see l4_fpage_cacheability_opt_t.
Definition ipc_types:337
@ Cached
Cacheability option to enable caches for the mapping.
Definition ipc_types:339
Dataspace protocol defintion.
Dataspace interface.
unsigned int l4_size_t
Unsigned size type.
Definition l4int.h:24
unsigned long l4_umword_t
Unsigned machine word.
Definition l4int.h:40
unsigned long l4_addr_t
Address type.
Definition l4int.h:34
@ L4_ERANGE
Range error.
Definition err.h:48
@ L4_EACCESS
Permission denied.
Definition err.h:40
@ L4_EINVAL
Invalid argument.
Definition err.h:46
@ L4_ENODEV
No such thing.
Definition err.h:44
@ L4_EOK
Ok.
Definition err.h:32
@ L4_EPERM
No permission.
Definition err.h:33
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:703
@ L4_CAP_FPAGE_W
Interface specific 'W' right for capability flexpages.
Definition __l4_fpage.h:157
l4_addr_t l4_trunc_page(l4_addr_t address) L4_NOTHROW
Round an address down to the next lower page boundary.
Definition consts.h:448
l4_addr_t l4_trunc_size(l4_addr_t address, unsigned char bits) L4_NOTHROW
Round an address down to the next lower flexpage with size bits.
Definition consts.h:459
l4_addr_t l4_round_page(l4_addr_t address) L4_NOTHROW
Round address up to the next page.
Definition consts.h:473
#define L4_LOG2_PAGESIZE
Number of bits used for page offset.
Definition consts.h:409
#define L4_PAGESHIFT
Size of a page, log2-based.
Definition consts.h:26
l4_addr_t l4_round_size(l4_addr_t value, unsigned char bits) L4_NOTHROW
Round value up to the next alignment with bits size.
Definition consts.h:484
Common L4 ABI Data Types.
Documentation of the L4 Runtime Environment utility functionality in C++.
Definition l4re.dox:21
L4Re C++ Interfaces.
Definition cmd_control:14
String.
@ Caching_mask
Mask for caching flags.
Definition dataspace:99
@ W
Request write-only mapping.
Definition dataspace:79
L4 flexpage type.
Definition __l4_fpage.h:76