5 * \brief Region mapper server template.
8 * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
9 * Alexander Warg <warg@os.inf.tu-dresden.de>
10 * economic rights: Technische Universität Dresden (Germany)
12 * This file is part of TUD:OS and distributed under the terms of the
13 * GNU General Public License 2.
14 * Please see the COPYING-GPL-2 file for details.
16 * As a special exception, you may use this file as part of a free software
17 * library without restriction. Specifically, if other files instantiate
18 * templates or use macros or inline functions from this file, or you compile
19 * this file and link it with other files to produce an executable, this
20 * file does not by itself cause the resulting executable to be covered by
21 * the GNU General Public License. This exception does not however
22 * invalidate any other reasons why the executable file might be covered by
23 * the GNU General Public License.
27 #include <l4/sys/types.h>
28 #include <l4/re/rm-sys.h>
30 #include <l4/re/util/region_mapping>
32 namespace L4Re { namespace Util {
34 template<typename Rm_server, typename RM, typename IOS>
35 int region_map_server(RM *rm, IOS &ios)
46 l4_cap_idx_t client_cap_idx = L4_INVALID_CAP;
48 typename Rm_server::Dataspace ds = typename Rm_server::Dataspace();
52 ios >> start >> size >> flags >> offs >> align;
53 if (!(flags & Rm::Reserved))
55 ios >> client_cap_idx >> ds_cap;
57 if (int r = Rm_server::validate_ds(ds_cap, flags, &ds))
61 size = l4_round_page(size);
62 start = l4_trunc_page(start);
64 if (size < L4_PAGESIZE)
67 unsigned r_flags = flags & Rm::Region_flags;
68 unsigned a_flags = flags & Rm::Attach_flags;
70 start = l4_addr_t(rm->attach((void*)start, size,
71 typename RM::Region_handler(ds, client_cap_idx, offs, r_flags),
74 if (start == L4_INVALID_ADDR)
75 return -L4_EADDRNOTAVAIL;
85 ios >> addr >> size >> flags;
88 typename RM::Region_handler h;
89 int err = rm->detach((void*)addr, size, flags, &r, &h);
96 ios << l4_addr_t(r.start()) << (unsigned long)r.size()
97 << h.client_cap_idx();
101 case Rm_::Attach_area:
108 ios >> start >> size >> flags >> align;
109 start = rm->attach_area(start, size, flags, align);
110 if (start == L4_INVALID_ADDR)
111 return -L4_EADDRNOTAVAIL;
117 case Rm_::Detach_area:
121 if (!rm->detach_area(start))
128 if (!Rm_server::Have_find)
132 unsigned flag_area = 0;
136 typename RM::Node r = rm->find(Region(addr, addr + size -1));
139 r = rm->area_find(Region(addr, addr + size - 1));
142 flag_area = Rm::In_area;
145 addr = r->first.start();
146 size = r->first.end() + 1 - addr;
148 unsigned flags = r->second.flags() | flag_area;
150 ios << addr << size << flags << r->second.offset()
151 << Rm_server::find_res(r->second.memory());
160 template<typename Dbg, typename RM, typename IOS>
161 int region_pf_handler(RM *rm, IOS &ios)
163 l4_umword_t addr, pc;
165 Dbg(Dbg::Server).printf("page fault: %lx pc=%lx\n", addr, pc);
167 register unsigned writable = addr & 2;
170 typename RM::Node n = rm->find(addr);
172 if (!n || !n->second.memory())
174 Dbg(Dbg::Warn, "rm").printf("unhandled %s page fault @%lx pc=%lx\n",
175 writable ? "write" : "read", addr, pc);
177 // generate exception
178 ios << (l4_umword_t)~0;
182 if (n->second.is_ro() && writable)
184 Dbg(Dbg::Warn, "rm").printf("write page fault in readonly region @%lx pc=%lx\n",
186 // generate exception
187 ios << (l4_umword_t)~0;
191 typename RM::Region_handler::Ops::Map_result result;
192 if (int err = n->second.map(addr, n->first, writable, &result))
194 Dbg(Dbg::Warn, "rm").printf("mapping for pf failed with %d @%lx pc=%lx\n",
196 // generate exception
197 ios << (l4_umword_t)~0;