diff --git a/repos/base-codezero/src/core/include/ipc_pager.h b/repos/base-codezero/src/core/include/ipc_pager.h
index dd0c243baf..6e9d387f1f 100644
--- a/repos/base-codezero/src/core/include/ipc_pager.h
+++ b/repos/base-codezero/src/core/include/ipc_pager.h
@@ -71,7 +71,7 @@ namespace Genode {
/**
* Special paging server class
*/
- class Ipc_pager : public Native_capability
+ class Ipc_pager
{
private:
@@ -96,11 +96,6 @@ namespace Genode {
public:
- /**
- * Constructor
- */
- Ipc_pager();
-
/**
* Wait for a new page fault received as short message IPC
*/
@@ -141,9 +136,9 @@ namespace Genode {
void acknowledge_wakeup();
/**
- * Return thread ID of last faulter
+ * Returns true if the last request was send from a core thread
*/
- Native_thread_id last() const { return _last; }
+ bool request_from_core() { return true; }
/**
* Return badge for faulting thread
diff --git a/repos/base-codezero/src/core/ipc_pager.cc b/repos/base-codezero/src/core/ipc_pager.cc
deleted file mode 100644
index c7694d2bca..0000000000
--- a/repos/base-codezero/src/core/ipc_pager.cc
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * \brief Pager support for Codezero
- * \author Norman Feske
- * \date 2010-02-16
- */
-
-/*
- * Copyright (C) 2010-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
-
-/* Codezero includes */
-#include
-#include
-
-
-using namespace Genode;
-using namespace Codezero;
-
-enum { verbose_page_faults = false };
-
-
-/************************
- ** Page-fault utility **
- ************************/
-
-class Fault
-{
- public:
-
- enum Type { READ, WRITE, EXEC, UNKNOWN };
-
- private:
-
- /**
- * Translate Codezero page-fault information to generic fault type
- *
- * \param sr status
- * \param pte page-table entry
- */
- static Type _fault_type(umword_t sr, umword_t pte)
- {
- if (is_prefetch_abort(sr))
- return EXEC;
-
- if ((pte & PTE_PROT_MASK) == (__MAP_USR_RO & PTE_PROT_MASK))
- return WRITE;
-
- return READ;
- }
-
- Type _type;
- umword_t _addr;
- umword_t _ip;
-
- public:
-
- /**
- * Constructor
- *
- * \param kdata Codezero-specific page-fault information
- */
- Fault(struct fault_kdata const &kdata)
- :
- _type(_fault_type(kdata.fsr, kdata.pte)),
- _addr(_type == EXEC ? kdata.faulty_pc : kdata.far),
- _ip(kdata.faulty_pc)
- { }
-
- Type type() const { return _type; }
- umword_t addr() const { return _addr; }
- umword_t ip() const { return _ip; }
-};
-
-
-/**
- * Print page-fault information in a human-readable form
- */
-inline void print_page_fault(Fault &fault, int from)
-{
- printf("page (%s%s%s) fault from %d at pf_addr=%lx, pf_ip=%lx\n",
- fault.type() == Fault::READ ? "r" : "-",
- fault.type() == Fault::WRITE ? "w" : "-",
- fault.type() == Fault::EXEC ? "x" : "-",
- from, fault.addr(), fault.ip());
-}
-
-
-/***************
- ** IPC pager **
- ***************/
-
-void Ipc_pager::wait_for_fault()
-{
- for (;;) {
- int ret = l4_receive(L4_ANYTHREAD);
-
- if (ret < 0) {
- PERR("pager: l4_received returned ret=%d", ret);
- continue;
- }
-
- umword_t tag = l4_get_tag();
- int faulter_tid = l4_get_sender();
-
- if (tag != L4_IPC_TAG_PFAULT) {
- PWRN("got an unexpected IPC from %d", faulter_tid);
- continue;
- }
-
- /* copy fault information from message registers */
- struct fault_kdata fault_kdata;
- for (unsigned i = 0; i < sizeof(fault_kdata_t)/sizeof(umword_t); i++)
- ((umword_t *)&fault_kdata)[i] = read_mr(MR_UNUSED_START + i);
-
- Fault fault(fault_kdata);
-
- if (verbose_page_faults)
- print_page_fault(fault, faulter_tid);
-
- /* determine corresponding page in our own address space */
- _pf_addr = fault.addr();
- _pf_write = fault.type() == Fault::WRITE;
- _pf_ip = fault.ip();
- _last = faulter_tid;
-
- return;
- }
-}
-
-
-void Ipc_pager::reply_and_wait_for_fault()
-{
- /* install mapping */
- umword_t flags = _reply_mapping.writeable() ? MAP_USR_RW
- : MAP_USR_RO;
-
- /*
- * XXX: remove heuristics for mapping device registers.
- */
- if (_reply_mapping.from_phys() == 0x10120000 /* LCD */
- || _reply_mapping.from_phys() == 0x10006000 /* keyboard */
- || _reply_mapping.from_phys() == 0x10007000) /* mouse */
- flags = MAP_USR_IO;
-
- int ret = l4_map((void *)_reply_mapping.from_phys(),
- (void *)_reply_mapping.to_virt(),
- _reply_mapping.num_pages(), flags, _last);
-
- /* wake up faulter if mapping succeeded */
- if (ret < 0)
- PERR("l4_map returned %d, putting thread %d to sleep", ret, _last);
- else
- acknowledge_wakeup();
-
- /* wait for next page fault */
- wait_for_fault();
-}
-
-
-void Ipc_pager::acknowledge_wakeup()
-{
- enum { SUCCESS = 0 };
- l4_set_sender(_last);
- l4_ipc_return(SUCCESS);
-}
-
-
-Ipc_pager::Ipc_pager() : Native_capability(thread_myself(), 0) { }
-
diff --git a/repos/base-codezero/src/core/pager.cc b/repos/base-codezero/src/core/pager.cc
index 34b66ee0e6..53e98dd077 100644
--- a/repos/base-codezero/src/core/pager.cc
+++ b/repos/base-codezero/src/core/pager.cc
@@ -1,105 +1,182 @@
/*
- * \brief Dummy pager framework
+ * \brief Pager support for Codezero
* \author Norman Feske
- * \date 2009-10-02
+ * \date 2010-02-16
*/
/*
- * Copyright (C) 2009-2013 Genode Labs GmbH
+ * Copyright (C) 2010-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.
*/
-/* Core includes */
+/* Genode includes */
+#include
#include
+/* Codezero includes */
+#include
+#include
+
+
using namespace Genode;
+using namespace Codezero;
+
+enum { verbose_page_faults = false };
-/**********************
- ** Pager activation **
- **********************/
+/************************
+ ** Page-fault utility **
+ ************************/
-void Pager_activation_base::entry()
+class Fault
{
- Ipc_pager pager;
- _cap = pager;
- _cap_valid.unlock();
+ public:
- bool reply = false;
+ enum Type { READ, WRITE, EXEC, UNKNOWN };
- while (1) {
+ private:
- if (reply)
- pager.reply_and_wait_for_fault();
- else
- pager.wait_for_fault();
+ /**
+ * Translate Codezero page-fault information to generic fault type
+ *
+ * \param sr status
+ * \param pte page-table entry
+ */
+ static Type _fault_type(umword_t sr, umword_t pte)
+ {
+ if (is_prefetch_abort(sr))
+ return EXEC;
- /* lookup referenced object */
- Object_pool::Guard _obj(_ep ? _ep->lookup_and_lock(pager.badge()) : 0);
- Pager_object * obj = _obj;
- reply = false;
+ if ((pte & PTE_PROT_MASK) == (__MAP_USR_RO & PTE_PROT_MASK))
+ return WRITE;
- /* handle request */
- if (obj) {
- reply = !obj->pager(pager);
- /* something strange occurred - leave thread in pagefault */
+ return READ;
+ }
+
+ Type _type;
+ umword_t _addr;
+ umword_t _ip;
+
+ public:
+
+ /**
+ * Constructor
+ *
+ * \param kdata Codezero-specific page-fault information
+ */
+ Fault(struct fault_kdata const &kdata)
+ :
+ _type(_fault_type(kdata.fsr, kdata.pte)),
+ _addr(_type == EXEC ? kdata.faulty_pc : kdata.far),
+ _ip(kdata.faulty_pc)
+ { }
+
+ Type type() const { return _type; }
+ umword_t addr() const { return _addr; }
+ umword_t ip() const { return _ip; }
+};
+
+
+/**
+ * Print page-fault information in a human-readable form
+ */
+inline void print_page_fault(Fault &fault, int from)
+{
+ printf("page (%s%s%s) fault from %d at pf_addr=%lx, pf_ip=%lx\n",
+ fault.type() == Fault::READ ? "r" : "-",
+ fault.type() == Fault::WRITE ? "w" : "-",
+ fault.type() == Fault::EXEC ? "x" : "-",
+ from, fault.addr(), fault.ip());
+}
+
+
+/***************
+ ** IPC pager **
+ ***************/
+
+void Ipc_pager::wait_for_fault()
+{
+ for (;;) {
+ int ret = l4_receive(L4_ANYTHREAD);
+
+ if (ret < 0) {
+ PERR("pager: l4_received returned ret=%d", ret);
continue;
}
- /*
- * 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.fault_ip());
+ umword_t tag = l4_get_tag();
+ int faulter_tid = l4_get_sender();
- /* send reply to the calling region-manager session */
- pager.acknowledge_wakeup();
+ if (tag != L4_IPC_TAG_PFAULT) {
+ PWRN("got an unexpected IPC from %d", faulter_tid);
+ continue;
+ }
- /* answer page fault of resolved pager object */
- pager.set_reply_dst(obj->cap());
- pager.acknowledge_wakeup();
+ /* copy fault information from message registers */
+ struct fault_kdata fault_kdata;
+ for (unsigned i = 0; i < sizeof(fault_kdata_t)/sizeof(umword_t); i++)
+ ((umword_t *)&fault_kdata)[i] = read_mr(MR_UNUSED_START + i);
+
+ Fault fault(fault_kdata);
+
+ if (verbose_page_faults)
+ print_page_fault(fault, faulter_tid);
+
+ /* determine corresponding page in our own address space */
+ _pf_addr = fault.addr();
+ _pf_write = fault.type() == Fault::WRITE;
+ _pf_ip = fault.ip();
+ _last = faulter_tid;
+
+ return;
}
}
+void Ipc_pager::reply_and_wait_for_fault()
+{
+ /* install mapping */
+ umword_t flags = _reply_mapping.writeable() ? MAP_USR_RW
+ : MAP_USR_RO;
+
+ /*
+ * XXX: remove heuristics for mapping device registers.
+ */
+ if (_reply_mapping.from_phys() == 0x10120000 /* LCD */
+ || _reply_mapping.from_phys() == 0x10006000 /* keyboard */
+ || _reply_mapping.from_phys() == 0x10007000) /* mouse */
+ flags = MAP_USR_IO;
+
+ int ret = l4_map((void *)_reply_mapping.from_phys(),
+ (void *)_reply_mapping.to_virt(),
+ _reply_mapping.num_pages(), flags, _last);
+
+ /* wake up faulter if mapping succeeded */
+ if (ret < 0)
+ PERR("l4_map returned %d, putting thread %d to sleep", ret, _last);
+ else
+ acknowledge_wakeup();
+
+ /* wait for next page fault */
+ wait_for_fault();
+}
+
+
+void Ipc_pager::acknowledge_wakeup()
+{
+ enum { SUCCESS = 0 };
+ l4_set_sender(_last);
+ l4_ipc_return(SUCCESS);
+}
+
+
/**********************
** Pager entrypoint **
**********************/
-Pager_entrypoint::Pager_entrypoint(Cap_session *, Pager_activation_base *a)
-: _activation(a)
-{ _activation->ep(this); }
-
-
-void Pager_entrypoint::dissolve(Pager_object *obj)
+Untyped_capability Pager_entrypoint::_manage(Pager_object *obj)
{
- remove_locked(obj);
-}
-
-
-Pager_capability Pager_entrypoint::manage(Pager_object *obj)
-{
- /* return invalid capability if no activation is present */
- if (!_activation) return Pager_capability();
-
- _activation->cap();
-
- Untyped_capability cap = Native_capability(_activation->cap().dst(), obj->badge());
-
- /* add server object to object pool */
- obj->cap(cap);
- insert(obj);
-
- /* return capability that uses the object id as badge */
- return reinterpret_cap_cast(cap);
+ return Untyped_capability(_tid.l4id, obj->badge());
}
diff --git a/repos/base-codezero/src/core/target.inc b/repos/base-codezero/src/core/target.inc
index 9e724784f6..721ef7c495 100644
--- a/repos/base-codezero/src/core/target.inc
+++ b/repos/base-codezero/src/core/target.inc
@@ -12,11 +12,11 @@ SRC_CC += cap_session_component.cc \
dump_alloc.cc \
io_mem_session_component.cc \
io_mem_session_support.cc \
- ipc_pager.cc \
irq_session_component.cc \
main.cc \
pager.cc \
- pager_common.cc \
+ pager_ep.cc \
+ pager_object.cc \
pd_session_component.cc \
platform.cc \
platform_pd.cc \
@@ -58,5 +58,6 @@ vpath dataspace_component.cc $(GEN_CORE_DIR)
vpath core_mem_alloc.cc $(GEN_CORE_DIR)
vpath dump_alloc.cc $(GEN_CORE_DIR)
vpath context_area.cc $(GEN_CORE_DIR)
-vpath pager_common.cc $(GEN_CORE_DIR)
+vpath pager_ep.cc $(GEN_CORE_DIR)
+vpath pager_object.cc $(GEN_CORE_DIR)
vpath %.cc $(REP_DIR)/src/core
diff --git a/repos/base-fiasco/src/core/include/ipc_pager.h b/repos/base-fiasco/src/core/include/ipc_pager.h
index f8576e695d..62d699af4f 100644
--- a/repos/base-fiasco/src/core/include/ipc_pager.h
+++ b/repos/base-fiasco/src/core/include/ipc_pager.h
@@ -85,7 +85,7 @@ namespace Genode {
/**
* Special paging server class
*/
- class Ipc_pager : public Native_capability
+ class Ipc_pager
{
private:
@@ -96,11 +96,6 @@ namespace Genode {
public:
- /**
- * Constructor
- */
- Ipc_pager();
-
/**
* Wait for a new page fault received as short message IPC
*/
@@ -144,9 +139,13 @@ namespace Genode {
void acknowledge_wakeup();
/**
- * Return thread ID of last faulter
+ * Returns true if the last request was send from a core thread
*/
- Native_thread_id last() const { return _last; }
+ bool request_from_core()
+ {
+ enum { CORE_TASK_ID = 4 };
+ return _last.id.task == CORE_TASK_ID;
+ }
/**
* Return badge for faulting thread
diff --git a/repos/base-fiasco/src/core/ipc_pager.cc b/repos/base-fiasco/src/core/ipc_pager.cc
deleted file mode 100644
index 5451adb292..0000000000
--- a/repos/base-fiasco/src/core/ipc_pager.cc
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * \brief Pager support for Fiasco
- * \author Christian Helmuth
- * \date 2006-06-14
- */
-
-/*
- * Copyright (C) 2006-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
-
-/* Core includes */
-#include
-
-namespace Fiasco {
-#include
-#include
-}
-
-using namespace Genode;
-using namespace Fiasco;
-
-
-void Ipc_pager::wait_for_fault()
-{
- l4_msgdope_t result;
-
- do {
- l4_ipc_wait(&_last,
- L4_IPC_SHORT_MSG, &_pf_addr, &_pf_ip,
- L4_IPC_NEVER, &result);
-
- if (L4_IPC_IS_ERROR(result))
- PERR("Ipc error %lx", L4_IPC_ERROR(result));
-
- } while (L4_IPC_IS_ERROR(result));
-}
-
-
-void Ipc_pager::reply_and_wait_for_fault()
-{
- l4_msgdope_t result;
-
- l4_ipc_reply_and_wait(_last,
- L4_IPC_SHORT_FPAGE, _reply_mapping.dst_addr(),
- _reply_mapping.fpage().fpage, &_last,
- L4_IPC_SHORT_MSG, &_pf_addr, &_pf_ip,
- L4_IPC_SEND_TIMEOUT_0, &result);
-
- if (L4_IPC_IS_ERROR(result)) {
- PERR("Ipc error %lx", L4_IPC_ERROR(result));
-
- /* ignore all errors and wait for next proper message */
- wait_for_fault();
- }
-}
-
-
-void Ipc_pager::acknowledge_wakeup()
-{
- /* answer wakeup call from one of core's region-manager sessions */
- l4_msgdope_t result;
- l4_ipc_send(_last, L4_IPC_SHORT_MSG, 0, 0, L4_IPC_SEND_TIMEOUT_0, &result);
-}
-
-
-Ipc_pager::Ipc_pager() : Native_capability(Fiasco::l4_myself(), 0) { }
diff --git a/repos/base-fiasco/src/core/pager.cc b/repos/base-fiasco/src/core/pager.cc
index 9e1f8bc30b..2c15cc3767 100644
--- a/repos/base-fiasco/src/core/pager.cc
+++ b/repos/base-fiasco/src/core/pager.cc
@@ -1,10 +1,7 @@
/*
- * \brief Fiasco pager framework
- * \author Norman Feske
+ * \brief Pager support for Fiasco
* \author Christian Helmuth
- * \date 2006-07-14
- *
- * FIXME Isn't this file generic?
+ * \date 2006-06-14
*/
/*
@@ -14,7 +11,11 @@
* under the terms of the GNU General Public License version 2.
*/
+/* Genode includes */
+#include
+
/* Core includes */
+#include
#include
namespace Fiasco {
@@ -23,101 +24,61 @@ namespace Fiasco {
}
using namespace Genode;
+using namespace Fiasco;
-/**********************
- ** Pager activation **
- **********************/
+/***************
+ ** Ipc_pager **
+ ***************/
-void Pager_activation_base::entry()
+void Ipc_pager::wait_for_fault()
{
- Ipc_pager pager;
- _cap = pager;
- _cap_valid.unlock();
+ l4_msgdope_t result;
- Pager_object * obj;
- bool reply = false;
+ do {
+ l4_ipc_wait(&_last,
+ L4_IPC_SHORT_MSG, &_pf_addr, &_pf_ip,
+ L4_IPC_NEVER, &result);
- while (1) {
+ if (L4_IPC_IS_ERROR(result))
+ PERR("Ipc error %lx", L4_IPC_ERROR(result));
- if (reply)
- pager.reply_and_wait_for_fault();
- else
- pager.wait_for_fault();
+ } while (L4_IPC_IS_ERROR(result));
+}
- /* lookup referenced object */
- Object_pool::Guard _obj(_ep ? _ep->lookup_and_lock(pager.badge()) : 0);
- obj = _obj;
- reply = false;
- /* handle request */
- if (obj) {
- reply = !obj->pager(pager);
- /* something strange occurred - leave thread in pagefault */
- continue;
- } else {
+void Ipc_pager::reply_and_wait_for_fault()
+{
+ l4_msgdope_t result;
- /* 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) {
+ l4_ipc_reply_and_wait(_last,
+ L4_IPC_SHORT_FPAGE, _reply_mapping.dst_addr(),
+ _reply_mapping.fpage().fpage, &_last,
+ L4_IPC_SHORT_MSG, &_pf_addr, &_pf_ip,
+ L4_IPC_SEND_TIMEOUT_0, &result);
- PWRN("page fault from unknown partner %x.%02x",
- (int)pager.last().id.task, (int)pager.last().id.lthread);
+ if (L4_IPC_IS_ERROR(result)) {
+ PERR("Ipc error %lx", L4_IPC_ERROR(result));
- } else {
+ /* ignore all errors and wait for next proper message */
+ wait_for_fault();
+ }
+}
- /*
- * 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.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();
- }
- }
- };
+void Ipc_pager::acknowledge_wakeup()
+{
+ /* answer wakeup call from one of core's region-manager sessions */
+ l4_msgdope_t result;
+ l4_ipc_send(_last, L4_IPC_SHORT_MSG, 0, 0, L4_IPC_SEND_TIMEOUT_0, &result);
}
/**********************
- ** Pager entrypoint **
+ ** Pager Entrypoint **
**********************/
-Pager_entrypoint::Pager_entrypoint(Cap_session *, Pager_activation_base *a)
-: _activation(a)
-{ _activation->ep(this); }
-
-
-void Pager_entrypoint::dissolve(Pager_object *obj)
+Untyped_capability Pager_entrypoint::_manage(Pager_object *obj)
{
- remove_locked(obj);
-}
-
-
-Pager_capability Pager_entrypoint::manage(Pager_object *obj)
-{
- /* return invalid capability if no activation is present */
- if (!_activation) return Pager_capability();
-
- Native_capability cap(_activation->cap().dst(), obj->badge());
-
- /* add server object to object pool */
- obj->cap(cap);
- insert(obj);
-
- /* return capability that uses the object id as badge */
- return reinterpret_cap_cast(cap);
+ return Untyped_capability(_tid.l4id, obj->badge());
}
diff --git a/repos/base-fiasco/src/core/target.inc b/repos/base-fiasco/src/core/target.inc
index 9f205b361e..3c588bbbe6 100644
--- a/repos/base-fiasco/src/core/target.inc
+++ b/repos/base-fiasco/src/core/target.inc
@@ -12,12 +12,12 @@ SRC_CC += cap_session_component.cc \
io_mem_session_component.cc \
io_mem_session_support.cc \
io_port_session_component.cc \
- ipc_pager.cc \
irq_session_component.cc \
main.cc \
multiboot_info.cc \
pager.cc \
- pager_common.cc \
+ pager_ep.cc \
+ pager_object.cc \
pd_session_component.cc \
platform.cc \
platform_pd.cc \
@@ -58,6 +58,7 @@ vpath trace_session_component.cc $(GEN_CORE_DIR)
vpath dataspace_component.cc $(GEN_CORE_DIR)
vpath dump_alloc.cc $(GEN_CORE_DIR)
vpath context_area.cc $(GEN_CORE_DIR)
-vpath pager_common.cc $(GEN_CORE_DIR)
+vpath pager_object.cc $(GEN_CORE_DIR)
+vpath pager_ep.cc $(GEN_CORE_DIR)
vpath core_printf.cc $(BASE_DIR)/src/base/console
vpath %.cc $(REP_DIR)/src/core
diff --git a/repos/base-foc/src/core/pager.cc b/repos/base-foc/src/core/pager.cc
index 9b646bf8f9..1d82bc3224 100644
--- a/repos/base-foc/src/core/pager.cc
+++ b/repos/base-foc/src/core/pager.cc
@@ -4,8 +4,6 @@
* \author Christian Helmuth
* \author Stefan Kalkowski
* \date 2006-07-14
- *
- * FIXME Isn't this file generic?
*/
/*
@@ -32,33 +30,20 @@ namespace Fiasco {
using namespace Genode;
-/**********************
- ** Pager activation **
- **********************/
-
-void Pager_activation_base::entry()
+void Pager_entrypoint::entry()
{
- Ipc_pager pager;
- _cap = Native_capability(Thread_base::_thread_cap);
- _cap_valid.unlock();
-
bool reply_pending = false;
while (1) {
if (reply_pending)
- pager.reply_and_wait_for_fault();
+ _pager.reply_and_wait_for_fault();
else
- pager.wait_for_fault();
+ _pager.wait_for_fault();
reply_pending = false;
- if (!_ep) {
- PWRN("Pager entrypoint not yet defined");
- continue;
- }
-
/* lookup referenced object */
- Object_pool::Guard obj(_ep->lookup_and_lock(pager.badge()));
+ Object_pool::Guard obj(lookup_and_lock(_pager.badge()));
/* the pager_object might be destroyed, while we got the message */
if (!obj) {
@@ -66,14 +51,14 @@ void Pager_activation_base::entry()
continue;
}
- switch (pager.msg_type()) {
+ switch (_pager.msg_type()) {
case Ipc_pager::PAGEFAULT:
case Ipc_pager::EXCEPTION:
{
- if (pager.is_exception()) {
+ if (_pager.is_exception()) {
Lock::Guard guard(obj->state.lock);
- pager.get_regs(&obj->state);
+ _pager.get_regs(&obj->state);
obj->state.exceptions++;
obj->state.in_exception = true;
obj->submit_exception_signal();
@@ -81,12 +66,12 @@ void Pager_activation_base::entry()
}
/* handle request */
- if (obj->pager(pager)) {
+ if (obj->pager(_pager)) {
/* could not resolv - leave thread in pagefault */
PDBG("Could not resolve pf=%p ip=%p",
- (void*)pager.fault_addr(), (void*)pager.fault_ip());
+ (void*)_pager.fault_addr(), (void*)_pager.fault_ip());
} else {
- pager.set_reply_dst(obj->badge());
+ _pager.set_reply_dst(obj->badge());
reply_pending = true;
continue;
}
@@ -104,20 +89,20 @@ void Pager_activation_base::entry()
*/
/* send reply to the caller */
- pager.set_reply_dst(Native_thread());
- pager.acknowledge_wakeup();
+ _pager.set_reply_dst(Native_thread());
+ _pager.acknowledge_wakeup();
{
Lock::Guard guard(obj->state.lock);
/* revert exception flag */
obj->state.in_exception = false;
/* set new register contents */
- pager.set_regs(obj->state);
+ _pager.set_regs(obj->state);
}
/* send wake up message to requested thread */
- pager.set_reply_dst(obj->badge());
- pager.acknowledge_exception();
+ _pager.set_reply_dst(obj->badge());
+ _pager.acknowledge_exception();
break;
}
@@ -128,7 +113,7 @@ void Pager_activation_base::entry()
case Ipc_pager::PAUSE:
{
Lock::Guard guard(obj->state.lock);
- pager.get_regs(&obj->state);
+ _pager.get_regs(&obj->state);
obj->state.exceptions++;
obj->state.in_exception = true;
@@ -138,31 +123,19 @@ void Pager_activation_base::entry()
* that case we unblock it immediately.
*/
if (!obj->state.paused) {
- pager.set_reply_dst(obj->badge());
+ _pager.set_reply_dst(obj->badge());
reply_pending = true;
}
break;
}
default:
- PERR("Got unknown message type %x!", pager.msg_type());
+ PERR("Got unknown message type %x!", _pager.msg_type());
}
};
}
-/**********************
- ** Pager entrypoint **
- **********************/
-
-Pager_entrypoint::Pager_entrypoint(Cap_session *cap_session,
- Pager_activation_base *a)
-: _activation(a), _cap_session(cap_session)
-{
- _activation->ep(this);
-}
-
-
void Pager_entrypoint::dissolve(Pager_object *obj)
{
/* cleanup at cap session */
@@ -176,11 +149,7 @@ Pager_capability Pager_entrypoint::manage(Pager_object *obj)
{
using namespace Fiasco;
- /* return invalid capability if no activation is present */
- if (!_activation) return Pager_capability();
-
- Native_capability c = _activation->cap();
- Native_capability cap(_cap_session->alloc(c));
+ Native_capability cap(_cap_session->alloc({Thread_base::_thread_cap}));
/* add server object to object pool */
obj->cap(cap);
diff --git a/repos/base-foc/src/core/target.inc b/repos/base-foc/src/core/target.inc
index a06c8e9cfc..78a79f0372 100644
--- a/repos/base-foc/src/core/target.inc
+++ b/repos/base-foc/src/core/target.inc
@@ -19,7 +19,7 @@ SRC_CC += cap_session_component.cc \
main.cc \
multiboot_info.cc \
pager.cc \
- pager_common.cc \
+ pager_object.cc \
pd_session_component.cc \
pd_session_extension.cc \
platform.cc \
@@ -59,7 +59,7 @@ vpath rm_session_component.cc $(GEN_CORE_DIR)
vpath rom_session_component.cc $(GEN_CORE_DIR)
vpath signal_session_component.cc $(GEN_CORE_DIR)
vpath trace_session_component.cc $(GEN_CORE_DIR)
-vpath pager_common.cc $(GEN_CORE_DIR)
+vpath pager_object.cc $(GEN_CORE_DIR)
vpath core_printf.cc $(BASE_DIR)/src/base/console
vpath %.cc $(REP_DIR)/src/core
vpath %.cc $(REP_DIR)/src/base/thread
diff --git a/repos/base-hw/src/core/include/pager.h b/repos/base-hw/src/core/include/pager.h
index 4249d8afec..75be292002 100644
--- a/repos/base-hw/src/core/include/pager.h
+++ b/repos/base-hw/src/core/include/pager.h
@@ -47,15 +47,7 @@ namespace Genode
*/
class Pager_entrypoint;
- /**
- * A thread that processes one page fault of a pager object at a time
- */
- class Pager_activation_base;
-
- /**
- * Pager-activation base with custom stack size
- */
- template class Pager_activation;
+ enum { PAGER_EP_STACK_SIZE = sizeof(addr_t) * 2048 };
}
struct Genode::Mapping
@@ -198,26 +190,30 @@ class Genode::Pager_object
void thread_cap(Thread_capability const & c);
};
-class Genode::Pager_activation_base
-: public Thread_base,
- public Kernel_object,
- public Ipc_pager
+
+class Genode::Pager_entrypoint : public Object_pool,
+ public Thread,
+ public Kernel_object,
+ public Ipc_pager
{
- private:
-
- Lock _startup_lock;
- Pager_entrypoint * _ep;
-
public:
/**
* Constructor
*
- * \param name name of the new thread
- * \param stack_size stack size of the new thread
+ * \param a activation that shall handle the objects of the entrypoint
*/
- Pager_activation_base(char const * const name,
- size_t const stack_size);
+ Pager_entrypoint(Cap_session * cap_session);
+
+ /**
+ * Associate pager object 'obj' with entry point
+ */
+ Pager_capability manage(Pager_object * const obj);
+
+ /**
+ * Dissolve pager object 'obj' from entry point
+ */
+ void dissolve(Pager_object * const obj);
/**
* Bring current mapping data into effect
@@ -233,55 +229,6 @@ class Genode::Pager_activation_base
**********************/
void entry();
-
-
- /***************
- ** Accessors **
- ***************/
-
- void ep(Pager_entrypoint * const ep);
-};
-
-class Genode::Pager_entrypoint : public Object_pool
-{
- private:
-
- Pager_activation_base * const _activation;
-
- public:
-
- /**
- * Constructor
- *
- * \param a activation that shall handle the objects of the entrypoint
- */
- Pager_entrypoint(Cap_session *, Pager_activation_base * const a);
-
- /**
- * Associate pager object 'obj' with entry point
- */
- Pager_capability manage(Pager_object * const obj);
-
- /**
- * Dissolve pager object 'obj' from entry point
- */
- void dissolve(Pager_object * const obj);
-};
-
-template
-class Genode::Pager_activation : public Pager_activation_base
-{
- public:
-
- /**
- * Constructor
- */
- Pager_activation()
- :
- Pager_activation_base("pager_activation", STACK_SIZE)
- {
- start();
- }
};
#endif /* _CORE__INCLUDE__PAGER_H_ */
diff --git a/repos/base-hw/src/core/pager.cc b/repos/base-hw/src/core/pager.cc
index 2fd3389584..a2160c1ebf 100644
--- a/repos/base-hw/src/core/pager.cc
+++ b/repos/base-hw/src/core/pager.cc
@@ -97,21 +97,6 @@ Pager_object::Pager_object(unsigned const badge, Affinity::Location)
{ }
-/***************************
- ** Pager_activation_base **
- ***************************/
-
-void Pager_activation_base::ep(Pager_entrypoint * const ep) { _ep = ep; }
-
-
-Pager_activation_base::Pager_activation_base(char const * const name,
- size_t const stack_size)
-: Thread_base(0, name, stack_size),
- Kernel_object(true),
- _startup_lock(Lock::LOCKED), _ep(0)
-{ }
-
-
/**********************
** Pager_entrypoint **
**********************/
@@ -122,15 +107,16 @@ void Pager_entrypoint::dissolve(Pager_object * const o)
}
-Pager_entrypoint::Pager_entrypoint(Cap_session *,
- Pager_activation_base * const activation)
-: _activation(activation) {
- _activation->ep(this); }
+Pager_entrypoint::Pager_entrypoint(Cap_session *)
+: Thread("pager_ep"),
+ Kernel_object(true)
+{ start(); }
Pager_capability Pager_entrypoint::manage(Pager_object * const o)
{
- o->start_paging(_activation->kernel_object());
+ o->start_paging(kernel_object());
insert(o);
return reinterpret_cap_cast(o->cap());
}
+
diff --git a/repos/base-hw/src/core/rm_session_support.cc b/repos/base-hw/src/core/rm_session_support.cc
index 0400b0beca..2f73037bb8 100644
--- a/repos/base-hw/src/core/rm_session_support.cc
+++ b/repos/base-hw/src/core/rm_session_support.cc
@@ -36,11 +36,11 @@ void Rm_client::unmap(addr_t, addr_t virt_base, size_t size)
}
-/***************************
- ** Pager_activation_base **
- ***************************/
+/**********************
+ ** Pager_entrypoint **
+ **********************/
-int Pager_activation_base::apply_mapping()
+int Pager_entrypoint::apply_mapping()
{
Page_flags const flags =
Page_flags::apply_mapping(_mapping.writable,
@@ -54,10 +54,8 @@ int Pager_activation_base::apply_mapping()
}
-void Pager_activation_base::entry()
+void Pager_entrypoint::entry()
{
- /* get ready to receive faults */
- _startup_lock.unlock();
while (1)
{
/* receive fault */
@@ -71,7 +69,7 @@ void Pager_activation_base::entry()
* FIXME: The implicit lookup of the oject isn't needed.
*/
unsigned const pon = po->cap().local_name();
- Object_pool::Guard pog(_ep->lookup_and_lock(pon));
+ Object_pool::Guard pog(lookup_and_lock(pon));
if (!pog) continue;
/* fetch fault data */
diff --git a/repos/base-linux/src/core/include/pager.h b/repos/base-linux/src/core/include/pager.h
index 4eedab99ea..8bcafa6d67 100644
--- a/repos/base-linux/src/core/include/pager.h
+++ b/repos/base-linux/src/core/include/pager.h
@@ -45,14 +45,12 @@ namespace Genode {
void release() { }
};
- class Pager_activation_base { };
struct Pager_entrypoint
{
- Pager_entrypoint(Cap_session *, Pager_activation_base *) { }
+ Pager_entrypoint(Cap_session *) { }
Pager_object *lookup_and_lock(Pager_capability) { return 0; }
};
- template class Pager_activation : public Pager_activation_base { };
}
#endif /* _CORE__INCLUDE__PAGER_H_ */
diff --git a/repos/base-nova/src/core/include/pager.h b/repos/base-nova/src/core/include/pager.h
index 84c43ccb78..556990f82a 100644
--- a/repos/base-nova/src/core/include/pager.h
+++ b/repos/base-nova/src/core/include/pager.h
@@ -379,9 +379,8 @@ namespace Genode {
* \param cap_session Cap_session for creating capabilities
* for the pager objects managed by this
* entry point
- * \param a initial activation
*/
- Pager_entrypoint(Cap_session *cap_session, Pager_activation_base *a = 0);
+ Pager_entrypoint(Cap_session *cap_session);
/**
* Associate Pager_object with the entry point
diff --git a/repos/base-nova/src/core/pager.cc b/repos/base-nova/src/core/pager.cc
index cf2d19b418..9b26741081 100644
--- a/repos/base-nova/src/core/pager.cc
+++ b/repos/base-nova/src/core/pager.cc
@@ -620,9 +620,8 @@ void Pager_activation_base::entry() { }
**********************/
-Pager_entrypoint::Pager_entrypoint(Cap_session *cap_session,
- Pager_activation_base *a)
-: _activation(a), _cap_session(cap_session)
+Pager_entrypoint::Pager_entrypoint(Cap_session *cap_session)
+: _cap_session(cap_session)
{
/* sanity check space for pager threads */
if (kernel_hip()->cpu_max() > PAGER_CPUS) {
@@ -631,20 +630,11 @@ Pager_entrypoint::Pager_entrypoint(Cap_session *cap_session,
nova_die();
}
- /* determine boot cpu */
- unsigned master_cpu = boot_cpu();
-
/* detect enabled CPUs and create per CPU a pager thread */
typedef Pager_activation Pager;
Pager * pager_of_cpu = reinterpret_cast(&pager_activation_mem);
for (unsigned i = 0; i < kernel_hip()->cpu_max(); i++, pager_of_cpu++) {
- if (i == master_cpu) {
- pager_threads[master_cpu] = a;
- a->ep(this);
- continue;
- }
-
if (!kernel_hip()->is_cpu_enabled(i))
continue;
diff --git a/repos/base-okl4/src/core/include/ipc_pager.h b/repos/base-okl4/src/core/include/ipc_pager.h
index 4654c83b77..0a55bd7fd8 100644
--- a/repos/base-okl4/src/core/include/ipc_pager.h
+++ b/repos/base-okl4/src/core/include/ipc_pager.h
@@ -73,7 +73,7 @@ namespace Genode {
/**
* Special paging server class
*/
- class Ipc_pager : public Native_capability
+ class Ipc_pager
{
private:
@@ -99,11 +99,6 @@ namespace Genode {
public:
- /**
- * Constructor
- */
- Ipc_pager();
-
/**
* Wait for a new fault received as short message IPC
*/
@@ -147,14 +142,13 @@ namespace Genode {
void acknowledge_wakeup();
/**
- * Return thread ID of last faulter
+ * Returns true if the last request was send from a core thread
*/
- Native_thread_id last() const { return _last; }
-
- /**
- * Return address space where the last page fault occurred
- */
- unsigned long last_space() const { return _last_space; }
+ bool request_from_core() const
+ {
+ enum { CORE_SPACE = 0 };
+ return _last_space == CORE_SPACE;
+ }
/**
* Return badge for faulting thread
diff --git a/repos/base-okl4/src/core/ipc_pager.cc b/repos/base-okl4/src/core/ipc_pager.cc
deleted file mode 100644
index 7314b08ef9..0000000000
--- a/repos/base-okl4/src/core/ipc_pager.cc
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * \brief Pager support for OKL4
- * \author Norman Feske
- * \date 2009-03-31
- */
-
-/*
- * Copyright (C) 2009-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
-
-/* Core includes */
-#include
-
-namespace Okl4 { extern "C" {
-#include
-#include
-#include
-#include
-} }
-
-static const bool verbose_page_fault = false;
-static const bool verbose_exception = false;
-
-
-using namespace Genode;
-using namespace Okl4;
-
-/**
- * Print page-fault information in a human-readable form
- */
-static inline void print_page_fault(L4_Word_t type, L4_Word_t addr, L4_Word_t ip,
- unsigned long badge)
-{
- printf("page (%s%s%s) fault at fault_addr=%lx, fault_ip=%lx, from=%lx\n",
- type & L4_Readable ? "r" : "-",
- type & L4_Writable ? "w" : "-",
- type & L4_eXecutable ? "x" : "-",
- addr, ip, badge);
-}
-
-
-/**
- * Return the global thread ID of the calling thread
- *
- * On OKL4 we cannot use 'L4_Myself()' to determine our own thread's
- * identity. By convention, each thread stores its global ID in a
- * defined entry of its UTCB.
- */
-static inline Okl4::L4_ThreadId_t thread_get_my_global_id()
-{
- Okl4::L4_ThreadId_t myself;
- myself.raw = Okl4::__L4_TCR_ThreadWord(UTCB_TCR_THREAD_WORD_MYSELF);
- return myself;
-}
-
-
-/*************
- ** Mapping **
- *************/
-
-Mapping::Mapping(addr_t dst_addr, addr_t src_addr,
- Cache_attribute cacheability, bool io_mem,
- unsigned l2size, bool rw)
-:
- _fpage(L4_FpageLog2(dst_addr, l2size)),
- /*
- * OKL4 does not support write-combining as mapping attribute.
- */
- _phys_desc(L4_PhysDesc(src_addr, 0))
-{
- L4_Set_Rights(&_fpage, rw ? L4_ReadWriteOnly : L4_ReadeXecOnly);
-}
-
-
-Mapping::Mapping() { }
-
-
-/***************
- ** IPC pager **
- ***************/
-
-void Ipc_pager::wait_for_fault()
-{
- /* wait for fault */
- _faulter_tag = L4_Wait(&_last);
-
- /*
- * Read fault information
- */
-
- /* exception */
- if (is_exception()) {
- L4_StoreMR(1, &_fault_ip);
-
- if (verbose_exception)
- PERR("Exception (label 0x%x) occured in space %d at IP 0x%p",
- (int)L4_Label(_faulter_tag), (int)L4_SenderSpace().raw,
- (void *)_fault_ip);
- }
-
- /* page fault */
- else {
- L4_StoreMR(1, &_fault_addr);
- L4_StoreMR(2, &_fault_ip);
-
- if (verbose_page_fault)
- print_page_fault(L4_Label(_faulter_tag), _fault_addr, _fault_ip, _last.raw);
- }
- _last_space = L4_SenderSpace().raw;
-}
-
-
-void Ipc_pager::reply_and_wait_for_fault()
-{
- L4_SpaceId_t to_space;
- to_space.raw = L4_ThreadNo(_last) >> Thread_id_bits::THREAD;
-
- /* map page to faulting space */
- int ret = L4_MapFpage(to_space, _reply_mapping.fpage(),
- _reply_mapping.phys_desc());
-
- if (ret != 1)
- PERR("L4_MapFpage returned %d, error_code=%d",
- ret, (int)L4_ErrorCode());
-
- /* reply to page-fault message to resume the faulting thread */
- acknowledge_wakeup();
-
- wait_for_fault();
-}
-
-
-void Ipc_pager::acknowledge_wakeup()
-{
- /* answer wakeup call from one of core's region-manager sessions */
- L4_LoadMR(0, 0);
- L4_Send(_last);
-}
-
-
-Ipc_pager::Ipc_pager() : Native_capability(thread_get_my_global_id(), 0) { }
-
diff --git a/repos/base-okl4/src/core/pager.cc b/repos/base-okl4/src/core/pager.cc
index d1e28953f3..07dc0ff478 100644
--- a/repos/base-okl4/src/core/pager.cc
+++ b/repos/base-okl4/src/core/pager.cc
@@ -1,5 +1,5 @@
/*
- * \brief OKL4-specific pager framework
+ * \brief Pager support for OKL4
* \author Norman Feske
* \date 2009-03-31
*/
@@ -11,85 +11,137 @@
* under the terms of the GNU General Public License version 2.
*/
+/* Genode includes */
+#include
+
/* Core includes */
+#include
#include
+namespace Okl4 { extern "C" {
+#include
+#include
+#include
+#include
+} }
+
+static const bool verbose_page_fault = false;
+static const bool verbose_exception = false;
+
+
using namespace Genode;
+using namespace Okl4;
-
-/**********************
- ** Pager activation **
- **********************/
-
-void Pager_activation_base::entry()
+/**
+ * Print page-fault information in a human-readable form
+ */
+static inline void print_page_fault(L4_Word_t type, L4_Word_t addr, L4_Word_t ip,
+ unsigned long badge)
{
- Ipc_pager pager;
- _cap = pager;
- _cap_valid.unlock();
+ printf("page (%s%s%s) fault at fault_addr=%lx, fault_ip=%lx, from=%lx\n",
+ type & L4_Readable ? "r" : "-",
+ type & L4_Writable ? "w" : "-",
+ type & L4_eXecutable ? "x" : "-",
+ addr, ip, badge);
+}
- bool reply_pending = false;
- while (1) {
- if (reply_pending)
- pager.reply_and_wait_for_fault();
- else
- pager.wait_for_fault();
+/**
+ * Return the global thread ID of the calling thread
+ *
+ * On OKL4 we cannot use 'L4_Myself()' to determine our own thread's
+ * identity. By convention, each thread stores its global ID in a
+ * defined entry of its UTCB.
+ */
+static inline Okl4::L4_ThreadId_t thread_get_my_global_id()
+{
+ Okl4::L4_ThreadId_t myself;
+ myself.raw = Okl4::__L4_TCR_ThreadWord(UTCB_TCR_THREAD_WORD_MYSELF);
+ return myself;
+}
- reply_pending = false;
- /* lookup referenced object */
- Object_pool::Guard _obj(_ep ? _ep->lookup_and_lock(pager.badge()) : 0);
- Pager_object *obj = _obj;
+/*************
+ ** Mapping **
+ *************/
- /* handle request */
- if (obj) {
- if (pager.is_exception()) {
- obj->submit_exception_signal();
- continue;
- }
+Mapping::Mapping(addr_t dst_addr, addr_t src_addr,
+ Cache_attribute cacheability, bool io_mem,
+ unsigned l2size, bool rw)
+:
+ _fpage(L4_FpageLog2(dst_addr, l2size)),
+ /*
+ * OKL4 does not support write-combining as mapping attribute.
+ */
+ _phys_desc(L4_PhysDesc(src_addr, 0))
+{
+ L4_Set_Rights(&_fpage, rw ? L4_ReadWriteOnly : L4_ReadeXecOnly);
+}
- /* send reply if page-fault handling succeeded */
- if (!obj->pager(pager))
- reply_pending = true;
- continue;
+Mapping::Mapping() { }
- } else {
- /*
- * Prevent threads outside of core to mess with our wake-up
- * interface. This condition can trigger if a process gets
- * destroyed which triggered a page fault shortly before getting
- * killed. In this case, 'wait_for_fault()' returns (because of
- * the page fault delivery) but the pager-object lookup will fail
- * (because core removed the process already).
- */
- enum { CORE_SPACE = 0 };
- if (pager.last_space() == CORE_SPACE) {
+/***************
+ ** IPC pager **
+ ***************/
- /*
- * 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.fault_ip());
+void Ipc_pager::wait_for_fault()
+{
+ /* wait for fault */
+ _faulter_tag = L4_Wait(&_last);
- /* send reply to the calling region-manager session */
- pager.acknowledge_wakeup();
+ /*
+ * Read fault information
+ */
- /* answer page fault of resolved pager object */
- pager.set_reply_dst(obj->cap());
- pager.acknowledge_wakeup();
- }
- }
- };
+ /* exception */
+ if (is_exception()) {
+ L4_StoreMR(1, &_fault_ip);
+
+ if (verbose_exception)
+ PERR("Exception (label 0x%x) occured in space %d at IP 0x%p",
+ (int)L4_Label(_faulter_tag), (int)L4_SenderSpace().raw,
+ (void *)_fault_ip);
+ }
+
+ /* page fault */
+ else {
+ L4_StoreMR(1, &_fault_addr);
+ L4_StoreMR(2, &_fault_ip);
+
+ if (verbose_page_fault)
+ print_page_fault(L4_Label(_faulter_tag), _fault_addr, _fault_ip, _last.raw);
+ }
+ _last_space = L4_SenderSpace().raw;
+}
+
+
+void Ipc_pager::reply_and_wait_for_fault()
+{
+ L4_SpaceId_t to_space;
+ to_space.raw = L4_ThreadNo(_last) >> Thread_id_bits::THREAD;
+
+ /* map page to faulting space */
+ int ret = L4_MapFpage(to_space, _reply_mapping.fpage(),
+ _reply_mapping.phys_desc());
+
+ if (ret != 1)
+ PERR("L4_MapFpage returned %d, error_code=%d",
+ ret, (int)L4_ErrorCode());
+
+ /* reply to page-fault message to resume the faulting thread */
+ acknowledge_wakeup();
+
+ wait_for_fault();
+}
+
+
+void Ipc_pager::acknowledge_wakeup()
+{
+ /* answer wakeup call from one of core's region-manager sessions */
+ L4_LoadMR(0, 0);
+ L4_Send(_last);
}
@@ -97,28 +149,7 @@ void Pager_activation_base::entry()
** Pager entrypoint **
**********************/
-Pager_entrypoint::Pager_entrypoint(Cap_session *, Pager_activation_base *a)
-: _activation(a)
-{ _activation->ep(this); }
-
-
-void Pager_entrypoint::dissolve(Pager_object *obj)
+Untyped_capability Pager_entrypoint::_manage(Pager_object *obj)
{
- remove_locked(obj);
-}
-
-
-Pager_capability Pager_entrypoint::manage(Pager_object *obj)
-{
- /* return invalid capability if no activation is present */
- if (!_activation) return Pager_capability();
-
- Native_capability cap = Native_capability(_activation->cap().dst(), obj->badge());
-
- /* add server object to object pool */
- obj->cap(cap);
- insert(obj);
-
- /* return capability that uses the object id as badge */
- return reinterpret_cap_cast(cap);
+ return Untyped_capability(_tid.l4id, obj->badge());
}
diff --git a/repos/base-okl4/src/core/target.inc b/repos/base-okl4/src/core/target.inc
index e6c3eac31f..7c42a54d77 100644
--- a/repos/base-okl4/src/core/target.inc
+++ b/repos/base-okl4/src/core/target.inc
@@ -15,12 +15,12 @@ SRC_CC += cap_session_component.cc \
dump_alloc.cc \
io_mem_session_component.cc \
io_mem_session_support.cc \
- ipc_pager.cc \
irq_session_component.cc \
main.cc \
okl4_pd_session_component.cc \
pager.cc \
- pager_common.cc \
+ pager_ep.cc \
+ pager_object.cc \
pd_session_component.cc \
platform.cc \
platform_pd.cc \
@@ -61,7 +61,8 @@ vpath dataspace_component.cc $(GEN_CORE_DIR)
vpath core_mem_alloc.cc $(GEN_CORE_DIR)
vpath dump_alloc.cc $(GEN_CORE_DIR)
vpath context_area.cc $(GEN_CORE_DIR)
-vpath pager_common.cc $(GEN_CORE_DIR)
+vpath pager_ep.cc $(GEN_CORE_DIR)
+vpath pager_object.cc $(GEN_CORE_DIR)
vpath %.cc $(REP_DIR)/src/core
vpath core_printf.cc $(BASE_DIR)/src/base/console
diff --git a/repos/base-pistachio/src/core/include/ipc_pager.h b/repos/base-pistachio/src/core/include/ipc_pager.h
index 4f5e8b2c2e..36cc7e7a16 100644
--- a/repos/base-pistachio/src/core/include/ipc_pager.h
+++ b/repos/base-pistachio/src/core/include/ipc_pager.h
@@ -83,7 +83,7 @@ namespace Genode {
/**
* Special paging server class
*/
- class Ipc_pager : public Native_capability
+ class Ipc_pager
{
private:
@@ -108,11 +108,6 @@ namespace Genode {
public:
- /**
- * Constructor
- */
- Ipc_pager();
-
/**
* Wait for a new fault received as short message IPC
*/
@@ -156,9 +151,9 @@ namespace Genode {
void acknowledge_wakeup();
/**
- * Return thread ID of last faulter
+ * Returns true if the last request was send from a core thread
*/
- Native_thread_id last() const { return _last; }
+ bool request_from_core() { return true; }
/**
* Return badge for faulting thread
diff --git a/repos/base-pistachio/src/core/ipc_pager.cc b/repos/base-pistachio/src/core/ipc_pager.cc
deleted file mode 100644
index 6771a912ac..0000000000
--- a/repos/base-pistachio/src/core/ipc_pager.cc
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * \brief Pager support for Pistachio
- * \author Christian Helmuth
- * \date 2006-06-14
- */
-
-/*
- * Copyright (C) 2006-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
-#include
-
-/* Core includes */
-#include
-
-namespace Pistachio
-{
-#include
-#include
-#include
-#include
-}
-
-using namespace Genode;
-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);
-
- fpage += rw ? L4_FullyAccessible : L4_Readable;
-
- if (grant)
- _grant_item = L4_GrantItem(fpage, dst_addr);
- else
- _map_item = L4_MapItem(fpage, dst_addr);
-}
-
-
-Mapping::Mapping() { _map_item = L4_MapItem(L4_Nilpage, 0); }
-
-
-/***************
- ** IPC pager **
- ***************/
-
-void Ipc_pager::wait_for_fault()
-{
- 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;
- }
-
- } while (failed);
-
- 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);
-
- _last = sender;
-}
-
-
-void Ipc_pager::reply_and_wait_for_fault()
-{
- /*
- * 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);
-}
-
-
-void Ipc_pager::acknowledge_wakeup()
-{
- PERR("acknowledge_wakeup called, not yet implemented");
-// /* answer wakeup call from one of core's region-manager sessions */
-// l4_msgdope_t result;
-// l4_ipc_send(_last, L4_IPC_SHORT_MSG, 0, 0, L4_IPC_SEND_TIMEOUT_0, &result);
-}
-
-
-Ipc_pager::Ipc_pager()
-: Native_capability(L4_Myself(), 0)
-{ }
-
diff --git a/repos/base-pistachio/src/core/pager.cc b/repos/base-pistachio/src/core/pager.cc
index e6a0461877..a701c564ae 100644
--- a/repos/base-pistachio/src/core/pager.cc
+++ b/repos/base-pistachio/src/core/pager.cc
@@ -1,10 +1,7 @@
/*
- * \brief Pistachio pager framework
- * \author Norman Feske
+ * \brief Pager support for Pistachio
* \author Christian Helmuth
- * \date 2006-07-14
- *
- * FIXME Isn't this file generic?
+ * \date 2006-06-14
*/
/*
@@ -14,83 +11,128 @@
* under the terms of the GNU General Public License version 2.
*/
+/* Genode includes */
+#include
+#include
+
/* Core includes */
+#include
#include
-using namespace Genode;
-
-
-namespace Pistachio {
-#include
+namespace Pistachio
+{
+#include
+#include
+#include
+#include
}
-/**********************
- ** Pager activation **
- **********************/
+using namespace Genode;
+using namespace Pistachio;
-void Pager_activation_base::entry()
+
+/*************
+ ** Mapping **
+ *************/
+
+Mapping::Mapping(addr_t dst_addr, addr_t src_addr,
+ Cache_attribute, bool io_mem, unsigned l2size,
+ bool rw, bool grant)
{
- Ipc_pager pager;
- _cap = pager;
- _cap_valid.unlock();
+ L4_Fpage_t fpage = L4_FpageLog2(src_addr, l2size);
- Pager_object * obj;
- bool reply = false;
+ fpage += rw ? L4_FullyAccessible : L4_Readable;
- while (1) {
+ if (grant)
+ _grant_item = L4_GrantItem(fpage, dst_addr);
+ else
+ _map_item = L4_MapItem(fpage, dst_addr);
+}
- if (reply)
- pager.reply_and_wait_for_fault();
- else
- pager.wait_for_fault();
- /* lookup referenced object */
- Object_pool::Guard _obj(_ep ? _ep->lookup_and_lock(pager.badge()) : 0);
- obj = _obj;
- reply = false;
+Mapping::Mapping() { _map_item = L4_MapItem(L4_Nilpage, 0); }
- /* handle request */
- if (obj) {
- /* if something strange occurred - leave thread in pagefault */
- reply = !obj->pager(pager);
- continue;
- } 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) {
+/***************
+ ** IPC pager **
+ ***************/
-#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);
+void Ipc_pager::wait_for_fault()
+{
+ L4_MsgTag_t result;
+ L4_ThreadId_t sender = L4_nilthread;
+ bool failed;
- } else {
+ do {
+ L4_Accept(L4_UntypedWordsAcceptor);
+ result = L4_Wait(&sender);
+ failed = L4_IpcFailed(result);
+ if (failed)
+ PERR("Page fault IPC error. (continuable)");
- /*
- * 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.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();
- }
+ if (L4_UntypedWords(result) != 2) {
+ PERR("Malformed page-fault ipc. (sender = 0x%08lx)",
+ sender.raw);
+ failed = true;
}
+
+ } while (failed);
+
+ 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);
+
+ _last = sender;
+}
+
+
+void Ipc_pager::reply_and_wait_for_fault()
+{
+ /*
+ * 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);
+}
+
+
+void Ipc_pager::acknowledge_wakeup()
+{
+ PERR("acknowledge_wakeup called, not yet implemented");
+// /* answer wakeup call from one of core's region-manager sessions */
+// l4_msgdope_t result;
+// l4_ipc_send(_last, L4_IPC_SHORT_MSG, 0, 0, L4_IPC_SEND_TIMEOUT_0, &result);
}
@@ -98,28 +140,7 @@ void Pager_activation_base::entry()
** Pager entrypoint **
**********************/
-Pager_entrypoint::Pager_entrypoint(Cap_session *, Pager_activation_base *a)
-: _activation(a)
-{ _activation->ep(this); }
-
-
-void Pager_entrypoint::dissolve(Pager_object *obj)
+Untyped_capability Pager_entrypoint::_manage(Pager_object *obj)
{
- remove_locked(obj);
-}
-
-
-Pager_capability Pager_entrypoint::manage(Pager_object *obj)
-{
- /* return invalid capability if no activation is present */
- if (!_activation) return Pager_capability();
-
- Native_capability cap = Native_capability(_activation->cap().dst(), obj->badge());
-
- /* add server object to object pool */
- obj->cap(cap);
- insert(obj);
-
- /* return capability that uses the object id as badge */
- return reinterpret_cap_cast(cap);
+ return Untyped_capability(_tid.l4id, obj->badge());
}
diff --git a/repos/base-pistachio/src/core/target.inc b/repos/base-pistachio/src/core/target.inc
index 3130cf763c..ed9ebf03f0 100644
--- a/repos/base-pistachio/src/core/target.inc
+++ b/repos/base-pistachio/src/core/target.inc
@@ -13,14 +13,14 @@ SRC_CC = cap_session_component.cc \
dump_alloc.cc \
io_mem_session_component.cc \
io_mem_session_support.cc \
- ipc_pager.cc \
irq_session_component.cc \
kip.cc \
main.cc \
multiboot_info.cc \
pd_session_component.cc \
pager.cc \
- pager_common.cc \
+ pager_ep.cc \
+ pager_object.cc \
platform.cc \
platform_pd.cc \
platform_services.cc \
@@ -57,7 +57,8 @@ vpath trace_session_component.cc $(GEN_CORE_DIR)
vpath dataspace_component.cc $(GEN_CORE_DIR)
vpath dump_alloc.cc $(GEN_CORE_DIR)
vpath context_area.cc $(GEN_CORE_DIR)
-vpath pager_common.cc $(GEN_CORE_DIR)
+vpath pager_ep.cc $(GEN_CORE_DIR)
+vpath pager_object.cc $(GEN_CORE_DIR)
vpath core_printf.cc $(BASE_DIR)/src/base/console
vpath kip.cc $(REP_DIR)/src/base/kip
vpath %.cc $(REP_DIR)/src/core
diff --git a/repos/base-sel4/lib/mk/core.mk b/repos/base-sel4/lib/mk/core.mk
index bdea0a7b60..9d22dcb02d 100644
--- a/repos/base-sel4/lib/mk/core.mk
+++ b/repos/base-sel4/lib/mk/core.mk
@@ -30,7 +30,8 @@ SRC_CC += \
dump_alloc.cc \
context_area.cc \
capability_space.cc \
- pager.cc
+ pager.cc \
+ pager_ep.cc
LIBS += core_printf base-common syscall
@@ -56,5 +57,6 @@ vpath trace_session_component.cc $(GEN_CORE_DIR)
vpath dataspace_component.cc $(GEN_CORE_DIR)
vpath core_mem_alloc.cc $(GEN_CORE_DIR)
vpath dump_alloc.cc $(GEN_CORE_DIR)
+vpath pager_ep.cc $(GEN_CORE_DIR)
vpath %.cc $(REP_DIR)/src/core
diff --git a/repos/base-sel4/src/core/include/ipc_pager.h b/repos/base-sel4/src/core/include/ipc_pager.h
index beaa4bad9e..8e3cccc052 100644
--- a/repos/base-sel4/src/core/include/ipc_pager.h
+++ b/repos/base-sel4/src/core/include/ipc_pager.h
@@ -129,9 +129,9 @@ namespace Genode {
void acknowledge_wakeup();
/**
- * Return thread ID of last faulter
+ * Returns true if the last request was send from a core thread
*/
- Native_thread_id last() const { return _last; }
+ bool request_from_core() { return false; }
/**
* Return badge for faulting thread
diff --git a/repos/base-sel4/src/core/pager.cc b/repos/base-sel4/src/core/pager.cc
index 1b0b177ee1..1abb2c11e7 100644
--- a/repos/base-sel4/src/core/pager.cc
+++ b/repos/base-sel4/src/core/pager.cc
@@ -97,51 +97,7 @@ void Ipc_pager::acknowledge_wakeup()
}
-Ipc_pager::Ipc_pager()
-:
- Native_capability(Capability_space::create_ep_cap(*Thread_base::myself())),
- _last(0)
-{ }
-
-
-
-/**********************
- ** Pager activation **
- **********************/
-
-void Pager_activation_base::entry()
-{
- Ipc_pager pager;
- _cap = pager;
- _cap_valid.unlock();
-
- bool reply_pending = false;
- while (1) {
-
- if (reply_pending)
- pager.reply_and_wait_for_fault();
- else
- pager.wait_for_fault();
-
- reply_pending = false;
-
- /* lookup referenced object */
- Object_pool::Guard _obj(_ep ? _ep->lookup_and_lock(pager.badge()) : 0);
- Pager_object *obj = _obj;
-
- /* handle request */
- if (obj) {
- if (pager.is_exception()) {
- obj->submit_exception_signal();
- continue;
- }
-
- /* send reply if page-fault handling succeeded */
- if (!obj->pager(pager))
- reply_pending = true;
- }
- }
-}
+Ipc_pager::Ipc_pager() : _last(0) { }
/******************
@@ -164,39 +120,16 @@ void Pager_object::unresolved_page_fault_occurred()
** Pager entrypoint **
**********************/
-Pager_entrypoint::Pager_entrypoint(Cap_session *, Pager_activation_base *a)
-: _activation(a)
-{ _activation->ep(this); }
-
-
-void Pager_entrypoint::dissolve(Pager_object *obj)
+Untyped_capability Pager_entrypoint::_manage(Pager_object *obj)
{
- remove_locked(obj);
-}
-
-
-Pager_capability Pager_entrypoint::manage(Pager_object *obj)
-{
- /* return invalid capability if no activation is present */
- if (!_activation) return Pager_capability();
-
/*
* 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.
*/
- Native_capability ep_cap = _activation->cap();
-
Rpc_obj_key rpc_obj_key((addr_t)obj->badge());
- Untyped_capability new_obj_cap =
- Capability_space::create_rpc_obj_cap(ep_cap, 0, rpc_obj_key);
-
- /* add server object to object pool */
- obj->cap(new_obj_cap);
- insert(obj);
-
- return reinterpret_cap_cast(new_obj_cap);
+ Untyped_capability ep_cap(Capability_space::create_ep_cap(*this));
+ return Capability_space::create_rpc_obj_cap(ep_cap, nullptr, rpc_obj_key);
}
-
diff --git a/repos/base/src/core/include/pager.h b/repos/base/src/core/include/pager.h
index 85a5ff69c4..5fa003ceb6 100644
--- a/repos/base/src/core/include/pager.h
+++ b/repos/base/src/core/include/pager.h
@@ -2,11 +2,12 @@
* \brief Paging-server framework
* \author Norman Feske
* \author Christian Helmuth
+ * \author Stefan Kalkowski
* \date 2006-04-28
*/
/*
- * Copyright (C) 2006-2013 Genode Labs GmbH
+ * Copyright (C) 2006-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.
@@ -16,31 +17,31 @@
#define _CORE__INCLUDE__PAGER_H_
#include
-#include
-#include
-#include
#include
-#include
#include
#include
+#include
namespace Genode {
+ /**
+ * Special server object for paging
+ *
+ * A 'Pager_object' is very similar to a 'Rpc_object'. It is just a
+ * special implementation for page-fault handling, which does not allow to
+ * define a "badge" for pager capabilities.
+ */
class Pager_object;
+
+ /**
+ * Paging entry point
+ */
class Pager_entrypoint;
- class Pager_activation_base;
- template class Pager_activation;
+
+ enum { PAGER_EP_STACK_SIZE = sizeof(addr_t) * 2048 };
}
-
-/**
- * Special server object for paging
- *
- * A 'Pager_object' is very similar to a 'Rpc_object'. It is just a
- * special implementation for page-fault handling, which does not allow to
- * define a "badge" for pager capabilities.
- */
class Genode::Pager_object : public Object_pool::Entry
{
protected:
@@ -125,69 +126,15 @@ class Genode::Pager_object : public Object_pool::Entry
};
-/**
- * A 'Pager_activation' processes one page fault of a 'Pager_object' at a time.
- */
-class Genode::Pager_activation_base: public Thread_base
+class Genode::Pager_entrypoint : public Object_pool,
+ public Thread
{
private:
- enum { WEIGHT = Cpu_session::DEFAULT_WEIGHT };
+ Ipc_pager _pager;
+ Cap_session *_cap_session;
- Native_capability _cap;
- Pager_entrypoint *_ep; /* entry point to which the
- activation belongs */
- /**
- * Lock used for blocking until '_cap' is initialized
- */
- Lock _cap_valid;
-
- public:
-
- Pager_activation_base(const char *name, size_t stack_size)
- : Thread_base(WEIGHT, name, stack_size), _cap(Native_capability()),
- _ep(0), _cap_valid(Lock::LOCKED) { }
-
- /**
- * Set entry point, which the activation serves
- *
- * This method is only called by the 'Pager_entrypoint'
- * constructor.
- */
- void ep(Pager_entrypoint *ep) { _ep = ep; }
-
- /**
- * Thread interface
- */
- void entry();
-
- /**
- * Return capability to this activation
- *
- * This method should only be called from 'Pager_entrypoint'
- */
- Native_capability cap()
- {
- /* ensure that the initialization of our 'Ipc_pager' is done */
- if (!_cap.valid())
- _cap_valid.lock();
- return _cap;
- }
-};
-
-
-/**
- * Paging entry point
- *
- * For a paging entry point can hold only one activation. So, paging is
- * strictly serialized for one entry point.
- */
-class Genode::Pager_entrypoint : public Object_pool
-{
- private:
-
- Pager_activation_base *_activation;
- Cap_session *_cap_session;
+ Untyped_capability _manage(Pager_object *obj);
public:
@@ -197,9 +144,10 @@ class Genode::Pager_entrypoint : public Object_pool
* \param cap_session Cap_session for creating capabilities
* for the pager objects managed by this
* entry point
- * \param a initial activation
*/
- Pager_entrypoint(Cap_session *cap_session, Pager_activation_base *a = 0);
+ Pager_entrypoint(Cap_session *cap_session)
+ : Thread("pager_ep"),
+ _cap_session(cap_session) { start(); }
/**
* Associate Pager_object with the entry point
@@ -210,16 +158,13 @@ class Genode::Pager_entrypoint : public Object_pool
* Dissolve Pager_object from entry point
*/
void dissolve(Pager_object *obj);
-};
-template
-class Genode::Pager_activation : public Pager_activation_base
-{
- public:
+ /**********************
+ ** Thread interface **
+ **********************/
- Pager_activation() : Pager_activation_base("pager", STACK_SIZE)
- { start(); }
+ void entry();
};
#endif /* _CORE__INCLUDE__PAGER_H_ */
diff --git a/repos/base/src/core/include/rm_root.h b/repos/base/src/core/include/rm_root.h
index 242ae725b9..a25c2b9fd3 100644
--- a/repos/base/src/core/include/rm_root.h
+++ b/repos/base/src/core/include/rm_root.h
@@ -29,12 +29,7 @@ namespace Genode {
Rpc_entrypoint *_ds_ep;
Rpc_entrypoint *_thread_ep;
Allocator *_md_alloc;
-
- enum { PAGER_STACK_SIZE = 2*4096 };
- Pager_activation _pager_thread;
-
Pager_entrypoint _pager_ep;
-
addr_t _vm_start;
size_t _vm_size;
@@ -105,8 +100,8 @@ namespace Genode {
:
Root_component(session_ep, md_alloc),
_ds_ep(ds_ep), _thread_ep(thread_ep), _md_alloc(md_alloc),
- _pager_thread(), _pager_ep(cap_session, &_pager_thread),
- _vm_start(vm_start), _vm_size(vm_size) { }
+ _pager_ep(cap_session), _vm_start(vm_start), _vm_size(vm_size)
+ { }
/**
* Return pager entrypoint
diff --git a/repos/base/src/core/pager_ep.cc b/repos/base/src/core/pager_ep.cc
new file mode 100644
index 0000000000..42af9444e2
--- /dev/null
+++ b/repos/base/src/core/pager_ep.cc
@@ -0,0 +1,103 @@
+/*
+ * \brief Generic implmentation of pager entrypoint
+ * \author Norman Feske
+ * \author Stefan Kalkowski
+ * \date 2009-03-31
+ */
+
+/*
+ * Copyright (C) 2009-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.
+ */
+
+/* Core includes */
+#include
+
+using namespace Genode;
+
+
+void Pager_entrypoint::entry()
+{
+ bool reply_pending = false;
+
+ while (1) {
+
+ if (reply_pending)
+ _pager.reply_and_wait_for_fault();
+ else
+ _pager.wait_for_fault();
+
+ reply_pending = false;
+
+ /* lookup referenced object */
+ Object_pool::Guard _obj(lookup_and_lock(_pager.badge()));
+ Pager_object *obj = _obj;
+
+ /* handle request */
+ if (obj) {
+ if (_pager.is_exception()) {
+ obj->submit_exception_signal();
+ continue;
+ }
+
+ /* send reply if page-fault handling succeeded */
+ reply_pending = !obj->pager(_pager);
+ continue;
+
+ } else {
+
+ /*
+ * Prevent threads outside of core to mess with our wake-up
+ * interface. This condition can trigger if a process gets
+ * destroyed which triggered a page fault shortly before getting
+ * killed. In this case, 'wait_for_fault()' returns (because of
+ * the page fault delivery) but the pager-object lookup will fail
+ * (because core removed the process already).
+ */
+ if (_pager.request_from_core()) {
+
+ /*
+ * 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.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();
+ }
+ }
+ };
+}
+
+
+void Pager_entrypoint::dissolve(Pager_object *obj)
+{
+ remove_locked(obj);
+}
+
+
+Pager_capability Pager_entrypoint::manage(Pager_object *obj)
+{
+ Native_capability cap = _manage(obj);
+
+ /* add server object to object pool */
+ obj->cap(cap);
+ insert(obj);
+
+ /* return capability that uses the object id as badge */
+ return reinterpret_cap_cast(cap);
+}
diff --git a/repos/base/src/core/pager_common.cc b/repos/base/src/core/pager_object.cc
similarity index 100%
rename from repos/base/src/core/pager_common.cc
rename to repos/base/src/core/pager_object.cc