]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4re-core/l4re/include/impl/rm_impl.h
Update
[l4.git] / l4 / pkg / l4re-core / l4re / include / impl / rm_impl.h
1 /**
2  * \file
3  * \brief  Region map 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/rm>
24 #include <l4/re/dataspace>
25
26 #include <l4/sys/cxx/ipc_client>
27
28 #include <l4/sys/task>
29 #include <l4/sys/err.h>
30
31 L4_RPC_DEF(L4Re::Rm::reserve_area);
32 L4_RPC_DEF(L4Re::Rm::free_area);
33 L4_RPC_DEF(L4Re::Rm::attach);
34 L4_RPC_DEF(L4Re::Rm::detach);
35 L4_RPC_DEF(L4Re::Rm::get_regions);
36 L4_RPC_DEF(L4Re::Rm::get_areas);
37 L4_RPC_DEF(L4Re::Rm::find);
38
39 namespace L4Re
40 {
41
42 long
43 Rm::attach(l4_addr_t *start, unsigned long size, unsigned long flags,
44            L4::Ipc::Cap<Dataspace> mem, l4_addr_t offs,
45            unsigned char align) const throw()
46 {
47   if (flags & Reserved)
48     mem = L4::Ipc::Cap<L4Re::Dataspace>();
49
50   long e = attach_t::call(c(), start, size, flags, mem, offs, align, mem.cap().cap());
51   if (e < 0)
52     return e;
53
54   if (flags & Eager_map)
55     {
56       unsigned long fl = (flags & Read_only)
57         ? Dataspace::Map_ro
58         : Dataspace::Map_rw;
59       e = mem.cap()->map_region(offs, fl, *start, *start + size);
60     }
61   return e;
62 }
63
64 int
65 Rm::detach(l4_addr_t start, unsigned long size, L4::Cap<Dataspace> *mem,
66            L4::Cap<L4::Task> task, unsigned flags) const throw()
67 {
68   l4_addr_t rstart = 0, rsize = 0;
69   l4_cap_idx_t mem_cap = L4_INVALID_CAP;
70   long e = detach_t::call(c(), start, size, flags, rstart, rsize, mem_cap);
71   if (L4_UNLIKELY(e < 0))
72     return e;
73
74   if (mem)
75     *mem = L4::Cap<L4Re::Dataspace>(mem_cap);
76
77   if (!task.is_valid())
78     return e;
79
80   rsize = l4_round_page(rsize);
81   unsigned order = L4_LOG2_PAGESIZE;
82   unsigned long sz = (1UL << order);
83   for (unsigned long p = rstart; rsize; p += sz, rsize -= sz)
84     {
85       while (sz > rsize)
86         {
87           --order;
88           sz >>= 1;
89         }
90
91       for (;;)
92         {
93           unsigned long m = sz << 1;
94           if (m > rsize)
95             break;
96
97           if (p & (m - 1))
98             break;
99
100           ++order;
101           sz <<= 1;
102         }
103
104       task->unmap(l4_fpage(p, order, L4_FPAGE_RWX),
105                   L4_FP_ALL_SPACES);
106     }
107
108   return e;
109 }
110 }