20template<
typename DERIVED,
typename Dbg>
24 DERIVED *rm() {
return static_cast<DERIVED*
>(
this); }
25 DERIVED
const *rm()
const {
return static_cast<DERIVED
const *
>(
this); }
32 long op_attach(L4Re::Rm::Rights,
l4_addr_t &_start,
33 unsigned long size, Rm::Flags flags,
34 L4::Ipc::Snd_fpage ds_cap, L4Re::Rm::Offset offs,
36 L4::Ipc::String<> name, L4Re::Rm::Offset backing_offset)
38 typename DERIVED::Dataspace ds;
42 if (
long r = rm()->validate_ds
43 (
static_cast<DERIVED*
>(
this)->server_iface(), ds_cap,
44 flags.region_flags(), &ds))
54 Rm::Region_flags r_flags = flags.region_flags();
55 Rm::Attach_flags a_flags = flags.attach_flags();
57 typename DERIVED::Region_handler handler(ds, client_cap_idx, offs, r_flags);
58 start =
l4_addr_t(rm()->attach(
reinterpret_cast<void*
>(start), size,
59 handler, a_flags, align,
62 name.length ? name.length - 1 : 0,
75 long op_free_area(L4Re::Rm::Rights,
l4_addr_t start)
77 if (!rm()->detach_area(start))
86 long op_find(L4Re::Rm::Rights,
l4_addr_t &addr,
unsigned long &size,
87 L4Re::Rm::Flags &flags, L4Re::Rm::Offset &offset,
88 L4::Cap<L4Re::Dataspace> &m)
90 if (!DERIVED::Have_find)
93 Rm::Flags flag_area { 0 };
95 typename DERIVED::Node r = rm()->find(Region(addr, addr + size -1));
98 r = rm()->area_find(Region(addr, addr + size - 1));
104 addr = r->first.start();
105 size = r->first.end() + 1 - addr;
107 flags = r->second.flags() | flag_area;
108 offset = r->second.offset();
109 m = L4::Cap<L4Re::Dataspace>(DERIVED::find_res(r->second.memory()));
116 long op_detach(L4Re::Rm::Rights,
l4_addr_t addr,
117 unsigned long size,
unsigned flags,
122 typename DERIVED::Region_handler h;
123 int err = rm()->detach(
reinterpret_cast<void*
>(addr), size, flags, &r, &h);
140 mem_cap = h.client_cap_idx();
147 long op_reserve_area(L4Re::Rm::Rights,
l4_addr_t &start,
unsigned long size,
148 L4Re::Rm::Flags flags,
unsigned char align)
150 start = rm()->attach_area(start, size, flags, align);
159 long op_get_regions(L4Re::Rm::Rights,
l4_addr_t addr,
160 L4::Ipc::Ret_array<L4Re::Rm::Region> regions)
162 typename DERIVED::Node r;
164 while ((r = rm()->lower_bound(Region(addr))))
166 Rm::Region &x = regions.value[num];
167 x.start = r->first.start();
168 x.end = r->first.end();
169 x.flags = r->second.flags();
171 if (++num >= regions.max)
174 if (x.end >= rm()->max_addr())
184 long op_get_areas(L4Re::Rm::Rights,
l4_addr_t addr,
185 L4::Ipc::Ret_array<L4Re::Rm::Area> areas)
187 typename DERIVED::Node r;
189 while ((r = rm()->lower_bound_area(Region(addr))))
191 Rm::Area &x = areas.value[num];
192 x.start = r->first.start();
193 x.end = r->first.end();
195 if (++num >= areas.max)
198 if (x.end >= rm()->max_addr())
207 static void pager_set_result(L4::Ipc::Opt<L4::Ipc::Snd_fpage> *fp,
208 L4::Ipc::Snd_fpage
const &f)
211 static void pager_set_result(L4::Ipc::Opt<L4::Ipc::Snd_fpage> *, ...)
218 long op_io_page_fault(L4::Io_pager::Rights, l4_fpage_t,
l4_umword_t,
219 L4::Ipc::Opt<L4::Ipc::Snd_fpage> &)
226 L4::Ipc::Opt<L4::Ipc::Snd_fpage> &fp)
228 Dbg(Dbg::Server).printf(
"page fault: %lx pc=%lx\n", addr, pc);
230 bool need_w = addr & 2;
231 bool need_x = addr & 4;
233 typename DERIVED::Node n = rm()->find(addr);
235 if (!n || !n->second.memory())
237 Dbg(Dbg::Warn,
"rm").printf(
"unhandled %s page fault at 0x%lx pc=0x%lx\n",
239 need_x ?
"instruction" :
"read", addr, pc);
246 Dbg(Dbg::Warn,
"rm").printf(
"write page fault in readonly region at 0x%lx pc=0x%lx\n",
254 Dbg(Dbg::Warn,
"rm").printf(
"instruction page fault in non-exec region at 0x%lx pc=0x%lx\n",
265 Dbg(Dbg::Warn,
"rm").printf(
"page fault handling in kernel-memory provided region or reserved region at 0x%lx pc=0x%lx\n",
271 typename DERIVED::Region_handler::Ops::Map_result map_res;
272 if (
int err = n->second.map(addr, n->first, need_w, &map_res))
274 Dbg(Dbg::Warn,
"rm").printf(
"mapping for page fault failed with error %d at 0x%lx pc=0x%lx\n",
280 pager_set_result(&fp, map_res);
284 long op_get_info(L4Re::Rm::Rights,
l4_addr_t addr,
285 L4::Ipc::String<char> &name, L4Re::Rm::Offset &backing_offset)
287#ifdef CONFIG_L4RE_REGION_INFO
288 typename DERIVED::Node r = rm()->find(Region(addr));
291 backing_offset = r->first.backing_offset();
293 char const *src = r->first.name();
294 unsigned src_len = r->first.name_len();
295 for (i = 0; i < src_len && i < name.length - 1; ++i)
296 name.data[i] = src[i];
303 (void)backing_offset;
unsigned long l4_umword_t
Unsigned machine word.
unsigned long l4_addr_t
Address type.
unsigned long l4_cap_idx_t
Capability selector type.
@ L4_INVALID_CAP
Invalid capability selector.
@ L4_ENOENT
No such entity.
@ L4_EACCESS
Permission denied.
@ L4_EINVAL
Invalid argument.
@ L4_ENODEV
No such thing.
@ 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.
Documentation of the L4 Runtime Environment utility functionality in C++.
@ Reserved
Region is reserved (blocked).
@ Kernel
Kernel-provided memory (KUMEM).
@ In_area
Search only in area, or map into area.