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 <stdio.h>
14#include <stddef.h>
15#include <l4/bid_config.h>
16#include <l4/sys/types.h>
17#include <l4/cxx/minmax>
18#include <l4/re/dataspace>
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 l4_ret_t 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 l4_ret_t 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 l4_ret_t 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 l4_ret_t 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 l4_ret_t clear(unsigned long offs, unsigned long size) const noexcept
193 {
194 if (!check_limit(offs))
195 return -L4_ERANGE;
196
197 size = cxx::min(size, round_size() - offs);
198 memset(reinterpret_cast<void *>(_ds_start + offs), 0, size);
199 return 0;
200 }
201
213 virtual l4_ret_t allocate([[maybe_unused]] l4_addr_t offset,
214 [[maybe_unused]] l4_size_t size,
215 [[maybe_unused]] unsigned access) noexcept
216 {
217 return -L4_ENODEV;
218 }
219
225 virtual unsigned long page_shift() const noexcept
226 { return L4_LOG2_PAGESIZE; }
227
233 virtual bool is_static() const noexcept
234 { return true; }
235
248 virtual l4_ret_t map_info([[maybe_unused]] l4_addr_t &start_addr,
249 [[maybe_unused]] l4_addr_t &end_addr) noexcept
250 { return -L4_EPERM; }
251
252
253 l4_ret_t op_map(L4Re::Dataspace::Rights rights,
254 L4Re::Dataspace::Offset offset,
255 L4Re::Dataspace::Map_addr spot,
256 L4Re::Dataspace::Flags flags,
258 {
259 auto rf = map_flags(rights);
260 if (!rf.w() && flags.w())
261 return -L4_EPERM;
262
263 return map(offset, spot, flags & rf, 0, ~0, fp);
264 }
265
266 l4_ret_t op_allocate(L4Re::Dataspace::Rights rights,
267 L4Re::Dataspace::Offset offset,
268 L4Re::Dataspace::Size size)
269 { return allocate(offset, size, rights & 3); }
270
271 l4_ret_t op_copy_in(L4Re::Dataspace::Rights rights,
272 L4Re::Dataspace::Offset dst_offs,
273 L4::Ipc::Snd_fpage const &src_cap,
274 L4Re::Dataspace::Offset src_offs,
275 L4Re::Dataspace::Size sz)
276 {
277 if (!src_cap.id_received())
278 return -L4_EINVAL;
279
280 if (!(rights & L4_CAP_FPAGE_W))
281 return -L4_EACCESS;
282
283 if (sz == 0)
284 return L4_EOK;
285
286 return copy(dst_offs, src_cap.data(), src_offs, sz);
287 }
288
289 l4_ret_t op_info(L4Re::Dataspace::Rights rights, L4Re::Dataspace::Stats &s)
290 {
291 s.size = size();
292 // only return writable if really writable
293 s.flags = Dataspace::Flags(0);
294 if (map_flags(rights).w())
296 return L4_EOK;
297 }
298
299 l4_ret_t op_clear(L4Re::Dataspace::Rights rights,
300 L4Re::Dataspace::Offset offset,
301 L4Re::Dataspace::Size size)
302 {
303 if (!map_flags(rights).w())
304 return -L4_EACCESS;
305
306 return clear(offset, size);
307 }
308
309 l4_ret_t op_map_info(L4Re::Dataspace::Rights,
310 [[maybe_unused]] l4_addr_t &start_addr,
311 [[maybe_unused]] l4_addr_t &end_addr)
312 {
313#ifdef CONFIG_MMU
314 return 0;
315#else
316 return map_info(start_addr, end_addr);
317#endif
318 }
319
320protected:
321 unsigned long size() const noexcept
322 { return _ds_size; }
323 unsigned long map_flags() const noexcept
324 { return _map_flags; }
325 unsigned long page_size() const noexcept
326 { return 1UL << page_shift(); }
327 unsigned long round_size() const noexcept
328 { return l4_round_size(size(), page_shift()); }
329 bool check_limit(l4_addr_t offset) const noexcept
330 { return offset < round_size(); }
331
332 L4Re::Dataspace::Flags
333 map_flags(L4Re::Dataspace::Rights rights = L4_CAP_FPAGE_W) const noexcept
334 {
335 auto f = (_rw_flags & L4Re::Dataspace::Flags(0x0f)) | L4Re::Dataspace::F::Caching_mask;
336 if (!(rights & L4_CAP_FPAGE_W))
338
339 return f;
340 }
341
342protected:
343 void size(unsigned long size) noexcept { _ds_size = size; }
344
345 l4_addr_t _ds_start;
346 l4_size_t _ds_size;
347 Map_type _map_flags;
348 Cache_type _cache_flags;
349 L4Re::Dataspace::Flags _rw_flags;
350};
351
352}}
Interface for memory-like objects.
Definition dataspace:53
virtual l4_ret_t allocate(l4_addr_t offset, l4_size_t size, unsigned access) noexcept
Allocate a region within a dataspace.
virtual unsigned long page_shift() const noexcept
Define the size of the flexpage to map.
virtual l4_ret_t map_info(l4_addr_t &start_addr, l4_addr_t &end_addr) noexcept
Return mapping information for no-MMU systems.
virtual l4_ret_t 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 l4_ret_t 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 void take() noexcept
Take a reference to this dataspace.
virtual l4_ret_t clear(unsigned long offs, unsigned long size) const noexcept
Clear a region in the dataspace.
l4_ret_t 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 unsigned long release() noexcept
Release a reference to this 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:280
Send item or return item.
Definition ipc_types:300
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:488
Map_type
(Defined for send items only.) Kind of mapping.
Definition ipc_types:305
@ Map
Flag as usual map operation.
Definition ipc_types:306
Cacheopt
(Defined for memory send items only.) Caching options, see l4_fpage_cacheability_opt_t.
Definition ipc_types:313
@ Cached
Cacheability option to enable caches for the mapping.
Definition ipc_types:315
Dataspace interface.
unsigned int l4_size_t
Unsigned size type.
Definition l4int.h:22
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:49
@ L4_EACCESS
Permission denied.
Definition err.h:41
@ L4_EINVAL
Invalid argument.
Definition err.h:47
@ L4_ENODEV
No such thing.
Definition err.h:45
@ L4_EOK
Ok.
Definition err.h:33
@ L4_EPERM
No permission.
Definition err.h:34
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:740
@ 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:465
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:476
l4_addr_t l4_round_page(l4_addr_t address) L4_NOTHROW
Round address up to the next page.
Definition consts.h:490
#define L4_LOG2_PAGESIZE
Number of bits used for page offset.
Definition consts.h:426
#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:501
Common L4 ABI Data Types.
l4_int16_t l4_ret_t
Return value of an IPC call as well as an RPC call.
Definition types.h:29
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