2011-12-22 15:19:25 +00:00
|
|
|
/*
|
|
|
|
* \brief Pistachio pager framework
|
|
|
|
* \author Norman Feske
|
|
|
|
* \author Christian Helmuth
|
|
|
|
* \date 2006-07-14
|
|
|
|
*
|
|
|
|
* FIXME Isn't this file generic?
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2013-01-10 20:44:47 +00:00
|
|
|
* Copyright (C) 2006-2013 Genode Labs GmbH
|
2011-12-22 15:19:25 +00:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
|
|
* under the terms of the GNU General Public License version 2.
|
|
|
|
*/
|
|
|
|
|
2015-06-19 12:58:18 +00:00
|
|
|
/* Core includes */
|
|
|
|
#include <pager.h>
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
using namespace Genode;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Pistachio {
|
|
|
|
#include <l4/thread.h>
|
|
|
|
}
|
|
|
|
|
|
|
|
/**********************
|
|
|
|
** Pager activation **
|
|
|
|
**********************/
|
|
|
|
|
|
|
|
void Pager_activation_base::entry()
|
|
|
|
{
|
|
|
|
Ipc_pager pager;
|
|
|
|
_cap = pager;
|
|
|
|
_cap_valid.unlock();
|
|
|
|
|
2012-12-14 09:03:55 +00:00
|
|
|
Pager_object * obj;
|
|
|
|
bool reply = false;
|
|
|
|
|
2011-12-22 15:19:25 +00:00
|
|
|
while (1) {
|
|
|
|
|
2012-12-14 09:03:55 +00:00
|
|
|
if (reply)
|
|
|
|
pager.reply_and_wait_for_fault();
|
|
|
|
else
|
|
|
|
pager.wait_for_fault();
|
|
|
|
|
2011-12-22 15:19:25 +00:00
|
|
|
/* lookup referenced object */
|
2012-12-14 09:03:55 +00:00
|
|
|
Object_pool<Pager_object>::Guard _obj(_ep ? _ep->lookup_and_lock(pager.badge()) : 0);
|
|
|
|
obj = _obj;
|
|
|
|
reply = false;
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
/* handle request */
|
|
|
|
if (obj) {
|
2012-12-14 09:03:55 +00:00
|
|
|
/* if something strange occurred - leave thread in pagefault */
|
|
|
|
reply = !obj->pager(pager);
|
|
|
|
continue;
|
2011-12-22 15:19:25 +00:00
|
|
|
} else {
|
|
|
|
|
|
|
|
/* prevent threads outside of core to mess with our wake-up interface */
|
|
|
|
// enum { CORE_TASK_ID = 4 };
|
|
|
|
// if (pager.last().id.task != CORE_TASK_ID) {
|
|
|
|
|
|
|
|
#warning Check for messages from outside of core
|
|
|
|
if (0) {
|
|
|
|
PWRN("page fault to 0x%08lx from unknown partner %lx.",
|
|
|
|
Pistachio::L4_Myself().raw,
|
|
|
|
pager.last().raw);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We got a request from one of cores region-manager sessions
|
|
|
|
* to answer the pending page fault of a resolved region-manager
|
|
|
|
* client. Hence, we have to send the page-fault reply to the
|
|
|
|
* specified thread and answer the call of the region-manager
|
|
|
|
* session.
|
|
|
|
*
|
|
|
|
* When called from a region-manager session, we receive the
|
|
|
|
* core-local address of the targeted pager object via the
|
|
|
|
* first message word, which corresponds to the 'fault_ip'
|
|
|
|
* argument of normal page-fault messages.
|
|
|
|
*/
|
|
|
|
obj = reinterpret_cast<Pager_object *>(pager.fault_ip());
|
|
|
|
|
|
|
|
/* send reply to the calling region-manager session */
|
|
|
|
pager.acknowledge_wakeup();
|
|
|
|
|
|
|
|
/* answer page fault of resolved pager object */
|
|
|
|
pager.set_reply_dst(obj->cap());
|
|
|
|
pager.acknowledge_wakeup();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**********************
|
|
|
|
** Pager entrypoint **
|
|
|
|
**********************/
|
|
|
|
|
|
|
|
Pager_entrypoint::Pager_entrypoint(Cap_session *, Pager_activation_base *a)
|
|
|
|
: _activation(a)
|
|
|
|
{ _activation->ep(this); }
|
|
|
|
|
|
|
|
|
|
|
|
void Pager_entrypoint::dissolve(Pager_object *obj)
|
|
|
|
{
|
2012-12-14 09:03:55 +00:00
|
|
|
remove_locked(obj);
|
2011-12-22 15:19:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Pager_capability Pager_entrypoint::manage(Pager_object *obj)
|
|
|
|
{
|
|
|
|
/* return invalid capability if no activation is present */
|
|
|
|
if (!_activation) return Pager_capability();
|
|
|
|
|
2012-03-09 11:25:11 +00:00
|
|
|
Native_capability cap = Native_capability(_activation->cap().dst(), obj->badge());
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
/* add server object to object pool */
|
|
|
|
obj->cap(cap);
|
|
|
|
insert(obj);
|
|
|
|
|
|
|
|
/* return capability that uses the object id as badge */
|
|
|
|
return reinterpret_cap_cast<Pager_object>(cap);
|
|
|
|
}
|