]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/moe/server/src/dataspace_cont.cc
update
[l4.git] / l4 / pkg / moe / server / src / dataspace_cont.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 "dataspace_cont.h"
11 #include "pages.h"
12
13 Moe::Dataspace_cont::Dataspace_cont(void *start, unsigned long size,
14                                     unsigned long flags)
15 : Dataspace(size, flags), _start((char*)start)
16 {
17   if (!can_cow())
18     return;
19
20   char *end = _start + l4_round_page(this->size());
21   for (char *x = (char *)l4_trunc_page((l4_addr_t)_start); x < end;
22        x += L4_PAGESIZE)
23     Moe::Pages::share(x);
24 }
25
26
27 Moe::Dataspace::Address 
28 Moe::Dataspace_cont::address(l4_addr_t offset,
29                              Ds_rw rw, l4_addr_t hot_spot,
30                              l4_addr_t min, l4_addr_t max) const
31 {
32   if (!check_limit(offset))
33     return Address(-L4_ERANGE);
34
35   min = l4_trunc_page(min);
36   //max = l4_round_page(max);
37
38   l4_addr_t adr = l4_addr_t(_start) + offset;
39   unsigned char order = L4_PAGESHIFT;
40
41   while (order < 30 /* limit to 1GB flexpage */)
42     {
43       l4_addr_t map_base = l4_trunc_size(adr, order + 1);
44       if (map_base < l4_addr_t(_start))
45         break;
46
47       if (map_base + (1UL << (order + 1)) -1 > (l4_addr_t(_start) + round_size() - 1))
48         break;
49
50       map_base = l4_trunc_size(hot_spot, order + 1);
51       if (map_base < min)
52         break;
53
54       if (map_base + (1UL << (order + 1)) -1 > max)
55         break;
56
57       l4_addr_t mask = ~(~0UL << (order + 1));
58       if (hot_spot == ~0UL || ((adr ^ hot_spot) & mask))
59         break;
60
61       ++order;
62     }
63
64   l4_addr_t map_base = l4_trunc_size(adr, order);
65   l4_addr_t offs = adr & ~(~0UL << order);
66
67   if (!is_writable())
68     rw = Read_only;
69
70   return Address(map_base, order, rw, offs);
71 }
72
73 void Moe::Dataspace_cont::unmap(bool ro) const throw()
74 {
75   unsigned long _size = round_size();
76   l4_addr_t offs = 0;
77
78   while (_size)
79     {
80       Address addr = address(offs, Writable, ~0);
81       l4_fpage_t fp
82          = l4_fpage_set_rights(addr.fp(), ro ? L4_FPAGE_W : L4_FPAGE_RWX);
83       l4_task_unmap(L4_BASE_TASK_CAP, fp, L4_FP_OTHER_SPACES);
84       _size -= (1UL << l4_fpage_size(fp));
85       offs  += (1UL << l4_fpage_size(fp));
86     }
87 }
88
89 int
90 Moe::Dataspace_cont::phys(l4_addr_t offset,
91                           l4_addr_t &phys_addr, l4_size_t &phys_size) throw()
92 {
93   // XXX where is the pinned flag?
94   // XXX lets assume this is contiguous...
95
96   if (offset >= size())
97     return -L4_EINVAL;
98
99   phys_addr = (l4_addr_t)start() + offset;
100   phys_size = size() - offset;
101   return 0;
102 }