23namespace L4Re {
namespace Util {
28#ifdef CONFIG_L4RE_REGION_INFO
30 unsigned char _dbg_name_len = 0;
31 static_assert(
sizeof(_dbg_name) < 256);
32 Rm::Offset _dbg_backing_offset = 0;
36 Region() noexcept : _start(~0UL), _end(~0UL) {}
37 Region(
l4_addr_t addr) noexcept : _start(addr), _end(addr) {}
39 : _start(start), _end(end) {}
41 char const *name,
unsigned name_len,
42 Rm::Offset backing_offset) noexcept
43 : _start(start), _end(end)
45#ifdef CONFIG_L4RE_REGION_INFO
46 _dbg_name_len = name_len >
sizeof(_dbg_name)
47 ?
sizeof(_dbg_name) : name_len;
48 for (
unsigned i = 0; i < _dbg_name_len; ++i)
49 _dbg_name[i] = name[i];
51 _dbg_backing_offset = backing_offset;
58 l4_addr_t start() const noexcept {
return _start; }
59 l4_addr_t end() const noexcept {
return _end; }
60 unsigned long size() const noexcept {
return end() - start() + 1; }
61 bool invalid() const noexcept {
return _start == ~0UL && _end == ~0UL; }
62 bool operator < (Region
const &o)
const noexcept
63 {
return end() < o.start(); }
64 bool contains(Region
const &o)
const noexcept
65 {
return o.start() >= start() && o.end() <= end(); }
66 bool operator == (Region
const &o)
const noexcept
67 {
return o.start() == start() && o.end() == end(); }
70#ifdef CONFIG_L4RE_REGION_INFO
71 char const *name()
const {
return _dbg_name; }
72 unsigned char name_len()
const {
return _dbg_name_len; }
73 Rm::Offset backing_offset()
const {
return _dbg_backing_offset; }
75 char const *name()
const {
return "N/A"; }
76 unsigned char name_len()
const {
return 3; }
77 Rm::Offset backing_offset()
const {
return 0; }
81template<
typename DS,
typename OPS >
85 L4Re::Rm::Offset _offs;
93 typedef typename OPS::Map_result Map_result;
95 Region_handler() noexcept : _offs(0), _mem(), _flags() {}
96 Region_handler(Dataspace
const &mem,
l4_cap_idx_t client_cap,
97 L4Re::Rm::Offset offset = 0,
99 : _offs(offset), _mem(mem), _client_cap(client_cap), _flags(flags)
102 Dataspace
const &memory() const noexcept
112 L4Re::Rm::Offset offset() const noexcept
117 constexpr bool is_ro() const noexcept
132 Region_handler operator + (
l4_int64_t offset)
const noexcept
134 Region_handler n = *
this; n._offs += offset;
return n;
137 void free(
l4_addr_t start,
unsigned long size)
const noexcept
139 Ops::free(
this, start, size);
142 int map(
l4_addr_t addr, Region
const &r,
bool writable,
143 Map_result *result)
const
145 return Ops::map(
this, addr, r, writable, result);
150 return Ops::map_info(
this, start_addr, end_addr);
156template<
typename Hdlr,
template<
typename T>
class Alloc >
179 typedef Hdlr Region_handler;
181 typedef typename Tree::Iterator Iterator;
182 typedef typename Tree::Const_iterator Const_iterator;
183 typedef typename Tree::Rev_iterator Rev_iterator;
184 typedef typename Tree::Const_rev_iterator Const_rev_iterator;
186 Iterator begin() noexcept {
return _rm.begin(); }
187 Const_iterator begin() const noexcept {
return _rm.begin(); }
188 Iterator end() noexcept {
return _rm.end(); }
189 Const_iterator end() const noexcept {
return _rm.end(); }
191 Iterator area_begin() noexcept {
return _am.begin(); }
192 Const_iterator area_begin() const noexcept {
return _am.begin(); }
193 Iterator area_end() noexcept {
return _am.end(); }
194 Const_iterator area_end() const noexcept {
return _am.end(); }
195 Node area_find(Key_type
const &c)
const noexcept {
return _am.find_node(c); }
197 l4_addr_t min_addr() const noexcept {
return _start; }
198 l4_addr_t max_addr() const noexcept {
return _end; }
203 Node find(Key_type
const &key)
const noexcept
205 Node n = _rm.find_node(key);
212 if (!n->first.contains(key))
218 Node lower_bound(Key_type
const &key)
const noexcept
220 Node n = _rm.lower_bound_node(key);
224 Node lower_bound_area(Key_type
const &key)
const noexcept
226 Node n = _am.lower_bound_node(key);
231 L4Re::Rm::Flags flags = L4Re::Rm::Flags(0),
242 c = Region(addr, addr + size - 1);
243 Node r = _am.find_node(c);
250 if (addr < min_addr() || (addr + size - 1) > max_addr())
252 addr = find_free(addr, max_addr(), size, align, flags);
256 c = Region(addr, addr + size - 1);
257 Node r = _am.find_node(c);
261 if (r->first.end() >= max_addr())
264 addr = r->first.end() + 1;
267 if (_am.insert(c, Hdlr(
typename Hdlr::Dataspace(), 0, 0, flags.region_flags())).second == 0)
273 bool detach_area(
l4_addr_t addr)
noexcept
275 if (_am.remove(addr))
281 void *attach(
void *addr,
unsigned long size, Hdlr
const &hdlr,
282 L4Re::Rm::Flags flags = L4Re::Rm::Flags(0),
284 char const *name =
nullptr,
unsigned name_len = 0,
285 L4Re::Rm::Offset backing_offset = 0) noexcept
291 int err = hdlr.map_info(&beg, &end);
296 beg += hdlr.offset();
297 end = beg + size - 1U;
303 &&
reinterpret_cast<l4_addr_t>(addr) != beg)
309 &&
reinterpret_cast<l4_addr_t>(addr) > beg)
322 Node r = _am.find_node(Region(beg, beg + size - 1));
326 end = r->first.end();
331 beg = find_free(beg, end, size, align, flags);
337 && _am.find_node(Region(beg, beg + size - 1)))
340 if (beg < min_addr() || beg + size - 1 > end)
343 if (_rm.insert(Region(beg, beg + size - 1,
344 name, name_len, backing_offset), hdlr).second
346 return reinterpret_cast<void*
>(beg);
351 int detach(
void *addr,
unsigned long sz,
unsigned flags,
352 Region *reg, Hdlr *hdlr)
noexcept
355 Region dr(a, a + sz - 1);
363 Hdlr
const &h = r->second;
374 h_copy.free(0, g.size());
386 else if (dr.start() <= g.start())
391 h.free(0, dr.end() + 1 - g.start());
393 unsigned long sz = dr.end() + 1 - g.start();
394 Item &cn =
const_cast<Item &
>(*r);
395 cn.first = Region(dr.end() + 1, g.end());
396 cn.second = cn.second + sz;
400 *reg = Region(g.start(), dr.end());
406 else if (dr.end() >= g.end())
412 h.free(dr.start() - g.start(), g.end() + 1 - dr.start());
414 Item &cn =
const_cast<Item &
>(*r);
415 cn.first = Region(g.start(), dr.start() - 1);
419 *reg = Region(dr.start(), g.end());
426 else if (g.contains(dr))
431 h.free(dr.start() - g.start(), dr.size());
434 Item &cn =
const_cast<Item &
>(*r);
435 cn.first = Region(g.start(), dr.start()-1);
441 err = _rm.insert(Region(dr.end() + 1, g.end()),
442 h + (dr.end() + 1 - g.start())).second;
457 unsigned char align, L4Re::Rm::Flags flags)
const noexcept;
462template<
typename Hdlr,
template<
typename T>
class Alloc >
465 unsigned long size,
unsigned char align, L4Re::Rm::Flags flags)
const noexcept
469 if (addr == ~0UL || addr < min_addr() || addr >= end)
477 if (addr > 0 && addr - 1 > end - size)
480 Region c(addr, addr + size - 1);
481 r = _rm.find_node(c);
487 if (r->first.end() > end - size)
495 else if (r->first.end() > end - size)
@ Detached_ds
Detached data sapce.
@ Detach_again
Detached data space, more to do.
@ Split_ds
Splitted data space, and done.
@ Kept_ds
Kept data space.
@ Detach_overlap
Do an unmap of all overlapping regions.
@ Detach_keep
Do not free the detached data space, ignore the F::Detach_free.
Region Key_type
Type of the key values.
Base_type::Node Node
Return type for find.
ITEM_TYPE Item_type
Type for the items store in the set.
unsigned long l4_addr_t
Address type.
signed long long l4_int64_t
Signed 64bit value.
unsigned long l4_cap_idx_t
Capability selector type.
@ L4_INVALID_CAP
Invalid capability selector.
@ L4_ENOENT
No such entity.
#define L4_INVALID_PTR
Invalid address as pointer type.
#define L4_PAGESHIFT
Size of a page, log2-based.
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.
@ L4_INVALID_ADDR
Invalid address.
Common L4 ABI Data Types.
Region_flags
Region flags (permissions, cacheability, special).
@ Reserved
Region is reserved (blocked)
@ Detach_free
Free the portion of the data space after detach.
@ Caching_mask
Mask of all Rm cache bits.
@ Search_addr
Search for a suitable address range.
@ In_area
Search only in area, or map into area.