sel4: add signal support

Fixes #1716
Issue #2044
This commit is contained in:
Alexander Boettcher 2016-06-29 15:22:08 +02:00 committed by Christian Helmuth
parent 93e2eecc52
commit e89b28ca1b
8 changed files with 262 additions and 3 deletions

View File

@ -59,7 +59,6 @@ vpath io_mem_session_component.cc $(GEN_CORE_DIR)
vpath io_mem_session_support.cc $(GEN_CORE_DIR)
vpath io_port_session_component.cc $(GEN_CORE_DIR)/spec/x86
vpath platform_services.cc $(GEN_CORE_DIR)/spec/x86
vpath signal_source_component.cc $(GEN_CORE_DIR)
vpath trace_session_component.cc $(GEN_CORE_DIR)
vpath dataspace_component.cc $(GEN_CORE_DIR)
vpath core_mem_alloc.cc $(GEN_CORE_DIR)
@ -67,4 +66,3 @@ vpath core_rpc_cap_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

View File

@ -192,3 +192,16 @@ Native_capability Capability_space::import(Ipc_cap_data ipc_cap_data)
return Native_capability(data);
}
Native_capability
Capability_space::create_notification_cap(Cap_sel &notify_cap)
{
Pd_session const *pd_session = nullptr;
Native_capability::Data &data =
local_capability_space().create_capability(notify_cap, pd_session,
Rpc_obj_key());
return Native_capability(data);
}

View File

