/* * \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 #include using namespace Genode; /*************************** ** Pager_activation_base ** ***************************/ void Pager_activation_base::entry() { /* acknowledge that we're ready to work */ Ipc_pager pager; _cap = pager; _cap_valid.unlock(); /* wait for the first pagefault */ bool reply = false; while (1) { if (reply) pager.resolve_and_wait_for_fault(); else pager.wait_for_fault(); /* lookup pager object for the current faulter */ Object_pool::Guard o(_ep ? _ep->lookup_and_lock(pager.badge()) : 0); if (!o) { PERR("%s:%d: Invalid pager object", __FILE__, __LINE__); while (1) ; } /* let pager handle the pagefault, apply mapping, await pagefault */ reply = !o->pager(pager); } } /********************** ** Pager_entrypoint ** **********************/ Pager_entrypoint::Pager_entrypoint(Cap_session *, Pager_activation_base * const a) : _activation(a) { _activation->ep(this); } void Pager_entrypoint::dissolve(Pager_object * const o) { remove_locked(o); } Pager_capability Pager_entrypoint::manage(Pager_object * const o) { /* do we have an activation */ if (!_activation) return Pager_capability(); /* create cap with the object badge as local name */ Native_capability c; c = Native_capability(_activation->cap().dst(), o->badge()); /* let activation provide the pager object */ o->cap(c); insert(o); /* return pager-object cap */ return reinterpret_cap_cast(c); } /*************** ** Ipc_pager ** ***************/ void Ipc_pager::wait_for_fault() { /* receive first message */ size_t s = Kernel::wait_for_request(); while (1) { switch (s) { case sizeof(Pagefault): { /* message is a pagefault */ Native_utcb * const utcb = Thread_base::myself()->utcb(); Pagefault * const pf = (Pagefault *)utcb; if (pf->valid()) { /* give our caller the chance to handle the fault */ _pagefault = *pf; return; } /* pagefault is invalid so get the next message */ else { PERR("%s:%d: Invalid pagefault", __FILE__, __LINE__); continue; } continue; } case sizeof(Pagefault_resolved): { /* message is a release request from a RM session */ Native_utcb * const utcb = Thread_base::myself()->utcb(); Pagefault_resolved * const msg = (Pagefault_resolved *)utcb; /* resume faulter, send ack to RM and get the next message */ Kernel::resume_thread(msg->pager_object->badge()); s = Kernel::reply(0, 1); continue; } default: { PERR("%s:%d: Invalid message format", __FILE__, __LINE__); continue; } } } }