]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/vmm/server/src/ds_mmio_mapper.h
Update
[l4.git] / l4 / pkg / vmm / server / src / ds_mmio_mapper.h
1 /*
2  * (c) 2013-2014 Alexander Warg <warg@os.inf.tu-dresden.de>
3  *     economic rights: Technische Universität Dresden (Germany)
4  *
5  * This file is part of TUD:OS and distributed under the terms of the
6  * GNU General Public License 2.
7  * Please see the COPYING-GPL-2 file for details.
8  */
9 #pragma once
10
11 #include <l4/re/dataspace>
12 #include <l4/util/util.h>
13
14 #include "mmio_device.h"
15 #include "vcpu.h"
16
17 class Ds_handler : public Vmm::Mmio_device
18 {
19   L4::Cap<L4Re::Dataspace> _ds;
20   l4_addr_t _offset;
21   bool access(l4_addr_t pfa, l4_addr_t offset, Vmm::Cpu vcpu,
22               L4::Cap<L4::Task> vm_task, l4_addr_t min, l4_addr_t max)
23   {
24     long res;
25 #ifdef MAP_OTHER
26     res = _ds->map(offset + _offset,
27                    vcpu.pf_write() ? L4Re::Dataspace::Map_rw : 0,
28                    pfa, min, max, vm_task);
29 #else
30     (void)vm_task;
31     unsigned char ps = L4_PAGESHIFT;
32
33     if (l4_trunc_size(pfa, L4_SUPERPAGESHIFT) >= min
34         && l4_round_size(pfa, L4_SUPERPAGESHIFT) <= max)
35       ps = L4_SUPERPAGESHIFT;
36
37     res = L4Re::chksys(vm_task->map(L4Re::This_task,
38                                     l4_fpage(l4_trunc_size(_local_start + offset, ps),
39                                              ps,
40                                              vcpu.pf_write()
41                                                ? L4_FPAGE_RWX : L4_FPAGE_RX),
42                                     l4_trunc_size(pfa, ps)));
43 #endif
44
45     if (res < 0)
46       {
47         Err().printf("cannot handle VM memory access @ %lx ip=%lx r=%ld\n",
48                      pfa, vcpu->r.ip, res);
49         l4_sleep_forever();
50       }
51     return true;
52   }
53
54 #ifndef MAP_OTHER
55   l4_addr_t _local_start;
56 #endif
57
58 public:
59   explicit Ds_handler(L4::Cap<L4Re::Dataspace> ds,
60                       l4_addr_t local_start,
61                       l4_size_t size = 0,
62                       l4_addr_t offset = 0)
63     : _ds(ds), _offset(offset)
64 #ifndef MAP_OTHER
65       , _local_start(local_start)
66 #endif
67   {
68 #ifndef MAP_OTHER
69     if (local_start == 0)
70       L4Re::chksys(L4Re::Env::env()->rm()->attach(&_local_start,
71                                                   size
72                                                     ? size
73                                                     : L4Re::chksys(ds->size()),
74                                                   L4Re::Rm::Search_addr
75                                                   | L4Re::Rm::Eager_map,
76                                                   L4::Ipc::make_cap_rw(ds),
77                                                   offset, L4_SUPERPAGESHIFT));
78 #endif
79   }
80 };