]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4re/include/impl/dataspace_impl.h
update
[l4.git] / l4 / pkg / l4re / include / impl / dataspace_impl.h
1 /**
2  * \file
3  * \brief  Dataspace client stub implementation
4  */
5 /*
6  * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
7  *               Alexander Warg <warg@os.inf.tu-dresden.de>
8  *     economic rights: Technische Universität Dresden (Germany)
9  *
10  * This file is part of TUD:OS and distributed under the terms of the
11  * GNU General Public License 2.
12  * Please see the COPYING-GPL-2 file for details.
13  *
14  * As a special exception, you may use this file as part of a free software
15  * library without restriction.  Specifically, if other files instantiate
16  * templates or use macros or inline functions from this file, or you compile
17  * this file and link it with other files to produce an executable, this
18  * file does not by itself cause the resulting executable to be covered by
19  * the GNU General Public License.  This exception does not however
20  * invalidate any other reasons why the executable file might be covered by
21  * the GNU General Public License.
22  */
23 #include <l4/re/dataspace>
24 #include <l4/re/dataspace-sys.h>
25 #include <l4/re/protocols>
26
27 #include <l4/cxx/exceptions>
28 #include <l4/cxx/ipc_helper>
29 #include <l4/cxx/ipc_stream>
30
31 inline
32 L4::Ipc_istream &operator >> (L4::Ipc_istream &s, L4Re::Dataspace::Stats &v)
33 { s.get(v); return s; }
34
35 namespace L4Re {
36
37 long
38 Dataspace::__map(unsigned long offset, unsigned char *size, unsigned long flags,
39                  l4_addr_t local_addr) const throw()
40 {
41   l4_addr_t spot = local_addr & ~(~0UL << l4_umword_t(*size));
42   l4_addr_t base = local_addr & (~0UL << l4_umword_t(*size));
43   L4::Ipc_iostream io(l4_utcb());
44   io << L4::Opcode(Dataspace_::Map) << offset << spot << flags;
45   io << L4::Rcv_fpage::mem(base, *size, 0);
46   long err = l4_error(io.call(cap(), L4Re::Protocol::Dataspace));
47   if (err < 0)
48     return err;
49
50   L4::Snd_fpage fp;
51   io >> fp;
52   *size = fp.rcv_order();
53   return err;
54 }
55
56 long
57 Dataspace::map_region(l4_addr_t offset, unsigned long flags,
58                       l4_addr_t min_addr, l4_addr_t max_addr) const throw()
59 {
60   min_addr   = l4_trunc_page(min_addr);
61   max_addr   = l4_round_page(max_addr);
62   unsigned char order = L4_LOG2_PAGESIZE;
63
64   long err = 0;
65
66   while (min_addr < max_addr)
67     {
68       unsigned char order_mapped;
69       order_mapped = order
70         = l4_fpage_max_order(order, min_addr, min_addr, max_addr, min_addr);
71       err = __map(offset, &order_mapped, flags, min_addr);
72       if (EXPECT_FALSE(err < 0))
73         return err;
74
75       if (order > order_mapped)
76         order = order_mapped;
77
78       min_addr += 1UL << order;
79       offset   += 1UL << order;
80
81       if (min_addr >= max_addr)
82         return 0;
83
84       while (min_addr != l4_trunc_size(min_addr, order)
85              || max_addr < l4_round_size(min_addr + 1,order))
86         --order;
87     }
88
89   return 0;
90 }
91
92
93 long
94 Dataspace::map(l4_addr_t offset, unsigned long flags,
95                l4_addr_t local_addr,
96                l4_addr_t min_addr, l4_addr_t max_addr) const throw()
97 {
98   min_addr   = l4_trunc_page(min_addr);
99   max_addr   = l4_round_page(max_addr);
100   local_addr = l4_trunc_page(local_addr);
101   unsigned char order
102     = l4_fpage_max_order(L4_LOG2_PAGESIZE, local_addr, min_addr, max_addr, local_addr);
103
104   return __map(offset, &order, flags, local_addr);
105 }
106
107 long
108 Dataspace::clear(unsigned long offset, unsigned long size) const throw()
109 {
110   L4::Ipc_iostream io(l4_utcb());
111   io << L4::Opcode(Dataspace_::Clear) << offset << size;
112   long err = l4_error(io.call(cap(), L4Re::Protocol::Dataspace));
113   if (EXPECT_FALSE(err < 0))
114     return err;
115
116   long sz;
117   io >> sz;
118   return sz;
119 }
120
121 int
122 Dataspace::info(Stats *stats) const throw()
123 {
124   L4::Ipc_iostream io(l4_utcb());
125   io << L4::Opcode(Dataspace_::Stats);
126   long err = l4_error(io.call(cap(), L4Re::Protocol::Dataspace));
127   if (EXPECT_FALSE(err < 0))
128     return err;
129
130   io >> *stats;
131   return 0;
132 }
133
134 long
135 Dataspace::size() const throw()
136 {
137   Stats stats;
138   int err = info(&stats);
139   if (err < 0)
140     return err;
141   return stats.size;
142 }
143
144 long
145 Dataspace::flags() const throw()
146 {
147   Stats stats;
148   int err = info(&stats);
149   if (err < 0)
150     return err;
151   return stats.flags;
152 }
153
154 long
155 Dataspace::copy_in(unsigned long dst_offs, L4::Cap<Dataspace> src,
156                    unsigned long src_offs, unsigned long size) const throw()
157 {
158   L4::Ipc_iostream io(l4_utcb());
159   io << L4::Opcode(Dataspace_::Copy) << dst_offs << src_offs << size << src;
160   return l4_error(io.call(cap(), L4Re::Protocol::Dataspace));
161 }
162
163 long
164 Dataspace::phys(l4_addr_t offset, l4_addr_t &phys_addr, l4_size_t &phys_size) const throw()
165 {
166   L4::Ipc_iostream io(l4_utcb());
167   io << L4::Opcode(Dataspace_::Phys) << offset;
168   long err = l4_error(io.call(cap(), L4Re::Protocol::Dataspace));
169   if (EXPECT_FALSE(err < 0))
170     return err;
171
172   io >> phys_addr >> phys_size;
173   return 0;
174 }
175
176 long
177 Dataspace::allocate(l4_addr_t offset, l4_size_t size) throw()
178 {
179   L4::Ipc_iostream io(l4_utcb());
180   io << L4::Opcode(Dataspace_::Allocate) << offset << size;
181   return l4_error(io.call(cap(), L4Re::Protocol::Dataspace));
182 }
183
184
185 long
186 Dataspace::take() const throw()
187 {
188   L4::Ipc_iostream io(l4_utcb());
189   io << L4::Opcode(Dataspace_::Take);
190   return l4_error(io.call(cap(), L4Re::Protocol::Dataspace));
191 }
192
193 long
194 Dataspace::release() const throw()
195 {
196   L4::Ipc_iostream io(l4_utcb());
197   io << L4::Opcode(Dataspace_::Release);
198   return l4_error(io.call(cap(), L4Re::Protocol::Dataspace));
199 }
200
201 };