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/sys/cxx/ipc_client>
25 #include <l4/sys/cxx/consts>
26
27 L4_RPC_DEF(L4Re::Dataspace::clear);
28 L4_RPC_DEF(L4Re::Dataspace::allocate);
29 L4_RPC_DEF(L4Re::Dataspace::copy_in);
30 L4_RPC_DEF(L4Re::Dataspace::info);
31
32 namespace L4Re {
33
34
35 long
__map(Dataspace::Offset offset,unsigned char * size,Dataspace::Flags flags,Dataspace::Map_addr local_addr)36 Dataspace::__map(Dataspace::Offset offset, unsigned char *size,
37 Dataspace::Flags flags,
38 Dataspace::Map_addr local_addr) const noexcept
39 {
40 Map_addr spot = local_addr & ~(~0ULL << l4_umword_t(*size));
41 Map_addr base = local_addr & (~0ULL << l4_umword_t(*size));
42 L4::Ipc::Rcv_fpage r;
43 r = L4::Ipc::Rcv_fpage::mem(base, *size, 0);
44
45 L4::Ipc::Snd_fpage fp;
46 long err = map_t::call(c(), offset, spot, flags, r, fp, l4_utcb());
47 if (L4_UNLIKELY(err < 0))
48 return err;
49
50 *size = fp.rcv_order();
51 return err;
52 }
53
54 long
map_region(Dataspace::Offset offset,Dataspace::Flags flags,Dataspace::Map_addr min_addr,Dataspace::Map_addr max_addr)55 Dataspace::map_region(Dataspace::Offset offset, Dataspace::Flags flags,
56 Dataspace::Map_addr min_addr,
57 Dataspace::Map_addr max_addr) const noexcept
58 {
59 min_addr = L4::trunc_page(min_addr);
60 max_addr = L4::round_page(max_addr);
61 unsigned char order = L4_LOG2_PAGESIZE;
62
63 long err = 0;
64
65 while (min_addr < max_addr)
66 {
67 unsigned char order_mapped;
68 order_mapped = order
69 = L4::max_order(order, min_addr, min_addr, max_addr, min_addr);
70
71 err = __map(offset, &order_mapped, flags, min_addr);
72 if (L4_UNLIKELY(err < 0))
73 return err;
74
75 if (order > order_mapped)
76 order = order_mapped;
77
78 min_addr += Map_addr(1) << order;
79 offset += Map_addr(1) << order;
80
81 if (min_addr >= max_addr)
82 return 0;
83
84 while (min_addr != L4::trunc_order(min_addr, order)
85 || max_addr < L4::round_order(min_addr + 1, order))
86 --order;
87 }
88
89 return 0;
90 }
91
92
93 long
map(Dataspace::Offset offset,Dataspace::Flags flags,Dataspace::Map_addr local_addr,Dataspace::Map_addr min_addr,Dataspace::Map_addr max_addr)94 Dataspace::map(Dataspace::Offset offset, Dataspace::Flags flags,
95 Dataspace::Map_addr local_addr,
96 Dataspace::Map_addr min_addr,
97 Dataspace::Map_addr max_addr) const noexcept
98 {
99 min_addr = L4::trunc_page(min_addr);
100 max_addr = L4::round_page(max_addr);
101 local_addr = L4::trunc_page(local_addr);
102 unsigned char order
103 = L4::max_order(L4_LOG2_PAGESIZE, local_addr, min_addr, max_addr, local_addr);
104
105 return __map(offset, &order, flags, local_addr);
106 }
107
108 Dataspace::Size
size()109 Dataspace::size() const noexcept
110 {
111 Stats stats = Stats();
112 int err = info(&stats);
113 if (err < 0)
114 return 0;
115 return stats.size;
116 }
117
118 Dataspace::Flags
flags()119 Dataspace::flags() const noexcept
120 {
121 Stats stats = Stats();
122 int err = info(&stats);
123 if (err < 0)
124 return Flags(0);
125 return stats.flags;
126 }
127
128 };
129