]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/moe/server/src/region.cc
update
[l4.git] / l4 / pkg / moe / server / src / region.cc
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 #include "exception.h"
13
14 #include <l4/sys/kip>
15
16 #include <l4/re/rm>
17 #include <l4/re/rm-sys.h>
18 #include <l4/re/protocols>
19
20 #include <l4/cxx/ipc_stream>
21 #include <l4/cxx/iostream>
22 #include <l4/cxx/exceptions>
23
24 #include <l4/re/util/region_mapping_svr>
25
26 Region_map::Region_map()
27   : Base(Moe::Virt_limit::start, Moe::Virt_limit::end)
28 {
29   L4::Kip::Mem_desc *md = L4::Kip::Mem_desc::first(const_cast<l4_kernel_info_t*>(kip()));
30   unsigned long cnt = L4::Kip::Mem_desc::count(const_cast<l4_kernel_info_t*>(kip()));
31
32   for (L4::Kip::Mem_desc *m = md; m < md + cnt; ++m)
33     {
34       if (m->type() != L4::Kip::Mem_desc::Reserved || !m->is_virtual())
35         continue;
36
37       l4_addr_t start = m->start();
38       l4_addr_t end = m->end();
39
40       attach_area(start, end - start + 1, L4Re::Rm::Reserved);
41     }
42
43   attach_area(0, L4_PAGESIZE);
44 }
45
46 int Region_ops::map(Region_handler const *h, l4_addr_t adr,
47                     L4Re::Util::Region const &r, bool writable,
48                     L4::Ipc::Snd_fpage *result)
49 {
50   l4_addr_t offs = adr - r.start();
51   offs = l4_trunc_page(offs);
52   Moe::Dataspace::Ds_rw rw = !h->is_ro() && writable
53                              ? Moe::Dataspace::Writable
54                              : Moe::Dataspace::Read_only;
55   if (h->is_ro() && writable)
56     Dbg(Dbg::Warn).printf("WARNING: "
57          "Writable mapping request on read-only region at %lx!\n",
58          adr);
59   *result = L4::Ipc::Snd_fpage(h->memory()->address(offs + h->offset(), rw, adr,
60                           r.start(), r.end()).fp(), offs + r.start());
61
62   return L4_EOK;
63 }
64
65 void
66 Region_ops::free(Region_handler const *h, l4_addr_t start, unsigned long size)
67 {
68   if (h->is_ro())
69     return;
70
71   h->memory()->clear(h->offset() + start, size);
72 }
73
74
75 class Rm_server
76 {
77 public:
78   typedef Moe::Dataspace const *Dataspace;
79   enum { Have_find = false };
80   static int validate_ds(L4::Ipc::Snd_fpage const &ds_cap,
81                          unsigned flags, Dataspace *ds)
82   {
83     if (flags & L4Re::Rm::Pager)
84       return -L4_EINVAL;
85
86     if (!ds_cap.id_received())
87       return -L4_ENOENT;
88
89     *ds = dynamic_cast<Moe::Dataspace*>(object_pool.find(ds_cap.data()));
90
91     if (!*ds)
92       return -L4_ENOENT;
93
94     if (flags & L4Re::Rm::Read_only)
95       return L4_EOK;
96
97     if (!(*ds)->is_writable() || !(ds_cap.data() & L4_FPAGE_X))
98       return -L4_EPERM;
99
100     return L4_EOK;
101   }
102
103   static l4_umword_t find_res(Dataspace const &) { return 0; }
104 };
105
106 int
107 Region_map::dispatch(l4_umword_t, L4::Ipc::Iostream &ios)
108 {
109   Dbg warn(Dbg::Warn, "WARN");
110   l4_msgtag_t tag;
111   ios >> tag;
112
113   switch (tag.label())
114     {
115     case L4_PROTO_PAGE_FAULT:
116     {
117       try
118         {
119           return L4Re::Util::region_pf_handler<Dbg>(this, ios);
120         }
121       catch (L4::Out_of_memory const &oom)
122         {
123           warn.printf("insufficient memory to resolve page fault!\n");
124           return -L4_ENOREPLY;
125         }
126     }
127  #if defined(ARCH_x86) || defined(ARCH_amd64)
128     case L4_PROTO_IO_PAGE_FAULT:
129         {
130           l4_umword_t addr, pc;
131           l4_fpage_t fp;
132           ios >> addr >> pc;
133           fp.raw = addr;
134           warn.printf("IO-port-fault: port=0x%lx size=%d pc=0x%lx\n",
135                       l4_fpage_page(fp), 1 << l4_fpage_size(fp), pc);
136         }
137       // return -1, this lets the kernel generate an exception.
138       return -1;
139 #endif
140    case L4Re::Protocol::Rm:
141       return L4Re::Util::region_map_server<Rm_server>(this, ios);
142     default:
143       return -L4_EBADPROTO;
144     }
145 }