1 /*
2 * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3 * Alexander Warg <warg@os.inf.tu-dresden.de>
4 * economic rights: Technische Universität Dresden (Germany)
5 *
6 * This file is part of TUD:OS and distributed under the terms of the
7 * GNU General Public License 2.
8 * Please see the COPYING-GPL-2 file for details.
9 */
10 #include "debug.h"
11 #include "region.h"
12
13 #include <l4/sys/kip>
14
15 #include <l4/re/rm>
16
17 #include <l4/cxx/iostream>
18 #include <l4/cxx/exceptions>
19
20 #include <l4/re/util/region_mapping_svr_2>
21
Region_map()22 Region_map::Region_map()
23 : Base(Moe::Virt_limit::start, Moe::Virt_limit::end)
24 {
25 for (auto const &m: L4::Kip::Mem_desc::all(kip()))
26 {
27 if (m.type() != L4::Kip::Mem_desc::Reserved || !m.is_virtual())
28 continue;
29
30 l4_addr_t start = m.start();
31 l4_addr_t end = m.end();
32
33 attach_area(start, end - start + 1, L4Re::Rm::F::Reserved);
34 }
35
36 attach_area(0, L4_PAGESIZE);
37 }
38
map(Region_handler const * h,l4_addr_t adr,L4Re::Util::Region const & r,bool need_w,L4::Ipc::Snd_fpage * result)39 int Region_ops::map(Region_handler const *h, l4_addr_t adr,
40 L4Re::Util::Region const &r, bool need_w,
41 L4::Ipc::Snd_fpage *result)
42 {
43 if (!h->memory())
44 return -L4_EADDRNOTAVAIL;
45
46 using L4::Ipc::Snd_fpage;
47 l4_addr_t offs = adr - r.start();
48 offs = l4_trunc_page(offs);
49 auto f = map_flags(h->flags());
50 if (!need_w)
51 f &= ~L4Re::Dataspace::F::W;
52
53 static Snd_fpage::Cacheopt const cache_map[] =
54 { Snd_fpage::None, Snd_fpage::Buffered, Snd_fpage::Uncached,
55 Snd_fpage::None };
56
57 auto ds_fpage = h->memory()->address(offs + h->offset(), f, adr,
58 r.start(), r.end());
59 if (ds_fpage.is_nil())
60 return -L4_EADDRNOTAVAIL;
61
62 *result = Snd_fpage(ds_fpage.fp(), offs + r.start(), Snd_fpage::Map,
63 cache_map[h->caching() >> L4Re::Rm::Caching_shift]);
64
65 return L4_EOK;
66 }
67
68 void
free(Region_handler const * h,l4_addr_t start,unsigned long size)69 Region_ops::free(Region_handler const *h, l4_addr_t start, unsigned long size)
70 {
71 if (h->is_ro() || !h->memory())
72 return;
73
74 h->memory()->clear(h->offset() + start, size);
75 }
76
77 int
validate_ds(void *,L4::Ipc::Snd_fpage const & ds_cap,L4Re::Rm::Region_flags flags,Dataspace * ds)78 Region_map::validate_ds(void *, L4::Ipc::Snd_fpage const &ds_cap,
79 L4Re::Rm::Region_flags flags, Dataspace *ds)
80 {
81 if (flags & L4Re::Rm::F::Pager)
82 return -L4_EINVAL;
83
84 if (!ds_cap.id_received())
85 return -L4_ENOENT;
86
87 auto *moe_ds = dynamic_cast<Moe::Dataspace*>(object_pool.find(ds_cap.data()));
88
89 if (!moe_ds)
90 return -L4_ENOENT;
91
92 *ds = moe_ds;
93
94 if ((map_flags(flags) & moe_ds->map_flags(ds_cap.data())) != map_flags(flags))
95 return -L4_EPERM;
96
97 return L4_EOK;
98 }
99
100 long
op_io_page_fault(L4::Io_pager::Rights,l4_fpage_t io_pfa,l4_umword_t pc,L4::Ipc::Opt<L4::Ipc::Snd_fpage> &)101 Region_map::op_io_page_fault(L4::Io_pager::Rights,
102 l4_fpage_t io_pfa, l4_umword_t pc,
103 L4::Ipc::Opt<L4::Ipc::Snd_fpage> &)
104 {
105 Dbg(Dbg::Warn).printf("IO-port-fault: port=0x%lx size=%d pc=0x%lx\n",
106 l4_fpage_ioport(io_pfa), 1 << l4_fpage_size(io_pfa), pc);
107 return -L4_ENOMEM;
108 }
109