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