From b1910cdd54d77183bcce7cd7fb7594a0c4c5fa17 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Thu, 14 Jan 2016 13:22:00 +0100 Subject: [PATCH] Integrate SIGNAL session into PD session This patch removes the SIGNAL service from core and moves its functionality to the PD session. Furthermore, it unifies the PD service implementation and terminology across the various base platforms. Issue #1841 --- repos/base-fiasco/src/core/target.inc | 6 +- .../include/signal_session/foc_source.h | 35 --- .../signal_session/source_rpc_object.h | 37 ---- .../client.h} | 10 +- .../include/signal_source/foc_signal_source.h | 30 +++ .../include/signal_source/rpc_object.h | 38 ++++ .../src/core/include/pd_session_component.h | 104 ++++++--- .../src/core/signal_source_component.cc | 5 +- repos/base-foc/src/core/target.inc | 2 - repos/base-hw/include/pd_session/connection.h | 2 +- repos/base-hw/include/signal_session/client.h | 57 ----- .../include/signal_session/connection.h | 35 --- .../include/signal_session/signal_session.h | 136 ------------ repos/base-hw/lib/mk/core.inc | 3 +- repos/base-hw/src/base/signal/signal.cc | 61 ++--- .../src/core/include/pd_session_component.h | 85 ------- .../base-hw/src/core/include/signal_broker.h | 152 +++++++++++++ repos/base-hw/src/core/include/signal_root.h | 96 -------- .../core/include/signal_session_component.h | 124 ----------- .../core/include/signal_source_component.h | 65 ++++++ .../base-hw/src/core/pd_upgrade_ram_quota.cc | 25 +++ .../src/core/signal_session_component.cc | 125 ----------- .../include/sync_session/sync_session.h | 2 +- .../include/linux_pd_session/client.h | 50 +++-- repos/base-linux/src/base/env/platform_env.h | 21 +- repos/base-linux/src/core/include/core_env.h | 21 +- .../src/core/include/pd_session_component.h | 133 ++++++----- .../src/core/pd_session_component.cc | 15 +- repos/base-linux/src/core/target.mk | 2 - repos/base-nova/include/pd_session/client.h | 57 +++-- .../base-nova/include/pd_session/pd_session.h | 75 ------- .../include/signal_session/nova_source.h | 35 --- .../signal_session/source_rpc_object.h | 47 ---- .../client.h} | 17 +- .../signal_source/nova_signal_source.h | 30 +++ repos/base-nova/src/base/signal/platform.cc | 7 +- .../src/core/include/pd_session_component.h | 77 ------- .../src/core/include/signal_broker.h | 135 +++++++++++ .../core/include/signal_session_component.h | 135 ----------- .../core/include/signal_source_component.h | 63 ++++++ ..._session_extension.cc => pd_assign_pci.cc} | 0 .../src/core/signal_session_component.cc | 113 ---------- repos/base-nova/src/core/target.inc | 5 +- .../src/core/include/pd_session_component.h | 90 +++++--- .../src/core/okl4_pd_session_component.cc | 2 +- repos/base-okl4/src/core/target.inc | 2 - repos/base-pistachio/src/core/target.inc | 6 +- repos/base-sel4/lib/mk/core.mk | 6 +- repos/base/include/base/env.h | 6 +- repos/base/include/base/rpc_server.h | 17 +- repos/base/include/base/signal.h | 17 +- repos/base/include/pd_session/client.h | 29 ++- repos/base/include/pd_session/connection.h | 2 +- repos/base/include/pd_session/pd_session.h | 119 +++++++++- .../base/include/signal_session/capability.h | 25 --- repos/base/include/signal_session/client.h | 43 ---- .../base/include/signal_session/connection.h | 32 --- .../include/signal_session/signal_session.h | 99 --------- .../include/signal_session/source_client.h | 33 --- repos/base/include/signal_source/capability.h | 22 ++ repos/base/include/signal_source/client.h | 30 +++ .../rpc_object.h} | 8 +- .../signal_source.h} | 31 +-- repos/base/src/base/env/platform_env.h | 1 + repos/base/src/base/server/common.cc | 7 +- repos/base/src/base/signal/common.cc | 17 +- repos/base/src/base/signal/platform.cc | 7 +- repos/base/src/base/signal/signal.cc | 33 ++- repos/base/src/core/include/assertion.h | 24 ++ repos/base/src/core/include/core_env.h | 46 ++-- repos/base/src/core/include/core_pd_session.h | 102 +++++++++ repos/base/src/core/include/pd_root.h | 12 +- .../src/core/include/pd_session_component.h | 87 ++++++-- repos/base/src/core/include/signal_broker.h | 110 +++++++++ repos/base/src/core/include/signal_root.h | 76 ------- .../core/include/signal_session_component.h | 209 ------------------ .../core/include/signal_source_component.h | 143 ++++++++++++ repos/base/src/core/main.cc | 11 - repos/base/src/core/pd_assign_pci.cc | 22 ++ repos/base/src/core/pd_session_component.cc | 2 +- repos/base/src/core/pd_upgrade_ram_quota.cc | 24 ++ .../base/src/core/signal_session_component.cc | 110 --------- .../base/src/core/signal_source_component.cc | 10 +- 83 files changed, 1711 insertions(+), 2234 deletions(-) delete mode 100644 repos/base-foc/include/signal_session/foc_source.h delete mode 100644 repos/base-foc/include/signal_session/source_rpc_object.h rename repos/base-foc/include/{signal_session/source_client.h => signal_source/client.h} (90%) create mode 100644 repos/base-foc/include/signal_source/foc_signal_source.h create mode 100644 repos/base-foc/include/signal_source/rpc_object.h delete mode 100644 repos/base-hw/include/signal_session/client.h delete mode 100644 repos/base-hw/include/signal_session/connection.h delete mode 100644 repos/base-hw/include/signal_session/signal_session.h delete mode 100644 repos/base-hw/src/core/include/pd_session_component.h create mode 100644 repos/base-hw/src/core/include/signal_broker.h delete mode 100644 repos/base-hw/src/core/include/signal_root.h delete mode 100644 repos/base-hw/src/core/include/signal_session_component.h create mode 100644 repos/base-hw/src/core/include/signal_source_component.h create mode 100644 repos/base-hw/src/core/pd_upgrade_ram_quota.cc delete mode 100644 repos/base-hw/src/core/signal_session_component.cc delete mode 100644 repos/base-nova/include/pd_session/pd_session.h delete mode 100644 repos/base-nova/include/signal_session/nova_source.h delete mode 100644 repos/base-nova/include/signal_session/source_rpc_object.h rename repos/base-nova/include/{signal_session/source_client.h => signal_source/client.h} (85%) create mode 100644 repos/base-nova/include/signal_source/nova_signal_source.h delete mode 100644 repos/base-nova/src/core/include/pd_session_component.h create mode 100644 repos/base-nova/src/core/include/signal_broker.h delete mode 100644 repos/base-nova/src/core/include/signal_session_component.h create mode 100644 repos/base-nova/src/core/include/signal_source_component.h rename repos/base-nova/src/core/{pd_session_extension.cc => pd_assign_pci.cc} (100%) delete mode 100644 repos/base-nova/src/core/signal_session_component.cc delete mode 100644 repos/base/include/signal_session/capability.h delete mode 100644 repos/base/include/signal_session/client.h delete mode 100644 repos/base/include/signal_session/connection.h delete mode 100644 repos/base/include/signal_session/signal_session.h delete mode 100644 repos/base/include/signal_session/source_client.h create mode 100644 repos/base/include/signal_source/capability.h create mode 100644 repos/base/include/signal_source/client.h rename repos/base/include/{signal_session/source_rpc_object.h => signal_source/rpc_object.h} (75%) rename repos/base/include/{signal_session/source.h => signal_source/signal_source.h} (55%) create mode 100644 repos/base/src/core/include/assertion.h create mode 100644 repos/base/src/core/include/core_pd_session.h create mode 100644 repos/base/src/core/include/signal_broker.h delete mode 100644 repos/base/src/core/include/signal_root.h delete mode 100644 repos/base/src/core/include/signal_session_component.h create mode 100644 repos/base/src/core/include/signal_source_component.h create mode 100644 repos/base/src/core/pd_assign_pci.cc create mode 100644 repos/base/src/core/pd_upgrade_ram_quota.cc delete mode 100644 repos/base/src/core/signal_session_component.cc diff --git a/repos/base-fiasco/src/core/target.inc b/repos/base-fiasco/src/core/target.inc index 3c588bbbe..72b747854 100644 --- a/repos/base-fiasco/src/core/target.inc +++ b/repos/base-fiasco/src/core/target.inc @@ -19,6 +19,8 @@ SRC_CC += cap_session_component.cc \ pager_ep.cc \ pager_object.cc \ pd_session_component.cc \ + pd_assign_pci.cc \ + pd_upgrade_ram_quota.cc \ platform.cc \ platform_pd.cc \ platform_services.cc \ @@ -28,7 +30,6 @@ SRC_CC += cap_session_component.cc \ rm_session_component.cc \ rm_session_support.cc \ rom_session_component.cc \ - signal_session_component.cc \ signal_source_component.cc \ thread_start.cc \ trace_session_component.cc @@ -49,10 +50,11 @@ vpath rom_session_component.cc $(GEN_CORE_DIR) vpath cap_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_component.cc $(GEN_CORE_DIR) vpath pd_session_component.cc $(GEN_CORE_DIR) +vpath pd_assign_pci.cc $(GEN_CORE_DIR) +vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) vpath rm_session_component.cc $(GEN_CORE_DIR) vpath io_mem_session_component.cc $(GEN_CORE_DIR) vpath io_mem_session_support.cc $(GEN_CORE_DIR) -vpath signal_session_component.cc $(GEN_CORE_DIR) vpath signal_source_component.cc $(GEN_CORE_DIR) vpath trace_session_component.cc $(GEN_CORE_DIR) vpath dataspace_component.cc $(GEN_CORE_DIR) diff --git a/repos/base-foc/include/signal_session/foc_source.h b/repos/base-foc/include/signal_session/foc_source.h deleted file mode 100644 index 267d33b8c..000000000 --- a/repos/base-foc/include/signal_session/foc_source.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * \brief Fiasco.OC-specific signal source RPC interface - * \author Norman Feske - * \author Stefan Kalkowski - * \date 2011-04-12 - */ - -/* - * Copyright (C) 2011-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. - */ - -#ifndef _INCLUDE__SIGNAL_SESSION__FOC_SOURCE_H_ -#define _INCLUDE__SIGNAL_SESSION__FOC_SOURCE_H_ - -#include -#include - -namespace Genode { - - struct Foc_signal_source : Signal_source - { - /********************* - ** RPC declaration ** - *********************/ - - GENODE_RPC(Rpc_request_semaphore, Native_capability, _request_semaphore); - - GENODE_RPC_INTERFACE_INHERIT(Signal_source, Rpc_request_semaphore); - }; -} - -#endif /* _INCLUDE__SIGNAL_SESSION__FOC_SOURCE_H_ */ diff --git a/repos/base-foc/include/signal_session/source_rpc_object.h b/repos/base-foc/include/signal_session/source_rpc_object.h deleted file mode 100644 index 15741ed24..000000000 --- a/repos/base-foc/include/signal_session/source_rpc_object.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * \brief Signal-source server interface - * \author Norman Feske - * \date 2010-02-03 - */ - -/* - * 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. - */ - -#ifndef _INCLUDE__SIGNAL_SESSION__SOURCE_RPC_OBJECT_H_ -#define _INCLUDE__SIGNAL_SESSION__SOURCE_RPC_OBJECT_H_ - -#include -#include - -namespace Genode { - - struct Signal_source_rpc_object : Rpc_object - { - protected: - - Native_capability _blocking_semaphore; - - public: - - Signal_source_rpc_object(Native_capability cap) - : _blocking_semaphore(cap) {} - - Native_capability _request_semaphore() { return _blocking_semaphore; } - }; -} - -#endif /* _INCLUDE__SIGNAL_SESSION__SOURCE_RPC_OBJECT_H_ */ diff --git a/repos/base-foc/include/signal_session/source_client.h b/repos/base-foc/include/signal_source/client.h similarity index 90% rename from repos/base-foc/include/signal_session/source_client.h rename to repos/base-foc/include/signal_source/client.h index ae87b670c..b5f65f598 100644 --- a/repos/base-foc/include/signal_session/source_client.h +++ b/repos/base-foc/include/signal_source/client.h @@ -20,12 +20,12 @@ * under the terms of the GNU General Public License version 2. */ -#ifndef _INCLUDE__SIGNAL_SESSION__SOURCE_CLIENT_H_ -#define _INCLUDE__SIGNAL_SESSION__SOURCE_CLIENT_H_ +#ifndef _INCLUDE__SIGNAL_SOURCE__CLIENT_H_ +#define _INCLUDE__SIGNAL_SOURCE__CLIENT_H_ #include #include -#include +#include namespace Fiasco { #include @@ -63,7 +63,7 @@ namespace Genode { /** * Constructor */ - Signal_source_client(Signal_source_capability cap) + Signal_source_client(Capability cap) : Rpc_client(static_cap_cast(cap)) { _init_sem(); } @@ -92,4 +92,4 @@ namespace Genode { }; } -#endif /* _INCLUDE__SIGNAL_SESSION__SOURCE_CLIENT_H_ */ +#endif /* _INCLUDE__SIGNAL_SOURCE__CLIENT_H_ */ diff --git a/repos/base-foc/include/signal_source/foc_signal_source.h b/repos/base-foc/include/signal_source/foc_signal_source.h new file mode 100644 index 000000000..1d66b8fac --- /dev/null +++ b/repos/base-foc/include/signal_source/foc_signal_source.h @@ -0,0 +1,30 @@ +/* + * \brief Fiasco.OC-specific signal source RPC interface + * \author Norman Feske + * \author Stefan Kalkowski + * \date 2011-04-12 + */ + +/* + * Copyright (C) 2011-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. + */ + +#ifndef _INCLUDE__SIGNAL_SOURCE__FOC_SIGNAL_SOURCE_H_ +#define _INCLUDE__SIGNAL_SOURCE__FOC_SIGNAL_SOURCE_H_ + +#include +#include + +namespace Genode { struct Foc_signal_source; } + + +struct Genode::Foc_signal_source : Signal_source +{ + GENODE_RPC(Rpc_request_semaphore, Native_capability, _request_semaphore); + GENODE_RPC_INTERFACE_INHERIT(Signal_source, Rpc_request_semaphore); +}; + +#endif /* _INCLUDE__SIGNAL_SOURCE__SIGNAL_SOURCE_H_ */ diff --git a/repos/base-foc/include/signal_source/rpc_object.h b/repos/base-foc/include/signal_source/rpc_object.h new file mode 100644 index 000000000..3afd8a56a --- /dev/null +++ b/repos/base-foc/include/signal_source/rpc_object.h @@ -0,0 +1,38 @@ +/* + * \brief Signal-source server interface + * \author Norman Feske + * \date 2010-02-03 + */ + +/* + * 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. + */ + +#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 _blocking_semaphore; + + public: + + Signal_source_rpc_object(Native_capability cap) + : _blocking_semaphore(cap) {} + + Native_capability _request_semaphore() { return _blocking_semaphore; } +}; + +#endif /* _INCLUDE__SIGNAL_SOURCE__RPC_OBJECT_H_ */ diff --git a/repos/base-foc/src/core/include/pd_session_component.h b/repos/base-foc/src/core/include/pd_session_component.h index 0fbafaf27..63c0d0b7c 100644 --- a/repos/base-foc/src/core/include/pd_session_component.h +++ b/repos/base-foc/src/core/include/pd_session_component.h @@ -16,48 +16,90 @@ #define _CORE__INCLUDE__PD_SESSION_COMPONENT_H_ /* Genode includes */ +#include #include #include /* core includes */ #include +#include -namespace Genode { - - class Pd_session_component : public Rpc_object - { - private: - - Platform_pd _pd; - Parent_capability _parent; - Rpc_entrypoint *_thread_ep; - - public: - - Pd_session_component(Rpc_entrypoint *thread_ep, - Allocator *md_alloc, const char *args) - : _thread_ep(thread_ep) { } - - /** - * Register quota donation at allocator guard - */ - void upgrade_ram_quota(size_t ram_quota) { } +namespace Genode { class Pd_session_component; } - /************************** - ** PD session interface ** - **************************/ +class Genode::Pd_session_component : public Rpc_object +{ + private: - int bind_thread(Thread_capability); - int assign_parent(Parent_capability); + Allocator_guard _md_alloc; /* guarded meta-data allocator */ + Platform_pd _pd; + Capability _parent; + Rpc_entrypoint &_thread_ep; + Signal_broker _signal_broker; + + size_t _ram_quota(char const * args) { + return Arg_string::find_arg(args, "ram_quota").long_value(0); } + + public: + + Pd_session_component(Rpc_entrypoint &thread_ep, + Rpc_entrypoint &receiver_ep, + Rpc_entrypoint &context_ep, + Allocator &md_alloc, + char const *args) + : + _md_alloc(&md_alloc, _ram_quota(args)), + _thread_ep(thread_ep), + _signal_broker(_md_alloc, receiver_ep, context_ep) + { } + + /** + * Register quota donation at allocator guard + */ + void upgrade_ram_quota(size_t ram_quota) { + _md_alloc.upgrade(ram_quota); } - /********************************** - ** Fiasco.OC specific functions ** - **********************************/ + /************************** + ** PD session interface ** + **************************/ - Native_capability task_cap(); - }; -} + int bind_thread(Thread_capability) override; + + int assign_parent(Capability) override; + + bool assign_pci(addr_t, uint16_t) override + { + PWRN("not implemented"); return false; + }; + + Signal_source_capability alloc_signal_source() override { + return _signal_broker.alloc_signal_source(); } + + void free_signal_source(Signal_source_capability sig_rec_cap) override { + _signal_broker.free_signal_source(sig_rec_cap); } + + Signal_context_capability + alloc_context(Signal_source_capability sig_rec_cap, unsigned long imprint) override + { + try { + return _signal_broker.alloc_context(sig_rec_cap, imprint); } + catch (Genode::Allocator::Out_of_memory) { + throw Pd_session::Out_of_metadata(); } + } + + void free_context(Signal_context_capability cap) override { + _signal_broker.free_context(cap); } + + void submit(Signal_context_capability cap, unsigned n) override { + _signal_broker.submit(cap, n); } + + + /********************************** + ** Fiasco.OC specific functions ** + **********************************/ + + Native_capability task_cap(); +}; #endif /* _CORE__INCLUDE__PD_SESSION_COMPONENT_H_ */ diff --git a/repos/base-foc/src/core/signal_source_component.cc b/repos/base-foc/src/core/signal_source_component.cc index 29fb7cd88..fec106e41 100644 --- a/repos/base-foc/src/core/signal_source_component.cc +++ b/repos/base-foc/src/core/signal_source_component.cc @@ -17,8 +17,8 @@ #include /* core includes */ -#include #include +#include namespace Fiasco { #include @@ -39,8 +39,7 @@ void Signal_source_component::release(Signal_context_component *context) } void Signal_source_component::submit(Signal_context_component *context, - Ipc_ostream *ostream, - int cnt) + unsigned long cnt) { /* enqueue signal to context */ context->increment_signal_cnt(cnt); diff --git a/repos/base-foc/src/core/target.inc b/repos/base-foc/src/core/target.inc index 78a79f037..89315c840 100644 --- a/repos/base-foc/src/core/target.inc +++ b/repos/base-foc/src/core/target.inc @@ -31,7 +31,6 @@ SRC_CC += cap_session_component.cc \ rm_session_component.cc \ rm_session_support.cc \ rom_session_component.cc \ - signal_session_component.cc \ signal_source_component.cc \ thread_start.cc \ trace_session_component.cc @@ -57,7 +56,6 @@ vpath pd_session_component.cc $(GEN_CORE_DIR) vpath ram_session_component.cc $(GEN_CORE_DIR) 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_object.cc $(GEN_CORE_DIR) vpath core_printf.cc $(BASE_DIR)/src/base/console diff --git a/repos/base-hw/include/pd_session/connection.h b/repos/base-hw/include/pd_session/connection.h index baa96b9c8..297ab9521 100644 --- a/repos/base-hw/include/pd_session/connection.h +++ b/repos/base-hw/include/pd_session/connection.h @@ -26,7 +26,7 @@ namespace Genode { struct Pd_connection; } struct Genode::Pd_connection : Connection, Pd_session_client { - enum { RAM_QUOTA = 20*1024 }; + enum { RAM_QUOTA = 28*1024 }; /** * Constructor diff --git a/repos/base-hw/include/signal_session/client.h b/repos/base-hw/include/signal_session/client.h deleted file mode 100644 index 3cdc55eb1..000000000 --- a/repos/base-hw/include/signal_session/client.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * \brief Client-side implementation of the signal session interface - * \author Martin Stein - * \date 2012-05-05 - */ - -/* - * 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. - */ - -#ifndef _INCLUDE__SIGNAL_SESSION__CLIENT_H_ -#define _INCLUDE__SIGNAL_SESSION__CLIENT_H_ - -/* Genode includes */ -#include -#include -#include - -namespace Genode -{ - /** - * Client-side implementation of the signal session interface - */ - struct Signal_session_client : Rpc_client - { - /** - * Constructor - * - * \param s targeted signal session - */ - explicit Signal_session_client(Signal_session_capability const s) - : Rpc_client(s) { } - - /****************************** - ** Signal_session interface ** - ******************************/ - - Signal_receiver_capability alloc_receiver() - { return call(); } - - Signal_context_capability - alloc_context(Signal_receiver_capability const r, - unsigned const imprint) { - return call(r, imprint); } - - void free_receiver(Signal_receiver_capability cap) { - call(cap); } - - void free_context(Signal_context_capability cap) { - call(cap); } - }; -} - -#endif /* _INCLUDE__SIGNAL_SESSION__CLIENT_H_ */ diff --git a/repos/base-hw/include/signal_session/connection.h b/repos/base-hw/include/signal_session/connection.h deleted file mode 100644 index 1b6abb51d..000000000 --- a/repos/base-hw/include/signal_session/connection.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * \brief Connection to signal service - * \author Stefan Kalkowski - * \author Norman Feske - * \date 2015-05-20 - * - * This is a shadow copy of the generic header in base, - * due to higher memory donation requirements in base-hw - */ - -/* - * Copyright (C) 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. - */ - -#ifndef _INCLUDE__SIGNAL_SESSION__CONNECTION_H_ -#define _INCLUDE__SIGNAL_SESSION__CONNECTION_H_ - -#include -#include - -namespace Genode { struct Signal_connection; } - - -struct Genode::Signal_connection : Connection, - Signal_session_client -{ - Signal_connection() - : Connection(session("ram_quota=32K")), - Signal_session_client(cap()) { } -}; - -#endif /* _INCLUDE__CAP_SESSION__CONNECTION_H_ */ diff --git a/repos/base-hw/include/signal_session/signal_session.h b/repos/base-hw/include/signal_session/signal_session.h deleted file mode 100644 index d168b63b3..000000000 --- a/repos/base-hw/include/signal_session/signal_session.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * \brief Signal session interface - * \author Martin Stein - * \date 2012-05-05 - */ - -/* - * 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. - */ - -#ifndef _INCLUDE__SIGNAL_SESSION__SIGNAL_SESSION_H_ -#define _INCLUDE__SIGNAL_SESSION__SIGNAL_SESSION_H_ - -/* Genode includes */ -#include -#include -#include - -namespace Genode -{ - class Signal_receiver; - class Signal_context; - - /* - * The 'dst' of this cap is used to communicate the ID of the - * corresponding signal-receiver kernel-object or 0 if the cap is invalid. - */ - typedef Capability Signal_receiver_capability; - - /* - * The 'dst' of this cap is used to communicate the ID of the - * corresponding signal-context kernel-object or 0 if the cap is invalid. - */ - typedef Capability Signal_context_capability; - - /** - * Signal session interface - */ - struct Signal_session : Session - { - class Out_of_metadata : public Exception { }; - class Create_receiver_failed : public Exception { }; - class Create_context_failed : public Exception { }; - class Kill_receiver_failed : public Exception { }; - class Kill_context_failed : public Exception { }; - - /** - * String that can be used to refer to this service - */ - static const char * service_name() { return "SIGNAL"; } - - /** - * Destructor - * - * \throw Kill_context_failed - * \throw Kill_receiver_failed - */ - virtual ~Signal_session() { } - - /** - * Create and manage a new signal receiver - * - * \return a cap that acts as reference to the created object - * - * \throw Out_of_metadata - * \throw Create_receiver_failed - */ - virtual Signal_receiver_capability alloc_receiver() = 0; - - /** - * Create and manage a new signal context - * - * \param r names the signal receiver that shall provide - * the new context - * \param imprint every signal that occures on the new context gets - * signed with this value - * - * \return a cap that acts as reference to the created object - * - * \throw Out_of_metadata - * \throw Create_context_failed - */ - virtual Signal_context_capability - alloc_context(Signal_receiver_capability r, - unsigned const imprint) = 0; - - /** - * Free a signal receiver - * - * \param cap capability of targeted signal receiver - * - * \throw Kill_receiver_failed - */ - virtual void free_receiver(Signal_receiver_capability cap) = 0; - - /** - * Free a signal context - * - * \param cap capability of targeted signal context - * - * \throw Kill_context_failed - */ - virtual void free_context(Signal_context_capability cap) = 0; - - - /********************* - ** RPC declaration ** - *********************/ - - GENODE_RPC_THROW(Rpc_alloc_receiver, Signal_receiver_capability, - alloc_receiver, GENODE_TYPE_LIST(Out_of_metadata, - Create_receiver_failed)); - - GENODE_RPC_THROW(Rpc_alloc_context, Signal_context_capability, - alloc_context, GENODE_TYPE_LIST(Out_of_metadata, - Create_context_failed), Signal_receiver_capability, - unsigned); - - GENODE_RPC_THROW(Rpc_free_receiver, void, free_receiver, - GENODE_TYPE_LIST(Kill_receiver_failed), - Signal_receiver_capability); - - GENODE_RPC_THROW(Rpc_free_context, void, free_context, - GENODE_TYPE_LIST(Kill_context_failed), - Signal_context_capability); - - GENODE_RPC_INTERFACE(Rpc_alloc_receiver, Rpc_alloc_context, - Rpc_free_receiver, Rpc_free_context); - }; -} - -#endif /* _INCLUDE__SIGNAL_SESSION__SIGNAL_SESSION_H_ */ - diff --git a/repos/base-hw/lib/mk/core.inc b/repos/base-hw/lib/mk/core.inc index 8fb2f0686..9e9dd9880 100644 --- a/repos/base-hw/lib/mk/core.inc +++ b/repos/base-hw/lib/mk/core.inc @@ -30,6 +30,8 @@ SRC_CC += io_mem_session_support.cc SRC_CC += irq_session_component.cc SRC_CC += main.cc SRC_CC += pd_session_component.cc +SRC_CC += pd_upgrade_ram_quota.cc +SRC_CC += pd_assign_pci.cc SRC_CC += platform.cc SRC_CC += platform_pd.cc SRC_CC += platform_thread.cc @@ -38,7 +40,6 @@ SRC_CC += ram_session_component.cc SRC_CC += ram_session_support.cc SRC_CC += rm_session_component.cc SRC_CC += rom_session_component.cc -SRC_CC += signal_session_component.cc SRC_CC += trace_session_component.cc SRC_CC += thread_start.cc SRC_CC += env.cc diff --git a/repos/base-hw/src/base/signal/signal.cc b/repos/base-hw/src/base/signal/signal.cc index 7dcc2bd29..1b66f54e6 100644 --- a/repos/base-hw/src/base/signal/signal.cc +++ b/repos/base-hw/src/base/signal/signal.cc @@ -12,9 +12,11 @@ */ /* Genode includes */ +#include #include #include -#include +#include +#include /* base-hw includes */ #include @@ -46,33 +48,22 @@ void Signal_transmitter::submit(unsigned cnt) Signal_receiver::Signal_receiver() { - /* create a kernel object that corresponds to the receiver */ - bool session_upgraded = 0; - Signal_connection * const s = signal_connection(); - while (1) { - try { - _cap = s->alloc_receiver(); - return; - } catch (Signal_session::Out_of_metadata) - { - /* upgrade session quota and try again, but only once */ - if (session_upgraded) { - PERR("failed to alloc signal receiver"); - _cap = Signal_receiver_capability(); - return; - } - PINF("upgrading quota donation for SIGNAL session"); - env()->parent()->upgrade(s->cap(), "ram_quota=8K"); - session_upgraded = 1; + retry( + [&] () { + _cap = env()->pd_session()->alloc_signal_source(); + }, + [&] () { + PINF("upgrading quota donation for PD session"); + env()->parent()->upgrade(env()->pd_session_cap(), "ram_quota=8K"); } - } + ); } void Signal_receiver::_platform_destructor() { /* release server resources of receiver */ - signal_connection()->free_receiver(_cap); + env()->pd_session()->free_signal_source(_cap); } @@ -91,27 +82,21 @@ Signal_context_capability Signal_receiver::manage(Signal_context * const c) Lock::Guard context_guard(c->_lock); if (c->_receiver) { throw Context_already_in_use(); } - /* create a context kernel-object at the receiver kernel-object */ - bool session_upgraded = 0; - Signal_connection * const s = signal_connection(); - while (1) { - try { - c->_cap = s->alloc_context(_cap, (unsigned long)c); + retry( + [&] () { + /* use signal context as imprint */ + c->_cap = env()->pd_session()->alloc_context(_cap, (unsigned long)c); c->_receiver = this; _contexts.insert(&c->_receiver_le); return c->_cap; - } catch (Signal_session::Out_of_metadata) - { - /* upgrade session quota and try again, but only once */ - if (session_upgraded) { - PERR("failed to alloc signal context"); - return Signal_context_capability(); - } - PINF("upgrading quota donation for signal session"); - env()->parent()->upgrade(s->cap(), "ram_quota=8K"); - session_upgraded = 1; + }, + [&] () { + PINF("upgrading quota donation for PD session"); + env()->parent()->upgrade(env()->pd_session_cap(), "ram_quota=8K"); } - } + ); + + return c->_cap; } diff --git a/repos/base-hw/src/core/include/pd_session_component.h b/repos/base-hw/src/core/include/pd_session_component.h deleted file mode 100644 index 38e66651e..000000000 --- a/repos/base-hw/src/core/include/pd_session_component.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * \brief Core-specific instance of the PD session interface - * \author Christian Helmuth - * \author Stefan Kalkowski - * \date 2006-07-17 - */ - -/* - * 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. - */ - -#ifndef _CORE__INCLUDE__PD_SESSION_COMPONENT_H_ -#define _CORE__INCLUDE__PD_SESSION_COMPONENT_H_ - -/* Genode includes */ -#include -#include -#include -#include - -/* core includes */ -#include - -namespace Genode { class Pd_session_component; } - - -class Genode::Pd_session_component : public Rpc_object -{ - private: - - /** - * Read and store the PD label - */ - struct Label { - - enum { MAX_LEN = 64 }; - char string[MAX_LEN]; - - Label(char const *args) - { - Arg_string::find_arg(args, "label").string(string, - sizeof(string), ""); - } - } const _label; - - Allocator_guard _md_alloc; /* guarded meta-data allocator */ - Platform_pd _pd; - Parent_capability _parent; - Rpc_entrypoint *_thread_ep; - - size_t _ram_quota(char const * args) { - return Arg_string::find_arg(args, "ram_quota").long_value(0); } - - public: - - Pd_session_component(Rpc_entrypoint * thread_ep, - Allocator * md_alloc, - char const * args) - : _label(args), - _md_alloc(md_alloc, _ram_quota(args)), - _pd(&_md_alloc, _label.string), - _thread_ep(thread_ep) { } - - /** - * Register quota donation at allocator guard - */ - void upgrade_ram_quota(size_t ram_quota) - { - _md_alloc.upgrade(ram_quota); - _pd.upgrade_slab(_md_alloc); - } - - - /**************************/ - /** PD session interface **/ - /**************************/ - - int bind_thread(Thread_capability); - int assign_parent(Parent_capability); -}; - -#endif /* _CORE__INCLUDE__PD_SESSION_COMPONENT_H_ */ diff --git a/repos/base-hw/src/core/include/signal_broker.h b/repos/base-hw/src/core/include/signal_broker.h new file mode 100644 index 000000000..05139725c --- /dev/null +++ b/repos/base-hw/src/core/include/signal_broker.h @@ -0,0 +1,152 @@ +/* + * \brief Base-hw-specific signal-delivery mechanism + * \author Norman Feske + * \date 2016-01-04 + */ + +/* + * 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 _CORE__INCLUDE__SIGNAL_BROKER_H_ +#define _CORE__INCLUDE__SIGNAL_BROKER_H_ + +/* Genode includes */ +#include + +/* core-local includes */ +#include +#include + +namespace Genode { class Signal_broker; } + + +class Genode::Signal_broker +{ + private: + + template + class Slab : public Tslab + { + private: + + uint8_t _first_block[BLOCK_SIZE]; + + public: + + Slab(Allocator * const allocator) + : Tslab(allocator, + (Slab_block*)&_first_block) { } + }; + + Allocator &_md_alloc; + Slab _sources_slab { &_md_alloc }; + Signal_source_pool _sources; + Slab _contexts_slab { &_md_alloc }; + Signal_context_pool _contexts; + + public: + + class Invalid_signal_source : public Exception { }; + + Signal_broker(Allocator &md_alloc, Rpc_entrypoint &, Rpc_entrypoint &) + : + _md_alloc(md_alloc) + { } + + ~Signal_broker() + { + _contexts.remove_all([this] (Signal_context_component *c) { + destroy(&_contexts_slab, c);}); + _sources.remove_all([this] (Signal_source_component *s) { + destroy(&_sources_slab, s);}); + } + + /* + * \throw Allocator::Out_of_memory + */ + Capability alloc_signal_source() + { + /* the _sources_slab may throw Allocator::Out_of_memory */ + Signal_source_component *s = new (_sources_slab) Signal_source_component(); + _sources.insert(s); + return reinterpret_cap_cast(s->cap()); + } + + void free_signal_source(Capability cap) + { + Signal_source_component *source = nullptr; + auto lambda = [&] (Signal_source_component *s) { + + if (!s) { + PERR("unknown signal source"); + return; + } + + source = s; + _sources.remove(source); + }; + _sources.apply(cap, lambda); + + /* destruct signal source outside the lambda to prevent deadlock */ + if (source) + destroy(&_sources_slab, source); + } + + /* + * \throw Allocator::Out_of_memory + * \throw Invalid_signal_source + */ + Signal_context_capability + alloc_context(Capability source, unsigned long imprint) + { + auto lambda = [&] (Signal_source_component *s) { + if (!s) { + PERR("unknown signal source"); + throw Invalid_signal_source(); + } + + /* the _contexts_slab may throw Allocator::Out_of_memory */ + Signal_context_component *c = new (_contexts_slab) + Signal_context_component(*s, imprint); + + _contexts.insert(c); + return reinterpret_cap_cast(c->cap()); + }; + return _sources.apply(source, lambda); + } + + void free_context(Signal_context_capability context_cap) + { + Signal_context_component *context = nullptr; + auto lambda = [&] (Signal_context_component *c) { + + if (!c) { + PERR("unknown signal context"); + return; + } + + context = c; + _contexts.remove(context); + }; + + _contexts.apply(context_cap, lambda); + + /* destruct context outside the lambda to prevent deadlock */ + if (context) + destroy(&_contexts_slab, context); + } + + void submit(Signal_context_capability cap, unsigned cnt) + { + /* + * This function is never called as base-hw delivers signals + * directly via the kernel. + */ + } +}; + +#endif /* _CORE__INCLUDE__SIGNAL_BROKER_H_ */ diff --git a/repos/base-hw/src/core/include/signal_root.h b/repos/base-hw/src/core/include/signal_root.h deleted file mode 100644 index f79053988..000000000 --- a/repos/base-hw/src/core/include/signal_root.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * \brief Signal root interface on HW-core - * \author Martin Stein - * \date 2012-05-06 - */ - -/* - * 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. - */ - -#ifndef _CORE__INCLUDE__SIGNAL_ROOT_H_ -#define _CORE__INCLUDE__SIGNAL_ROOT_H_ - -/* Genode includes */ -#include - -/* base-hw includes */ -#include - -/* core includes */ -#include - -namespace Genode -{ - /** - * Provide EP to signal root before it initialises root component - */ - class Signal_handler - { - enum { STACK_SIZE = 1024 * sizeof(addr_t) }; - - Rpc_entrypoint _entrypoint; - - public: - - /** - * Constructor - */ - Signal_handler(Cap_session * const c) - : _entrypoint(c, STACK_SIZE, "signal") { } - - /*************** - ** Accessors ** - ***************/ - - Rpc_entrypoint * entrypoint() { return &_entrypoint; } - }; - - /** - * Provides signal service by managing appropriate sessions to the clients - */ - class Signal_root : private Signal_handler, - public Root_component - { - public: - - /** - * Constructor - * - * \param md Meta-data allocator to be used by root component - * \param c CAP session to be used by the root entrypoint - */ - Signal_root(Allocator * const md, Cap_session * const c) : - Signal_handler(c), - Root_component(entrypoint(), md) - { } - - protected: - - /******************************** - ** 'Root_component' interface ** - ********************************/ - - Signal_session_component * _create_session(const char * args) - { - size_t ram_quota = - Arg_string::find_arg(args, "ram_quota").ulong_value(0); - return new (md_alloc()) - Signal_session_component(md_alloc(), ram_quota); - } - - void _upgrade_session(Signal_session_component *s, - const char * args) - { - size_t ram_quota = - Arg_string::find_arg(args, "ram_quota").ulong_value(0); - s->upgrade_ram_quota(ram_quota); - } - }; -} - -#endif /* _CORE__INCLUDE__SIGNAL_ROOT_H_ */ - diff --git a/repos/base-hw/src/core/include/signal_session_component.h b/repos/base-hw/src/core/include/signal_session_component.h deleted file mode 100644 index bd328695c..000000000 --- a/repos/base-hw/src/core/include/signal_session_component.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * \brief Server-sided implementation of a signal session - * \author Martin stein - * \date 2012-05-05 - */ - -/* - * 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. - */ - -#ifndef _CORE__INCLUDE__SIGNAL_SESSION_COMPONENT_H_ -#define _CORE__INCLUDE__SIGNAL_SESSION_COMPONENT_H_ - -/* Genode includes */ -#include -#include -#include -#include -#include - -/* core includes */ -#include -#include -#include - -namespace Genode -{ - /** - * Server-side implementation of a signal session - */ - class Signal_session_component; -} - - - -class Genode::Signal_session_component : public Rpc_object -{ - private: - - struct Receiver : Kernel_object, - Object_pool::Entry - { - using Pool = Object_pool; - - Receiver(); - }; - - - struct Context : Kernel_object, - Object_pool::Entry - { - using Pool = Object_pool; - - Context(Receiver &rcv, unsigned const imprint); - }; - - template - class Slab : public Tslab - { - private: - - uint8_t _first_block[BLOCK_SIZE]; - - public: - - Slab(Allocator * const allocator) - : Tslab(allocator, - (Slab_block*)&_first_block) { } - }; - - - Allocator_guard _allocator; - Slab _receivers_slab; - Receiver::Pool _receivers; - Slab _contexts_slab; - Context::Pool _contexts; - - /** - * Destruct receiver 'r' - */ - void _destruct_receiver(Receiver * const r); - - /** - * Destruct context 'c' - */ - void _destruct_context(Context * const c); - - public: - - /** - * Constructor - * - * \param allocator RAM allocator for meta data - * \param quota amount of RAM quota donated to this session - */ - Signal_session_component(Allocator * const allocator, - size_t const quota); - - ~Signal_session_component(); - - /** - * Raise the quota of this session by 'q' - */ - void upgrade_ram_quota(size_t const q) { _allocator.upgrade(q); } - - - /****************************** - ** Signal_session interface ** - ******************************/ - - Signal_receiver_capability alloc_receiver(); - - Signal_context_capability - alloc_context(Signal_receiver_capability, unsigned const); - - void free_receiver(Signal_receiver_capability); - - void free_context(Signal_context_capability); -}; - -#endif /* _CORE__INCLUDE__SIGNAL_SESSION_COMPONENT_H_ */ diff --git a/repos/base-hw/src/core/include/signal_source_component.h b/repos/base-hw/src/core/include/signal_source_component.h new file mode 100644 index 000000000..60e939248 --- /dev/null +++ b/repos/base-hw/src/core/include/signal_source_component.h @@ -0,0 +1,65 @@ +/* + * \brief Signal-delivery mechanism + * \author Norman Feske + * \date 2009-08-05 + */ + +/* + * 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. + */ + +#ifndef _CORE__INCLUDE__SIGNAL_SOURCE_COMPONENT_H_ +#define _CORE__INCLUDE__SIGNAL_SOURCE_COMPONENT_H_ + +/* Genode includes */ +#include + +/* core-local includes */ +#include +#include +#include + +namespace Genode { + + class Signal_context_component; + class Signal_source_component; + + typedef Object_pool Signal_context_pool; + typedef Object_pool Signal_source_pool; +} + + +struct Genode::Signal_context_component : Kernel_object, + Signal_context_pool::Entry +{ + inline Signal_context_component(Signal_source_component &s, + unsigned long const imprint); + + Signal_source_component *source() { ASSERT_NEVER_CALLED; } +}; + + +struct Genode::Signal_source_component : Kernel_object, + Signal_source_pool::Entry +{ + Signal_source_component() + : + Kernel_object(true), + Signal_source_pool::Entry(Kernel_object::_cap) + { } + + void submit(Signal_context_component *, unsigned long) { ASSERT_NEVER_CALLED; } +}; + + +Genode::Signal_context_component::Signal_context_component(Signal_source_component &s, + unsigned long const imprint) +: + Kernel_object(true, s.kernel_object(), imprint), + Signal_context_pool::Entry(Kernel_object::_cap) +{ } + +#endif /* _CORE__INCLUDE__SIGNAL_SOURCE_COMPONENT_H_ */ diff --git a/repos/base-hw/src/core/pd_upgrade_ram_quota.cc b/repos/base-hw/src/core/pd_upgrade_ram_quota.cc new file mode 100644 index 000000000..84962cb8f --- /dev/null +++ b/repos/base-hw/src/core/pd_upgrade_ram_quota.cc @@ -0,0 +1,25 @@ +/* + * \brief Core implementation of the PD session interface + * \author Norman Feske + * \date 2016-01-13 + */ + +/* + * 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. + */ + +/* core-local includes */ +#include + +using namespace Genode; + + +void Pd_session_component::upgrade_ram_quota(size_t ram_quota) +{ + _md_alloc.upgrade(ram_quota); + _pd.upgrade_slab(_md_alloc); +} + diff --git a/repos/base-hw/src/core/signal_session_component.cc b/repos/base-hw/src/core/signal_session_component.cc deleted file mode 100644 index f53f6432e..000000000 --- a/repos/base-hw/src/core/signal_session_component.cc +++ /dev/null @@ -1,125 +0,0 @@ -/* - * \brief Implementation of the SIGNAL service on the HW-core - * \author Martin Stein - * \date 2012-05-05 - */ - -/* - * 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 - -/* base-hw includes */ -#include - -/* core includes */ -#include - -using namespace Genode; - - -Signal_session_component::Receiver::Receiver() -: Kernel_object(true), - Signal_session_component::Receiver::Pool::Entry(Kernel_object::_cap) { } - - -Signal_session_component::Context::Context(Signal_session_component::Receiver &r, - unsigned const imprint) -: Kernel_object(true, r.kernel_object(), imprint), - Signal_session_component::Context::Pool::Entry(Kernel_object::_cap) { } - - -Signal_receiver_capability Signal_session_component::alloc_receiver() -{ - try { - Receiver * r = new (_receivers_slab) Receiver(); - _receivers.insert(r); - return reinterpret_cap_cast(r->cap()); - } catch (Allocator::Out_of_memory&) { - PERR("failed to allocate signal-receiver resources"); - throw Out_of_metadata(); - } - return reinterpret_cap_cast(Untyped_capability()); -} - - -void Signal_session_component::free_receiver(Signal_receiver_capability cap) -{ - /* look up ressource info */ - Receiver * receiver; - auto lambda = [&] (Receiver *r) { - receiver = r; - if (!receiver) { - PERR("unknown signal receiver"); - throw Kill_receiver_failed(); - } - /* release resources */ - _receivers.remove(receiver); - }; - _receivers.apply(cap, lambda); - destroy(&_receivers_slab, receiver); -} - - -Signal_context_capability -Signal_session_component::alloc_context(Signal_receiver_capability src, - unsigned const imprint) -{ - /* look up ressource info */ - auto lambda = [&] (Receiver *r) { - if (!r) { - PERR("unknown signal receiver"); - throw Create_context_failed(); - } - - try { - Context * c = new (_contexts_slab) Context(*r, imprint); - _contexts.insert(c); - return reinterpret_cap_cast(c->cap()); - } catch (Allocator::Out_of_memory&) { - PERR("failed to allocate signal-context resources"); - throw Out_of_metadata(); - } - return reinterpret_cap_cast(Untyped_capability()); - }; - return _receivers.apply(src, lambda); -} - - -void Signal_session_component::free_context(Signal_context_capability cap) -{ - /* look up ressource info */ - Context * context; - auto lambda = [&] (Context *c) { - context = c; - if (!context) { - PERR("unknown signal context"); - throw Kill_context_failed(); - } - /* release resources */ - _contexts.remove(context); - }; - _contexts.apply(cap, lambda); - destroy(&_contexts_slab, context); -} - - -Signal_session_component::Signal_session_component(Allocator * const allocator, - size_t const quota) -: _allocator(allocator, quota), _receivers_slab(&_allocator), - _contexts_slab(&_allocator) { } - - -Signal_session_component::~Signal_session_component() -{ - _contexts.remove_all([this] (Context * c) { - destroy(&_contexts_slab, c);}); - _receivers.remove_all([this] (Receiver * r) { - destroy(&_receivers_slab, r);}); -} diff --git a/repos/base-hw/src/test/cpu_quota/include/sync_session/sync_session.h b/repos/base-hw/src/test/cpu_quota/include/sync_session/sync_session.h index 740075774..25d4137fe 100644 --- a/repos/base-hw/src/test/cpu_quota/include/sync_session/sync_session.h +++ b/repos/base-hw/src/test/cpu_quota/include/sync_session/sync_session.h @@ -16,7 +16,7 @@ /* Genode includes */ #include -#include +#include namespace Sync { diff --git a/repos/base-linux/include/linux_pd_session/client.h b/repos/base-linux/include/linux_pd_session/client.h index d3c183870..07302706d 100644 --- a/repos/base-linux/include/linux_pd_session/client.h +++ b/repos/base-linux/include/linux_pd_session/client.h @@ -17,27 +17,45 @@ #include #include -namespace Genode { +namespace Genode { struct Linux_pd_session_client; } - struct Linux_pd_session_client : Rpc_client - { - explicit Linux_pd_session_client(Capability session) - : Rpc_client(session) { } +struct Genode::Linux_pd_session_client : Rpc_client +{ + explicit Linux_pd_session_client(Capability session) + : Rpc_client(session) { } - int bind_thread(Thread_capability thread) { - return call(thread); } + int bind_thread(Thread_capability thread) override { + return call(thread); } - int assign_parent(Parent_capability parent) { - return call(parent); } + int assign_parent(Capability parent) override { + return call(parent); } + + bool assign_pci(addr_t pci_config_memory_address, uint16_t bdf) override { + return call(pci_config_memory_address, bdf); } + + Signal_source_capability alloc_signal_source() override { + return call(); } + + void free_signal_source(Signal_source_capability cap) override { + call(cap); } + + Signal_context_capability alloc_context(Signal_source_capability source, + unsigned long imprint) override { + return call(source, imprint); } + + void free_context(Signal_context_capability cap) override { + call(cap); } + + void submit(Signal_context_capability receiver, unsigned cnt = 1) override { + call(receiver, cnt); } - /***************************** - * Linux-specific extension ** - *****************************/ + /***************************** + * Linux-specific extension ** + *****************************/ - void start(Capability binary) { - call(binary); } - }; -} + void start(Capability binary) { + call(binary); } +}; #endif /* _INCLUDE__LINUX_PD_SESSION__CLIENT_H_ */ diff --git a/repos/base-linux/src/base/env/platform_env.h b/repos/base-linux/src/base/env/platform_env.h index 7d3dc045c..b8b33d1c9 100644 --- a/repos/base-linux/src/base/env/platform_env.h +++ b/repos/base-linux/src/base/env/platform_env.h @@ -323,6 +323,7 @@ namespace Genode { Cpu_session_capability _cpu_session_cap; Expanding_cpu_session_client _cpu_session_client; Rm_session_mmap _rm_session_mmap; + Pd_session_capability _pd_session_cap; Pd_session_client _pd_session_client; public: @@ -339,7 +340,8 @@ namespace Genode { _cpu_session_cap(cpu_cap), _cpu_session_client(static_cap_cast(cpu_cap)), _rm_session_mmap(false), - _pd_session_client(pd_cap) + _pd_session_cap(pd_cap), + _pd_session_client(_pd_session_cap) { } @@ -347,12 +349,13 @@ namespace Genode { ** Env interface ** *******************/ - Ram_session *ram_session() { return &_ram_session_client; } - Ram_session_capability ram_session_cap() { return _ram_session_cap; } - Rm_session *rm_session() { return &_rm_session_mmap; } - Linux_cpu_session *cpu_session() { return &_cpu_session_client; } - Cpu_session_capability cpu_session_cap() { return _cpu_session_cap; } - Pd_session *pd_session() { return &_pd_session_client; } + Ram_session *ram_session() override { return &_ram_session_client; } + Ram_session_capability ram_session_cap() override { return _ram_session_cap; } + Rm_session *rm_session() override { return &_rm_session_mmap; } + Linux_cpu_session *cpu_session() override { return &_cpu_session_client; } + Cpu_session_capability cpu_session_cap() override { return _cpu_session_cap; } + Pd_session *pd_session() override { return &_pd_session_client; } + Pd_session_capability pd_session_cap() override { return _pd_session_cap; } /* * Support functions for implementing fork on Noux. @@ -451,8 +454,8 @@ namespace Genode { ** Env interface ** *******************/ - Parent *parent() { return &_parent(); } - Heap *heap() { return &_heap; } + Parent *parent() override { return &_parent(); } + Heap *heap() override { return &_heap; } }; } diff --git a/repos/base-linux/src/core/include/core_env.h b/repos/base-linux/src/core/include/core_env.h index d4576727b..67bcb6a0d 100644 --- a/repos/base-linux/src/core/include/core_env.h +++ b/repos/base-linux/src/core/include/core_env.h @@ -23,6 +23,7 @@ #include #include #include +#include /* internal base includes */ #include @@ -140,6 +141,17 @@ namespace Genode { Cap_session_component _cap_session; Entrypoint _entrypoint; Core_ram_session _ram_session; + + /* + * The core-local PD session is provided by a real RPC object + * dispatched by the same entrypoint as the signal-source RPC + * objects. This is needed to allow the 'Pd_session::submit' + * method to issue out-of-order replies to + * 'Signal_source::wait_for_signal' calls. + */ + Core_pd_session_component _pd_session_component; + Pd_session_client _pd_session_client; + Heap _heap; Ram_session_capability const _ram_session_cap; @@ -158,6 +170,8 @@ namespace Genode { _ram_session(&_entrypoint, &_entrypoint, platform()->ram_alloc(), platform()->core_mem_alloc(), "ram_quota=4M", platform()->ram_alloc()->avail()), + _pd_session_component(_entrypoint /* XXX use a different entrypoint */), + _pd_session_client(_entrypoint.manage(&_pd_session_component)), _heap(&_ram_session, Platform_env_base::rm_session()), _ram_session_cap(_entrypoint.manage(&_ram_session)) { } @@ -183,6 +197,7 @@ namespace Genode { Parent *parent() { return &_core_parent; } Ram_session *ram_session() { return &_ram_session; } Ram_session_capability ram_session_cap() { return _ram_session_cap; } + Pd_session *pd_session() { return &_pd_session_client; } Allocator *heap() { return &_heap; } Cpu_session_capability cpu_session_cap() { @@ -190,12 +205,6 @@ namespace Genode { return Cpu_session_capability(); } - Pd_session *pd_session() - { - PWRN("%s:%u not implemented", __FILE__, __LINE__); - return 0; - } - void reload_parent_cap(Capability::Dst, long) { } }; diff --git a/repos/base-linux/src/core/include/pd_session_component.h b/repos/base-linux/src/core/include/pd_session_component.h index 0ace51f22..e4e0623b5 100644 --- a/repos/base-linux/src/core/include/pd_session_component.h +++ b/repos/base-linux/src/core/include/pd_session_component.h @@ -21,61 +21,92 @@ /* core includes */ #include +#include namespace Genode { class Dataspace_component; - class Pd_session_component : public Rpc_object - { - private: - - enum { LABEL_MAX_LEN = 1024 }; - enum { ROOT_PATH_MAX_LEN = 512 }; - - unsigned long _pid; - char _label[LABEL_MAX_LEN]; - char _root[ROOT_PATH_MAX_LEN]; - unsigned _uid; - unsigned _gid; - Parent_capability _parent; - Rpc_entrypoint *_ds_ep; - - void _start(Dataspace_component *ds); - - public: - - /** - * Constructor - * - * \param ds_ep entrypoint where the dataspaces are managed - * \param md_alloc meta-data allocator - * \param args additional session arguments - */ - Pd_session_component(Rpc_entrypoint *ds_ep, Allocator * md_alloc, - const char *args); - - ~Pd_session_component(); - - /** - * Register quota donation at allocator guard - */ - void upgrade_ram_quota(size_t ram_quota) { } - - - /************************** - ** PD session interface ** - **************************/ - - int bind_thread(Thread_capability); - int assign_parent(Parent_capability parent); - - - /****************************** - ** Linux-specific extension ** - ******************************/ - - void start(Capability binary); - }; + class Pd_session_component; + class Parent; } + +class Genode::Pd_session_component : public Rpc_object +{ + private: + + enum { LABEL_MAX_LEN = 1024 }; + enum { ROOT_PATH_MAX_LEN = 512 }; + + unsigned long _pid; + char _label[LABEL_MAX_LEN]; + char _root[ROOT_PATH_MAX_LEN]; + unsigned _uid; + unsigned _gid; + Capability _parent; + Rpc_entrypoint &_ds_ep; + Signal_broker _signal_broker; + + void _start(Dataspace_component *ds); + + public: + + /** + * Constructor + * + * \param ds_ep entrypoint where the dataspaces are managed + * \param receiver_ep entrypoint holding signal-receiver component + * objects + * \param context_ep global pool of all signal contexts + * \param md_alloc meta-data allocator + * \param args additional session arguments + */ + Pd_session_component(Rpc_entrypoint &ds_ep, + Rpc_entrypoint &receiver_ep, + Rpc_entrypoint &context_ep, + Allocator &md_alloc, + const char *args); + + ~Pd_session_component(); + + /** + * Register quota donation at allocator guard + */ + void upgrade_ram_quota(size_t ram_quota) { } + + + /************************** + ** PD session interface ** + **************************/ + + int bind_thread(Thread_capability); + int assign_parent(Capability); + bool assign_pci(addr_t, uint16_t) { return false; } + + Signal_source_capability alloc_signal_source() override { + return _signal_broker.alloc_signal_source(); } + + void free_signal_source(Signal_source_capability cap) override { + _signal_broker.free_signal_source(cap); } + + Signal_context_capability + alloc_context(Signal_source_capability sig_rec_cap, unsigned long imprint) override + { + return _signal_broker.alloc_context(sig_rec_cap, imprint); + } + + void free_context(Signal_context_capability cap) override { + _signal_broker.free_context(cap); } + + void submit(Signal_context_capability cap, unsigned n) override { + _signal_broker.submit(cap, n); } + + + /****************************** + ** Linux-specific extension ** + ******************************/ + + void start(Capability binary); +}; + #endif /* _CORE__INCLUDE__PD_SESSION_COMPONENT_H_ */ diff --git a/repos/base-linux/src/core/pd_session_component.cc b/repos/base-linux/src/core/pd_session_component.cc index 5d5c986c9..3f2548275 100644 --- a/repos/base-linux/src/core/pd_session_component.cc +++ b/repos/base-linux/src/core/pd_session_component.cc @@ -397,11 +397,14 @@ void Pd_session_component::_start(Dataspace_component *ds) } -Pd_session_component::Pd_session_component(Rpc_entrypoint * ep, - Allocator * md_alloc, - const char * args) +Pd_session_component::Pd_session_component(Rpc_entrypoint &ds_ep, + Rpc_entrypoint &receiver_ep, + Rpc_entrypoint &context_ep, + Allocator &md_alloc, + const char *args) : - _pid(0), _uid(0), _gid(0), _ds_ep(ep) + _pid(0), _uid(0), _gid(0), _ds_ep(ds_ep), + _signal_broker(md_alloc, receiver_ep, context_ep) { Arg_string::find_arg(args, "label").string(_label, sizeof(_label), ""); @@ -449,7 +452,7 @@ Pd_session_component::~Pd_session_component() int Pd_session_component::bind_thread(Thread_capability) { return -1; } -int Pd_session_component::assign_parent(Parent_capability parent) +int Pd_session_component::assign_parent(Capability parent) { _parent = parent; return 0; @@ -459,6 +462,6 @@ int Pd_session_component::assign_parent(Parent_capability parent) void Pd_session_component::start(Capability binary) { /* lookup binary dataspace */ - _ds_ep->apply(binary, [&] (Dataspace_component *ds) { + _ds_ep.apply(binary, [&] (Dataspace_component *ds) { _start(ds); }); }; diff --git a/repos/base-linux/src/core/target.mk b/repos/base-linux/src/core/target.mk index 7d7e4a741..428a5d9e5 100644 --- a/repos/base-linux/src/core/target.mk +++ b/repos/base-linux/src/core/target.mk @@ -18,7 +18,6 @@ SRC_CC = main.cc \ dataspace_component.cc \ pd_session_component.cc \ io_mem_session_component.cc \ - signal_session_component.cc \ signal_source_component.cc \ trace_session_component.cc \ thread_linux.cc \ @@ -44,7 +43,6 @@ vpath ram_session_component.cc $(GEN_CORE_DIR) vpath cap_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_component.cc $(GEN_CORE_DIR) vpath platform_services.cc $(GEN_CORE_DIR) -vpath signal_session_component.cc $(GEN_CORE_DIR) vpath signal_source_component.cc $(GEN_CORE_DIR) vpath trace_session_component.cc $(GEN_CORE_DIR) vpath core_printf.cc $(BASE_DIR)/src/base/console diff --git a/repos/base-nova/include/pd_session/client.h b/repos/base-nova/include/pd_session/client.h index 9a29860dd..f874badb2 100644 --- a/repos/base-nova/include/pd_session/client.h +++ b/repos/base-nova/include/pd_session/client.h @@ -17,25 +17,52 @@ #include #include -namespace Genode { +namespace Genode { struct Pd_session_client; } - struct Pd_session_client : Rpc_client + +/* + * This implementation overrides the corresponding header in base/include + * to tweak the way the parent capability is passed to core. + */ +struct Genode::Pd_session_client : Rpc_client +{ + explicit Pd_session_client(Pd_session_capability session) + : Rpc_client(session) { } + + int bind_thread(Thread_capability thread) override { + return call(thread); } + + int assign_parent(Capability parent) override { - explicit Pd_session_client(Pd_session_capability session) - : Rpc_client(session) { } + /* + * NOVA-specific implementation + * + * We need to prevent NOVA from creating a new branch in the mapping + * tree. Instead, we need core to re-associate the supplied PD cap with + * the core-known PD session component of the parent. + */ + parent.solely_map(); + return call(parent); + } - int bind_thread(Thread_capability thread) { - return call(thread); } + bool assign_pci(addr_t pci_config_memory_address, uint16_t bdf) override { + return call(pci_config_memory_address, bdf); } - int assign_parent(Parent_capability parent) - { - parent.solely_map(); - return call(parent); - } + Signal_source_capability alloc_signal_source() override { + return call(); } - bool assign_pci(addr_t pci_config_memory_address, uint16_t bdf) { - return call(pci_config_memory_address, bdf); } - }; -} + void free_signal_source(Signal_source_capability cap) override { + call(cap); } + + Signal_context_capability alloc_context(Signal_source_capability source, + unsigned long imprint) override { + return call(source, imprint); } + + void free_context(Signal_context_capability cap) override { + call(cap); } + + void submit(Signal_context_capability receiver, unsigned cnt = 1) override { + call(receiver, cnt); } +}; #endif /* _INCLUDE__PD_SESSION__CLIENT_H_ */ diff --git a/repos/base-nova/include/pd_session/pd_session.h b/repos/base-nova/include/pd_session/pd_session.h deleted file mode 100644 index efa573acc..000000000 --- a/repos/base-nova/include/pd_session/pd_session.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * \brief Protection domain (PD) session interface - * \author Christian Helmuth - * \date 2006-06-27 - * - * A pd session represents the protection domain of a program. - */ - -/* - * 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. - */ - -#ifndef _INCLUDE__PD_SESSION__PD_SESSION_H_ -#define _INCLUDE__PD_SESSION__PD_SESSION_H_ - -#include -#include -#include - -namespace Genode { - - struct Pd_session : Session - { - static const char *service_name() { return "PD"; } - - virtual ~Pd_session() { } - - /** - * Bind thread to protection domain - * - * \param thread capability of thread to bind - * - * \return 0 on success or negative error code - * - * After successful bind, the thread will execute inside this - * protection domain when started. - */ - virtual int bind_thread(Thread_capability thread) = 0; - - /** - * Assign parent to protection domain - * - * \param parent capability of parent interface - * \return 0 on success, or negative error code - */ - virtual int assign_parent(Parent_capability parent) = 0; - - - /** - * Assign PCI device to a protection domain. - * - * \param pci_config_space virtual address of the 4K PCI config - * space extended memory of the device - * \param bdf bus/device/function of the PCI device - * \return true on success, or false in case of an error - */ - virtual bool assign_pci(addr_t pci_config_space, uint16_t bdf) = 0; - - /********************* - ** RPC declaration ** - *********************/ - - GENODE_RPC(Rpc_bind_thread, int, bind_thread, Thread_capability); - GENODE_RPC(Rpc_assign_parent, int, assign_parent, Parent_capability); - GENODE_RPC(Rpc_assign_pci, bool, assign_pci, addr_t, uint16_t); - - GENODE_RPC_INTERFACE(Rpc_bind_thread, Rpc_assign_parent, - Rpc_assign_pci); - }; -} - -#endif /* _INCLUDE__PD_SESSION__PD_SESSION_H_ */ diff --git a/repos/base-nova/include/signal_session/nova_source.h b/repos/base-nova/include/signal_session/nova_source.h deleted file mode 100644 index 8ba79f8a5..000000000 --- a/repos/base-nova/include/signal_session/nova_source.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * \brief NOVA-specific signal source RPC interface - * \author Norman Feske - * \date 2011-04-12 - */ - -/* - * Copyright (C) 2011-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. - */ - -#ifndef _INCLUDE__SIGNAL_SESSION__NOVA_SOURCE_H_ -#define _INCLUDE__SIGNAL_SESSION__NOVA_SOURCE_H_ - -#include -#include - -namespace Genode { - - struct Nova_signal_source : Signal_source - { - /********************* - ** RPC declaration ** - *********************/ - - GENODE_RPC(Rpc_register_semaphore, void, _register_semaphore, - Native_capability const &); - - GENODE_RPC_INTERFACE_INHERIT(Signal_source, Rpc_register_semaphore); - }; -} - -#endif /* _INCLUDE__SIGNAL_SESSION__NOVA_SOURCE_H_ */ diff --git a/repos/base-nova/include/signal_session/source_rpc_object.h b/repos/base-nova/include/signal_session/source_rpc_object.h deleted file mode 100644 index 39aeacf84..000000000 --- a/repos/base-nova/include/signal_session/source_rpc_object.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * \brief Signal-source server interface - * \author Norman Feske - * \date 2010-02-03 - * - * This file is only included by 'signal_session/server.h' and relies on the - * headers included there. No include guards are needed. It is a separate - * header file to make it easily replaceable by a platform-specific - * implementation. - */ - -/* - * Copyright (C) 2010-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. - */ - -#ifndef _INCLUDE__SIGNAL_SESSION__SOURCE_SERVER_H_ -#define _INCLUDE__SIGNAL_SESSION__SOURCE_SERVER_H_ - -#include -#include - -namespace Genode { struct Signal_source_rpc_object; } - -struct Genode::Signal_source_rpc_object : Rpc_object -{ - public: - - Native_capability _blocking_semaphore; - - public: - - void _register_semaphore(Native_capability const &cap) - { - if (_blocking_semaphore.valid()) - PWRN("overwritting blocking signal semaphore !!!"); - - _blocking_semaphore = cap; - } - - Signal_source_rpc_object() {} -}; - -#endif /* _INCLUDE__SIGNAL_SESSION__SOURCE_SERVER_H_ */ diff --git a/repos/base-nova/include/signal_session/source_client.h b/repos/base-nova/include/signal_source/client.h similarity index 85% rename from repos/base-nova/include/signal_session/source_client.h rename to repos/base-nova/include/signal_source/client.h index 8cd4aabfb..13794da41 100644 --- a/repos/base-nova/include/signal_session/source_client.h +++ b/repos/base-nova/include/signal_source/client.h @@ -18,11 +18,11 @@ * under the terms of the GNU General Public License version 2. */ -#ifndef _INCLUDE__SIGNAL_SESSION__SOURCE_CLIENT_H_ -#define _INCLUDE__SIGNAL_SESSION__SOURCE_CLIENT_H_ +#ifndef _INCLUDE__SIGNAL_SOURCE__CLIENT_H_ +#define _INCLUDE__SIGNAL_SOURCE__CLIENT_H_ #include -#include +#include /* NOVA includes */ #include @@ -60,9 +60,8 @@ namespace Genode { /** * Constructor */ - Signal_source_client(Signal_source_capability cap) - : Rpc_client( - static_cap_cast(cap)) + Signal_source_client(Capability cap) + : Rpc_client(static_cap_cast(cap)) { /* * Make sure that we have acquired the @@ -76,9 +75,9 @@ namespace Genode { ** Signal source interface ** *****************************/ - Signal wait_for_signal() + Signal wait_for_signal() override { - /* + /* * Block on semaphore, will be unblocked if * signal is available */ @@ -94,4 +93,4 @@ namespace Genode { }; } -#endif /* _INCLUDE__SIGNAL_SESSION__SOURCE_CLIENT_H_ */ +#endif /* _INCLUDE__SIGNAL_SOURCE__CLIENT_H_ */ diff --git a/repos/base-nova/include/signal_source/nova_signal_source.h b/repos/base-nova/include/signal_source/nova_signal_source.h new file mode 100644 index 000000000..5a2f22197 --- /dev/null +++ b/repos/base-nova/include/signal_source/nova_signal_source.h @@ -0,0 +1,30 @@ +/* + * \brief NOVA-specific signal source RPC interface + * \author Norman Feske + * \date 2011-04-12 + */ + +/* + * Copyright (C) 2011-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. + */ + +#ifndef _INCLUDE__SIGNAL_SOURCE__NOVA_SIGNAL_SOURCE_H_ +#define _INCLUDE__SIGNAL_SOURCE__NOVA_SIGNAL_SOURCE_H_ + +#include +#include + +namespace Genode { struct Nova_signal_source; } + +struct Genode::Nova_signal_source : Signal_source +{ + GENODE_RPC(Rpc_register_semaphore, void, register_semaphore, + Native_capability const &); + + GENODE_RPC_INTERFACE_INHERIT(Signal_source, Rpc_register_semaphore); +}; + +#endif /* _INCLUDE__SIGNAL_SOURCE__NOVA_SIGNAL_SOURCE_H_ */ diff --git a/repos/base-nova/src/base/signal/platform.cc b/repos/base-nova/src/base/signal/platform.cc index 23063d0e2..668615ff0 100644 --- a/repos/base-nova/src/base/signal/platform.cc +++ b/repos/base-nova/src/base/signal/platform.cc @@ -13,13 +13,12 @@ /* Genode includes */ -#include +#include +#include using namespace Genode; -/************************ - ** Signal transmitter ** - ************************/ + void Signal_transmitter::submit(unsigned cnt) { { diff --git a/repos/base-nova/src/core/include/pd_session_component.h b/repos/base-nova/src/core/include/pd_session_component.h deleted file mode 100644 index 57fb318b9..000000000 --- a/repos/base-nova/src/core/include/pd_session_component.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * \brief Core-specific instance of the PD session interface - * \author Christian Helmuth - * \date 2006-07-17 - */ - -/* - * 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. - */ - -#ifndef _CORE__INCLUDE__PD_SESSION_COMPONENT_H_ -#define _CORE__INCLUDE__PD_SESSION_COMPONENT_H_ - -/* Genode includes */ -#include -#include -#include - -/* core includes */ -#include - -namespace Genode { - - class Pd_session_component : public Rpc_object - { - private: - - /** - * Read and store the PD label - */ - struct Label { - - enum { MAX_LEN = 64 }; - char string[MAX_LEN]; - - /** - * Constructor - */ - Label(char const *args) - { - Arg_string::find_arg(args, "label").string(string, sizeof(string), ""); - } - - } const _label; - - Platform_pd _pd; - Parent_capability _parent; - Rpc_entrypoint *_thread_ep; - - public: - - Pd_session_component(Rpc_entrypoint *thread_ep, - Allocator * md_alloc, char const *args) - : _label(args), - _pd(md_alloc, _label.string), - _thread_ep(thread_ep) { } - - /** - * Register quota donation at allocator guard - */ - void upgrade_ram_quota(size_t ram_quota) { } - - - /**************************/ - /** PD session interface **/ - /**************************/ - - int bind_thread(Thread_capability); - int assign_parent(Parent_capability); - bool assign_pci(addr_t, uint16_t); - }; -} - -#endif /* _CORE__INCLUDE__PD_SESSION_COMPONENT_H_ */ diff --git a/repos/base-nova/src/core/include/signal_broker.h b/repos/base-nova/src/core/include/signal_broker.h new file mode 100644 index 000000000..8b6d0ecd5 --- /dev/null +++ b/repos/base-nova/src/core/include/signal_broker.h @@ -0,0 +1,135 @@ +/* + * \brief NOVA-specific signal-delivery mechanism + * \author Norman Feske + * \date 2016-01-04 + */ + +/* + * 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 _CORE__INCLUDE__SIGNAL_BROKER_H_ +#define _CORE__INCLUDE__SIGNAL_BROKER_H_ + +/* Genode includes */ +#include + +/* core-local includes */ +#include +#include + +namespace Genode { class Signal_broker; } + + +class Genode::Signal_broker +{ + private: + + Allocator &_md_alloc; + Rpc_entrypoint &_source_ep; + Object_pool _obj_pool; + Rpc_entrypoint &_context_ep; + Signal_source_component _source; + Signal_source_capability _source_cap; + Tslab _contexts_slab { &_md_alloc }; + + public: + + class Invalid_signal_source : public Exception { }; + + Signal_broker(Allocator &md_alloc, + Rpc_entrypoint &source_ep, + Rpc_entrypoint &context_ep) + : + _md_alloc(md_alloc), + _source_ep(source_ep), + _context_ep(context_ep), + _source(&_context_ep), + _source_cap(_source_ep.manage(&_source)) + { } + + ~Signal_broker() + { + /* remove source from entrypoint */ + _source_ep.dissolve(&_source); + + /* free all signal contexts */ + while (Signal_context_component *r = _contexts_slab.first_object()) + free_context(reinterpret_cap_cast(r->cap())); + } + + Signal_source_capability alloc_signal_source() { return _source_cap; } + + void free_signal_source(Signal_source_capability) { } + + /* + * \throw Allocator::Out_of_memory + */ + Signal_context_capability + alloc_context(Signal_source_capability, unsigned long imprint) + { + /* + * XXX For now, we ignore the signal-source argument as we + * create only a single receiver for each PD. + */ + + Native_capability sm = _source.blocking_semaphore(); + + if (!sm.valid()) { + PWRN("signal receiver sm is not valid"); + for (;;); + return Signal_context_capability(); + } + + Native_capability si(cap_map()->insert()); + Signal_context_capability cap = reinterpret_cap_cast(si); + + uint8_t res = Nova::create_si(cap.local_name(), __core_pd_sel, imprint, + sm.local_name()); + if (res != Nova::NOVA_OK) { + PWRN("creating signal failed - error %u", res); + return Signal_context_capability(); + } + + /* the _contexts_slab may throw Allocator::Out_of_memory */ + _obj_pool.insert(new (&_contexts_slab) Signal_context_component(cap)); + + /* return unique capability for the signal context */ + return cap; + } + + void free_context(Signal_context_capability context_cap) + { + Signal_context_component *context; + auto lambda = [&] (Signal_context_component *c) { + context = c; + if (context) _obj_pool.remove(context); + }; + _obj_pool.apply(context_cap, lambda); + + if (!context) { + PWRN("%p - specified signal-context capability has wrong type %lx", + this, context_cap.local_name()); + return; + } + destroy(&_contexts_slab, context); + + Nova::revoke(Nova::Obj_crd(context_cap.local_name(), 0)); + cap_map()->remove(context_cap.local_name(), 0); + } + + void submit(Signal_context_capability cap, unsigned cnt) + { + /* + * On NOVA, signals are submitted directly to the kernel, not + * by using core as a proxy. + */ + ASSERT_NEVER_CALLED; + } +}; + +#endif /* _CORE__INCLUDE__SIGNAL_BROKER_H_ */ diff --git a/repos/base-nova/src/core/include/signal_session_component.h b/repos/base-nova/src/core/include/signal_session_component.h deleted file mode 100644 index dfb201ee0..000000000 --- a/repos/base-nova/src/core/include/signal_session_component.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * \brief Signal service - * \author Norman Feske - * \date 2009-08-05 - */ - -/* - * 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. - */ - -#ifndef _CORE__INCLUDE__SIGNAL_SESSION_COMPONENT_H_ -#define _CORE__INCLUDE__SIGNAL_SESSION_COMPONENT_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace Genode { - - class Signal_source_component; - class Signal_context_component; - - typedef Fifo Signal_queue; - - class Signal_context_component : public Object_pool::Entry - { - public: - - /** - * Constructor - */ - Signal_context_component(Signal_context_capability cap) - : Object_pool::Entry(cap) { } - }; - - - class Signal_source_component : public Signal_source_rpc_object - { - public: - - /** - * Constructor - */ - Signal_source_component(Rpc_entrypoint *) { } - - /***************************** - ** Signal-source interface ** - *****************************/ - - Signal wait_for_signal() { return Signal(0, 0); } - }; - - - class Signal_session_component : public Rpc_object - { - private: - - Rpc_entrypoint *_source_ep; - Object_pool _signal_queue; - Signal_source_component _source; - Signal_source_capability _source_cap; - Allocator_guard _md_alloc; - Tslab _contexts_slab; - Ipc_ostream *_ipc_ostream; - - public: - - /** - * Constructor - * - * \param source_ep entrypoint holding signal-source component - * objects - * \param context_ep global pool of all signal contexts - * \param md_alloc backing-store allocator for - * signal-context component objects - * - * To maintain proper synchronization, 'signal_source_ep' must be - * the same entrypoint as used for the signal-session component. - * The 'signal_context_ep' is only used for associative array - * to map signal-context capabilities to 'Signal_context_component' - * objects and as capability allocator for such objects. - */ - Signal_session_component(Rpc_entrypoint *source_ep, - Rpc_entrypoint *context_ep, - Allocator *context_md_alloc, - size_t ram_quota); - - ~Signal_session_component(); - - /** - * Register quota donation at allocator guard - */ - void upgrade_ram_quota(size_t ram_quota) { _md_alloc.upgrade(ram_quota); } - - - /****************************** - ** Signal-session interface ** - ******************************/ - - Signal_source_capability signal_source(); - Signal_context_capability alloc_context(long imprint); - void free_context(Signal_context_capability context_cap); - void submit(Signal_context_capability context_cap, unsigned cnt); - - - /************************** - ** Rpc_object interface ** - **************************/ - - Rpc_exception_code dispatch(int opcode, Ipc_istream &is, Ipc_ostream &os) - { - /* - * Make IPC output stream available to the submit function. The - * stream is used to carry signal payload for the out-of-order - * handling of 'wait_for_signal' replies. - */ - _ipc_ostream = &os; - - /* dispatch RPC */ - return Rpc_object::dispatch(opcode, is, os); - } - }; -} - -#endif /* _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_ */ diff --git a/repos/base-nova/src/core/include/signal_source_component.h b/repos/base-nova/src/core/include/signal_source_component.h new file mode 100644 index 000000000..d284ca658 --- /dev/null +++ b/repos/base-nova/src/core/include/signal_source_component.h @@ -0,0 +1,63 @@ +/* + * \brief Signal-delivery mechanism + * \author Norman Feske + * \date 2009-08-05 + */ + +/* + * 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. + */ + +#ifndef _CORE__INCLUDE__SIGNAL_SOURCE_COMPONENT_H_ +#define _CORE__INCLUDE__SIGNAL_SOURCE_COMPONENT_H_ + +#include +#include +#include + +namespace Genode { + + class Signal_context_component; + class Signal_source_component; +} + + +struct Genode::Signal_context_component : Object_pool::Entry +{ + Signal_context_component(Signal_context_capability cap) + : Object_pool::Entry(cap) { } + + Signal_source_component *source() { ASSERT_NEVER_CALLED; } +}; + + +class Genode::Signal_source_component : public Rpc_object +{ + private: + + Native_capability _blocking_semaphore; + + public: + + Signal_source_component(Rpc_entrypoint *) { } + + void register_semaphore(Native_capability const &cap) + { + if (_blocking_semaphore.valid()) + PWRN("overwritting blocking signal semaphore !!!"); + + _blocking_semaphore = cap; + } + + Native_capability blocking_semaphore() const { return _blocking_semaphore; } + + Signal wait_for_signal() { /* unused on NOVA */ return Signal(0, 0); } + + void submit(Signal_context_component *, unsigned long) { /* unused on NOVA */ } +}; + +#endif /* _CORE__INCLUDE__SIGNAL_SOURCE_COMPONENT_H_ */ diff --git a/repos/base-nova/src/core/pd_session_extension.cc b/repos/base-nova/src/core/pd_assign_pci.cc similarity index 100% rename from repos/base-nova/src/core/pd_session_extension.cc rename to repos/base-nova/src/core/pd_assign_pci.cc diff --git a/repos/base-nova/src/core/signal_session_component.cc b/repos/base-nova/src/core/signal_session_component.cc deleted file mode 100644 index 9883e854c..000000000 --- a/repos/base-nova/src/core/signal_session_component.cc +++ /dev/null @@ -1,113 +0,0 @@ -/* - * \brief Implementation of the SIGNAL interface - * \author Alexander Boettcher - * \date 2015-03-04 - */ - -/* - * Copyright (C) 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. - */ - -/* Genode includes */ -#include - -/* core includes */ -#include - -using namespace Genode; - - -/****************************** - ** Signal-session component ** - ******************************/ - -Signal_session_component::Signal_session_component(Rpc_entrypoint *source_ep, - Rpc_entrypoint *context_ep, - Allocator *context_md_alloc, - size_t ram_quota) -: - _source_ep(source_ep), - _source(source_ep), - _source_cap(_source_ep->manage(&_source)), - _md_alloc(context_md_alloc, ram_quota), - _contexts_slab(&_md_alloc) -{ } - - -Signal_session_component::~Signal_session_component() -{ - /* remove _signal_source from entrypoint */ - _source_ep->dissolve(&_source); - - /* free all signal contexts */ - while (Signal_context_component *r = _contexts_slab.first_object()) - free_context(reinterpret_cap_cast(Native_capability(r->cap()))); -} - - -Signal_source_capability Signal_session_component::signal_source() -{ - return _source_cap; -} - -extern "C" Genode::addr_t __core_pd_sel; - -Signal_context_capability Signal_session_component::alloc_context(long imprint) -{ - Native_capability sm = _source._blocking_semaphore; - - if (!sm.valid()) { - PWRN("signal receiver sm is not valid"); - return Signal_context_capability(); - } - - Native_capability si(cap_map()->insert()); - Signal_context_capability cap = reinterpret_cap_cast(si); - - uint8_t res = Nova::create_si(cap.local_name(), __core_pd_sel, imprint, - sm.local_name()); - if (res != Nova::NOVA_OK) { - PWRN("creating signal failed - error %u", res); - return Signal_context_capability(); - } - - try { - _signal_queue.insert(new (&_contexts_slab) Signal_context_component(cap)); - } catch (Allocator::Out_of_memory) { - throw Out_of_metadata(); - } - - /* return unique capability for the signal context */ - return cap; -} - - -void Signal_session_component::free_context(Signal_context_capability context_cap) -{ - Signal_context_component *context; - auto lambda = [&] (Signal_context_component *c) { - context = c; - if (context) _signal_queue.remove(context); - }; - _signal_queue.apply(context_cap, lambda); - - if (!context) { - PWRN("%p - specified signal-context capability has wrong type %lx", - this, context_cap.local_name()); - return; - } - destroy(&_contexts_slab, context); - - Nova::revoke(Nova::Obj_crd(context_cap.local_name(), 0)); - cap_map()->remove(context_cap.local_name(), 0); -} - - -void Signal_session_component::submit(Signal_context_capability context_cap, - unsigned cnt) -{ - PDBG("should not be called"); -} diff --git a/repos/base-nova/src/core/target.inc b/repos/base-nova/src/core/target.inc index ea82231e6..4cd6a29c5 100644 --- a/repos/base-nova/src/core/target.inc +++ b/repos/base-nova/src/core/target.inc @@ -21,7 +21,8 @@ SRC_CC = context_area.cc \ main.cc \ pager.cc \ pd_session_component.cc \ - pd_session_extension.cc \ + pd_upgrade_ram_quota.cc \ + pd_assign_pci.cc \ platform.cc \ platform_pd.cc \ platform_services.cc \ @@ -31,7 +32,6 @@ SRC_CC = context_area.cc \ rm_session_component.cc \ rm_session_support.cc \ rom_session_component.cc \ - signal_session_component.cc \ thread_start.cc \ bios_data_area.cc \ trace_session_component.cc @@ -49,6 +49,7 @@ vpath ram_session_component.cc $(GEN_CORE_DIR) vpath rom_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_component.cc $(GEN_CORE_DIR) vpath pd_session_component.cc $(GEN_CORE_DIR) +vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) vpath rm_session_component.cc $(GEN_CORE_DIR) vpath trace_session_component.cc $(GEN_CORE_DIR) vpath io_port_session_component.cc $(GEN_CORE_DIR)/spec/x86 diff --git a/repos/base-okl4/src/core/include/pd_session_component.h b/repos/base-okl4/src/core/include/pd_session_component.h index 574bb9d13..2bb4d3b95 100644 --- a/repos/base-okl4/src/core/include/pd_session_component.h +++ b/repos/base-okl4/src/core/include/pd_session_component.h @@ -21,45 +21,71 @@ /* core includes */ #include +#include -namespace Genode { - - class Pd_session_component : public Rpc_object - { - private: - - Platform_pd _pd; - Rpc_entrypoint *_thread_ep; - - public: - - Pd_session_component(Rpc_entrypoint *thread_ep, - Allocator *md_alloc, const char *args) - : _thread_ep(thread_ep) { } - - /** - * Register quota donation at allocator guard - */ - void upgrade_ram_quota(size_t ram_quota) { } +namespace Genode { class Pd_session_component; } - /************************** - ** Pd session interface ** - **************************/ +class Genode::Pd_session_component : public Rpc_object +{ + private: - int bind_thread(Thread_capability); - int assign_parent(Parent_capability); + Platform_pd _pd; + Rpc_entrypoint &_thread_ep; + Signal_broker _signal_broker; + + public: + + Pd_session_component(Rpc_entrypoint &thread_ep, + Rpc_entrypoint &receiver_ep, + Rpc_entrypoint &context_ep, + Allocator &md_alloc, const char *args) + : + _thread_ep(thread_ep), + _signal_broker(md_alloc, receiver_ep, context_ep) + { } + + /** + * Register quota donation at allocator guard + */ + void upgrade_ram_quota(size_t ram_quota) { } - /***************************** - ** OKL4-specific additions ** - *****************************/ + /************************** + ** Pd session interface ** + **************************/ - void space_pager(Thread_capability thread); + int bind_thread(Thread_capability); + int assign_parent(Capability); + bool assign_pci(addr_t, uint16_t) { return false; } - Okl4::L4_SpaceId_t space_id() { - return Okl4::L4_SpaceId(_pd.pd_id()); } - }; -} + Signal_source_capability alloc_signal_source() override { + return _signal_broker.alloc_signal_source(); } + + void free_signal_source(Signal_source_capability cap) override { + _signal_broker.free_signal_source(cap); } + + Signal_context_capability + alloc_context(Signal_source_capability sig_rec_cap, unsigned long imprint) override + { + return _signal_broker.alloc_context(sig_rec_cap, imprint); + } + + void free_context(Signal_context_capability cap) override { + _signal_broker.free_context(cap); } + + void submit(Signal_context_capability cap, unsigned n) override { + _signal_broker.submit(cap, n); } + + + /***************************** + ** OKL4-specific additions ** + *****************************/ + + void space_pager(Thread_capability thread); + + Okl4::L4_SpaceId_t space_id() { + return Okl4::L4_SpaceId(_pd.pd_id()); } +}; #endif /* _CORE__INCLUDE__OKL4__PD_SESSION_COMPONENT_H_ */ diff --git a/repos/base-okl4/src/core/okl4_pd_session_component.cc b/repos/base-okl4/src/core/okl4_pd_session_component.cc index 73b53c471..7a8e8a7c8 100644 --- a/repos/base-okl4/src/core/okl4_pd_session_component.cc +++ b/repos/base-okl4/src/core/okl4_pd_session_component.cc @@ -21,7 +21,7 @@ using namespace Genode; void Pd_session_component::space_pager(Thread_capability thread) { - _thread_ep->apply(thread, [this] (Cpu_thread_component *cpu_thread) + _thread_ep.apply(thread, [this] (Cpu_thread_component *cpu_thread) { if (!cpu_thread) return; _pd.space_pager(cpu_thread->platform_thread()); diff --git a/repos/base-okl4/src/core/target.inc b/repos/base-okl4/src/core/target.inc index 1397fc271..72d49c16d 100644 --- a/repos/base-okl4/src/core/target.inc +++ b/repos/base-okl4/src/core/target.inc @@ -31,7 +31,6 @@ SRC_CC += cap_session_component.cc \ rm_session_component.cc \ rm_session_support.cc \ rom_session_component.cc \ - signal_session_component.cc \ signal_source_component.cc \ thread_start.cc \ trace_session_component.cc @@ -53,7 +52,6 @@ vpath pd_session_component.cc $(GEN_CORE_DIR) vpath rm_session_component.cc $(GEN_CORE_DIR) vpath io_mem_session_component.cc $(GEN_CORE_DIR) vpath io_mem_session_support.cc $(GEN_CORE_DIR) -vpath signal_session_component.cc $(GEN_CORE_DIR) vpath signal_source_component.cc $(GEN_CORE_DIR) vpath trace_session_component.cc $(GEN_CORE_DIR) vpath dataspace_component.cc $(GEN_CORE_DIR) diff --git a/repos/base-pistachio/src/core/target.inc b/repos/base-pistachio/src/core/target.inc index ed9ebf03f..febf05104 100644 --- a/repos/base-pistachio/src/core/target.inc +++ b/repos/base-pistachio/src/core/target.inc @@ -18,6 +18,8 @@ SRC_CC = cap_session_component.cc \ main.cc \ multiboot_info.cc \ pd_session_component.cc \ + pd_assign_pci.cc \ + pd_upgrade_ram_quota.cc \ pager.cc \ pager_ep.cc \ pager_object.cc \ @@ -30,7 +32,6 @@ SRC_CC = cap_session_component.cc \ rm_session_component.cc \ rm_session_support.cc \ rom_session_component.cc \ - signal_session_component.cc \ signal_source_component.cc \ thread_start.cc \ trace_session_component.cc @@ -48,10 +49,11 @@ vpath rom_session_component.cc $(GEN_CORE_DIR) vpath cap_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_component.cc $(GEN_CORE_DIR) vpath pd_session_component.cc $(GEN_CORE_DIR) +vpath pd_assign_pci.cc $(GEN_CORE_DIR) +vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) vpath rm_session_component.cc $(GEN_CORE_DIR) vpath io_mem_session_component.cc $(GEN_CORE_DIR) vpath io_mem_session_support.cc $(GEN_CORE_DIR) -vpath signal_session_component.cc $(GEN_CORE_DIR) vpath signal_source_component.cc $(GEN_CORE_DIR) vpath trace_session_component.cc $(GEN_CORE_DIR) vpath dataspace_component.cc $(GEN_CORE_DIR) diff --git a/repos/base-sel4/lib/mk/core.mk b/repos/base-sel4/lib/mk/core.mk index 9d22dcb02..9726f6a38 100644 --- a/repos/base-sel4/lib/mk/core.mk +++ b/repos/base-sel4/lib/mk/core.mk @@ -11,6 +11,8 @@ SRC_CC += \ cpu_session_component.cc \ cpu_session_support.cc \ pd_session_component.cc \ + pd_assign_pci.cc \ + pd_upgrade_ram_quota.cc \ io_mem_session_component.cc \ io_mem_session_support.cc \ thread_start.cc \ @@ -22,7 +24,6 @@ SRC_CC += \ rm_session_component.cc \ rm_session_support.cc \ irq_session_component.cc \ - signal_session_component.cc \ signal_source_component.cc \ trace_session_component.cc \ core_rm_session.cc \ @@ -47,11 +48,12 @@ vpath ram_session_component.cc $(GEN_CORE_DIR) vpath rom_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_component.cc $(GEN_CORE_DIR) vpath pd_session_component.cc $(GEN_CORE_DIR) +vpath pd_assign_pci.cc $(GEN_CORE_DIR) +vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) vpath rm_session_component.cc $(GEN_CORE_DIR) vpath io_mem_session_component.cc $(GEN_CORE_DIR) vpath io_mem_session_support.cc $(GEN_CORE_DIR) vpath platform_services.cc $(GEN_CORE_DIR) -vpath signal_session_component.cc $(GEN_CORE_DIR) vpath signal_source_component.cc $(GEN_CORE_DIR) vpath trace_session_component.cc $(GEN_CORE_DIR) vpath dataspace_component.cc $(GEN_CORE_DIR) diff --git a/repos/base/include/base/env.h b/repos/base/include/base/env.h index 29c9f201b..2af7ef55c 100644 --- a/repos/base/include/base/env.h +++ b/repos/base/include/base/env.h @@ -21,7 +21,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -80,6 +81,7 @@ struct Genode::Env * PD session of the component as created by the parent */ virtual Pd_session *pd_session() = 0; + virtual Pd_session_capability pd_session_cap() = 0; /** * Heap backed by the RAM session of the environment @@ -116,6 +118,4 @@ struct Genode::Env }; - - #endif /* _INCLUDE__BASE__ENV_H_ */ diff --git a/repos/base/include/base/rpc_server.h b/repos/base/include/base/rpc_server.h index 02dfd1eea..8db4b8969 100644 --- a/repos/base/include/base/rpc_server.h +++ b/repos/base/include/base/rpc_server.h @@ -385,16 +385,15 @@ class Genode::Rpc_entrypoint : Thread_base, public Object_pool * * \noapi * - * Note: This is a temporary API method, which is going to be - * removed. Please do not use this method. - * - * In combination with the 'reply_dst' accessor method, this - * method can be used to implement services that dispatch client - * requests out of order. In such cases, the server activation may - * send reply messages to multiple blocking clients before - * answering the original call. + * In combination with the 'reply_dst' accessor method, this method + * allows for the dispatching of client requests out of order. The only + * designated user of this method is core's PD service. The + * 'Pd_session::submit' RPC function uses it to send a reply to a + * caller of the 'Signal_source::wait_for_signal' RPC function before + * returning from the 'submit' call. */ - void explicit_reply(Untyped_capability reply_cap, int return_value); + void reply_signal_info(Untyped_capability reply_cap, + unsigned long imprint, unsigned long cnt); /** * Return true if the caller corresponds to the entrypoint called diff --git a/repos/base/include/base/signal.h b/repos/base/include/base/signal.h index 9f44d9211..a8f2d769a 100644 --- a/repos/base/include/base/signal.h +++ b/repos/base/include/base/signal.h @@ -20,7 +20,7 @@ #include #include #include -#include +#include /* only needed for base-hw */ namespace Kernel { struct Signal_receiver; } @@ -28,15 +28,18 @@ namespace Kernel { struct Signal_receiver; } namespace Genode { class Signal_source; + class Signal_receiver; class Signal_context; class Signal_context_registry; class Signal_transmitter; class Signal; class Signal_dispatcher_base; - class Signal_connection; - template class Signal_dispatcher; - Signal_connection * signal_connection(); + + template class Signal_dispatcher; + template class Signal_handler; + + typedef Capability Signal_context_capability; } @@ -129,8 +132,6 @@ class Genode::Signal_transmitter Signal_context_capability _context; /* destination */ - Signal_connection * connection(); - public: /** @@ -179,7 +180,7 @@ class Genode::Signal_receiver : Noncopyable * Provides the kernel-object name via the 'dst' method. This is * needed for 'base-hw' only. */ - Signal_receiver_capability _cap; + Capability _cap; /** * List of associated contexts @@ -286,7 +287,7 @@ class Genode::Signal_receiver : Noncopyable * source associated with the process. It must not be used for other * purposes. */ - static void dispatch_signals(Signal_source *signal_source); + static void dispatch_signals(Signal_source *); }; diff --git a/repos/base/include/pd_session/client.h b/repos/base/include/pd_session/client.h index b81438d74..7fbc4deae 100644 --- a/repos/base/include/pd_session/client.h +++ b/repos/base/include/pd_session/client.h @@ -28,18 +28,27 @@ struct Genode::Pd_session_client : Rpc_client int bind_thread(Thread_capability thread) override { return call(thread); } - int assign_parent(Parent_capability parent) override { + int assign_parent(Capability parent) override { return call(parent); } - /** - * Dummy stub for PCI-device assignment operation - * - * The assign_pci function exists only in the NOVA-specific version of the - * PD-session interface. This empty dummy stub merely exists to maintain - * API compatibility accross all base platforms so that drivers don't need - * to distinguish NOVA from non-NOVA. - */ - bool assign_pci(addr_t) { return false; } + bool assign_pci(addr_t pci_config_memory_address, uint16_t bdf) override { + return call(pci_config_memory_address, bdf); } + + Signal_source_capability alloc_signal_source() override { + return call(); } + + void free_signal_source(Signal_source_capability cap) override { + call(cap); } + + Signal_context_capability alloc_context(Signal_source_capability source, + unsigned long imprint) override { + return call(source, imprint); } + + void free_context(Signal_context_capability cap) override { + call(cap); } + + void submit(Signal_context_capability receiver, unsigned cnt = 1) override { + call(receiver, cnt); } }; #endif /* _INCLUDE__PD_SESSION__CLIENT_H_ */ diff --git a/repos/base/include/pd_session/connection.h b/repos/base/include/pd_session/connection.h index d1b4fa0bd..c3b023622 100644 --- a/repos/base/include/pd_session/connection.h +++ b/repos/base/include/pd_session/connection.h @@ -22,7 +22,7 @@ namespace Genode { struct Pd_connection; } struct Genode::Pd_connection : Connection, Pd_session_client { - enum { RAM_QUOTA = 4*1024 }; + enum { RAM_QUOTA = 4*1024*sizeof(long) }; /** * Constructor diff --git a/repos/base/include/pd_session/pd_session.h b/repos/base/include/pd_session/pd_session.h index 64ef234ba..a342bbcf4 100644 --- a/repos/base/include/pd_session/pd_session.h +++ b/repos/base/include/pd_session/pd_session.h @@ -1,6 +1,7 @@ /* * \brief Protection domain (PD) session interface * \author Christian Helmuth + * \author Norman Feske * \date 2006-06-27 * * A pd session represents the protection domain of a program. @@ -16,11 +17,17 @@ #ifndef _INCLUDE__PD_SESSION__PD_SESSION_H_ #define _INCLUDE__PD_SESSION__PD_SESSION_H_ +#include #include -#include #include +#include -namespace Genode { struct Pd_session; } +namespace Genode { + + struct Pd_session; + struct Parent; + struct Signal_context; +} struct Genode::Pd_session : Session @@ -47,17 +54,117 @@ struct Genode::Pd_session : Session * \param parent capability of parent interface * \return 0 on success, or negative error code */ - virtual int assign_parent(Parent_capability parent) = 0; + virtual int assign_parent(Capability parent) = 0; + + /** + * Assign PCI device to PD + * + * The specified address has to refer to the locally mapped PCI + * configuration space of the device. + * + * This function is solely used on the NOVA kernel. + */ + virtual bool assign_pci(addr_t pci_config_memory_address, uint16_t bdf) = 0; + + + /******************************** + ** Support for the signal API ** + ********************************/ + + typedef Capability Signal_source_capability; + + class Out_of_metadata : public Exception { }; + class Invalid_signal_source : public Exception { }; + + /** + * Create a new signal source + * + * \return a cap that acts as reference to the created source + * + * The signal source provides an interface to wait for incoming signals. + * + * \throw Out_of_metadata + */ + virtual Signal_source_capability alloc_signal_source() = 0; + + /** + * Free a signal source + * + * \param cap capability of the signal source to destroy + */ + virtual void free_signal_source(Signal_source_capability cap) = 0; + + /** + * Allocate signal context + * + * \param source signal source that shall provide the new context + * + * + * \param imprint opaque value that gets delivered with signals + * originating from the allocated signal-context capability + * \return new signal-context capability + * + * \throw Out_of_metadata + * \throw Invalid_signal_source + */ + virtual Capability + alloc_context(Signal_source_capability source, unsigned long imprint) = 0; + + /** + * Free signal-context + * + * \param cap capability of signal-context to release + */ + virtual void free_context(Capability cap) = 0; + + /** + * Submit signals to the specified signal context + * + * \param context signal destination + * \param cnt number of signals to submit at once + * + * The 'context' argument does not necessarily belong to this PD session. + * Normally, it is a capability obtained from a potentially untrusted + * component. Because we cannot trust this capability, signals are not + * submitted by invoking 'cap' directly but by using it as argument to our + * trusted PD-session interface. Otherwise, a potential signal receiver + * could supply a capability with a blocking interface to compromise the + * nonblocking behaviour of the signal submission. + */ + virtual void submit(Capability context, unsigned cnt = 1) = 0; + + + /*********************************** + ** Support for the RPC framework ** + ***********************************/ /********************* ** RPC declaration ** *********************/ - GENODE_RPC(Rpc_bind_thread, int, bind_thread, Thread_capability); - GENODE_RPC(Rpc_assign_parent, int, assign_parent, Parent_capability); + GENODE_RPC(Rpc_bind_thread, int, bind_thread, Thread_capability); + GENODE_RPC(Rpc_assign_parent, int, assign_parent, Capability); + GENODE_RPC(Rpc_assign_pci, bool, assign_pci, addr_t, uint16_t); - GENODE_RPC_INTERFACE(Rpc_bind_thread, Rpc_assign_parent); + GENODE_RPC_THROW(Rpc_alloc_signal_source, Signal_source_capability, + alloc_signal_source, GENODE_TYPE_LIST(Out_of_metadata)); + + GENODE_RPC(Rpc_free_signal_source, void, free_signal_source, Signal_source_capability); + + GENODE_RPC_THROW(Rpc_alloc_context, Capability, alloc_context, + GENODE_TYPE_LIST(Out_of_metadata, Invalid_signal_source), + Signal_source_capability, unsigned long); + + GENODE_RPC(Rpc_free_context, void, free_context, + Capability); + + GENODE_RPC(Rpc_submit, void, submit, Capability, unsigned); + + + GENODE_RPC_INTERFACE(Rpc_bind_thread, Rpc_assign_parent, Rpc_assign_pci, + Rpc_alloc_signal_source, Rpc_free_signal_source, + Rpc_alloc_context, Rpc_free_context, Rpc_submit); }; #endif /* _INCLUDE__PD_SESSION__PD_SESSION_H_ */ diff --git a/repos/base/include/signal_session/capability.h b/repos/base/include/signal_session/capability.h deleted file mode 100644 index fc4e1d247..000000000 --- a/repos/base/include/signal_session/capability.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * \brief Signal-session capability type - * \author Norman Feske - * \date 2009-08-05 - */ - -/* - * 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. - */ - -#ifndef _INCLUDE__SIGNAL_SESSION__CAPABILITY_H_ -#define _INCLUDE__SIGNAL_SESSION__CAPABILITY_H_ - -#include -#include - -namespace Genode { - - typedef Capability Signal_session_capability; -} - -#endif /* _INCLUDE__SIGNAL_SESSION__CAPABILITY_H_ */ diff --git a/repos/base/include/signal_session/client.h b/repos/base/include/signal_session/client.h deleted file mode 100644 index 008fbc09f..000000000 --- a/repos/base/include/signal_session/client.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * \brief Client-side signal session interface - * \author Norman Feske - * \date 2009-08-05 - */ - -/* - * 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. - */ - -#ifndef _INCLUDE__SIGNAL_SESSION__CLIENT_H_ -#define _INCLUDE__SIGNAL_SESSION__CLIENT_H_ - -#include -#include -#include -#include - -namespace Genode { struct Signal_session_client; } - - -struct Genode::Signal_session_client : Rpc_client -{ - explicit Signal_session_client(Signal_session_capability session) - : Rpc_client(session) { } - - Signal_source_capability signal_source() override { - return call(); } - - Signal_context_capability alloc_context(long imprint) override { - return call(imprint); } - - void free_context(Signal_context_capability cap) override { - call(cap); } - - void submit(Signal_context_capability receiver, unsigned cnt = 1) override { - call(receiver, cnt); } -}; - -#endif /* _INCLUDE__CAP_SESSION__CLIENT_H_ */ diff --git a/repos/base/include/signal_session/connection.h b/repos/base/include/signal_session/connection.h deleted file mode 100644 index 984759a6a..000000000 --- a/repos/base/include/signal_session/connection.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * \brief Connection to signal service - * \author Norman Feske - * \date 2009-08-05 - */ - -/* - * 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. - */ - -#ifndef _INCLUDE__SIGNAL_SESSION__CONNECTION_H_ -#define _INCLUDE__SIGNAL_SESSION__CONNECTION_H_ - -#include -#include - -namespace Genode { struct Signal_connection; } - - -struct Genode::Signal_connection : Connection, Signal_session_client -{ - Signal_connection() - : - Connection(session("ram_quota=16K")), - Signal_session_client(cap()) - { } -}; - -#endif /* _INCLUDE__CAP_SESSION__CONNECTION_H_ */ diff --git a/repos/base/include/signal_session/signal_session.h b/repos/base/include/signal_session/signal_session.h deleted file mode 100644 index ba9eb7026..000000000 --- a/repos/base/include/signal_session/signal_session.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * \brief Signal session interface - * \author Norman Feske - * \date 2009-08-05 - */ - -/* - * 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. - */ - -#ifndef _INCLUDE__SIGNAL_SESSION__SIGNAL_SESSION_H_ -#define _INCLUDE__SIGNAL_SESSION__SIGNAL_SESSION_H_ - -#include -#include -#include -#include - -namespace Genode { - - class Signal_context; - class Signal_receiver; - - typedef Capability Signal_receiver_capability; - typedef Capability Signal_context_capability; - typedef Capability Signal_source_capability; - - struct Signal_session; -} - - -struct Genode::Signal_session : Session -{ - static const char *service_name() { return "SIGNAL"; } - - virtual ~Signal_session() { } - - class Out_of_metadata : public Exception { }; - - /** - * Request capability for the signal-source interface - */ - virtual Signal_source_capability signal_source() = 0; - - /** - * Allocate signal context - * - * \param imprint opaque value that gets delivered with signals - * originating from the allocated signal-context - * capability - * \return new signal-context capability - * \throw Out_of_metadata - */ - virtual Signal_context_capability alloc_context(long imprint) = 0; - - /** - * Free signal-context - * - * \param cap capability of signal-context to release - */ - virtual void free_context(Signal_context_capability cap) = 0; - - /** - * Submit signals to the specified signal context - * - * \param context signal destination - * \param cnt number of signals to submit at once - * - * Note that the 'context' argument does not necessarily belong to - * the signal session. Normally, it is a capability obtained from - * a potentially untrusted source. Because we cannot trust this - * capability, signals are not submitted by invoking 'cap' directly - * but by using it as argument to our trusted signal-session - * interface. Otherwise, a potential signal receiver could supply - * a capability with a blocking interface to compromise the - * nonblocking behaviour of the signal submission. - */ - virtual void submit(Signal_context_capability context, - unsigned cnt = 1) = 0; - - - /********************* - ** RPC declaration ** - *********************/ - - GENODE_RPC(Rpc_signal_source, Signal_source_capability, signal_source); - GENODE_RPC_THROW(Rpc_alloc_context, Signal_context_capability, alloc_context, - GENODE_TYPE_LIST(Out_of_metadata), long); - GENODE_RPC(Rpc_free_context, void, free_context, Signal_context_capability); - GENODE_RPC(Rpc_submit, void, submit, Signal_context_capability, unsigned); - - GENODE_RPC_INTERFACE(Rpc_submit, Rpc_signal_source, Rpc_alloc_context, - Rpc_free_context); -}; - -#endif /* _INCLUDE__CAP_SESSION__CAP_SESSION_H_ */ diff --git a/repos/base/include/signal_session/source_client.h b/repos/base/include/signal_session/source_client.h deleted file mode 100644 index afdcc1fa4..000000000 --- a/repos/base/include/signal_session/source_client.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * \brief Signal-source client interface - * \author Norman Feske - * \date 2010-02-03 - * - * See documentation in 'signal_session/source.h'. - */ - -/* - * 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. - */ - -#ifndef _INCLUDE__SIGNAL_SESSION__SOURCE_CLIENT_H_ -#define _INCLUDE__SIGNAL_SESSION__SOURCE_CLIENT_H_ - -#include -#include - -namespace Genode { struct Signal_source_client; } - - -struct Genode::Signal_source_client : Rpc_client -{ - Signal_source_client(Signal_source_capability signal_source) - : Rpc_client(signal_source) { } - - Signal wait_for_signal() override { return call(); } -}; - -#endif /* _INCLUDE__SIGNAL_SESSION__SOURCE_CLIENT_H_ */ diff --git a/repos/base/include/signal_source/capability.h b/repos/base/include/signal_source/capability.h new file mode 100644 index 000000000..7fcd48915 --- /dev/null +++ b/repos/base/include/signal_source/capability.h @@ -0,0 +1,22 @@ +/* + * \brief Signal-source capability type + * \author Norman Feske + * \date 2016-01-04 + */ + +/* + * 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__CAPABILITY_H_ +#define _INCLUDE__SIGNAL_SOURCE__CAPABILITY_H_ + +#include +#include + +namespace Genode { typedef Capability Signal_source_capability; } + +#endif /* _INCLUDE__SIGNAL_SOURCE__CAPABILITY_H_ */ diff --git a/repos/base/include/signal_source/client.h b/repos/base/include/signal_source/client.h new file mode 100644 index 000000000..aa2448898 --- /dev/null +++ b/repos/base/include/signal_source/client.h @@ -0,0 +1,30 @@ +/* + * \brief Client-side signal-source interface + * \author Norman Feske + * \date 2016-01-04 + */ + +/* + * 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 + +namespace Genode { class Signal_source_client; } + +struct Genode::Signal_source_client : Rpc_client +{ + Signal_source_client(Capability signal_source) + : Rpc_client(signal_source) { } + + Signal wait_for_signal() override { return call(); } +}; + +#endif /* _INCLUDE__SIGNAL_SOURCE__CLIENT_H_ */ diff --git a/repos/base/include/signal_session/source_rpc_object.h b/repos/base/include/signal_source/rpc_object.h similarity index 75% rename from repos/base/include/signal_session/source_rpc_object.h rename to repos/base/include/signal_source/rpc_object.h index b60ff590d..cacd128c1 100644 --- a/repos/base/include/signal_session/source_rpc_object.h +++ b/repos/base/include/signal_source/rpc_object.h @@ -15,14 +15,14 @@ * under the terms of the GNU General Public License version 2. */ -#ifndef _INCLUDE__SIGNAL_SESSION__SOURCE_RPC_OBJECT_H_ -#define _INCLUDE__SIGNAL_SESSION__SOURCE_RPC_OBJECT_H_ +#ifndef _INCLUDE__SIGNAL_SOURCE__RPC_OBJECT_H_ +#define _INCLUDE__SIGNAL_SOURCE__RPC_OBJECT_H_ -#include #include +#include namespace Genode { struct Signal_source_rpc_object; } struct Genode::Signal_source_rpc_object : Rpc_object { }; -#endif /* _INCLUDE__SIGNAL_SESSION__SOURCE_RPC_OBJECT_H_ */ +#endif /* _INCLUDE__SIGNAL_SOURCE__RPC_OBJECT_H_ */ diff --git a/repos/base/include/signal_session/source.h b/repos/base/include/signal_source/signal_source.h similarity index 55% rename from repos/base/include/signal_session/source.h rename to repos/base/include/signal_source/signal_source.h index 5e4574cf9..5dbc4e99b 100644 --- a/repos/base/include/signal_session/source.h +++ b/repos/base/include/signal_source/signal_source.h @@ -3,10 +3,9 @@ * \author Norman Feske * \date 2010-02-03 * - * This file is only included by 'signal_session/signal_session.h' and relies - * on the headers included there. No include guards are needed. It is a - * separate header file to make it easily replaceable by a platform-specific - * implementation. + * This file is only included by 'pd_session/pd_session.h' and relies + * on the headers included there. It is a separate header file to make it + * easily replaceable by a platform-specific implementation. */ /* @@ -16,22 +15,19 @@ * under the terms of the GNU General Public License version 2. */ -#ifndef _INCLUDE__SIGNAL_SESSION__SOURCE_H_ -#define _INCLUDE__SIGNAL_SESSION__SOURCE_H_ - -#include - -namespace Genode { struct Signal_source; } +#ifndef _INCLUDE__SIGNAL_SOURCE__SIGNAL_SOURCE_H_ +#define _INCLUDE__SIGNAL_SOURCE__SIGNAL_SOURCE_H_ +namespace Genode { class Signal_source; } /** - * Blocking part of the signal-session interface + * Blocking part of the PD-session interface * * The blocking 'wait_for_signal()' operation cannot be part of the - * signal-session interface because otherwise, context allocations or + * PD-session interface because otherwise, context allocations or * signal submissions would not be possible while blocking for signals. - * Therefore, the blocking part is implemented a separate interface, - * which can be used by an independent thread. + * Therefore, the blocking part is implemented as a kernel-specific + * special case. */ struct Genode::Signal_source { @@ -44,10 +40,7 @@ struct Genode::Signal_source public: - Signal(long imprint, int num) : - _imprint(imprint), - _num(num) - { } + Signal(long imprint, int num) : _imprint(imprint), _num(num) { } Signal() : _imprint(0), _num(0) { } @@ -72,4 +65,4 @@ struct Genode::Signal_source GENODE_RPC_INTERFACE(Rpc_wait_for_signal); }; -#endif /* _INCLUDE__SIGNAL_SESSION__SOURCE_H_ */ +#endif /* _INCLUDE__SIGNAL_SOURCE__SIGNAL_SOURCE_H_ */ diff --git a/repos/base/src/base/env/platform_env.h b/repos/base/src/base/env/platform_env.h index 867e06b4b..f3ed2846b 100644 --- a/repos/base/src/base/env/platform_env.h +++ b/repos/base/src/base/env/platform_env.h @@ -144,6 +144,7 @@ class Genode::Platform_env : public Genode::Env, public Emergency_ram_reserve Cpu_session_capability cpu_session_cap() { return _resources.cpu; } Rm_session *rm_session() { return &_resources.rm; } Pd_session *pd_session() { return &_resources.pd; } + Pd_session_capability pd_session_cap() { return _resources.pd; } Allocator *heap() { return &_heap; } }; diff --git a/repos/base/src/base/server/common.cc b/repos/base/src/base/server/common.cc index 4a7428ac3..9042ccd05 100644 --- a/repos/base/src/base/server/common.cc +++ b/repos/base/src/base/server/common.cc @@ -49,7 +49,8 @@ void Rpc_entrypoint::omit_reply() } -void Rpc_entrypoint::explicit_reply(Untyped_capability reply_cap, int return_value) +void Rpc_entrypoint::reply_signal_info(Untyped_capability reply_cap, + unsigned long imprint, unsigned long cnt) { if (!_ipc_server) return; @@ -57,9 +58,9 @@ void Rpc_entrypoint::explicit_reply(Untyped_capability reply_cap, int return_val Untyped_capability last_reply_cap = _ipc_server->dst(); /* direct ipc server to the specified reply destination */ - _ipc_server->ret(return_value); + _ipc_server->ret(0); _ipc_server->dst(reply_cap); - *_ipc_server << IPC_REPLY; + *_ipc_server << Signal_source::Signal(imprint, cnt) << IPC_REPLY; /* restore reply capability of the original request */ _ipc_server->dst(last_reply_cap); diff --git a/repos/base/src/base/signal/common.cc b/repos/base/src/base/signal/common.cc index 446cc1910..29ad1b9f6 100644 --- a/repos/base/src/base/signal/common.cc +++ b/repos/base/src/base/signal/common.cc @@ -14,20 +14,12 @@ */ /* Genode includes */ +#include #include -#include +#include using namespace Genode; -/** - * Return process-wide signal session - */ -Signal_connection * Genode::signal_connection() -{ - static Signal_connection sc; - return ≻ -} - /************ ** Signal ** @@ -110,9 +102,6 @@ Signal_context::~Signal_context() ** Signal_transmitter ** ************************/ -Signal_connection * Signal_transmitter::connection() { return signal_connection(); } - - Signal_transmitter::Signal_transmitter(Signal_context_capability context) : _context(context) { } @@ -201,7 +190,7 @@ void Signal_receiver::_unsynchronized_dissolve(Signal_context * const context) _platform_begin_dissolve(context); /* tell core to stop sending signals referring to the context */ - signal_connection()->free_context(context->_cap); + env()->pd_session()->free_context(context->_cap); /* restore default initialization of signal context */ context->_receiver = 0; diff --git a/repos/base/src/base/signal/platform.cc b/repos/base/src/base/signal/platform.cc index d175021f7..728cdf62a 100644 --- a/repos/base/src/base/signal/platform.cc +++ b/repos/base/src/base/signal/platform.cc @@ -13,17 +13,20 @@ */ -#include +#include +#include using namespace Genode; + /************************ ** Signal transmitter ** ************************/ + void Signal_transmitter::submit(unsigned cnt) { { Trace::Signal_submit trace_event(cnt); } - connection()->submit(_context, cnt); + env()->pd_session()->submit(_context, cnt); } diff --git a/repos/base/src/base/signal/signal.cc b/repos/base/src/base/signal/signal.cc index 22f41f3e3..2a8e11ec8 100644 --- a/repos/base/src/base/signal/signal.cc +++ b/repos/base/src/base/signal/signal.cc @@ -11,10 +11,12 @@ * under the terms of the GNU General Public License version 2. */ +#include +#include #include #include #include -#include +#include using namespace Genode; @@ -63,7 +65,7 @@ class Signal_handler_thread : Thread, Lock Signal_source *Signal_handler_thread::signal_source() { - static Signal_source_client sigsrc(signal_connection()->signal_source()); + static Signal_source_client sigsrc(env()->pd_session()->alloc_signal_source()); return &sigsrc; } @@ -203,30 +205,23 @@ Signal_context_capability Signal_receiver::manage(Signal_context *context) /* register context at process-wide registry */ signal_context_registry()->insert(&context->_registry_le); - bool try_again = true; - for (;;) { - try { - + retry( + [&] () { /* use signal context as imprint */ - context->_cap = signal_connection()->alloc_context((long)context); - return context->_cap; - - } catch (Signal_session::Out_of_metadata) { - - /* give up if the error occurred a second time */ - if (try_again) { try_again = false; } - else { break; } - + context->_cap = env()->pd_session()->alloc_context(_cap, (long)context); + }, + [&] () { size_t const quota = 1024*sizeof(long); char buf[64]; snprintf(buf, sizeof(buf), "ram_quota=%zu", quota); - PINF("upgrading quota donation for SIGNAL session (%zu bytes)", quota); + PINF("upgrading quota donation for PD session (%zu bytes)", quota); - env()->parent()->upgrade(signal_connection()->cap(), buf); + env()->parent()->upgrade(env()->pd_session_cap(), buf); } - }; - return Signal_context_capability(); + ); + + return context->_cap; } diff --git a/repos/base/src/core/include/assertion.h b/repos/base/src/core/include/assertion.h new file mode 100644 index 000000000..159a454a7 --- /dev/null +++ b/repos/base/src/core/include/assertion.h @@ -0,0 +1,24 @@ +/* + * \brief Assertion macros + * \author Norman Feske + * \date 2016-01-13 + */ + +/* + * Copyright (C) 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. + */ + +#ifndef _CORE__INCLUDE__ASSERTION_H_ +#define _CORE__INCLUDE__ASSERTION_H_ + +/* Genode includes */ +#include + +#define ASSERT_NEVER_CALLED \ + PERR("Unexpected call of '%s' (%s:%u)", __FUNCTION__, __FILE__, __LINE__); \ + for (;;); throw 0UL; + +#endif /* _CORE__INCLUDE__ASSERTION_H_ */ diff --git a/repos/base/src/core/include/core_env.h b/repos/base/src/core/include/core_env.h index 02da1d5af..0a3cd1ab3 100644 --- a/repos/base/src/core/include/core_env.h +++ b/repos/base/src/core/include/core_env.h @@ -22,12 +22,14 @@ #include #include #include +#include #include /* core includes */ #include #include #include +#include #include #include @@ -113,30 +115,45 @@ namespace Genode { typedef Synchronized_ram_session Core_ram_session; + Core_parent _core_parent; + Cap_session_component _cap_session; + enum { ENTRYPOINT_STACK_SIZE = 2048 * sizeof(Genode::addr_t) }; - Core_parent _core_parent; - Cap_session_component _cap_session; Rpc_entrypoint _entrypoint; Core_rm_session _rm_session; Core_ram_session _ram_session; - Heap _heap; Ram_session_capability const _ram_session_cap; + /* + * The core-local PD session is provided by a real RPC object + * dispatched by the same entrypoint as the signal-source RPC + * objects. This is needed to allow the 'Pd_session::submit' + * method to issue out-of-order replies to + * 'Signal_source::wait_for_signal' calls. + */ + Core_pd_session_component _pd_session_component; + Pd_session_client _pd_session_client; + + Heap _heap; + public: /** * Constructor */ - Core_env() : + Core_env() + : _cap_session(platform()->core_mem_alloc(), "ram_quota=4K"), _entrypoint(&_cap_session, ENTRYPOINT_STACK_SIZE, "entrypoint"), _rm_session(&_entrypoint), _ram_session(&_entrypoint, &_entrypoint, platform()->ram_alloc(), platform()->core_mem_alloc(), "ram_quota=4M", platform()->ram_alloc()->avail()), - _heap(&_ram_session, &_rm_session), - _ram_session_cap(_entrypoint.manage(&_ram_session)) + _ram_session_cap(_entrypoint.manage(&_ram_session)), + _pd_session_component(_entrypoint /* XXX use a different entrypoint */), + _pd_session_client(_entrypoint.manage(&_pd_session_component)), + _heap(&_ram_session, &_rm_session) { } /** @@ -144,19 +161,20 @@ namespace Genode { */ ~Core_env() { parent()->exit(0); } - Cap_session *cap_session() { return &_cap_session; } Rpc_entrypoint *entrypoint() { return &_entrypoint; } + Cap_session *cap_session() { return &_cap_session; } /******************* ** Env interface ** *******************/ - Parent *parent() { return &_core_parent; } - Ram_session *ram_session() { return &_ram_session; } - Ram_session_capability ram_session_cap() { return _ram_session_cap; } - Rm_session *rm_session() { return &_rm_session; } - Allocator *heap() { return &_heap; } + Parent *parent() override { return &_core_parent; } + Ram_session *ram_session() override { return &_ram_session; } + Ram_session_capability ram_session_cap() override { return _ram_session_cap; } + Rm_session *rm_session() override { return &_rm_session; } + Pd_session *pd_session() override { return &_pd_session_client; } + Allocator *heap() override { return &_heap; } Cpu_session *cpu_session() { @@ -169,10 +187,10 @@ namespace Genode { return Cpu_session_capability(); } - Pd_session *pd_session() + Pd_session_capability pd_session_cap() override { PWRN("%s:%u not implemented", __FILE__, __LINE__); - return 0; + return Pd_session_capability(); } void reinit(Capability::Dst, long) { } diff --git a/repos/base/src/core/include/core_pd_session.h b/repos/base/src/core/include/core_pd_session.h new file mode 100644 index 000000000..63b0a7bef --- /dev/null +++ b/repos/base/src/core/include/core_pd_session.h @@ -0,0 +1,102 @@ +/* + * \brief Core-specific pseudo PD session + * \author Norman Feske + * \date 2016-01-13 + */ + +/* + * Copyright (C) 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. + */ + +#ifndef _CORE__INCLUDE__CORE_PD_SESSION_H_ +#define _CORE__INCLUDE__CORE_PD_SESSION_H_ + +/* Genode includes */ +#include +#include +#include + +/* core includes */ +#include +#include + +namespace Genode { class Core_pd_session_component; } + + +class Genode::Core_pd_session_component : public Rpc_object +{ + private: + + Rpc_entrypoint &_signal_source_ep; + + public: + + /** + * Constructor + * + * \param context_ep entrypoint that serves the signal-source + * components + */ + Core_pd_session_component(Rpc_entrypoint &signal_source_ep) + : + _signal_source_ep(signal_source_ep) + { } + + int bind_thread(Thread_capability thread) override + { + ASSERT_NEVER_CALLED; + } + + int assign_parent(Capability parent) override + { + ASSERT_NEVER_CALLED; + } + + bool assign_pci(addr_t pci_config_memory_address, uint16_t) override + { + ASSERT_NEVER_CALLED; + } + + Signal_source_capability alloc_signal_source() override + { + /* + * Even though core does not receive any signals, this function is + * called by the base-common initialization code on base-hw. We + * can savely return an invalid capability as it is never used. + */ + return Signal_source_capability(); + } + + void free_signal_source(Signal_source_capability cap) override + { + ASSERT_NEVER_CALLED; + } + + Capability + alloc_context(Signal_source_capability source, unsigned long imprint) override + { + ASSERT_NEVER_CALLED; + } + + void free_context(Capability cap) override + { + ASSERT_NEVER_CALLED; + } + + void submit(Capability cap, unsigned cnt = 1) override + { + _signal_source_ep.apply(cap, [&] (Signal_context_component *context) { + if (!context) { + PDBG("invalid signal-context capability"); + return; + } + + context->source()->submit(context, cnt); + }); + } +}; + +#endif /* _CORE__INCLUDE__CORE_PD_SESSION_H_ */ diff --git a/repos/base/src/core/include/pd_root.h b/repos/base/src/core/include/pd_root.h index a4bc2809e..6c0d9c572 100644 --- a/repos/base/src/core/include/pd_root.h +++ b/repos/base/src/core/include/pd_root.h @@ -25,19 +25,21 @@ namespace Genode { } -class Genode::Pd_root -: public Genode::Root_component +class Genode::Pd_root : public Genode::Root_component { private: - Rpc_entrypoint *_thread_ep; - Allocator *_md_alloc; + Rpc_entrypoint &_thread_ep; + Allocator &_md_alloc; protected: Pd_session_component *_create_session(const char *args) { + /* XXX use separate entrypoint for PD sessions */ return new (md_alloc()) Pd_session_component(_thread_ep, + _thread_ep, + _thread_ep, _md_alloc, args); } @@ -61,7 +63,7 @@ class Genode::Pd_root Rpc_entrypoint *thread_ep, Allocator *md_alloc) : Root_component(session_ep, md_alloc), - _thread_ep(thread_ep), _md_alloc(md_alloc) { } + _thread_ep(*thread_ep), _md_alloc(*md_alloc) { } }; #endif /* _CORE__INCLUDE__PD_ROOT_H_ */ diff --git a/repos/base/src/core/include/pd_session_component.h b/repos/base/src/core/include/pd_session_component.h index 824701d4f..f0b41ed32 100644 --- a/repos/base/src/core/include/pd_session_component.h +++ b/repos/base/src/core/include/pd_session_component.h @@ -2,11 +2,12 @@ * \brief Core-specific instance of the PD session interface * \author Christian Helmuth * \author Stefan Kalkowski + * \author Norman Feske * \date 2006-07-17 */ /* - * Copyright (C) 2006-2013 Genode Labs GmbH + * Copyright (C) 2006-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. @@ -23,6 +24,7 @@ /* core includes */ #include +#include namespace Genode { class Pd_session_component; } @@ -48,35 +50,86 @@ class Genode::Pd_session_component : public Rpc_object Allocator_guard _md_alloc; /* guarded meta-data allocator */ Platform_pd _pd; - Parent_capability _parent; - Rpc_entrypoint *_thread_ep; + Capability _parent; + Rpc_entrypoint &_thread_ep; + + Signal_broker _signal_broker; size_t _ram_quota(char const * args) { return Arg_string::find_arg(args, "ram_quota").long_value(0); } public: - Pd_session_component(Rpc_entrypoint * thread_ep, - Allocator * md_alloc, - char const * args) - : _label(args), - _md_alloc(md_alloc, _ram_quota(args)), - _pd(&_md_alloc, _label.string), - _thread_ep(thread_ep) { } + /** + * Constructor + * + * \param receiver_ep entrypoint holding signal-receiver component + * objects + * \param context_ep global pool of all signal contexts + * \param md_alloc backing-store allocator for + * signal-context component objects + * + * To maintain proper synchronization, 'receiver_ep' must be + * the same entrypoint as used for the signal-session component. + * The 'signal_context_ep' is only used for associative array + * to map signal-context capabilities to 'Signal_context_component' + * objects and as capability allocator for such objects. + */ + + Pd_session_component(Rpc_entrypoint &thread_ep, + Rpc_entrypoint &receiver_ep, + Rpc_entrypoint &context_ep, + Allocator &md_alloc, + char const *args) + : + _label(args), + _md_alloc(&md_alloc, _ram_quota(args)), + _pd(&_md_alloc, _label.string), + _thread_ep(thread_ep), + _signal_broker(_md_alloc, receiver_ep, context_ep) + { } /** * Register quota donation at allocator guard */ - void upgrade_ram_quota(size_t ram_quota) { - _md_alloc.upgrade(ram_quota); } + void upgrade_ram_quota(size_t ram_quota); - /**************************/ - /** PD session interface **/ - /**************************/ + /************************** + ** PD session interface ** + **************************/ - int bind_thread(Thread_capability); - int assign_parent(Parent_capability); + int bind_thread(Thread_capability) override; + int assign_parent(Capability) override; + bool assign_pci(addr_t, uint16_t) override; + + Signal_source_capability alloc_signal_source() override + { + try { + return _signal_broker.alloc_signal_source(); } + catch (Genode::Allocator::Out_of_memory) { + throw Pd_session::Out_of_metadata(); } + } + + void free_signal_source(Signal_source_capability sig_rec_cap) override { + _signal_broker.free_signal_source(sig_rec_cap); } + + Signal_context_capability + alloc_context(Signal_source_capability sig_rec_cap, unsigned long imprint) override + { + try { + return _signal_broker.alloc_context(sig_rec_cap, imprint); } + catch (Genode::Allocator::Out_of_memory) { + throw Pd_session::Out_of_metadata(); } + catch (Signal_broker::Invalid_signal_source) { + throw Pd_session::Invalid_signal_source(); } + } + + void free_context(Signal_context_capability cap) override { + _signal_broker.free_context(cap); } + + void submit(Signal_context_capability cap, unsigned n) override { + _signal_broker.submit(cap, n); } }; #endif /* _CORE__INCLUDE__PD_SESSION_COMPONENT_H_ */ diff --git a/repos/base/src/core/include/signal_broker.h b/repos/base/src/core/include/signal_broker.h new file mode 100644 index 000000000..d401bd830 --- /dev/null +++ b/repos/base/src/core/include/signal_broker.h @@ -0,0 +1,110 @@ +/* + * \brief Mechanism to deliver signals via core + * \author Norman Feske + * \date 2016-01-04 + */ + +/* + * 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 _CORE__INCLUDE__SIGNAL_BROKER_H_ +#define _CORE__INCLUDE__SIGNAL_BROKER_H_ + +#include +#include + +namespace Genode { class Signal_broker; } + +class Genode::Signal_broker +{ + private: + + Allocator &_md_alloc; + Rpc_entrypoint &_source_ep; + Rpc_entrypoint &_context_ep; + Signal_source_component _source; + Signal_source_capability _source_cap; + Tslab _contexts_slab { &_md_alloc }; + + public: + + class Invalid_signal_source : public Exception { }; + + Signal_broker(Allocator &md_alloc, + Rpc_entrypoint &source_ep, + Rpc_entrypoint &context_ep) + : + _md_alloc(md_alloc), + _source_ep(source_ep), + _context_ep(context_ep), + _source(&_context_ep), + _source_cap(_source_ep.manage(&_source)) + { } + + ~Signal_broker() + { + /* remove source from entrypoint */ + _source_ep.dissolve(&_source); + + /* free all signal contexts */ + while (Signal_context_component *r = _contexts_slab.first_object()) + free_context(r->cap()); + } + + Signal_source_capability alloc_signal_source() { return _source_cap; } + + void free_signal_source(Signal_source_capability) { } + + Signal_context_capability + alloc_context(Signal_source_capability, unsigned long imprint) + { + /* + * XXX For now, we ignore the signal-source argument as we + * create only a single receiver for each PD. + */ + Signal_context_component *context = new (&_contexts_slab) + Signal_context_component(imprint, &_source); + + return _context_ep.manage(context); + } + + void free_context(Signal_context_capability context_cap) + { + Signal_context_component *context; + + _context_ep.apply(context_cap, [&] (Signal_context_component *c) { + context = c; + if (!context) { + PWRN("specified signal-context capability has wrong type"); + return; + } + + _context_ep.dissolve(context); + }); + destroy(&_contexts_slab, context); + } + + void submit(Signal_context_capability cap, unsigned cnt) + { + _source_ep.apply(cap, [&] (Signal_context_component *context) { + if (!context) { + /* + * We do not use PWRN() to enable the build system to + * suppress this warning in release mode (SPECS += + * release). + */ + PDBG("invalid signal-context capability"); + return; + } + + context->source()->submit(context, cnt); + }); + } +}; + +#endif /* _CORE__INCLUDE__SIGNAL_BROKER_H_ */ diff --git a/repos/base/src/core/include/signal_root.h b/repos/base/src/core/include/signal_root.h deleted file mode 100644 index 3ee58ca47..000000000 --- a/repos/base/src/core/include/signal_root.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * \brief Signal root interface - * \author Norman Feske - * \date 2009-08-05 - */ - -/* - * 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. - */ - -#ifndef _CORE__INCLUDE__SIGNAL_ROOT_H_ -#define _CORE__INCLUDE__SIGNAL_ROOT_H_ - -/* Genode includes */ -#include - -/* core includes */ -#include - -namespace Genode { - - class Signal_handler - { - private: - - enum { STACK_SIZE = sizeof(addr_t)*1024 }; - Rpc_entrypoint _ep; - - public: - - Signal_handler(Cap_session *cap_session) : - _ep(cap_session, STACK_SIZE, "signal") - { } - - Rpc_entrypoint *entrypoint() { return &_ep; } - }; - - - class Signal_root : private Signal_handler, - public Root_component - { - protected: - - Signal_session_component *_create_session(const char *args) - { - size_t ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0); - return new (md_alloc()) - Signal_session_component(entrypoint(), entrypoint(), - md_alloc(), ram_quota); - } - - void _upgrade_session(Signal_session_component *s, const char *args) - { - size_t ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0); - s->upgrade_ram_quota(ram_quota); - } - - public: - - /** - * Constructor - * - * \param md_alloc meta-data allocator to be used by root component - */ - Signal_root(Allocator *md_alloc, Cap_session *cap_session) - : - Signal_handler(cap_session), - Root_component(entrypoint(), md_alloc) - { } - }; -} - -#endif /* _CORE__INCLUDE__SIGNAL_ROOT_H_ */ diff --git a/repos/base/src/core/include/signal_session_component.h b/repos/base/src/core/include/signal_session_component.h deleted file mode 100644 index 8a148a844..000000000 --- a/repos/base/src/core/include/signal_session_component.h +++ /dev/null @@ -1,209 +0,0 @@ -/* - * \brief Signal service - * \author Norman Feske - * \date 2009-08-05 - */ - -/* - * 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. - */ - -#ifndef _CORE__INCLUDE__SIGNAL_SESSION_COMPONENT_H_ -#define _CORE__INCLUDE__SIGNAL_SESSION_COMPONENT_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace Genode { - - class Signal_source_component; - class Signal_context_component; - - typedef Fifo Signal_queue; - - class Signal_context_component : public Rpc_object, - public Signal_queue::Element - { - private: - - long _imprint; - int _cnt; - Signal_source_component *_source; - - public: - - /** - * Constructor - */ - Signal_context_component(long imprint, Signal_source_component *source) - : _imprint(imprint), _cnt(0), _source(source) { } - - /** - * De-constructor - */ - ~Signal_context_component(); - - /** - * Increment number of signals to be delivered at once - */ - void increment_signal_cnt(int increment) { _cnt += increment; } - - /** - * Reset number of pending signals - */ - void reset_signal_cnt() { _cnt = 0; } - - long imprint() { return _imprint; } - int cnt() { return _cnt; } - Signal_source_component *source() { return _source; } - }; - - - class Signal_source_component : public Signal_source_rpc_object - { - /** - * Helper for clean destruction of signal-source component - * - * Normally, reply capabilities are implicitly destroyed when answering - * an RPC call. But when destructing a signal session while a signal- - * source client is blocking on a 'wait_for_signal' call, this - * blocking call will never return via the normal control flow - * (signal submission). In this case, the reply capability would - * outlive the signal session. To avoid the leakage of such reply - * capabilities, we let the signal-session destructor perform a - * core-local RPC call to the so-called 'Finalizer' object, which has - * the sole purpose of replying to the last outstanding - * 'wait_for_signal' call and thereby releasing the corresponding - * reply capability. - */ - struct Finalizer - { - GENODE_RPC(Rpc_exit, void, exit); - GENODE_RPC_INTERFACE(Rpc_exit); - }; - - struct Finalizer_component : Rpc_object - { - Signal_source_component &source; - - Finalizer_component(Signal_source_component &source) - : source(source) { } - - void exit(); - }; - - private: - - Signal_queue _signal_queue; - Rpc_entrypoint *_entrypoint; - Native_capability _reply_cap; - Finalizer_component _finalizer; - Capability _finalizer_cap; - - public: - - /** - * Constructor - */ - Signal_source_component(Rpc_entrypoint *rpc_entrypoint); - - ~Signal_source_component(); - - void release(Signal_context_component *context); - - void submit(Signal_context_component *context, - Ipc_ostream *ostream, - int cnt); - - - /***************************** - ** Signal-source interface ** - *****************************/ - - Signal wait_for_signal(); - }; - - - class Signal_session_component : public Rpc_object - { - private: - - Rpc_entrypoint *_source_ep; - Rpc_entrypoint *_context_ep; - Signal_source_component _source; - Signal_source_capability _source_cap; - Allocator_guard _md_alloc; - Tslab _contexts_slab; - Ipc_ostream *_ipc_ostream; - - public: - - /** - * Constructor - * - * \param source_ep entrypoint holding signal-source component - * objects - * \param context_ep global pool of all signal contexts - * \param md_alloc backing-store allocator for - * signal-context component objects - * - * To maintain proper synchronization, 'signal_source_ep' must be - * the same entrypoint as used for the signal-session component. - * The 'signal_context_ep' is only used for associative array - * to map signal-context capabilities to 'Signal_context_component' - * objects and as capability allocator for such objects. - */ - Signal_session_component(Rpc_entrypoint *source_ep, - Rpc_entrypoint *context_ep, - Allocator *context_md_alloc, - size_t ram_quota); - - ~Signal_session_component(); - - /** - * Register quota donation at allocator guard - */ - void upgrade_ram_quota(size_t ram_quota) { _md_alloc.upgrade(ram_quota); } - - - /****************************** - ** Signal-session interface ** - ******************************/ - - Signal_source_capability signal_source(); - Signal_context_capability alloc_context(long imprint); - void free_context(Signal_context_capability context_cap); - void submit(Signal_context_capability context_cap, unsigned cnt); - - - /************************** - ** Rpc_object interface ** - **************************/ - - Rpc_exception_code dispatch(int opcode, Ipc_istream &is, Ipc_ostream &os) - { - /* - * Make IPC output stream available to the submit function. The - * stream is used to carry signal payload for the out-of-order - * handling of 'wait_for_signal' replies. - */ - _ipc_ostream = &os; - - /* dispatch RPC */ - return Rpc_object::dispatch(opcode, is, os); - } - }; -} - -#endif /* _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_ */ diff --git a/repos/base/src/core/include/signal_source_component.h b/repos/base/src/core/include/signal_source_component.h new file mode 100644 index 000000000..758957764 --- /dev/null +++ b/repos/base/src/core/include/signal_source_component.h @@ -0,0 +1,143 @@ +/* + * \brief Signal-delivery mechanism + * \author Norman Feske + * \date 2009-08-05 + */ + +/* + * 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. + */ + +#ifndef _CORE__INCLUDE__SIGNAL_SOURCE_COMPONENT_H_ +#define _CORE__INCLUDE__SIGNAL_SOURCE_COMPONENT_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Genode { + + class Signal_context_component; + class Signal_source_component; + + typedef Fifo Signal_queue; +} + + +class Genode::Signal_context_component : public Rpc_object, + public Signal_queue::Element +{ + private: + + long _imprint; + int _cnt; + Signal_source_component *_source; + + public: + + /** + * Constructor + */ + Signal_context_component(long imprint, + Signal_source_component *source) + : _imprint(imprint), _cnt(0), _source(source) { } + + /** + * Destructor + */ + inline ~Signal_context_component(); + + /** + * Increment number of signals to be delivered at once + */ + void increment_signal_cnt(int increment) { _cnt += increment; } + + /** + * Reset number of pending signals + */ + void reset_signal_cnt() { _cnt = 0; } + + long imprint() { return _imprint; } + int cnt() { return _cnt; } + Signal_source_component *source() { return _source; } +}; + + +class Genode::Signal_source_component : public Signal_source_rpc_object +{ + /** + * Helper for clean destruction of signal-receiver component + * + * Normally, reply capabilities are implicitly destroyed when answering + * an RPC call. But when destructing a signal session while a signal- + * receiver client is blocking on a 'wait_for_signal' call, this + * blocking call will never return via the normal control flow + * (signal submission). In this case, the reply capability would + * outlive the signal session. To avoid the leakage of such reply + * capabilities, we let the signal-session destructor perform a + * core-local RPC call to the so-called 'Finalizer' object, which has + * the sole purpose of replying to the last outstanding + * 'wait_for_signal' call and thereby releasing the corresponding + * reply capability. + */ + struct Finalizer + { + GENODE_RPC(Rpc_exit, void, exit); + GENODE_RPC_INTERFACE(Rpc_exit); + }; + + struct Finalizer_component : Rpc_object + { + Signal_source_component &source; + + Finalizer_component(Signal_source_component &source) + : source(source) { } + + void exit(); + }; + + private: + + Signal_queue _signal_queue; + Rpc_entrypoint *_entrypoint; + Native_capability _reply_cap; + Finalizer_component _finalizer; + Capability _finalizer_cap; + + public: + + /** + * Constructor + */ + Signal_source_component(Rpc_entrypoint *rpc_entrypoint); + + ~Signal_source_component(); + + void release(Signal_context_component *context); + + void submit(Signal_context_component *context, + unsigned long cnt); + + /***************************** + ** Signal-receiver interface ** + *****************************/ + + Signal wait_for_signal() override; +}; + + +Genode::Signal_context_component::~Signal_context_component() +{ + if (is_enqueued() && _source) + _source->release(this); +} + +#endif /* _CORE__INCLUDE__SIGNAL_SOURCE_COMPONENT_H_ */ diff --git a/repos/base/src/core/main.cc b/repos/base/src/core/main.cc index 59c7c093e..ae2060866 100644 --- a/repos/base/src/core/main.cc +++ b/repos/base/src/core/main.cc @@ -33,7 +33,6 @@ #include #include #include -#include #include #include @@ -213,16 +212,6 @@ int main() */ static Sliced_heap sliced_heap(env()->ram_session(), env()->rm_session()); - /** - * Provide signal service before other services to enable the use of signal - * connection during service initialization. This has been introduced due - * to the use of the signal framework for paging (RM service) in base-hw. - */ - static Signal_root signal_root(&sliced_heap, core_env()->cap_session()); - char const * const signal_name = Signal_session::service_name(); - static Local_service signal_service(signal_name, &signal_root); - local_services.insert(&signal_service); - static Cap_root cap_root (e, &sliced_heap); static Ram_root ram_root (e, e, platform()->ram_alloc(), &sliced_heap); static Rom_root rom_root (e, e, platform()->rom_fs(), &sliced_heap); diff --git a/repos/base/src/core/pd_assign_pci.cc b/repos/base/src/core/pd_assign_pci.cc new file mode 100644 index 000000000..653fa816f --- /dev/null +++ b/repos/base/src/core/pd_assign_pci.cc @@ -0,0 +1,22 @@ +/* + * \brief Core implementation of the PD session interface + * \author Norman Feske + * \date 2016-01-13 + * + * This dummy is used on all kernels with no IOMMU support. + */ + +/* + * 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. + */ + +/* core-local includes */ +#include + +using namespace Genode; + +bool Pd_session_component::assign_pci(addr_t, uint16_t) { return false; } + diff --git a/repos/base/src/core/pd_session_component.cc b/repos/base/src/core/pd_session_component.cc index e78a51b30..71d1a7c21 100644 --- a/repos/base/src/core/pd_session_component.cc +++ b/repos/base/src/core/pd_session_component.cc @@ -26,7 +26,7 @@ using namespace Genode; int Pd_session_component::bind_thread(Thread_capability thread) { - return _thread_ep->apply(thread, [&] (Cpu_thread_component *cpu_thread) { + return _thread_ep.apply(thread, [&] (Cpu_thread_component *cpu_thread) { if (!cpu_thread) return -1; if (cpu_thread->bound()) { diff --git a/repos/base/src/core/pd_upgrade_ram_quota.cc b/repos/base/src/core/pd_upgrade_ram_quota.cc new file mode 100644 index 000000000..2422105f4 --- /dev/null +++ b/repos/base/src/core/pd_upgrade_ram_quota.cc @@ -0,0 +1,24 @@ +/* + * \brief Core implementation of the PD session interface + * \author Norman Feske + * \date 2016-01-13 + */ + +/* + * 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. + */ + +/* core-local includes */ +#include + +using namespace Genode; + + +void Pd_session_component::upgrade_ram_quota(size_t ram_quota) +{ + _md_alloc.upgrade(ram_quota); +} + diff --git a/repos/base/src/core/signal_session_component.cc b/repos/base/src/core/signal_session_component.cc deleted file mode 100644 index 645c971a9..000000000 --- a/repos/base/src/core/signal_session_component.cc +++ /dev/null @@ -1,110 +0,0 @@ -/* - * \brief Implementation of the SIGNAL interface - * \author Norman Feske - * \date 2009-08-11 - */ - -/* - * 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 - -using namespace Genode; - - -/****************************** - ** Signal-session component ** - ******************************/ - -Signal_session_component::Signal_session_component(Rpc_entrypoint *source_ep, - Rpc_entrypoint *context_ep, - Allocator *context_md_alloc, - size_t ram_quota) -: - _source_ep(source_ep), - _context_ep(context_ep), - _source(source_ep), - _source_cap(_source_ep->manage(&_source)), - _md_alloc(context_md_alloc, ram_quota), - _contexts_slab(&_md_alloc) -{ } - - -Signal_session_component::~Signal_session_component() -{ - /* remove _signal_source from entrypoint */ - _source_ep->dissolve(&_source); - - /* free all signal contexts */ - while (Signal_context_component *r = _contexts_slab.first_object()) - free_context(r->cap()); -} - - -Signal_source_capability Signal_session_component::signal_source() -{ - return _source_cap; -} - - -Signal_context_capability Signal_session_component::alloc_context(long imprint) -{ - Signal_context_component *context; - - try { context = new (&_contexts_slab) - Signal_context_component(imprint, &_source); } - - catch (Allocator::Out_of_memory) { throw Out_of_metadata(); } - - /* return unique capability for the signal context */ - return _context_ep->manage(context); -} - - -void Signal_session_component::free_context(Signal_context_capability context_cap) -{ - Signal_context_component *context; - _context_ep->apply(context_cap, [&] (Signal_context_component *c) { - context = c; - if (!context) { - PWRN("specified signal-context capability has wrong type"); - return; - } - - _context_ep->dissolve(context); - }); - destroy(&_contexts_slab, context); -} - - -void Signal_session_component::submit(Signal_context_capability context_cap, - unsigned cnt) -{ - _context_ep->apply(context_cap, [&] (Signal_context_component *context) { - if (!context) { - /* - * We do not use PWRN() to enable the build system to suppress this - * warning in release mode (SPECS += release). - */ - PDBG("invalid signal-context capability"); - return; - } - - context->source()->submit(context, _ipc_ostream, cnt); - }); -} - - -Signal_context_component::~Signal_context_component() -{ - if (is_enqueued() && _source) - _source->release(this); -} diff --git a/repos/base/src/core/signal_source_component.cc b/repos/base/src/core/signal_source_component.cc index 110ad5ce5..2c0d4d9fe 100644 --- a/repos/base/src/core/signal_source_component.cc +++ b/repos/base/src/core/signal_source_component.cc @@ -16,7 +16,7 @@ #include /* core includes */ -#include +#include using namespace Genode; @@ -33,8 +33,7 @@ void Signal_source_component::release(Signal_context_component *context) void Signal_source_component::submit(Signal_context_component *context, - Ipc_ostream *ostream, - int cnt) + unsigned long cnt) { /* * If the client does not block in 'wait_for_signal', the @@ -49,8 +48,7 @@ void Signal_source_component::submit(Signal_context_component *context, */ if (_reply_cap.valid()) { - *ostream << Signal(context->imprint(), context->cnt()); - _entrypoint->explicit_reply(_reply_cap, 0); + _entrypoint->reply_signal_info(_reply_cap, context->imprint(), context->cnt()); /* * We unblocked the client and, therefore, can invalidate @@ -108,6 +106,6 @@ void Signal_source_component::Finalizer_component::exit() if (!source._reply_cap.valid()) return; - source._entrypoint->explicit_reply(source._reply_cap, 0); + source._entrypoint->reply_signal_info(source._reply_cap, 0, 0); source._reply_cap = Untyped_capability(); }