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)
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.
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.
24 #include <l4/sys/types.h>
25 #include <l4/cxx/list>
26 #include <l4/cxx/ipc_server>
27 #include <l4/cxx/ipc_stream>
28 #include <l4/cxx/minmax>
29 #include <l4/re/dataspace>
30 #include <l4/re/dataspace-sys.h>
31 #include <l4/re/protocols>
32 #include <l4/re/util/dataspace_svr>
36 L4::Ipc_ostream &operator << (L4::Ipc_ostream &s,
37 L4Re::Dataspace::Stats const &st)
38 { s.put(st); return s; }
41 namespace L4Re { namespace Util {
44 Dataspace_svr::map(l4_addr_t offs, l4_addr_t hot_spot, unsigned long flags,
45 l4_addr_t min, l4_addr_t max, L4::Snd_fpage &memory)
47 int err = map_hook(offs, flags, min, max);
51 memory = L4::Snd_fpage();
53 offs = l4_trunc_page(offs);
54 hot_spot = l4_trunc_page(hot_spot);
56 if (!check_limit(offs))
59 printf("limit failed: off=%lx sz=%lx\n", offs, size());
64 min = l4_trunc_page(min);
65 max = l4_round_page(max);
67 l4_addr_t adr = _ds_start + offs;
68 unsigned char order = L4_PAGESHIFT;
70 while (order < 30 /* limit to 1GB flexpage */)
72 l4_addr_t map_base = l4_trunc_size(adr, order + 1);
73 if (map_base < _ds_start)
76 if (map_base + (1UL << (order + 1)) -1 > (_ds_start + round_size() - 1))
79 map_base = l4_trunc_size(hot_spot, order + 1);
83 if (map_base + (1UL << (order + 1)) -1 > max -1)
86 l4_addr_t mask = ~(~0UL << (order + 1));
87 if (hot_spot == ~0UL || ((adr ^ hot_spot) & mask))
93 l4_addr_t map_base = l4_trunc_size(adr, order);
94 //l4_addr_t map_offs = adr & ~(~0UL << order);
96 l4_fpage_t fpage = l4_fpage(map_base, order, flags && is_writable() ? L4_FPAGE_RWX : L4_FPAGE_RX);
98 memory = L4::Snd_fpage(fpage, hot_spot, _map_flags, _cache_flags);
104 Dataspace_svr::clear(l4_addr_t offs, unsigned long _size) const throw()
106 if (!check_limit(offs))
109 unsigned long sz = _size = cxx::min(_size, round_size()-offs);
113 unsigned long b_adr = _ds_start + offs;
114 unsigned long b_sz = cxx::min(_size - offs, sz);
116 memset((void *)b_adr, 0, b_sz);
126 Dataspace_svr::phys(l4_addr_t /*offset*/, l4_addr_t &/*phys_addr*/, l4_size_t &/*phys_size*/) throw()
132 Dataspace_svr::dispatch(l4_umword_t obj, L4::Ipc_iostream &ios)
137 L4::cout << "Dataspace_svr: DS: op=" << L4::n_hex(op) << "\n";
142 if (tag.label() != L4Re::Protocol::Dataspace)
143 return -L4_EBADPROTO;
147 case L4Re::Dataspace_::Map:
149 // L4_FPAGE_X means writable for DSs!
150 bool read_only = !is_writable() || !(obj & L4_FPAGE_X);
151 l4_addr_t offset, spot;
154 ios >> offset >> spot >> flags;
156 L4::cout << "MAPrq: " << L4::hex << offset << ", " << spot << ", "
160 if (read_only && (flags & 1))
163 long int ret = map(offset, spot, flags & 1, 0, ~0, fp);
165 L4::cout << "MAP: " << L4::hex << reinterpret_cast<unsigned long *>(&fp)[0]
166 << ", " << reinterpret_cast<unsigned long *>(&fp)[1]
167 << ", " << flags << ", " << (!read_only && (flags & 1))
168 << ", ret=" << ret << '\n';
175 case L4Re::Dataspace_::Clear:
177 if ((obj & 1) /* read only*/
178 || is_static() || !is_writable())
185 return clear(offs, sz);
187 case L4Re::Dataspace_::Stats:
189 L4Re::Dataspace::Stats s;
191 // only return writable if really writable
192 s.flags = (rw_flags() & ~Writable) | (!(obj & 1) && is_writable());
196 case L4Re::Dataspace_::Copy:
201 L4::Snd_fpage src_cap;
203 ios >> dst_offs >> src_offs >> sz >> src_cap;
205 if (!src_cap.id_received())
214 copy(dst_offs, src_cap.data(), src_offs, sz);
218 case L4Re::Dataspace_::Phys:
226 int ret = phys(offset, phys_addr, phys_size);
230 ios << phys_addr << phys_size;
234 case L4Re::Dataspace_::Take:
236 //L4::cout << "Dataspace_svr: T[" << this << "]: refs=" << ref_cnt() << '\n';
238 case L4Re::Dataspace_::Release:
239 if ((release() == 0) && !is_static())
241 //L4::cout << "Dataspace_svr: R[" << this << "]: refs=" << ref_cnt() << '\n';
245 //L4::cout << "Dataspace_svr: R[" << this << "]: refs=" << ref_cnt() << '\n';