29 namespace L4Re {
namespace Util {
31 template<
typename DERIVED,
typename Dbg>
35 DERIVED *rm() {
return static_cast<DERIVED*
>(
this); }
36 DERIVED
const *rm()
const {
return static_cast<DERIVED
const *
>(
this); }
43 long op_attach(L4Re::Rm::Rights,
l4_addr_t &_start,
44 unsigned long size, Rm::Flags flags,
48 typename DERIVED::Dataspace ds;
52 if (
long r = rm()->validate_ds(
static_cast<DERIVED*
>(
this)->server_iface(), ds_cap, flags.region_flags(), &ds))
62 Rm::Region_flags r_flags = flags.region_flags();
63 Rm::Attach_flags a_flags = flags.attach_flags();
65 start =
l4_addr_t(rm()->attach((
void*)start, size,
66 typename DERIVED::Region_handler(ds, client_cap_idx, offs, r_flags),
79 long op_free_area(L4Re::Rm::Rights,
l4_addr_t start)
81 if (!rm()->detach_area(start))
90 long op_find(L4Re::Rm::Rights,
l4_addr_t &addr,
unsigned long &size,
91 L4Re::Rm::Flags &flags, L4Re::Rm::Offset &offset,
94 if (!DERIVED::Have_find)
97 Rm::Flags flag_area { 0 };
99 typename DERIVED::Node r = rm()->find(Region(addr, addr + size -1));
102 r = rm()->area_find(Region(addr, addr + size - 1));
108 addr = r->first.start();
109 size = r->first.end() + 1 - addr;
111 flags = r->second.flags() | flag_area;
112 offset = r->second.offset();
120 long op_detach(L4Re::Rm::Rights,
l4_addr_t addr,
121 unsigned long size,
unsigned flags,
126 typename DERIVED::Region_handler h;
127 int err = rm()->detach((
void*)addr, size, flags, &r, &h);
136 mem_cap = h.client_cap_idx();
143 long op_reserve_area(L4Re::Rm::Rights,
l4_addr_t &start,
unsigned long size,
144 L4Re::Rm::Flags flags,
unsigned char align)
146 start = rm()->attach_area(start, size, flags, align);
155 long op_get_regions(L4Re::Rm::Rights,
l4_addr_t addr,
158 typename DERIVED::Node r;
160 while ((r = rm()->lower_bound(Region(addr))))
163 x.start = r->first.start();
164 x.end = r->first.end();
166 if (++num >= regions.max)
169 if (x.end >= rm()->max_addr())
179 long op_get_areas(L4Re::Rm::Rights,
l4_addr_t addr,
182 typename DERIVED::Node r;
184 while ((r = rm()->lower_bound_area(Region(addr))))
187 x.start = r->first.start();
188 x.end = r->first.end();
190 if (++num >= areas.max)
193 if (x.end >= rm()->max_addr())
223 Dbg(Dbg::Server).printf(
"page fault: %lx pc=%lx\n", addr, pc);
225 bool need_w = addr & 2;
226 bool need_x = addr & 4;
228 typename DERIVED::Node n = rm()->find(addr);
230 if (!n || !n->second.memory())
232 Dbg(Dbg::Warn,
"rm").printf(
"unhandled %s page fault at 0x%lx pc=0x%lx\n",
233 need_w ?
"write" :
"read", addr, pc);
238 if (!(n->second.flags() & L4Re::Rm::F::W) && need_w)
240 Dbg(Dbg::Warn,
"rm").printf(
"write page fault in readonly region at 0x%lx pc=0x%lx\n",
246 if (!(n->second.flags() & L4Re::Rm::F::X) && need_x)
248 Dbg(Dbg::Warn,
"rm").printf(
"instruction page fault in non-exec region at 0x%lx pc=0x%lx\n",
254 typename DERIVED::Region_handler::Ops::Map_result map_res;
255 if (
int err = n->second.map(addr, n->first, need_w, &map_res))
257 Dbg(Dbg::Warn,
"rm").printf(
"mapping for page fault failed with error %d at 0x%lx pc=0x%lx\n",
263 pager_set_result(&fp, map_res);
Range Area
An area is a range of virtual addresses which is reserved, see L4Re::Rm::reserve_area().
Range Region
A region is a range of virtual addresses which is backed by a dataspace.
Generic RPC wrapper for L4 flex-pages.
unsigned long l4_umword_t
Unsigned machine word.
unsigned long l4_addr_t
Address type.
unsigned long l4_cap_idx_t
L4 Capability selector Type.
@ L4_ENOENT
No such entity.
@ L4_EACCESS
Permission denied.
@ L4_EINVAL
Invalid argument.
@ L4_EADDRNOTAVAIL
Address not available.
l4_addr_t l4_trunc_page(l4_addr_t address) L4_NOTHROW
Round an address down to the next lower page boundary.
l4_addr_t l4_round_page(l4_addr_t address) L4_NOTHROW
Round address up to the next page.
#define L4_PAGESIZE
Minimal page size (in bytes).
@ L4_INVALID_ADDR
Invalid address.
Common L4 ABI Data Types.
@ Reserved
Region is reserved (blocked)
@ In_area
Search only in area, or map into area.
Attribute for defining an optional RPC argument.
Dynamically sized output array of type T.