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)
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.
15 #include <l4/re/dataspace>
19 #include <l4/cxx/iostream>
20 #include <l4/cxx/l4iostream>
22 #include "dispatcher.h"
28 using L4Re::Dataspace;
29 using L4Re::Util::Region;
31 Region_map::Region_map()
38 extern char __L4_KIP_ADDR__[];
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__);
43 for (L4::Kip::Mem_desc *m = md; m < md + cnt; ++m)
48 l4_addr_t start = m->start();
49 l4_addr_t end = m->end();
53 case L4::Kip::Mem_desc::Conventional:
54 set_limits(start, end);
56 case L4::Kip::Mem_desc::Reserved:
57 attach_area(start, end - start + 1, L4Re::Rm::Reserved);
65 attach_area(0, L4_PAGESIZE);
70 Region_ops::map(Region_handler const *h, l4_addr_t local_addr,
71 Region const &r, bool writable, l4_umword_t *result)
74 if ((h->flags() & Rm::Reserved) || !h->memory().is_valid())
77 if (h->flags() & Rm::Pager)
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),
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());
96 void Region_ops::unmap(Region_handler const *h, l4_addr_t vaddr,
97 l4_addr_t offs, unsigned long size)
99 (void)h; (void)vaddr; (void)offs; (void)size;
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),
106 if (h->flags() & (Rm::Pager | Rm::Reserved))
109 if (!(h->flags() & Rm::No_alias))
112 L4::Cap<L4Re::Dataspace> ds = L4::cap_cast<L4Re::Dataspace>(h->memory());
114 // swipe out memory pages if they are not aliasd somewhere else
115 // the DSM may free thoses pages
116 ds->clear(offs, size);
121 Region_ops::free(Region_handler const *h, l4_addr_t start, unsigned long size)
123 if ((h->flags() & Rm::Reserved) || !h->memory().is_valid())
126 if (h->flags() & Rm::Pager)
129 L4::Cap<L4Re::Dataspace> ds = L4::cap_cast<L4Re::Dataspace>(h->memory());
130 ds->clear(h->offset() + start, size);
134 Region_ops::take(Region_handler const * /*h*/)
137 if (h->flags() & (Rm::Pager | Rm::Reserved))
140 L4::cap_cast<L4Re::Dataspace>(h->memory())->take();
145 Region_ops::release(Region_handler const * /*h*/)
148 if (h->flags() & (Rm::Pager | Rm::Reserved))
151 L4::cap_cast<L4Re::Dataspace>(h->memory())->release();
156 Region_map::debug_dump(unsigned long /*function*/) const
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(),
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(),
173 Region_map::op_exception(L4::Exception::Rights, l4_exc_regs_t &u,
174 L4::Ipc::Opt<L4::Ipc::Snd_fpage> &)
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);
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> &)
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);