2011-12-22 16:19:25 +01:00
|
|
|
/*
|
|
|
|
* \brief Pager support for Fiasco.OC
|
|
|
|
* \author Stefan Kalkowski
|
|
|
|
* \date 2011-01-11
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2017-02-20 13:23:52 +01:00
|
|
|
* Copyright (C) 2011-2017 Genode Labs GmbH
|
2011-12-22 16:19:25 +01:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
2017-02-20 13:23:52 +01:00
|
|
|
* under the terms of the GNU Affero General Public License version 3.
|
2011-12-22 16:19:25 +01:00
|
|
|
*/
|
|
|
|
|
2015-06-19 14:58:18 +02:00
|
|
|
/* Genode includes */
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
#include <base/log.h>
|
2011-12-22 16:19:25 +01:00
|
|
|
#include <base/thread.h>
|
|
|
|
|
2016-06-13 13:53:58 +02:00
|
|
|
/* core includes */
|
2015-06-19 14:58:18 +02:00
|
|
|
#include <ipc_pager.h>
|
|
|
|
|
2016-06-13 13:53:58 +02:00
|
|
|
/* base-internal includes */
|
|
|
|
#include <base/internal/native_utcb.h>
|
2016-06-15 15:04:54 +02:00
|
|
|
#include <base/internal/cap_map.h>
|
2016-06-13 13:53:58 +02:00
|
|
|
|
|
|
|
/* Fiasco includes */
|
2011-12-22 16:19:25 +01:00
|
|
|
namespace Fiasco {
|
|
|
|
#include <l4/sys/ipc.h>
|
|
|
|
}
|
|
|
|
|
|
|
|
using namespace Genode;
|
|
|
|
using namespace Fiasco;
|
|
|
|
|
|
|
|
void Ipc_pager::_parse(unsigned long label) {
|
|
|
|
_badge = label & ~0x3;
|
|
|
|
_parse_msg_type();
|
|
|
|
if (_type == PAGEFAULT || _type == EXCEPTION)
|
|
|
|
_parse_pagefault();
|
|
|
|
if (_type == PAUSE || _type == EXCEPTION)
|
|
|
|
memcpy(&_regs, l4_utcb_exc(), sizeof(l4_exc_regs_t));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Ipc_pager::_parse_pagefault()
|
|
|
|
{
|
|
|
|
if (_tag.is_exception()) {
|
|
|
|
_pf_addr = l4_utcb_exc_pfa(l4_utcb_exc());
|
|
|
|
_pf_ip = l4_utcb_exc_pc(l4_utcb_exc());
|
|
|
|
} else {
|
|
|
|
_pf_addr = l4_utcb_mr()->mr[0];
|
|
|
|
_pf_ip = l4_utcb_mr()->mr[1];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Ipc_pager::_parse_msg_type()
|
|
|
|
{
|
|
|
|
if (_tag.is_exception() && !l4_utcb_exc_is_pf(l4_utcb_exc())) {
|
|
|
|
_parse_exception();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_tag.is_page_fault())
|
|
|
|
_type = PAGEFAULT;
|
|
|
|
else {
|
|
|
|
_type = WAKE_UP;
|
|
|
|
_pf_ip = l4_utcb_mr()->mr[1];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-03-03 19:45:53 +01:00
|
|
|
/* Build with frame pointer to make GDB backtraces work. See issue #1061. */
|
|
|
|
__attribute__((optimize("-fno-omit-frame-pointer")))
|
|
|
|
__attribute__((noinline))
|
2011-12-22 16:19:25 +01:00
|
|
|
void Ipc_pager::wait_for_fault()
|
|
|
|
{
|
|
|
|
l4_umword_t label;
|
|
|
|
|
|
|
|
do {
|
|
|
|
_tag = l4_ipc_wait(l4_utcb(), &label, L4_IPC_NEVER);
|
|
|
|
int err = l4_ipc_error(_tag, l4_utcb());
|
|
|
|
if (!err) {
|
|
|
|
_parse(label);
|
|
|
|
return;
|
|
|
|
}
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
error("Ipc error ", err, " in pagefault from ", Hex(label & ~0x3));
|
2011-12-22 16:19:25 +01:00
|
|
|
} while (true);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Ipc_pager::reply_and_wait_for_fault()
|
|
|
|
{
|
|
|
|
l4_umword_t label;
|
|
|
|
l4_msgtag_t snd_tag = l4_msgtag(0, 0, 1, 0);
|
|
|
|
|
|
|
|
l4_umword_t grant = _reply_mapping.grant() ? L4_MAP_ITEM_GRANT : 0;
|
|
|
|
l4_utcb_mr()->mr[0] = _reply_mapping.dst_addr() | L4_ITEM_MAP | grant;
|
2012-06-18 15:20:31 +02:00
|
|
|
|
2014-06-19 16:37:31 +02:00
|
|
|
switch (_reply_mapping.cacheability()) {
|
|
|
|
case WRITE_COMBINED:
|
2012-06-18 15:20:31 +02:00
|
|
|
l4_utcb_mr()->mr[0] |= L4_FPAGE_BUFFERABLE << 4;
|
2014-06-19 16:37:31 +02:00
|
|
|
break;
|
|
|
|
case CACHED:
|
|
|
|
l4_utcb_mr()->mr[0] |= L4_FPAGE_CACHEABLE << 4;
|
|
|
|
break;
|
|
|
|
case UNCACHED:
|
|
|
|
if (!_reply_mapping.iomem())
|
|
|
|
l4_utcb_mr()->mr[0] |= L4_FPAGE_BUFFERABLE << 4;
|
|
|
|
else
|
|
|
|
l4_utcb_mr()->mr[0] |= L4_FPAGE_UNCACHEABLE << 4;
|
|
|
|
break;
|
|
|
|
}
|
2011-12-22 16:19:25 +01:00
|
|
|
l4_utcb_mr()->mr[1] = _reply_mapping.fpage().raw;
|
|
|
|
|
2016-01-23 14:42:55 +01:00
|
|
|
_tag = l4_ipc_send_and_wait(_last.kcap, l4_utcb(), snd_tag,
|
2011-12-22 16:19:25 +01:00
|
|
|
&label, L4_IPC_SEND_TIMEOUT_0);
|
|
|
|
int err = l4_ipc_error(_tag, l4_utcb());
|
|
|
|
if (err) {
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
error("Ipc error ", err, " in pagefault from ", Hex(label & ~0x3));
|
2011-12-22 16:19:25 +01:00
|
|
|
wait_for_fault();
|
|
|
|
} else
|
|
|
|
_parse(label);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Ipc_pager::acknowledge_wakeup()
|
|
|
|
{
|
2016-01-23 14:42:55 +01:00
|
|
|
l4_cap_idx_t dst = Fiasco::Capability::valid(_last.kcap) ? _last.kcap : L4_SYSF_REPLY;
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
/* answer wakeup call from one of core's region-manager sessions */
|
|
|
|
l4_ipc_send(dst, l4_utcb(), l4_msgtag(0, 0, 0, 0), L4_IPC_SEND_TIMEOUT_0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-09-26 11:49:00 +02:00
|
|
|
void Ipc_pager::acknowledge_exception()
|
|
|
|
{
|
|
|
|
memcpy(l4_utcb_exc(), &_regs, sizeof(l4_exc_regs_t));
|
2016-01-23 14:42:55 +01:00
|
|
|
l4_cap_idx_t dst = Fiasco::Capability::valid(_last.kcap) ? _last.kcap : L4_SYSF_REPLY;
|
2017-11-29 13:15:52 +01:00
|
|
|
Fiasco::l4_msgtag_t const msg_tag =
|
|
|
|
l4_ipc_send(dst, l4_utcb(),
|
|
|
|
l4_msgtag(0, L4_UTCB_EXCEPTION_REGS_SIZE, 0, 0),
|
|
|
|
L4_IPC_SEND_TIMEOUT_0);
|
|
|
|
|
|
|
|
Fiasco::l4_umword_t const err = l4_ipc_error(msg_tag, l4_utcb());
|
|
|
|
if (err) {
|
|
|
|
warning("failed to acknowledge exception, l4_ipc_err=", err);
|
|
|
|
}
|
2013-09-26 11:49:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
Ipc_pager::Ipc_pager()
|
2016-06-15 15:04:54 +02:00
|
|
|
:
|
|
|
|
Native_capability(*(Cap_index*)Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE]),
|
|
|
|
_badge(0)
|
|
|
|
{ }
|
2011-12-22 16:19:25 +01:00
|
|
|
|