]> 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 #pragma once
2
3 #include <l4/re/dataspace>
4 #include <l4/util/util.h>
5
6 #include "arm_mmio_device.h"
7
8 class Ds_handler : public Vmm::Mmio_device
9 {
10   L4::Cap<L4Re::Dataspace> _ds;
11   l4_addr_t _offset;
12   bool access(l4_addr_t pfa, l4_addr_t offset, l4_vcpu_state_t *vcpu,
13               L4::Cap<L4::Task> vm_task, l4_addr_t min, l4_addr_t max)
14   {
15     Vmm::Arm::Hsr hsr(vcpu->r.err);
16     long res;
17 #ifdef MAP_OTHER
18     res = _ds->map(offset + _offset,
19                    hsr.pf_write() ? L4Re::Dataspace::Map_rw : 0,
20                    pfa, min, max, vm_task);
21 #else
22     (void)vm_task;
23     unsigned char ps = L4_PAGESHIFT;
24
25     if (l4_trunc_size(pfa, L4_SUPERPAGESHIFT) >= min
26         && l4_round_size(pfa, L4_SUPERPAGESHIFT) <= max)
27       ps = L4_SUPERPAGESHIFT;
28
29     res = L4Re::chksys(vm_task->map(L4Re::This_task,
30                                     l4_fpage(l4_trunc_size(_local_start + offset, ps),
31                                              ps,
32                                              hsr.pf_write()
33                                                ? L4_FPAGE_RWX : L4_FPAGE_RX),
34                                     l4_trunc_size(pfa, ps)));
35 #endif
36
37     if (res < 0)
38       {
39         Err().printf("cannot handle VM memory access @ %lx ip=%lx r=%ld\n",
40                      pfa, vcpu->r.ip, res);
41         l4_sleep_forever();
42       }
43     return true;
44   }
45
46 #ifndef MAP_OTHER
47   l4_addr_t _local_start;
48 #endif
49
50 public:
51   explicit Ds_handler(L4::Cap<L4Re::Dataspace> ds,
52                       l4_addr_t local_start,
53                       l4_size_t size = 0,
54                       l4_addr_t offset = 0)
55     : _ds(ds), _offset(offset)
56 #ifndef MAP_OTHER
57       , _local_start(local_start)
58 #endif
59   {
60 #ifndef MAP_OTHER
61     if (local_start == 0)
62       L4Re::chksys(L4Re::Env::env()->rm()->attach(&_local_start,
63                                                   size
64                                                     ? size
65                                                     : L4Re::chksys(ds->size()),
66                                                   L4Re::Rm::Search_addr
67                                                   | L4Re::Rm::Eager_map,
68                                                   ds, offset, L4_SUPERPAGESHIFT));
69 #endif
70   }
71 };