3 * \brief Dataspace client stub implementation
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)
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.
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.
23 #include <l4/re/dataspace>
24 #include <l4/re/dataspace-sys.h>
25 #include <l4/re/protocols>
27 #include <l4/cxx/exceptions>
28 #include <l4/cxx/ipc_helper>
29 #include <l4/cxx/ipc_stream>
32 L4::Ipc_istream &operator >> (L4::Ipc_istream &s, L4Re::Dataspace::Stats &v)
33 { s.get(v); return s; }
38 Dataspace::__map(unsigned long offset, unsigned char *size, unsigned long flags,
39 l4_addr_t local_addr) const throw()
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));
52 *size = fp.rcv_order();
57 Dataspace::map_region(l4_addr_t offset, unsigned long flags,
58 l4_addr_t min_addr, l4_addr_t max_addr) const throw()
60 min_addr = l4_trunc_page(min_addr);
61 max_addr = l4_round_page(max_addr);
62 unsigned char order = L4_LOG2_PAGESIZE;
66 while (min_addr < max_addr)
68 unsigned char order_mapped;
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))
75 if (order > order_mapped)
78 min_addr += 1UL << order;
79 offset += 1UL << order;
81 if (min_addr >= max_addr)
84 while (min_addr != l4_trunc_size(min_addr, order)
85 || max_addr < l4_round_size(min_addr + 1,order))
94 Dataspace::map(l4_addr_t offset, unsigned long flags,
96 l4_addr_t min_addr, l4_addr_t max_addr) const throw()
98 min_addr = l4_trunc_page(min_addr);
99 max_addr = l4_round_page(max_addr);
100 local_addr = l4_trunc_page(local_addr);
102 = l4_fpage_max_order(L4_LOG2_PAGESIZE, local_addr, min_addr, max_addr, local_addr);
104 return __map(offset, &order, flags, local_addr);
108 Dataspace::clear(unsigned long offset, unsigned long size) const throw()
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))
122 Dataspace::info(Stats *stats) const throw()
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))
135 Dataspace::size() const throw()
138 int err = info(&stats);
145 Dataspace::flags() const throw()
148 int err = info(&stats);
155 Dataspace::copy_in(unsigned long dst_offs, L4::Cap<Dataspace> src,
156 unsigned long src_offs, unsigned long size) const throw()
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));
164 Dataspace::phys(l4_addr_t offset, l4_addr_t &phys_addr, l4_size_t &phys_size) const throw()
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))
172 io >> phys_addr >> phys_size;
177 Dataspace::allocate(l4_addr_t offset, l4_size_t size) throw()
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));
186 Dataspace::take() const throw()
188 L4::Ipc_iostream io(l4_utcb());
189 io << L4::Opcode(Dataspace_::Take);
190 return l4_error(io.call(cap(), L4Re::Protocol::Dataspace));
194 Dataspace::release() const throw()
196 L4::Ipc_iostream io(l4_utcb());
197 io << L4::Opcode(Dataspace_::Release);
198 return l4_error(io.call(cap(), L4Re::Protocol::Dataspace));