From e89b28ca1b275d7c281cafe49e3bb52daf0d72da Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Wed, 29 Jun 2016 15:22:08 +0200 Subject: [PATCH] sel4: add signal support Fixes #1716 Issue #2044 --- repos/base-sel4/lib/mk/core.mk | 2 - repos/base-sel4/src/core/capability_space.cc | 13 +++ .../src/core/include/kernel_object.h | 7 ++ .../src/core/signal_source_component.cc | 94 +++++++++++++++++++ .../src/include/signal_source/client.h | 79 ++++++++++++++++ .../src/include/signal_source/rpc_object.h | 37 ++++++++ .../signal_source/sel4_signal_source.h | 29 ++++++ .../src/core/include/core_capability_space.h | 4 +- 8 files changed, 262 insertions(+), 3 deletions(-) create mode 100644 repos/base-sel4/src/core/signal_source_component.cc create mode 100644 repos/base-sel4/src/include/signal_source/client.h create mode 100644 repos/base-sel4/src/include/signal_source/rpc_object.h create mode 100644 repos/base-sel4/src/include/signal_source/sel4_signal_source.h diff --git a/repos/base-sel4/lib/mk/core.mk b/repos/base-sel4/lib/mk/core.mk index 2018a41b6..005ba3a35 100644 --- a/repos/base-sel4/lib/mk/core.mk +++ b/repos/base-sel4/lib/mk/core.mk @@ -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 - diff --git a/repos/base-sel4/src/core/capability_space.cc b/repos/base-sel4/src/core/capability_space.cc index e27685189..9bf930e41 100644 --- a/repos/base-sel4/src/core/capability_space.cc +++ b/repos/base-sel4/src/core/capability_space.cc @@ -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 ¬ify_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); +} diff --git a/repos/base-sel4/src/core/include/kernel_object.h b/repos/base-sel4/src/core/include/kernel_object.h index 9eb22fb3f..b69daa755 100644 --- a/repos/base-sel4/src/core/include/kernel_object.h +++ b/repos/base-sel4/src/core/include/kernel_object.h @@ -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 }; diff --git a/repos/base-sel4/src/core/signal_source_component.cc b/repos/base-sel4/src/core/signal_source_component.cc new file mode 100644 index 000000000..bb510fefc --- /dev/null +++ b/repos/base-sel4/src/core/signal_source_component.cc @@ -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 + +/* core includes */ +#include +#include + +/* base-internal include */ +#include + + +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(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(); + _entrypoint->dissolve(&_finalizer); +} + + +void Signal_source_component::Finalizer_component::exit() { } diff --git a/repos/base-sel4/src/include/signal_source/client.h b/repos/base-sel4/src/include/signal_source/client.h new file mode 100644 index 000000000..0add6d376 --- /dev/null +++ b/repos/base-sel4/src/include/signal_source/client.h @@ -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 +#include + +#include + +#include +namespace Genode { + class Signal_source_client; +} + +class Genode::Signal_source_client : public Rpc_client +{ + private: + + Native_capability _notify; + + /** + * Request notification object from signal-source server + */ + void _init_notify() + { + _notify = call(); + } + + public: + + /** + * Constructor + */ + Signal_source_client(Capability cap) + : Rpc_client(static_cap_cast(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(); + + 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_ */ diff --git a/repos/base-sel4/src/include/signal_source/rpc_object.h b/repos/base-sel4/src/include/signal_source/rpc_object.h new file mode 100644 index 000000000..8af43f2e1 --- /dev/null +++ b/repos/base-sel4/src/include/signal_source/rpc_object.h @@ -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 +#include + +namespace Genode { struct Signal_source_rpc_object; } + + +struct Genode::Signal_source_rpc_object : Rpc_object +{ + protected: + + Native_capability _notify; + + public: + + Signal_source_rpc_object() {} + + Native_capability _request_notify() { return _notify; } +}; + +#endif /* _INCLUDE__SIGNAL_SOURCE__RPC_OBJECT_H_ */ diff --git a/repos/base-sel4/src/include/signal_source/sel4_signal_source.h b/repos/base-sel4/src/include/signal_source/sel4_signal_source.h new file mode 100644 index 000000000..2b8dabe90 --- /dev/null +++ b/repos/base-sel4/src/include/signal_source/sel4_signal_source.h @@ -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 +#include + +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_ */ diff --git a/repos/base/src/core/include/core_capability_space.h b/repos/base/src/core/include/core_capability_space.h index 0eb5db185..f05a97923 100644 --- a/repos/base/src/core/include/core_capability_space.h +++ b/repos/base/src/core/include/core_capability_space.h @@ -17,7 +17,7 @@ /* base-internal includes */ #include -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 ¬ify_cap); } } #endif /* _CORE__INCLUDE__CORE_CAPABILITY_SPACE_H_ */