genode/repos/base-sel4/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

136 lines
2.5 KiB
C++

/*
* \brief Pager
* \author Norman Feske
* \date 2015-05-01
*/
/*
* Copyright (C) 2015 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/sleep.h>
/* core includes */
#include <pager.h>
#include <core_capability_space.h>
#include <install_mapping.h>
/* base-internal includes */
#include <internal/capability_space_sel4.h>
/* seL4 includes */
#include <sel4/interfaces/sel4_client.h>
#include <sel4/arch/pfIPC.h>
using namespace Genode;
static bool const verbose = false;
struct Fault_info
{
addr_t ip = 0;
addr_t pf = 0;
bool write = 0;
Fault_info(seL4_MessageInfo_t msg_info)
:
ip(seL4_GetMR(0)),
pf(seL4_GetMR(1)),
write(seL4_Fault_isWriteFault(seL4_GetMR(3)))
{
if (verbose)
PINF("PF: ip=0x%lx, pf=0x%lx, write=%d", ip, pf, write);
}
};
/***************
** IPC pager **
***************/
void Ipc_pager::wait_for_fault()
{
_last = 0;
reply_and_wait_for_fault();
}
void Ipc_pager::reply_and_wait_for_fault()
{
if (_last)
install_mapping(_reply_mapping, _last);
seL4_Word badge = Rpc_obj_key::INVALID;
seL4_MessageInfo_t page_fault_msg_info;
if (_last) {
seL4_MessageInfo_t const reply_msg = seL4_MessageInfo_new(0, 0, 0, 0);
page_fault_msg_info =
seL4_ReplyWait(Thread_base::myself()->tid().ep_sel, reply_msg, &badge);
} else {
page_fault_msg_info =
seL4_Wait(Thread_base::myself()->tid().ep_sel, &badge);
}
Fault_info const fault_info(page_fault_msg_info);
_pf_ip = fault_info.ip;
_pf_addr = fault_info.pf;
_pf_write = fault_info.write;
_last = badge;
}
void Ipc_pager::acknowledge_wakeup()
{
PDBG("not implemented");
}
Ipc_pager::Ipc_pager() : _last(0) { }
/******************
** Pager object **
******************/
void Pager_object::wake_up()
{
PDBG("not implemented");
}
void Pager_object::unresolved_page_fault_occurred()
{
state.unresolved_page_fault = true;
}
/**********************
** Pager entrypoint **
**********************/
Untyped_capability Pager_entrypoint::_manage(Pager_object *obj)
{
/*
* Create minted endpoint capability of the pager entrypoint.
* The badge of the page-fault message is used to find the pager
* object for faulted thread.
*/
Rpc_obj_key rpc_obj_key((addr_t)obj->badge());
Untyped_capability ep_cap(Capability_space::create_ep_cap(*this));
return Capability_space::create_rpc_obj_cap(ep_cap, nullptr, rpc_obj_key);
}