]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4re-core/l4re_kernel/server/src/region.cc
Update
[l4.git] / l4 / pkg / l4re-core / l4re_kernel / server / src / region.cc
1 /*
2  * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3  *               Alexander Warg <warg@os.inf.tu-dresden.de>
4  *     economic rights: Technische Universität Dresden (Germany)
5  *
6  * This file is part of TUD:OS and distributed under the terms of the
7  * GNU General Public License 2.
8  * Please see the COPYING-GPL-2 file for details.
9  */
10 #include "region.h"
11 #include "globals.h"
12
13 #include <l4/sys/kip>
14
15 #include <l4/re/dataspace>
16 #include <l4/re/rm>
17 #include <l4/re/env>
18
19 #include <l4/cxx/iostream>
20 #include <l4/cxx/l4iostream>
21
22 #include "dispatcher.h"
23 #include "debug.h"
24
25 #include <cstdio>
26
27 using L4Re::Rm;
28 using L4Re::Dataspace;
29 using L4Re::Util::Region;
30
31 Region_map::Region_map()
32   : Base(0,0)
33 {}
34
35 void
36 Region_map::init()
37 {
38   extern char __L4_KIP_ADDR__[];
39
40   L4::Kip::Mem_desc *md = L4::Kip::Mem_desc::first(__L4_KIP_ADDR__);
41   unsigned long cnt = L4::Kip::Mem_desc::count(__L4_KIP_ADDR__);
42
43   for (L4::Kip::Mem_desc *m = md; m < md + cnt; ++m)
44     {
45       if (!m->is_virtual())
46         continue;
47
48       l4_addr_t start = m->start();
49       l4_addr_t end = m->end();
50       
51       switch (m->type())
52         {
53         case L4::Kip::Mem_desc::Conventional:
54           set_limits(start, end);
55           break;
56         case L4::Kip::Mem_desc::Reserved:
57           attach_area(start, end - start + 1, L4Re::Rm::Reserved);
58           break;
59         default:
60           break;
61         }
62     }
63
64   // reserve page at 0
65   attach_area(0, L4_PAGESIZE);
66 }
67
68
69 int
70 Region_ops::map(Region_handler const *h, l4_addr_t local_addr,
71                 Region const &r, bool writable, l4_umword_t *result)
72 {
73   *result = 0;
74   if ((h->flags() & Rm::Reserved) || !h->memory().is_valid())
75     return -L4_ENOENT;
76
77   if (h->flags() & Rm::Pager)
78     {
79       l4_mword_t result;
80       L4::Ipc::Snd_fpage rfp;
81       L4::cap_reinterpret_cast<L4::Pager>(h->memory())
82         ->page_fault((local_addr | (writable ? 2 : 0)), -3UL, result,
83                      L4::Ipc::Rcv_fpage::mem(0, L4_WHOLE_ADDRESS_SPACE, 0),
84                      rfp);
85       return L4_EOK;
86     }
87   else
88     {
89       l4_addr_t offset = local_addr - r.start() + h->offset();
90       L4::Cap<L4Re::Dataspace> ds = L4::cap_cast<L4Re::Dataspace>(h->memory());
91       unsigned flags = writable | (h->caching() >> Rm::Caching_ds_shift);
92       return ds->map(offset, flags, local_addr, r.start(), r.end());
93     }
94 }
95
96 void Region_ops::unmap(Region_handler const *h, l4_addr_t vaddr,
97                        l4_addr_t offs, unsigned long size)
98 {
99   (void)h; (void)vaddr; (void)offs; (void)size;
100 #if 0
101   for (l4_addr_t a = vaddr; a < vaddr + size; a += L4_PAGESIZE)
102     l4_task_unmap(L4Re::This_task,
103                   l4_fpage(a, L4_LOG2_PAGESIZE, L4_FPAGE_RWX),
104                   L4_FP_ALL_SPACES);
105
106   if (h->flags() & (Rm::Pager | Rm::Reserved))
107     return;
108
109   if (!(h->flags() & Rm::No_alias))
110     return;
111
112   L4::Cap<L4Re::Dataspace> ds = L4::cap_cast<L4Re::Dataspace>(h->memory());
113
114   // swipe out memory pages if they are not aliasd somewhere else
115   // the DSM may free thoses pages
116   ds->clear(offs, size);
117 #endif
118 }
119
120 void
121 Region_ops::free(Region_handler const *h, l4_addr_t start, unsigned long size)
122 {
123   if ((h->flags() & Rm::Reserved) || !h->memory().is_valid())
124     return;
125
126   if (h->flags() & Rm::Pager)
127     return;
128
129   L4::Cap<L4Re::Dataspace> ds = L4::cap_cast<L4Re::Dataspace>(h->memory());
130   ds->clear(h->offset() + start, size);
131 }
132
133 void
134 Region_ops::take(Region_handler const * /*h*/)
135 {
136 #if 0
137   if (h->flags() & (Rm::Pager | Rm::Reserved))
138     return;
139
140   L4::cap_cast<L4Re::Dataspace>(h->memory())->take();
141 #endif
142 }
143
144 void
145 Region_ops::release(Region_handler const * /*h*/)
146 {
147 #if 0
148   if (h->flags() & (Rm::Pager | Rm::Reserved))
149     return;
150
151   L4::cap_cast<L4Re::Dataspace>(h->memory())->release();
152 #endif
153 }
154
155 void
156 Region_map::debug_dump(unsigned long /*function*/) const
157 {
158   printf("Region mapping: limits [%lx-%lx]\n", min_addr(), max_addr());
159   printf(" Area map:\n");
160   for (Region_map::Const_iterator i = area_begin(); i != area_end(); ++i)
161     printf("  [%10lx-%10lx] -> flags=%x\n",
162            i->first.start(), i->first.end(),
163            i->second.flags());
164   printf(" Region map:\n");
165   for (Region_map::Const_iterator i = begin(); i != end(); ++i)
166     printf("  [%10lx-%10lx] -> (offs=%lx, ds=%lx, flags=%x)\n",
167            i->first.start(), i->first.end(),
168            i->second.offset(), i->second.memory().cap(),
169            i->second.flags());
170 }
171
172 int
173 Region_map::op_exception(L4::Exception::Rights, l4_exc_regs_t &u,
174                          L4::Ipc::Opt<L4::Ipc::Snd_fpage> &)
175 {
176   Dbg w(Dbg::Warn);
177   w.printf("unhandled exception: pc=0x%lx (pfa=%lx)\n", l4_utcb_exc_pc(&u),
178            l4_utcb_exc_pfa(&u));
179   w.printf("Global::l4re_aux->ldr_flags=%lx\n", Global::l4re_aux->ldr_flags);
180
181   return -L4_ENOREPLY;
182 }
183
184 long
185 Region_map::op_io_page_fault(L4::Io_pager::Rights,
186                              l4_fpage_t io_pfa, l4_umword_t pc,
187                              L4::Ipc::Opt<l4_mword_t> &result,
188                              L4::Ipc::Opt<L4::Ipc::Snd_fpage> &)
189 {
190   Err().printf("IO-port-fault: port=0x%lx size=%d pc=0x%lx\n",
191                l4_fpage_page(io_pfa), 1 << l4_fpage_size(io_pfa), pc);
192   result = ~0;
193   return -1;
194 }
195