genode/repos/base-hw/src/core/pager.cc
Stefan Kalkowski eafe5e81e3 core: unify and simplify paging code (Fix #1641)
For most platforms except of NOVA a distinction between pager entrypoint
and pager activation is not needed, and only exists due to historical
reasons. Moreover, the pager thread's execution path is almost identical
between most platforms excluding NOVA, HW, and Fisco.OC. Therefore,
this commit unifies the pager loop for the other platforms, and removes
the pager activation class.
2015-08-21 10:58:59 +02:00

123 lines
2.8 KiB
C++

/*
* \brief Pager implementations that are specific for the HW-core
* \author Martin Stein
* \date 2012-03-29
*/
/*
* Copyright (C) 2012-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Genode includes */
#include <base/printf.h>
/* core includes*/
#include <pager.h>
#include <platform_thread.h>
#include <platform_pd.h>
using namespace Genode;
/*************
** Mapping **
*************/
Mapping::Mapping(addr_t const va, addr_t const pa,
Cache_attribute const c, bool const io,
unsigned const sl2, bool const w)
:
virt_address(va), phys_address(pa), cacheable(c),
io_mem(io), size_log2(sl2), writable(w)
{ }
Mapping::Mapping()
:
virt_address(0), phys_address(0), cacheable(CACHED),
io_mem(0), size_log2(0), writable(0)
{ }
void Mapping::prepare_map_operation() { }
/***************
** Ipc_pager **
***************/
addr_t Ipc_pager::fault_ip() const { return _fault.ip; }
addr_t Ipc_pager::fault_addr() const { return _fault.addr; }
bool Ipc_pager::is_write_fault() const { return _fault.writes; }
void Ipc_pager::set_reply_mapping(Mapping m) { _mapping = m; }
/******************
** Pager_object **
******************/
Thread_capability Pager_object::thread_cap() const { return _thread_cap; }
void Pager_object::thread_cap(Thread_capability const & c) { _thread_cap = c; }
void Pager_object::wake_up()
{
using Object = Kernel_object<Kernel::Signal_context>;
Kernel::ack_signal(Object::_cap.dst());
}
void Pager_object::start_paging(Kernel::Signal_receiver * receiver)
{
using Object = Kernel_object<Kernel::Signal_context>;
using Entry = Object_pool<Pager_object>::Entry;
create(receiver, (unsigned long)this);
Entry::cap(Object::_cap);
}
void Pager_object::exception_handler(Signal_context_capability) { }
void Pager_object::unresolved_page_fault_occurred()
{
Platform_thread * const pt = (Platform_thread *)badge();
if (pt && pt->pd())
PERR("%s -> %s: unresolved pagefault at ip=%p sp=%p",
pt->pd()->label(), pt->label(), (void*)pt->state().ip, (void*)pt->state().sp);
}
Pager_object::Pager_object(unsigned const badge, Affinity::Location)
: Object_pool<Pager_object>::Entry(Kernel_object<Kernel::Signal_context>::_cap),
_badge(badge)
{ }
/**********************
** Pager_entrypoint **
**********************/
void Pager_entrypoint::dissolve(Pager_object * const o)
{
remove_locked(o);
}
Pager_entrypoint::Pager_entrypoint(Cap_session *)
: Thread<PAGER_EP_STACK_SIZE>("pager_ep"),
Kernel_object<Kernel::Signal_receiver>(true)
{ start(); }
Pager_capability Pager_entrypoint::manage(Pager_object * const o)
{
o->start_paging(kernel_object());
insert(o);
return reinterpret_cap_cast<Pager_object>(o->cap());
}