L4Re Operating System Framework
Interface and Usage Documentation
Loading...
Searching...
No Matches
region_mapping_svr_2
1// vi:set ft=cpp: -*- Mode: C++ -*-
7/*
8 * (c) 2014 Alexander Warg <alexander.warg@kernkonzept.com>
9 *
10 * This file is part of TUD:OS and distributed under the terms of the
11 * GNU General Public License 2.
12 * Please see the COPYING-GPL-2 file for details.
13 *
14 * As a special exception, you may use this file as part of a free software
15 * library without restriction. Specifically, if other files instantiate
16 * templates or use macros or inline functions from this file, or you compile
17 * this file and link it with other files to produce an executable, this
18 * file does not by itself cause the resulting executable to be covered by
19 * the GNU General Public License. This exception does not however
20 * invalidate any other reasons why the executable file might be covered by
21 * the GNU General Public License.
22 */
23#pragma once
24
25#include <l4/sys/types.h>
26#include <l4/re/rm>
28
29namespace L4Re { namespace Util {
30
31template<typename DERIVED, typename Dbg>
32struct Rm_server
33{
34private:
35 DERIVED *rm() { return static_cast<DERIVED*>(this); }
36 DERIVED const *rm() const { return static_cast<DERIVED const *>(this); }
37
38public:
39
43 long op_attach(L4Re::Rm::Rights, l4_addr_t &_start,
44 unsigned long size, Rm::Flags flags,
45 L4::Ipc::Snd_fpage ds_cap, L4Re::Rm::Offset offs,
46 unsigned char align, l4_cap_idx_t client_cap_idx)
47 {
48 typename DERIVED::Dataspace ds;
49
50 if (!(flags & Rm::F::Reserved))
51 {
52 if (long r = rm()->validate_ds
53 (static_cast<DERIVED*>(this)->server_iface(), ds_cap,
54 flags.region_flags(), &ds))
55 return r;
56 }
57
58 size = l4_round_page(size);
59 l4_addr_t start = l4_trunc_page(_start);
60
61 if (size < L4_PAGESIZE)
62 return -L4_EINVAL;
63
64 Rm::Region_flags r_flags = flags.region_flags();
65 Rm::Attach_flags a_flags = flags.attach_flags();
66
67 typename DERIVED::Region_handler handler(ds, client_cap_idx, offs, r_flags);
68 start = l4_addr_t(rm()->attach(reinterpret_cast<void*>(start), size,
69 handler, a_flags, align));
70
71 if (start == L4_INVALID_ADDR)
72 return -L4_EADDRNOTAVAIL;
73
74 _start = start;
75 return L4_EOK;
76 }
77
81 long op_free_area(L4Re::Rm::Rights, l4_addr_t start)
82 {
83 if (!rm()->detach_area(start))
84 return -L4_ENOENT;
85
86 return L4_EOK;
87 }
88
92 long op_find(L4Re::Rm::Rights, l4_addr_t &addr, unsigned long &size,
93 L4Re::Rm::Flags &flags, L4Re::Rm::Offset &offset,
95 {
96 if (!DERIVED::Have_find)
97 return -L4_EPERM;
98
99 Rm::Flags flag_area { 0 };
100
101 typename DERIVED::Node r = rm()->find(Region(addr, addr + size -1));
102 if (!r)
103 {
104 r = rm()->area_find(Region(addr, addr + size - 1));
105 if (!r)
106 return -L4_ENOENT;
107 flag_area = Rm::F::In_area;
108 }
109
110 addr = r->first.start();
111 size = r->first.end() + 1 - addr;
112
113 flags = r->second.flags() | flag_area;
114 offset = r->second.offset();
115 m = L4::Cap<L4Re::Dataspace>(DERIVED::find_res(r->second.memory()));
116 return L4_EOK;
117 }
118
122 long op_detach(L4Re::Rm::Rights, l4_addr_t addr,
123 unsigned long size, unsigned flags,
124 l4_addr_t &start, l4_addr_t &rsize,
125 l4_cap_idx_t &mem_cap)
126 {
127 Region r;
128 typename DERIVED::Region_handler h;
129 int err = rm()->detach(reinterpret_cast<void*>(addr), size, flags, &r, &h);
130 if (err < 0)
131 {
132 start = rsize = 0;
133 mem_cap = L4_INVALID_CAP;
134 return err;
135 }
136
137 if (r.invalid())
138 {
139 start = rsize = 0;
140 mem_cap = L4_INVALID_CAP;
141 return -L4_ENOENT;
142 }
143
144 start = r.start();
145 rsize = r.size();
146 mem_cap = h.client_cap_idx();
147 return err;
148 }
149
153 long op_reserve_area(L4Re::Rm::Rights, l4_addr_t &start, unsigned long size,
154 L4Re::Rm::Flags flags, unsigned char align)
155 {
156 start = rm()->attach_area(start, size, flags, align);
157 if (start == L4_INVALID_ADDR)
158 return -L4_EADDRNOTAVAIL;
159 return L4_EOK;
160 }
161
165 long op_get_regions(L4Re::Rm::Rights, l4_addr_t addr,
167 {
168 typename DERIVED::Node r;
169 unsigned num = 0;
170 while ((r = rm()->lower_bound(Region(addr))))
171 {
172 Rm::Region &x = regions.value[num];
173 x.start = r->first.start();
174 x.end = r->first.end();
175
176 if (++num >= regions.max)
177 break;
178
179 if (x.end >= rm()->max_addr())
180 break;
181 addr = x.end + 1;
182 }
183 return num;
184 }
185
189 long op_get_areas(L4Re::Rm::Rights, l4_addr_t addr,
191 {
192 typename DERIVED::Node r;
193 unsigned num = 0;
194 while ((r = rm()->lower_bound_area(Region(addr))))
195 {
196 Rm::Area &x = areas.value[num];
197 x.start = r->first.start();
198 x.end = r->first.end();
199
200 if (++num >= areas.max)
201 break;
202
203 if (x.end >= rm()->max_addr())
204 break;
205
206 addr = x.end + 1;
207 }
208 return num;
209 }
210
211private:
212 static void pager_set_result(L4::Ipc::Opt<L4::Ipc::Snd_fpage> *fp,
213 L4::Ipc::Snd_fpage const &f)
214 { *fp = f; }
215
216 static void pager_set_result(L4::Ipc::Opt<L4::Ipc::Snd_fpage> *, ...)
217 {}
218public:
219
223 long op_io_page_fault(L4::Io_pager::Rights, l4_fpage_t, l4_umword_t,
225 {
226 // generate exception
227 return -L4_ENOMEM;
228 }
229
230 long op_page_fault(L4::Pager::Rights, l4_umword_t addr, l4_umword_t pc,
232 {
233 Dbg(Dbg::Server).printf("page fault: %lx pc=%lx\n", addr, pc);
234
235 bool need_w = addr & 2;
236 bool need_x = addr & 4;
237
238 typename DERIVED::Node n = rm()->find(addr);
239
240 if (!n || !n->second.memory())
241 {
242 Dbg(Dbg::Warn, "rm").printf("unhandled %s page fault at 0x%lx pc=0x%lx\n",
243 need_w ? "write" :
244 need_x ? "instruction" : "read", addr, pc);
245 // generate exception
246 return -L4_ENOMEM;
247 }
248
249 if (!(n->second.flags() & L4Re::Rm::F::W) && need_w)
250 {
251 Dbg(Dbg::Warn, "rm").printf("write page fault in readonly region at 0x%lx pc=0x%lx\n",
252 addr, pc);
253 // generate exception
254 return -L4_EACCESS;
255 }
256
257 if (!(n->second.flags() & L4Re::Rm::F::X) && need_x)
258 {
259 Dbg(Dbg::Warn, "rm").printf("instruction page fault in non-exec region at 0x%lx pc=0x%lx\n",
260 addr, pc);
261 // generate exception
262 return -L4_EACCESS;
263 }
264
265 typename DERIVED::Region_handler::Ops::Map_result map_res;
266 if (int err = n->second.map(addr, n->first, need_w, &map_res))
267 {
268 Dbg(Dbg::Warn, "rm").printf("mapping for page fault failed with error %d at 0x%lx pc=0x%lx\n",
269 err, addr, pc);
270 // generate exception
271 return -L4_ENOMEM;
272 }
273
274 pager_set_result(&fp, map_res);
275 return L4_EOK;
276 }
277};
278
279}}
Range Area
An area is a range of virtual addresses which is reserved, see L4Re::Rm::reserve_area().
Definition rm:701
Range Region
A region is a range of virtual addresses which is backed by a dataspace.
Definition rm:693
C++ interface for capabilities.
Definition capability.h:219
Send flex-page.
Definition ipc_types:408
unsigned long l4_umword_t
Unsigned machine word.
Definition l4int.h:51
unsigned long l4_addr_t
Address type.
Definition l4int.h:45
unsigned long l4_cap_idx_t
Capability selector type.
Definition types.h:359
@ L4_INVALID_CAP
Invalid capability selector.
Definition consts.h:168
@ L4_ENOENT
No such entity.
Definition err.h:45
@ L4_EACCESS
Permission denied.
Definition err.h:51
@ L4_EINVAL
Invalid argument.
Definition err.h:57
@ L4_EOK
Ok.
Definition err.h:43
@ L4_EADDRNOTAVAIL
Address not available.
Definition err.h:63
@ L4_EPERM
No permission.
Definition err.h:44
@ L4_ENOMEM
No memory.
Definition err.h:50
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:437
l4_addr_t l4_round_page(l4_addr_t address) L4_NOTHROW
Round address up to the next page.
Definition consts.h:462
#define L4_PAGESIZE
Minimal page size (in bytes).
Definition consts.h:380
@ L4_INVALID_ADDR
Invalid address.
Definition consts.h:494
Common L4 ABI Data Types.
L4Re C++ Interfaces.
Definition l4re.dox:17
Region handling.
Region mapper interface.
@ Reserved
Region is reserved (blocked)
Definition rm:161
@ X
Executable region.
Definition rm:148
@ W
Writable region.
Definition rm:146
@ In_area
Search only in area, or map into area.
Definition rm:127
Attribute for defining an optional RPC argument.
Definition ipc_types:148
Dynamically sized output array of type T.
Definition ipc_ret_array:35
L4 flexpage type.
Definition __l4_fpage.h:85