@ -48,6 +48,13 @@ namespace Genode {
};
struct Notification_kobj
{
enum { SEL4_TYPE = seL4_NotificationObject, SIZE_LOG2 = 4 };
static char const *name() { return "notification"; }
};
struct Cnode_kobj
{
enum { SEL4_TYPE = seL4_CapTableObject, SIZE_LOG2 = 4 };

View File

@ -0,0 +1,94 @@
/*
* \brief Implementation of the SIGNAL interface
* \author Alexander Boettcher
* \date 2016-07-09
*/
/*
* Copyright (C) 2016 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 <base/log.h>
/* core includes */
#include <platform.h>
#include <signal_source_component.h>
/* base-internal include */
#include <core_capability_space.h>
using namespace Genode;
/*****************************
** Signal-source component **
*****************************/
void Signal_source_component::release(Signal_context_component *context)
{
if (context && context->enqueued())
_signal_queue.remove(context);
}
void Signal_source_component::submit(Signal_context_component *context,
unsigned long cnt)
{
/*
* If the client does not block in 'wait_for_signal', the
* signal will be delivered as result of the next
* 'wait_for_signal' call.
*/
context->increment_signal_cnt(cnt);
if (context->enqueued())
return;
_signal_queue.enqueue(context);
seL4_Signal(Capability_space::ipc_cap_data(_notify).sel.value());
}
Signal_source::Signal Signal_source_component::wait_for_signal()
{
if (_signal_queue.empty())
return Signal(0, 0); /* just a dummy */
/* dequeue and return pending signal */
Signal_context_component *context = _signal_queue.dequeue();
Signal result(context->imprint(), context->cnt());
context->reset_signal_cnt();
return result;
}
Signal_source_component::Signal_source_component(Rpc_entrypoint *ep)
:
_entrypoint(ep), _finalizer(*this),
_finalizer_cap(_entrypoint->manage(&_finalizer))
{
Platform &platform = *platform_specific();
Range_allocator &phys_alloc = *platform.ram_alloc();
/* allocate notification object within core's CNode */
Cap_sel ny_sel = platform.core_sel_alloc().alloc();
create<Notification_kobj>(phys_alloc, platform.core_cnode().sel(), ny_sel);
_notify = Capability_space::create_notification_cap(ny_sel);
}
Signal_source_component::~Signal_source_component()
{
_finalizer_cap.call<Finalizer::Rpc_exit>();
_entrypoint->dissolve(&_finalizer);
}
void Signal_source_component::Finalizer_component::exit() { }

View File

@ -0,0 +1,79 @@
/*
* \brief seL4-specific signal-source client interface
* \author Alexander Boettcher
* \date 2016-07-09
*/
/*
* Copyright (C) 2016 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.
*/
#ifndef _INCLUDE__SIGNAL_SOURCE__CLIENT_H_
#define _INCLUDE__SIGNAL_SOURCE__CLIENT_H_
#include <base/rpc_client.h>
#include <signal_source/sel4_signal_source.h>
#include <base/internal/capability_space_sel4.h>
#include <base/log.h>
namespace Genode {
class Signal_source_client;
}
class Genode::Signal_source_client : public Rpc_client<SeL4_signal_source>
{
private:
Native_capability _notify;
/**
* Request notification object from signal-source server
*/
void _init_notify()
{
_notify = call<Rpc_request_notify_obj>();
}
public:
/**
* Constructor
*/
Signal_source_client(Capability<Signal_source> cap)
: Rpc_client<SeL4_signal_source>(static_cap_cast<SeL4_signal_source>(cap))
{ _init_notify(); }
/*****************************
** Signal source interface **
*****************************/
Signal wait_for_signal() override
{
unsigned const dst_sel = Capability_space::ipc_cap_data(_notify).sel.value();
Signal signal;
do {
/*
* Ask ever for a new signal. The seL4 asynchronous mechanism
* squashes multiple notifications into one, so that we may
* miss to ask for a pending signal.
*/
signal = call<Rpc_wait_for_signal>();
if (!signal.imprint()) {
/* block on notification until signal context was submitted */
seL4_CPtr src = dst_sel;
seL4_Wait(src, nullptr);
}
} while (!signal.imprint());
return signal;
}
};
#endif /* _INCLUDE__SIGNAL_SOURCE__CLIENT_H_ */

View File

@ -0,0 +1,37 @@
/*
* \brief Signal-source server interface
* \author Alexander Boettcher
* \date 2016-07-09
*/
/*
* Copyright (C) 2016 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.
*/
#ifndef _INCLUDE__SIGNAL_SOURCE__RPC_OBJECT_H_
#define _INCLUDE__SIGNAL_SOURCE__RPC_OBJECT_H_
#include <base/rpc_server.h>
#include <signal_source/sel4_signal_source.h>
namespace Genode { struct Signal_source_rpc_object; }
struct Genode::Signal_source_rpc_object : Rpc_object<SeL4_signal_source,
Signal_source_rpc_object>
{
protected:
Native_capability _notify;
public:
Signal_source_rpc_object() {}
Native_capability _request_notify() { return _notify; }
};
#endif /* _INCLUDE__SIGNAL_SOURCE__RPC_OBJECT_H_ */

View File

@ -0,0 +1,29 @@
/*
* \brief seL4-specific signal source RPC interface
* \author Alexander Boettcher
* \date 2016-07-09
*/
/*
* Copyright (C) 2016 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.
*/
#ifndef _INCLUDE__SIGNAL_SOURCE__SEL4_SIGNAL_SOURCE_H_
#define _INCLUDE__SIGNAL_SOURCE__SEL4_SIGNAL_SOURCE_H_
#include <signal_source/signal_source.h>
#include <base/rpc_server.h>
namespace Genode { struct SeL4_signal_source; }
struct Genode::SeL4_signal_source : Signal_source
{
GENODE_RPC(Rpc_request_notify_obj, Native_capability, _request_notify);
GENODE_RPC_INTERFACE_INHERIT(Signal_source, Rpc_request_notify_obj);
};
#endif /* _INCLUDE__SIGNAL_SOURCE__SEL4_SIGNAL_SOURCE_H_ */

View File

@ -17,7 +17,7 @@
/* base-internal includes */
#include <base/internal/rpc_obj_key.h>
namespace Genode { class Pd_session; }
namespace Genode { class Cap_sel; class Pd_session; }
namespace Genode { namespace Capability_space {
@ -28,6 +28,8 @@ namespace Genode { namespace Capability_space {
Native_capability create_rpc_obj_cap(Native_capability ep_cap,
Pd_session const *,
Rpc_obj_key);
Native_capability create_notification_cap(Genode::Cap_sel &notify_cap);
} }
#endif /* _CORE__INCLUDE__CORE_CAPABILITY_SPACE_H_ */