]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4re-core/l4re/util/libs/dataspace_svr.cc
Update
[l4.git] / l4 / pkg / l4re-core / l4re / util / libs / dataspace_svr.cc
1 // vi:ft=cpp
2 /*
3  * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
4  *               Alexander Warg <warg@os.inf.tu-dresden.de>,
5  *               Torsten Frenzel <frenzel@os.inf.tu-dresden.de>
6  *     economic rights: Technische Universität Dresden (Germany)
7  *
8  * This file is part of TUD:OS and distributed under the terms of the
9  * GNU General Public License 2.
10  * Please see the COPYING-GPL-2 file for details.
11  *
12  * As a special exception, you may use this file as part of a free software
13  * library without restriction.  Specifically, if other files instantiate
14  * templates or use macros or inline functions from this file, or you compile
15  * this file and link it with other files to produce an executable, this
16  * file does not by itself cause the resulting executable to be covered by
17  * the GNU General Public License.  This exception does not however
18  * invalidate any other reasons why the executable file might be covered by
19  * the GNU General Public License.
20  */
21 #include <cstring>
22 #include <cstddef>
23 #include <cstdio>
24 #include <l4/sys/types.h>
25 #include <l4/cxx/list>
26 #include <l4/cxx/minmax>
27 #include <l4/re/dataspace>
28 #include <l4/re/dataspace-sys.h>
29 #include <l4/re/util/dataspace_svr>
30
31 #if 0
32 inline
33 L4::Ipc::Ostream &operator << (L4::Ipc_ostream &s,
34                               L4Re::Dataspace::Stats const &st)
35 { s.put(st); return s; }
36 #endif
37
38 namespace L4Re { namespace Util {
39
40 int
41 Dataspace_svr::map(l4_addr_t offs, l4_addr_t hot_spot, unsigned long flags,
42                     l4_addr_t min, l4_addr_t max, L4::Ipc::Snd_fpage &memory)
43 {
44   int err = map_hook(offs, flags, min, max);
45   if (err < 0)
46     return err;
47
48   memory = L4::Ipc::Snd_fpage();
49
50   offs     = l4_trunc_page(offs);
51   hot_spot = l4_trunc_page(hot_spot);
52
53   if (!check_limit(offs))
54     {
55 #if 0
56       printf("limit failed: off=%lx sz=%lx\n", offs, size());
57 #endif
58       return -L4_ERANGE;
59     }
60
61   min = l4_trunc_page(min);
62   max = l4_round_page(max);
63
64   l4_addr_t addr = _ds_start + offs;
65   unsigned char order = L4_PAGESHIFT;
66
67   while (order < 30 /* limit to 1GB flexpage */)
68     {
69       l4_addr_t map_base = l4_trunc_size(addr, order + 1);
70       if (map_base < _ds_start)
71         break;
72
73       if (map_base + (1UL << (order + 1)) -1 > (_ds_start + round_size() - 1))
74         break;
75
76       map_base = l4_trunc_size(hot_spot, order + 1);
77       if (map_base < min)
78         break;
79
80       if (map_base + (1UL << (order + 1)) -1 > max -1)
81         break;
82
83       l4_addr_t mask = ~(~0UL << (order + 1));
84       if (hot_spot == ~0UL || ((addr ^ hot_spot) & mask))
85         break;
86
87       ++order;
88     }
89
90   l4_addr_t map_base = l4_trunc_size(addr, order);
91   //l4_addr_t map_offs = addr & ~(~0UL << order);
92
93   l4_fpage_t fpage = l4_fpage(map_base, order, flags && is_writable() ?  L4_FPAGE_RWX : L4_FPAGE_RX);
94
95   memory = L4::Ipc::Snd_fpage(fpage, hot_spot, _map_flags, _cache_flags);
96
97   return L4_EOK;
98 }
99
100 long
101 Dataspace_svr::clear(l4_addr_t offs, unsigned long _size) const throw()
102 {
103   if (!check_limit(offs))
104     return -L4_ERANGE;
105
106   unsigned long sz = _size = cxx::min(_size, round_size()-offs);
107
108   while (sz)
109     {
110       unsigned long b_addr = _ds_start + offs;
111       unsigned long b_sz = cxx::min(_size - offs, sz);
112
113       memset((void *)b_addr, 0, b_sz);
114
115       offs += b_sz;
116       sz -= b_sz;
117     }
118
119   return _size;
120 }
121
122 int
123 Dataspace_svr::phys(l4_addr_t /*offset*/, l4_addr_t &/*phys_addr*/, l4_size_t &/*phys_size*/) throw()
124 {
125   return -L4_EINVAL;
126 }
127
128 }}