2011-12-22 15:19:25 +00:00
|
|
|
/*
|
2015-07-29 08:58:17 +00:00
|
|
|
* \brief Pager support for Pistachio
|
2011-12-22 15:19:25 +00:00
|
|
|
* \author Christian Helmuth
|
2015-07-29 08:58:17 +00:00
|
|
|
* \date 2006-06-14
|
2011-12-22 15:19:25 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
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-07-29 08:58:17 +00:00
|
|
|
/* Genode includes */
|
|
|
|
#include <base/printf.h>
|
|
|
|
#include <base/sleep.h>
|
|
|
|
|
2016-03-11 16:32:43 +00:00
|
|
|
/* base-internal includes */
|
|
|
|
#include <base/internal/native_thread.h>
|
|
|
|
|
2015-06-19 12:58:18 +00:00
|
|
|
/* Core includes */
|
2015-07-29 08:58:17 +00:00
|
|
|
#include <ipc_pager.h>
|
2015-06-19 12:58:18 +00:00
|
|
|
#include <pager.h>
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2015-07-29 08:58:17 +00:00
|
|
|
namespace Pistachio
|
|
|
|
{
|
|
|
|
#include <l4/message.h>
|
|
|
|
#include <l4/ipc.h>
|
|
|
|
#include <l4/schedule.h>
|
|
|
|
#include <l4/kdebug.h>
|
|
|
|
}
|
|
|
|
|
2011-12-22 15:19:25 +00:00
|
|
|
using namespace Genode;
|
2015-07-29 08:58:17 +00:00
|
|
|
using namespace Pistachio;
|
|
|
|
|
|
|
|
|
|
|
|
/*************
|
|
|
|
** Mapping **
|
|
|
|
*************/
|
|
|
|
|
|
|
|
Mapping::Mapping(addr_t dst_addr, addr_t src_addr,
|
|
|
|
Cache_attribute, bool io_mem, unsigned l2size,
|
|
|
|
bool rw, bool grant)
|
|
|
|
{
|
|
|
|
L4_Fpage_t fpage = L4_FpageLog2(src_addr, l2size);
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2015-07-29 08:58:17 +00:00
|
|
|
fpage += rw ? L4_FullyAccessible : L4_Readable;
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2015-07-29 08:58:17 +00:00
|
|
|
if (grant)
|
|
|
|
_grant_item = L4_GrantItem(fpage, dst_addr);
|
|
|
|
else
|
|
|
|
_map_item = L4_MapItem(fpage, dst_addr);
|
2011-12-22 15:19:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-07-29 08:58:17 +00:00
|
|
|
Mapping::Mapping() { _map_item = L4_MapItem(L4_Nilpage, 0); }
|
|
|
|
|
|
|
|
|
|
|
|
/***************
|
|
|
|
** IPC pager **
|
|
|
|
***************/
|
|
|
|
|
|
|
|
void Ipc_pager::wait_for_fault()
|
2011-12-22 15:19:25 +00:00
|
|
|
{
|
2015-07-29 08:58:17 +00:00
|
|
|
L4_MsgTag_t result;
|
|
|
|
L4_ThreadId_t sender = L4_nilthread;
|
|
|
|
bool failed;
|
|
|
|
|
|
|
|
do {
|
|
|
|
L4_Accept(L4_UntypedWordsAcceptor);
|
|
|
|
result = L4_Wait(&sender);
|
|
|
|
failed = L4_IpcFailed(result);
|
|
|
|
if (failed)
|
|
|
|
PERR("Page fault IPC error. (continuable)");
|
|
|
|
|
|
|
|
if (L4_UntypedWords(result) != 2) {
|
|
|
|
PERR("Malformed page-fault ipc. (sender = 0x%08lx)",
|
|
|
|
sender.raw);
|
|
|
|
failed = true;
|
2011-12-22 15:19:25 +00:00
|
|
|
}
|
|
|
|
|
2015-07-29 08:58:17 +00:00
|
|
|
} while (failed);
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2015-07-29 08:58:17 +00:00
|
|
|
L4_Msg_t msg;
|
|
|
|
// TODO Error checking. Did we really receive 2 words?
|
|
|
|
L4_Store(result, &msg);
|
|
|
|
|
|
|
|
_pf_addr = L4_Get(&msg, 0);
|
|
|
|
_pf_ip = L4_Get(&msg, 1);
|
|
|
|
_flags = L4_Label(result);
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2015-07-29 08:58:17 +00:00
|
|
|
_last = sender;
|
|
|
|
}
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
|
2015-07-29 08:58:17 +00:00
|
|
|
void Ipc_pager::reply_and_wait_for_fault()
|
2011-12-22 15:19:25 +00:00
|
|
|
{
|
2015-07-29 08:58:17 +00:00
|
|
|
/*
|
|
|
|
* XXX call memory-control if mapping has enabled write-combining
|
|
|
|
*/
|
|
|
|
|
|
|
|
L4_Msg_t msg;
|
|
|
|
L4_Accept(L4_UntypedWordsAcceptor);
|
|
|
|
L4_Clear(&msg);
|
|
|
|
|
|
|
|
/* this should work even if _map_item is a grant item */
|
|
|
|
L4_Append(&msg, _map_item);
|
|
|
|
L4_Load(&msg);
|
|
|
|
L4_MsgTag_t result = L4_ReplyWait(_last, &_last);
|
|
|
|
|
|
|
|
if (L4_IpcFailed(result)) {
|
|
|
|
PERR("Page fault IPC error. (continuable)");
|
|
|
|
wait_for_fault();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (L4_UntypedWords(result) != 2) {
|
|
|
|
PERR("Malformed page-fault ipc. (sender = 0x%08lx)", _last.raw);
|
|
|
|
wait_for_fault();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
L4_Clear(&msg);
|
|
|
|
// TODO Error checking. Did we really receive 2 words?
|
|
|
|
L4_Store(result, &msg);
|
|
|
|
|
|
|
|
_pf_addr = L4_Get(&msg, 0);
|
|
|
|
_pf_ip = L4_Get(&msg, 1);
|
|
|
|
_flags = L4_Label(result);
|
2011-12-22 15:19:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-07-29 08:58:17 +00:00
|
|
|
void Ipc_pager::acknowledge_wakeup()
|
2011-12-22 15:19:25 +00:00
|
|
|
{
|
2016-03-18 21:53:25 +00:00
|
|
|
L4_Reply(_last);
|
2015-07-29 08:58:17 +00:00
|
|
|
}
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
|
2015-07-29 08:58:17 +00:00
|
|
|
/**********************
|
|
|
|
** Pager entrypoint **
|
|
|
|
**********************/
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2015-08-10 11:34:16 +00:00
|
|
|
Untyped_capability Pager_entrypoint::_pager_object_cap(unsigned long badge)
|
2015-07-29 08:58:17 +00:00
|
|
|
{
|
2016-03-11 16:32:43 +00:00
|
|
|
return Untyped_capability(native_thread().l4id, badge);
|
2011-12-22 15:19:25 +00:00
|
|
|
}
|