diff --git a/repos/base-fiasco/include/base/native_capability.h b/repos/base-fiasco/include/base/native_capability.h deleted file mode 100644 index ef9537d60..000000000 --- a/repos/base-fiasco/include/base/native_capability.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * \brief Native capability type on L4/Fiasco - * \author Norman Feske - * \date 2008-07-26 - */ - -/* - * Copyright (C) 2008-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__BASE__NATIVE_CAPABILITY_H_ -#define _INCLUDE__BASE__NATIVE_CAPABILITY_H_ - -/* Genode includes */ -#include -#include - -namespace Fiasco { -#include -} - -namespace Genode { - - struct Cap_dst_policy - { - typedef Fiasco::l4_threadid_t Dst; - static bool valid(Dst id) { return !Fiasco::l4_is_invalid_id(id); } - static Dst invalid() - { - using namespace Fiasco; - return L4_INVALID_ID; - } - static void copy(void* dst, Native_capability_tpl* src); - }; - - typedef Native_capability_tpl Native_capability; -} - -#endif /* _INCLUDE__BASE__NATIVE_CAPABILITY_H_ */ diff --git a/repos/base-fiasco/lib/mk/base-common.mk b/repos/base-fiasco/lib/mk/base-common.mk index 256326a15..9d03d7f92 100644 --- a/repos/base-fiasco/lib/mk/base-common.mk +++ b/repos/base-fiasco/lib/mk/base-common.mk @@ -8,9 +8,7 @@ include $(BASE_DIR)/lib/mk/base-common.inc LIBS += startup -SRC_CC += cap_copy.cc +SRC_CC += capability.cc capability_raw.cc SRC_CC += signal_submit.cc SRC_CC += rpc_dispatch_loop.cc SRC_CC += thread.cc thread_bootstrap.cc thread_myself.cc - -vpath cap_copy.cc $(BASE_DIR)/src/lib/startup diff --git a/repos/base-fiasco/lib/mk/base.mk b/repos/base-fiasco/lib/mk/base.mk index a32c7ebd7..eec5dc939 100644 --- a/repos/base-fiasco/lib/mk/base.mk +++ b/repos/base-fiasco/lib/mk/base.mk @@ -2,3 +2,4 @@ include $(BASE_DIR)/lib/mk/base.inc SRC_CC += thread_start.cc SRC_CC += cache.cc +SRC_CC += capability_space.cc diff --git a/repos/base-fiasco/src/core/include/rpc_cap_factory.h b/repos/base-fiasco/src/core/include/rpc_cap_factory.h new file mode 100644 index 000000000..fd1514523 --- /dev/null +++ b/repos/base-fiasco/src/core/include/rpc_cap_factory.h @@ -0,0 +1,39 @@ +/* + * \brief RPC capability factory + * \author Norman Feske + * \date 2016-01-19 + */ + +/* + * 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__RPC_CAP_FACTORY_H_ +#define _CORE__INCLUDE__RPC_CAP_FACTORY_H_ + +#include +#include +#include + +namespace Genode { class Rpc_cap_factory; } + +class Genode::Rpc_cap_factory +{ + private: + + static Native_capability _alloc(Rpc_cap_factory *owner, + Native_capability ep); + + public: + + Rpc_cap_factory(Allocator &md_alloc) { } + + Native_capability alloc(Native_capability ep); + + void free(Native_capability cap); +}; + +#endif /* _CORE__INCLUDE__RPC_CAP_FACTORY_H_ */ diff --git a/repos/base-fiasco/src/core/pager.cc b/repos/base-fiasco/src/core/pager.cc index 6ba162810..8aa7655f3 100644 --- a/repos/base-fiasco/src/core/pager.cc +++ b/repos/base-fiasco/src/core/pager.cc @@ -20,6 +20,7 @@ /* base-internal includes */ #include +#include namespace Fiasco { #include @@ -83,5 +84,5 @@ void Ipc_pager::acknowledge_wakeup() Untyped_capability Pager_entrypoint::_pager_object_cap(unsigned long badge) { - return Untyped_capability(native_thread().l4id, badge); + return Capability_space::import(native_thread().l4id, Rpc_obj_key(badge)); } diff --git a/repos/base-fiasco/src/core/pager_object.cc b/repos/base-fiasco/src/core/pager_object.cc index f04c0cc96..a5d626766 100644 --- a/repos/base-fiasco/src/core/pager_object.cc +++ b/repos/base-fiasco/src/core/pager_object.cc @@ -14,6 +14,9 @@ /* core includes */ #include +/* base-internal includes */ +#include + /* Fiasco includes */ namespace Fiasco { #include @@ -37,7 +40,7 @@ void Pager_object::wake_up() l4_msgdope_t ipc_result; l4_umword_t dummy = 0; - l4_ipc_call(cap().dst(), L4_IPC_SHORT_MSG, + l4_ipc_call(Capability_space::ipc_cap_data(cap()).dst, L4_IPC_SHORT_MSG, 0, /* fault address */ (l4_umword_t)this, /* instruction pointer */ &rcv_header, &dummy, &dummy, L4_IPC_NEVER, &ipc_result); diff --git a/repos/base-fiasco/src/core/platform.cc b/repos/base-fiasco/src/core/platform.cc index 49c110e19..96c2636bd 100644 --- a/repos/base-fiasco/src/core/platform.cc +++ b/repos/base-fiasco/src/core/platform.cc @@ -21,6 +21,7 @@ #include #include #include +#include /* core includes */ #include @@ -137,7 +138,7 @@ Platform::Sigma0::Sigma0() : Pager_object(Cpu_session_capability(), Thread_capability(), 0, Affinity::Location()) { - cap(reinterpret_cap_cast(Native_capability(Fiasco::sigma0_threadid, 0))); + cap(Capability_space::import(Fiasco::sigma0_threadid, Rpc_obj_key())); } @@ -156,7 +157,7 @@ Platform::Core_pager::Core_pager(Platform_pd *core_pd) Platform_thread::pager(sigma0()); core_pd->bind_thread(this); - cap(Native_capability(native_thread_id(), 0)); + cap(Capability_space::import(native_thread_id(), Rpc_obj_key())); /* pager needs to know core's pd ID */ _core_pager_arg = core_pd->pd_id(); diff --git a/repos/base-fiasco/src/core/platform_thread.cc b/repos/base-fiasco/src/core/platform_thread.cc index 18e7e7b81..e1eeed7a5 100644 --- a/repos/base-fiasco/src/core/platform_thread.cc +++ b/repos/base-fiasco/src/core/platform_thread.cc @@ -22,6 +22,9 @@ /* core includes */ #include +/* base-internal includes */ +#include + /* Fiasco includes */ namespace Fiasco { #include @@ -38,7 +41,9 @@ int Platform_thread::start(void *ip, void *sp) { l4_umword_t dummy, old_eflags; l4_threadid_t thread = _l4_thread_id; - l4_threadid_t pager = _pager ? _pager->cap().dst() : L4_INVALID_ID; + l4_threadid_t pager = _pager + ? Capability_space::ipc_cap_data(_pager->cap()).dst + : L4_INVALID_ID; l4_threadid_t preempter = L4_INVALID_ID; l4_threadid_t cap_handler = L4_INVALID_ID; diff --git a/repos/base-fiasco/src/core/target.inc b/repos/base-fiasco/src/core/target.inc index 5fbc8dc0d..5009ac58b 100644 --- a/repos/base-fiasco/src/core/target.inc +++ b/repos/base-fiasco/src/core/target.inc @@ -9,6 +9,7 @@ SRC_CC += stack_area.cc \ cpu_session_component.cc \ cpu_thread_component.cc \ cpu_session_support.cc \ + capability_space.cc \ dataspace_component.cc \ default_log.cc \ dump_alloc.cc \ @@ -22,7 +23,7 @@ SRC_CC += stack_area.cc \ pager_ep.cc \ pager_object.cc \ pd_session_component.cc \ - rpc_cap_factory.cc \ + rpc_cap_factory_l4.cc \ pd_assign_pci.cc \ pd_upgrade_ram_quota.cc \ platform.cc \ @@ -56,7 +57,8 @@ vpath cpu_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_support.cc $(GEN_CORE_DIR) vpath cpu_thread_component.cc $(GEN_CORE_DIR) vpath pd_session_component.cc $(GEN_CORE_DIR) -vpath rpc_cap_factory.cc $(GEN_CORE_DIR) +vpath capability_space.cc $(GEN_CORE_DIR) +vpath rpc_cap_factory_l4.cc $(GEN_CORE_DIR) vpath core_rpc_cap_alloc.cc $(GEN_CORE_DIR) vpath core_region_map.cc $(GEN_CORE_DIR) vpath pd_assign_pci.cc $(GEN_CORE_DIR) diff --git a/repos/base-fiasco/src/include/base/internal/parent_cap.h b/repos/base-fiasco/src/include/base/internal/parent_cap.h new file mode 100644 index 000000000..9896bfbff --- /dev/null +++ b/repos/base-fiasco/src/include/base/internal/parent_cap.h @@ -0,0 +1,40 @@ +/* + * \brief Interface to obtain the parent capability for the component + * \author Norman Feske + * \date 2015-05-12 + */ + +/* + * Copyright (C) 2015-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__BASE__INTERNAL__PARENT_CAP_H_ +#define _INCLUDE__BASE__INTERNAL__PARENT_CAP_H_ + +/* Genode includes */ +#include + +/* base-internal includes */ +#include +#include + + +namespace Genode { + + static inline Parent_capability parent_cap() + { + Native_capability::Raw &raw = *(Native_capability::Raw *)&_parent_cap; + + Fiasco::l4_threadid_t tid; + tid.raw = raw.v[0]; + + Native_capability cap = Capability_space::import(tid, Rpc_obj_key(raw.v[1])); + + return reinterpret_cap_cast(cap); + } +} + +#endif /* _INCLUDE__BASE__INTERNAL__PARENT_CAP_H_ */ diff --git a/repos/base-fiasco/src/include/base/internal/rpc_destination.h b/repos/base-fiasco/src/include/base/internal/rpc_destination.h new file mode 100644 index 000000000..2dae9af38 --- /dev/null +++ b/repos/base-fiasco/src/include/base/internal/rpc_destination.h @@ -0,0 +1,38 @@ +/* + * \brief RPC destination type + * \author Norman Feske + * \date 2016-03-11 + */ + +/* + * 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__BASE__INTERNAL__RPC_DESTINATION_H_ +#define _INCLUDE__BASE__INTERNAL__RPC_DESTINATION_H_ + +/* Fiasco includes */ +namespace Fiasco { +#include +} + +namespace Genode { + + typedef Fiasco::l4_threadid_t Rpc_destination; + + static inline Rpc_destination invalid_rpc_destination() + { + using namespace Fiasco; + return L4_INVALID_ID; + } + + static void print(Output &out, Rpc_destination const &dst) + { + Genode::print(out, "thread=", dst.id.task, ".", dst.id.lthread); + } +} + +#endif /* _INCLUDE__BASE__INTERNAL__RPC_DESTINATION_H_ */ diff --git a/repos/base-fiasco/src/lib/base/capability_raw.cc b/repos/base-fiasco/src/lib/base/capability_raw.cc new file mode 100644 index 000000000..90222e4dc --- /dev/null +++ b/repos/base-fiasco/src/lib/base/capability_raw.cc @@ -0,0 +1,28 @@ +/* + * \brief Capability + * \author Norman Feske + * \date 2016-06-16 + */ + +/* + * 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. + */ + +#include + +/* base-internal includes */ +#include + +using namespace Genode; + + +Native_capability::Raw Native_capability::raw() const +{ + Capability_space::Ipc_cap_data const cap_data = + Capability_space::ipc_cap_data(*this); + + return { { cap_data.dst.raw, cap_data.rpc_obj_key.value(), 0, 0 } }; +} diff --git a/repos/base-fiasco/src/lib/base/ipc.cc b/repos/base-fiasco/src/lib/base/ipc.cc index 40e5ba069..6d5719b85 100644 --- a/repos/base-fiasco/src/lib/base/ipc.cc +++ b/repos/base-fiasco/src/lib/base/ipc.cc @@ -13,17 +13,18 @@ /* Genode includes */ #include +#include #include #include /* base-internal includes */ #include +#include /* Fiasco includes */ namespace Fiasco { #include #include -#include } using namespace Genode; @@ -93,8 +94,14 @@ class Msg_header for (unsigned i = 0; i < num_caps; i++) { Native_capability const &cap = snd_msg.cap(i); - _cap_tid[i] = cap.dst(); - _cap_local_name[i] = cap.local_name(); + + if (cap.valid()) { + Capability_space::Ipc_cap_data const cap_data = + Capability_space::ipc_cap_data(snd_msg.cap(i)); + + _cap_tid[i] = cap_data.dst; + _cap_local_name[i] = cap_data.rpc_obj_key.value(); + } } } @@ -115,9 +122,20 @@ class Msg_header */ void extract_caps(Msgbuf_base &rcv_msg) const { - for (unsigned i = 0; i < min((unsigned)MAX_CAPS_PER_MSG, num_caps); i++) - rcv_msg.insert(Native_capability(_cap_tid[i], - _cap_local_name[i])); + for (unsigned i = 0; i < min((unsigned)MAX_CAPS_PER_MSG, num_caps); i++) { + + Rpc_obj_key const rpc_obj_key(_cap_local_name[i]); + bool const cap_valid = !Fiasco::l4_is_invalid_id(_cap_tid[i]); + + Native_capability cap; + if (cap_valid) { + cap = Capability_space::lookup(rpc_obj_key); + if (!cap.valid()) + cap = Capability_space::import(_cap_tid[i], rpc_obj_key); + } + + rcv_msg.insert(cap); + } } }; @@ -132,14 +150,17 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst, { using namespace Fiasco; + Capability_space::Ipc_cap_data const dst_data = + Capability_space::ipc_cap_data(dst); + Msg_header &snd_header = snd_msg.header(); - snd_header.prepare_snd_msg(dst.local_name(), snd_msg); + snd_header.prepare_snd_msg(dst_data.rpc_obj_key.value(), snd_msg); Msg_header &rcv_header = rcv_msg.header(); rcv_header.prepare_rcv_msg(rcv_msg); l4_msgdope_t ipc_result; - l4_ipc_call(dst.dst(), + l4_ipc_call(dst_data.dst, snd_header.msg_start(), snd_header.protocol_word, snd_header.num_caps, @@ -176,7 +197,8 @@ void Genode::ipc_reply(Native_capability caller, Rpc_exception_code exc, snd_header.prepare_snd_msg(exc.value, snd_msg); l4_msgdope_t result; - l4_ipc_send(caller.dst(), snd_header.msg_start(), + l4_ipc_send(Capability_space::ipc_cap_data(caller).dst, + snd_header.msg_start(), snd_header.protocol_word, snd_header.num_caps, L4_IPC_SEND_TIMEOUT_0, &result); @@ -212,7 +234,8 @@ Genode::Rpc_request Genode::ipc_reply_wait(Reply_capability const &last_caller, * Use short IPC for reply if possible. This is the common case of * returning an integer as RPC result. */ - l4_ipc_reply_and_wait(last_caller.dst(), snd_header.msg_start(), + l4_ipc_reply_and_wait(Capability_space::ipc_cap_data(last_caller).dst, + snd_header.msg_start(), snd_header.protocol_word, snd_header.num_caps, &caller, rcv_header.msg_start(), @@ -250,11 +273,15 @@ Genode::Rpc_request Genode::ipc_reply_wait(Reply_capability const &last_caller, rcv_header.extract_caps(request_msg); - return Rpc_request(Native_capability(caller, 0), rcv_header.protocol_word); + return Rpc_request(Capability_space::import(caller, Rpc_obj_key()), + rcv_header.protocol_word); } -Ipc_server::Ipc_server() : Native_capability(Fiasco::l4_myself(), 0) { } +Ipc_server::Ipc_server() +: + Native_capability(Capability_space::import(Fiasco::l4_myself(), Rpc_obj_key())) +{ } Ipc_server::~Ipc_server() { } diff --git a/repos/base-foc/include/base/native_capability.h b/repos/base-foc/include/base/native_capability.h deleted file mode 100644 index cf0c8ecd4..000000000 --- a/repos/base-foc/include/base/native_capability.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * \brief Platform-specific capability type - * \author Norman Feske - * \date 2009-10-02 - */ - -/* - * 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__BASE__NATIVE_CAPABILITY_H_ -#define _INCLUDE__BASE__NATIVE_CAPABILITY_H_ - -/* Fiasco includes */ -namespace Fiasco { -#include -} - -/* Genode includes */ -#include - -namespace Genode { - - /** - * Native_capability in Fiasco.OC is just a reference to a Cap_index. - * - * As Cap_index objects cannot be copied around, but Native_capability - * have to, we have to use this indirection. - */ - class Native_capability - { - public: - - typedef Fiasco::l4_cap_idx_t Dst; - - struct Raw - { - long local_name; - }; - - private: - - Cap_index* _idx; - - protected: - - inline void _inc() - { - if (_idx) - _idx->inc(); - } - - inline void _dec() - { - if (_idx && !_idx->dec()) { - cap_map()->remove(_idx); - } - } - - public: - - /** - * Default constructor creates an invalid capability - */ - Native_capability() : _idx(0) { } - - /** - * Construct capability manually - */ - Native_capability(Cap_index* idx) - : _idx(idx) { _inc(); } - - Native_capability(const Native_capability &o) - : _idx(o._idx) { _inc(); } - - ~Native_capability() { _dec(); } - - /** - * Return Cap_index object referenced by this object - */ - Cap_index* idx() const { return _idx; } - - /** - * Overloaded comparision operator - */ - bool operator==(const Native_capability &o) const { - return _idx == o._idx; } - - Native_capability& operator=(const Native_capability &o){ - if (this == &o) - return *this; - - _dec(); - _idx = o._idx; - _inc(); - return *this; - } - - /******************************************* - ** Interface provided by all platforms ** - *******************************************/ - - long local_name() const { return _idx ? _idx->id() : 0; } - Dst dst() const { return _idx ? Dst(_idx->kcap()) : Dst(); } - bool valid() const { return (_idx != 0) && _idx->valid(); } - - Raw raw() const { return { local_name() }; } - }; -} - -#endif /* _INCLUDE__BASE__NATIVE_CAPABILITY_H_ */ diff --git a/repos/base-foc/include/base/thread_state.h b/repos/base-foc/include/base/thread_state.h index c12c398a4..2bcb9c68d 100644 --- a/repos/base-foc/include/base/thread_state.h +++ b/repos/base-foc/include/base/thread_state.h @@ -20,6 +20,11 @@ #include #include +/* Fiasco includes */ +namespace Fiasco { +#include +} + namespace Genode { struct Thread_state : Thread_state_base diff --git a/repos/base-foc/include/foc/capability_space.h b/repos/base-foc/include/foc/capability_space.h new file mode 100644 index 000000000..2c6100dde --- /dev/null +++ b/repos/base-foc/include/foc/capability_space.h @@ -0,0 +1,42 @@ +/* + * \brief Utilities for direct capability-space manipulation + * \author Norman Feske + * \date 2016-07-08 + * + * This interface is needed by L4Linux. + */ + +/* + * 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__FOC__CAPABILITY_SPACE_H_ +#define _INCLUDE__FOC__CAPABILITY_SPACE_H_ + +#include +#include + +namespace Genode { namespace Capability_space { + + /** + * Allocate kernel capability selector without associating it with a + * Genode capability + */ + Fiasco::l4_cap_idx_t alloc_kcap(); + + /** + * Release kernel capability selector + */ + void free_kcap(Fiasco::l4_cap_idx_t); + + /** + * Request kernel capability selector associated with Genode capability + */ + Fiasco::l4_cap_idx_t kcap(Native_capability); + +} } + +#endif /* _INCLUDE__FOC__CAPABILITY_SPACE_H_ */ diff --git a/repos/base-foc/include/foc/receive_window.h b/repos/base-foc/include/foc/receive_window.h index 587eae26d..77c0bb1af 100644 --- a/repos/base-foc/include/foc/receive_window.h +++ b/repos/base-foc/include/foc/receive_window.h @@ -17,7 +17,6 @@ /* Genode includes */ #include #include -#include namespace Genode { struct Receive_window; } @@ -29,7 +28,7 @@ class Genode::Receive_window /** * Base of capability receive window. */ - Cap_index* _rcv_idx_base = nullptr; + Native_capability::Data * _rcv_idx_base = nullptr; enum { MAX_CAPS_PER_MSG = Msgbuf_base::MAX_CAPS_PER_MSG }; @@ -37,29 +36,21 @@ class Genode::Receive_window Receive_window() { } - ~Receive_window() - { - if (_rcv_idx_base) - cap_idx_alloc()->free(_rcv_idx_base, MAX_CAPS_PER_MSG); - } + ~Receive_window(); - void init() - { - _rcv_idx_base = cap_idx_alloc()->alloc_range(MAX_CAPS_PER_MSG); - } + void init(); /** * Return address of capability receive window */ - addr_t rcv_cap_sel_base() { return _rcv_idx_base->kcap(); } + addr_t rcv_cap_sel_base(); /** * Return received selector with index i * * \return capability selector, or 0 if index is invalid */ - addr_t rcv_cap_sel(unsigned i) { - return rcv_cap_sel_base() + i*Fiasco::L4_CAP_SIZE; } + addr_t rcv_cap_sel(unsigned i); }; #endif /* _INCLUDE__FOC__RECEIVE_WINDOW_H_ */ diff --git a/repos/base-foc/include/signal_source/client.h b/repos/base-foc/include/signal_source/client.h index 286be602e..bc43d5a61 100644 --- a/repos/base-foc/include/signal_source/client.h +++ b/repos/base-foc/include/signal_source/client.h @@ -27,87 +27,40 @@ #include #include -/* base-internal includes */ -#include +namespace Genode { class Signal_source_client; } -namespace Fiasco { -#include -} -namespace Genode { +class Genode::Signal_source_client : public Rpc_client +{ + private: - class Signal_source_client : public Rpc_client - { - private: + /** + * Capability with 'dst' referring to a Fiasco.OC IRQ object + */ + Native_capability _sem; - /** - * Capability with 'dst' referring to a Fiasco.OC IRQ object - */ - Native_capability _sem; + public: - /** - * Request Fiasco.OC IRQ object from signal-source server - */ - void _init_sem() - { - using namespace Fiasco; + /** + * Constructor + */ + Signal_source_client(Capability cap); - /* request mapping of semaphore capability selector */ - _sem = call(); + /** + * Destructor + */ + ~Signal_source_client(); - l4_msgtag_t tag = l4_irq_attach(_sem.dst(), 0, - Thread::myself()->native_thread().kcap); - if (l4_error(tag)) - PERR("l4_irq_attach failed with %ld!", l4_error(tag)); - } - public: + /***************************** + ** Signal source interface ** + *****************************/ - /** - * Constructor - */ - Signal_source_client(Capability cap) - : Rpc_client(static_cap_cast(cap)) - { _init_sem(); } - - /** - * Destructor - */ - ~Signal_source_client() - { - Fiasco::l4_irq_detach(_sem.dst()); - } - - /***************************** - ** Signal source interface ** - *****************************/ - - /* Build with frame pointer to make GDB backtraces work. See issue #1061. */ - __attribute__((optimize("-fno-omit-frame-pointer"))) - __attribute__((noinline)) - Signal wait_for_signal() - { - using namespace Fiasco; - - Signal signal; - do { - - /* block on semaphore until signal context was submitted */ - l4_irq_receive(_sem.dst(), L4_IPC_NEVER); - - /* - * The following request will return immediately and either - * return a valid or a null signal. The latter may happen in - * the case a submitted signal context was destroyed (by the - * submitter) before we have a chance to raise our request. - */ - signal = call(); - - } while (!signal.imprint()); - - return signal; - } - }; -} + /* + * Build with frame pointer to make GDB backtraces work. See issue #1061. + */ + __attribute__((optimize("-fno-omit-frame-pointer"))) + Signal wait_for_signal(); +}; #endif /* _INCLUDE__SIGNAL_SOURCE__CLIENT_H_ */ diff --git a/repos/base-foc/lib/mk/base-common.inc b/repos/base-foc/lib/mk/base-common.inc index 2cabb463b..bc07de1c6 100644 --- a/repos/base-foc/lib/mk/base-common.inc +++ b/repos/base-foc/lib/mk/base-common.inc @@ -12,3 +12,5 @@ SRC_CC += spin_lock.cc cap_map.cc SRC_CC += signal_submit.cc SRC_CC += rpc_dispatch_loop.cc SRC_CC += thread.cc thread_bootstrap.cc thread_myself.cc utcb.cc +SRC_CC += capability.cc +SRC_CC += signal_source_client.cc diff --git a/repos/base-foc/src/core/include/cap_index.h b/repos/base-foc/src/core/include/cap_index.h index a9d149ec3..3c42e1e7e 100644 --- a/repos/base-foc/src/core/include/cap_index.h +++ b/repos/base-foc/src/core/include/cap_index.h @@ -1,5 +1,5 @@ /* - * \brief Core-specific capability index. + * \brief Core-specific capability index * \author Stefan Kalkowski * \date 2012-02-22 */ @@ -14,39 +14,39 @@ #ifndef _CORE__INCLUDE__CAP_INDEX_H_ #define _CORE__INCLUDE__CAP_INDEX_H_ -/* Genode includes */ -#include - /* base-internal includes */ #include +#include namespace Genode { class Platform_thread; class Pd_session_component; - - class Core_cap_index : public Cap_index - { - private: - - Pd_session_component *_session; - Platform_thread *_pt; - Native_thread _gate; - - public: - - Core_cap_index(Pd_session_component *session = 0, - Platform_thread *pt = 0, - Native_thread gate = Native_thread() ) - : _session(session), _pt(pt), _gate(gate) {} - - Pd_session_component *session() { return _session; } - Platform_thread *pt() { return _pt; } - Native_thread gate() { return _gate; } - - void session(Pd_session_component *c) { _session = c; } - void pt(Platform_thread *t) { _pt = t; } - }; + class Core_cap_index; } + +class Genode::Core_cap_index : public Native_capability::Data +{ + private: + + Pd_session_component *_session; + Platform_thread const *_pt; + Native_thread _gate; + + public: + + Core_cap_index(Pd_session_component *session = 0, + Platform_thread *pt = 0, + Native_thread gate = Native_thread() ) + : _session(session), _pt(pt), _gate(gate) {} + + Pd_session_component const *session() const { return _session; } + Platform_thread const *pt() const { return _pt; } + Native_thread gate() const { return _gate; } + + void session(Pd_session_component *c) { _session = c; } + void pt(Platform_thread const *t) { _pt = t; } +}; + #endif /* _CORE__INCLUDE__CAP_INDEX_H_ */ diff --git a/repos/base-foc/src/core/include/platform_thread.h b/repos/base-foc/src/core/include/platform_thread.h index 570781074..4c7ff52aa 100644 --- a/repos/base-foc/src/core/include/platform_thread.h +++ b/repos/base-foc/src/core/include/platform_thread.h @@ -170,7 +170,7 @@ namespace Genode { * Return identification of thread when faulting */ unsigned long pager_object_badge() { - return (unsigned long) _thread.local.dst(); } + return (unsigned long) _thread.local.data()->kcap(); } /** * Set CPU quota of the thread to 'quota' @@ -187,11 +187,11 @@ namespace Genode { ** Fiasco-specific Accessors ** *******************************/ - Cap_mapping& thread() { return _thread; } - Cap_mapping& gate() { return _gate; } - const char *name() const { return _name; } - bool core_thread() const { return _core_thread; } - addr_t utcb() const { return _utcb; } + Cap_mapping const & thread() const { return _thread; } + Cap_mapping & gate() { return _gate; } + const char *name() const { return _name; } + bool core_thread() const { return _core_thread; } + addr_t utcb() const { return _utcb; } }; } diff --git a/repos/base-foc/src/core/ipc_pager.cc b/repos/base-foc/src/core/ipc_pager.cc index 32797cc18..3f2abc5fa 100644 --- a/repos/base-foc/src/core/ipc_pager.cc +++ b/repos/base-foc/src/core/ipc_pager.cc @@ -20,6 +20,7 @@ /* base-internal includes */ #include +#include /* Fiasco includes */ namespace Fiasco { @@ -139,6 +140,8 @@ void Ipc_pager::acknowledge_exception() Ipc_pager::Ipc_pager() -: Native_capability((Cap_index*)Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE]), - _badge(0) { } +: + Native_capability(*(Cap_index*)Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE]), + _badge(0) +{ } diff --git a/repos/base-foc/src/core/irq_session_component.cc b/repos/base-foc/src/core/irq_session_component.cc index dfb54cf32..9e2903b46 100644 --- a/repos/base-foc/src/core/irq_session_component.cc +++ b/repos/base-foc/src/core/irq_session_component.cc @@ -56,7 +56,7 @@ class Genode::Interrupt_handler : public Thread_deprecated<2048*sizeof(long)> static Fiasco::l4_cap_idx_t handler_cap() { static Interrupt_handler handler; - return handler._thread_cap.dst(); + return handler._thread_cap.data()->kcap(); } }; diff --git a/repos/base-foc/src/core/native_cpu_component.cc b/repos/base-foc/src/core/native_cpu_component.cc index fafa5c540..7aaac41a6 100644 --- a/repos/base-foc/src/core/native_cpu_component.cc +++ b/repos/base-foc/src/core/native_cpu_component.cc @@ -38,7 +38,7 @@ void Genode::Native_cpu_component::enable_vcpu(Genode::Thread_capability thread_ auto lambda = [&] (Cpu_thread_component *thread) { if (!thread) return; - l4_cap_idx_t tid = thread->platform_thread().thread().local.dst(); + l4_cap_idx_t tid = thread->platform_thread().thread().local.data()->kcap(); l4_msgtag_t tag = l4_thread_vcpu_control(tid, vcpu_state); if (l4_msgtag_has_error(tag)) @@ -86,7 +86,7 @@ Genode::Native_capability Genode::Native_cpu_component::alloc_irq() } /* construct cap and hold a reference in the irq container object */ - Genode::Native_capability cap(i); + Genode::Native_capability cap(*i); return (node->add(cap)) ? cap : Genode::Native_capability(); } diff --git a/repos/base-foc/src/core/pager_object.cc b/repos/base-foc/src/core/pager_object.cc index 4eb500117..ee2e03e69 100644 --- a/repos/base-foc/src/core/pager_object.cc +++ b/repos/base-foc/src/core/pager_object.cc @@ -14,6 +14,9 @@ /* core includes */ #include +/* base-internal includes */ +#include + /* Fiasco.OC includes */ namespace Fiasco { #include @@ -32,7 +35,7 @@ void Pager_object::wake_up() l4_utcb_mr()->mr[0] = 0; /* fault address */ l4_utcb_mr()->mr[1] = (l4_umword_t)this; /* instruction pointer */ - l4_ipc_call(cap().dst(), l4_utcb(), l4_msgtag(0, 2, 0, 0), L4_IPC_NEVER); + l4_ipc_call(cap().data()->kcap(), l4_utcb(), l4_msgtag(0, 2, 0, 0), L4_IPC_NEVER); } diff --git a/repos/base-foc/src/core/platform.cc b/repos/base-foc/src/core/platform.cc index de66f41bc..1dbac6c97 100644 --- a/repos/base-foc/src/core/platform.cc +++ b/repos/base-foc/src/core/platform.cc @@ -137,7 +137,7 @@ Platform::Sigma0::Sigma0(Cap_index* i) * We use the Pager_object here in a slightly different manner, * just to tunnel the pager cap to the Platform_thread::start method. */ - cap(i); + cap(*i); } @@ -158,8 +158,8 @@ Platform::Core_pager::Core_pager(Platform_pd *core_pd, Sigma0 *sigma0) using namespace Fiasco; l4_thread_control_start(); - l4_thread_control_pager(thread().local.dst()); - l4_thread_control_exc_handler(thread().local.dst()); + l4_thread_control_pager(thread().local.data()->kcap()); + l4_thread_control_exc_handler(thread().local.data()->kcap()); l4_msgtag_t tag = l4_thread_control_commit(L4_BASE_THREAD_CAP); if (l4_msgtag_has_error(tag)) PWRN("l4_thread_control_commit failed!"); diff --git a/repos/base-foc/src/core/platform_pd.cc b/repos/base-foc/src/core/platform_pd.cc index 3ee2bf20a..c80b80961 100644 --- a/repos/base-foc/src/core/platform_pd.cc +++ b/repos/base-foc/src/core/platform_pd.cc @@ -70,7 +70,7 @@ bool Platform_pd::bind_thread(Platform_thread *thread) /* if it's no core-thread we have to map parent and pager gate cap */ if (!thread->core_thread()) - _task.map(_task.local.dst()); + _task.map(_task.local.data()->kcap()); /* inform thread about binding */ thread->bind(this); @@ -100,13 +100,13 @@ void Platform_pd::assign_parent(Native_capability parent) if (_parent.remote == Fiasco::L4_INVALID_CAP && parent.valid()) { _parent.local = parent; _parent.remote = PARENT_CAP; - _parent.map(_task.local.dst()); + _parent.map(_task.local.data()->kcap()); } } Platform_pd::Platform_pd(Core_cap_index* i) -: _task(Native_capability(i), TASK_CAP) +: _task(Native_capability(*i), TASK_CAP) { for (unsigned i = 0; i < THREAD_MAX; i++) _threads[i] = (Platform_thread*) 0; @@ -122,7 +122,7 @@ Platform_pd::Platform_pd(Allocator *, char const *) l4_fpage_t utcb_area = l4_fpage(utcb_area_start(), log2(UTCB_AREA_SIZE), 0); l4_msgtag_t tag = l4_factory_create_task(L4_BASE_FACTORY_CAP, - _task.local.dst(), utcb_area); + _task.local.data()->kcap(), utcb_area); if (l4_msgtag_has_error(tag)) PERR("pd creation failed"); } diff --git a/repos/base-foc/src/core/platform_thread.cc b/repos/base-foc/src/core/platform_thread.cc index ec65c3e68..aea50d2b2 100644 --- a/repos/base-foc/src/core/platform_thread.cc +++ b/repos/base-foc/src/core/platform_thread.cc @@ -39,24 +39,24 @@ int Platform_thread::start(void *ip, void *sp) { /* map the pager cap */ if (_platform_pd) - _pager.map(_platform_pd->native_task().dst()); + _pager.map(_platform_pd->native_task().data()->kcap()); /* reserve utcb area and associate thread with this task */ l4_thread_control_start(); l4_thread_control_pager(_pager.remote); l4_thread_control_exc_handler(_pager.remote); - l4_thread_control_bind((l4_utcb_t *)_utcb, _platform_pd->native_task().dst()); - l4_msgtag_t tag = l4_thread_control_commit(_thread.local.dst()); + l4_thread_control_bind((l4_utcb_t *)_utcb, _platform_pd->native_task().data()->kcap()); + l4_msgtag_t tag = l4_thread_control_commit(_thread.local.data()->kcap()); if (l4_msgtag_has_error(tag)) { PWRN("l4_thread_control_commit for %lx failed!", - (unsigned long) _thread.local.dst()); + (unsigned long) _thread.local.data()->kcap()); return -1; } _state = RUNNING; /* set ip and sp and run the thread */ - tag = l4_thread_ex_regs(_thread.local.dst(), (l4_addr_t) ip, + tag = l4_thread_ex_regs(_thread.local.data()->kcap(), (l4_addr_t) ip, (l4_addr_t) sp, 0); if (l4_msgtag_has_error(tag)) { PWRN("l4_thread_ex_regs failed!"); @@ -92,7 +92,7 @@ void Platform_thread::pause() * The pager thread, which also acts as exception handler, will * leave the thread in exception state until, it gets woken again */ - l4_thread_ex_regs_ret(_thread.local.dst(), &_pager_obj->state.ip, + l4_thread_ex_regs_ret(_thread.local.data()->kcap(), &_pager_obj->state.ip, &_pager_obj->state.sp, &flags); /* @@ -111,14 +111,14 @@ void Platform_thread::pause() * the requested thread, and stored its thread state */ while (exc == _pager_obj->state.exceptions && !_pager_obj->state.in_exception) - l4_thread_switch(_thread.local.dst()); + l4_thread_switch(_thread.local.data()->kcap()); } } void Platform_thread::single_step(bool enabled) { - Fiasco::l4_cap_idx_t const tid = thread().local.dst(); + Fiasco::l4_cap_idx_t const tid = thread().local.data()->kcap(); enum { THREAD_SINGLE_STEP = 0x40000 }; int const flags = enabled ? THREAD_SINGLE_STEP : 0; @@ -148,8 +148,8 @@ void Platform_thread::resume() void Platform_thread::bind(Platform_pd *pd) { _platform_pd = pd; - _gate.map(pd->native_task().dst()); - _irq.map(pd->native_task().dst()); + _gate.map(pd->native_task().data()->kcap()); + _irq.map(pd->native_task().data()->kcap()); } @@ -160,12 +160,12 @@ void Platform_thread::unbind() l4_thread_control_start(); l4_thread_control_pager(_gate.remote); l4_thread_control_exc_handler(_gate.remote); - if (l4_msgtag_has_error(l4_thread_control_commit(_thread.local.dst()))) + if (l4_msgtag_has_error(l4_thread_control_commit(_thread.local.data()->kcap()))) PWRN("l4_thread_control_commit for %lx failed!", - (unsigned long) _thread.local.dst()); + (unsigned long) _thread.local.data()->kcap()); /* now force it into a pagefault */ - l4_thread_ex_regs(_thread.local.dst(), 0, 0, L4_THREAD_EX_REGS_CANCEL); + l4_thread_ex_regs(_thread.local.data()->kcap(), 0, 0, L4_THREAD_EX_REGS_CANCEL); } _platform_pd = (Platform_pd*) 0; @@ -204,7 +204,7 @@ Thread_state Platform_thread::state() void Platform_thread::cancel_blocking() { - l4_irq_trigger(_irq.local.dst()); + l4_irq_trigger(_irq.local.data()->kcap()); } @@ -217,9 +217,9 @@ void Platform_thread::affinity(Affinity::Location location) l4_sched_param_t params = l4_sched_param(_prio); params.affinity = l4_sched_cpu_set(cpu, 0, 1); l4_msgtag_t tag = l4_scheduler_run_thread(L4_BASE_SCHEDULER_CAP, - _thread.local.dst(), ¶ms); + _thread.local.data()->kcap(), ¶ms); if (l4_error(tag)) - PWRN("setting affinity of %lx to %d failed!", _thread.local.dst(), cpu); + PWRN("setting affinity of %lx to %d failed!", _thread.local.data()->kcap(), cpu); } @@ -239,7 +239,7 @@ static Rpc_cap_factory &thread_cap_factory() void Platform_thread::_create_thread() { l4_msgtag_t tag = l4_factory_create_thread(L4_BASE_FACTORY_CAP, - _thread.local.dst()); + _thread.local.data()->kcap()); if (l4_msgtag_has_error(tag)) PERR("cannot create more thread kernel-objects!"); @@ -252,22 +252,22 @@ void Platform_thread::_finalize_construction(const char *name) { /* create irq for new thread */ l4_msgtag_t tag = l4_factory_create_irq(L4_BASE_FACTORY_CAP, - _irq.local.dst()); + _irq.local.data()->kcap()); if (l4_msgtag_has_error(tag)) PWRN("creating thread's irq failed"); /* attach thread to irq */ - tag = l4_irq_attach(_irq.local.dst(), 0, _thread.local.dst()); + tag = l4_irq_attach(_irq.local.data()->kcap(), 0, _thread.local.data()->kcap()); if (l4_msgtag_has_error(tag)) PWRN("attaching thread's irq failed"); /* set human readable name in kernel debugger */ strncpy(_name, name, sizeof(_name)); - Fiasco::l4_debugger_set_object_name(_thread.local.dst(), name); + Fiasco::l4_debugger_set_object_name(_thread.local.data()->kcap(), name); /* set priority of thread */ l4_sched_param_t params = l4_sched_param(_prio); - l4_scheduler_run_thread(L4_BASE_SCHEDULER_CAP, _thread.local.dst(), + l4_scheduler_run_thread(L4_BASE_SCHEDULER_CAP, _thread.local.data()->kcap(), ¶ms); } @@ -289,7 +289,8 @@ Platform_thread::Platform_thread(size_t, const char *name, unsigned prio, _pager_obj(0), _prio(Cpu_session::scale_priority(DEFAULT_PRIORITY, prio)) { - ((Core_cap_index*)_thread.local.idx())->pt(this); + /* XXX remove const cast */ + ((Core_cap_index *)_thread.local.data())->pt(this); _create_thread(); _finalize_construction(name); affinity(location); @@ -300,14 +301,15 @@ Platform_thread::Platform_thread(Core_cap_index* thread, Core_cap_index* irq, const char *name) : _state(RUNNING), _core_thread(true), - _thread(Native_capability(thread), L4_BASE_THREAD_CAP), - _irq(Native_capability(irq)), + _thread(Native_capability(*thread), L4_BASE_THREAD_CAP), + _irq(Native_capability(*irq)), _utcb(0), _platform_pd(0), _pager_obj(0), _prio(Cpu_session::scale_priority(DEFAULT_PRIORITY, 0)) { - reinterpret_cast(_thread.local.idx())->pt(this); + /* XXX remove const cast */ + ((Core_cap_index *)_thread.local.data())->pt(this); _finalize_construction(name); } @@ -322,7 +324,8 @@ Platform_thread::Platform_thread(const char *name) _pager_obj(0), _prio(Cpu_session::scale_priority(DEFAULT_PRIORITY, 0)) { - ((Core_cap_index*)_thread.local.idx())->pt(this); + /* XXX remove const cast */ + ((Core_cap_index *)_thread.local.data())->pt(this); _create_thread(); _finalize_construction(name); } diff --git a/repos/base-foc/src/core/rpc_cap_factory.cc b/repos/base-foc/src/core/rpc_cap_factory.cc index 84346bddc..8672f2072 100644 --- a/repos/base-foc/src/core/rpc_cap_factory.cc +++ b/repos/base-foc/src/core/rpc_cap_factory.cc @@ -69,7 +69,7 @@ void Cap_mapping::map(Fiasco::l4_cap_idx_t task) return; l4_msgtag_t tag = l4_task_map(task, L4_BASE_TASK_CAP, - l4_obj_fpage(local.dst(), 0, L4_FPAGE_RWX), + l4_obj_fpage(local.data()->kcap(), 0, L4_FPAGE_RWX), ((l4_cap_idx_t)remote) | L4_ITEM_MAP); if (l4_msgtag_has_error(tag)) PERR("mapping cap failed"); @@ -77,7 +77,7 @@ void Cap_mapping::map(Fiasco::l4_cap_idx_t task) Cap_mapping::Cap_mapping(bool alloc, Fiasco::l4_cap_idx_t r) -: local(alloc ? _get_cap() : 0), remote(r) { } +: local(alloc ? *_get_cap() : *(Native_capability::Data *)nullptr), remote(r) { } Cap_mapping::Cap_mapping(Native_capability cap, Fiasco::l4_cap_idx_t r) @@ -100,7 +100,7 @@ Native_capability Rpc_cap_factory::alloc(Native_capability ep) try { using namespace Fiasco; - Core_cap_index* ref = static_cast(ep.idx()); + Core_cap_index const * ref = static_cast(ep.data()); ASSERT(ref && ref->pt(), "No valid platform_thread"); @@ -118,7 +118,7 @@ Native_capability Rpc_cap_factory::alloc(Native_capability ep) l4_msgtag_t tag = l4_factory_create_gate(L4_BASE_FACTORY_CAP, idx->kcap(), - ref->pt()->thread().local.dst(), id); + ref->pt()->thread().local.data()->kcap(), id); if (l4_msgtag_has_error(tag)) { PERR("l4_factory_create_gate failed!"); cap_map()->remove(idx); @@ -131,7 +131,7 @@ Native_capability Rpc_cap_factory::alloc(Native_capability ep) // XXX remove cast idx->session((Pd_session_component *)this); idx->pt(ref->pt()); - cap = Native_capability(idx); + cap = Native_capability(*idx); } catch (Cap_id_allocator::Out_of_ids) { PERR("Out of capability ids"); } @@ -155,8 +155,9 @@ void Rpc_cap_factory::free(Native_capability cap) if (!cap.valid()) return; - /* proof whether the capability was created by this cap_session */ - if (static_cast(cap.idx())->session() != (Pd_session_component *)this) return; + /* check whether the capability was created by this cap_session */ + if (static_cast(cap.data())->session() != (Pd_session_component *)this) + return; Entry * entry; _pool.apply(cap, [&] (Entry *e) { diff --git a/repos/base-foc/src/core/signal_source_component.cc b/repos/base-foc/src/core/signal_source_component.cc index 309f5f25e..8ec92bd49 100644 --- a/repos/base-foc/src/core/signal_source_component.cc +++ b/repos/base-foc/src/core/signal_source_component.cc @@ -48,7 +48,7 @@ void Signal_source_component::submit(Signal_context_component *context, _signal_queue.enqueue(context); /* wake up client */ - Fiasco::l4_irq_trigger(_blocking_semaphore.dst()); + Fiasco::l4_irq_trigger(_blocking_semaphore.data()->kcap()); } } @@ -70,14 +70,14 @@ Signal_source::Signal Signal_source_component::wait_for_signal() Signal_source_component::Signal_source_component(Rpc_entrypoint *ep) : - Signal_source_rpc_object(cap_map()->insert(platform_specific()->cap_id_alloc()->alloc())), + Signal_source_rpc_object(*cap_map()->insert(platform_specific()->cap_id_alloc()->alloc())), _entrypoint(ep), _finalizer(*this), _finalizer_cap(_entrypoint->manage(&_finalizer)) { using namespace Fiasco; l4_msgtag_t res = l4_factory_create_irq(L4_BASE_FACTORY_CAP, - _blocking_semaphore.dst()); + _blocking_semaphore.data()->kcap()); if (l4_error(res)) PERR("Allocation of irq object failed!"); } diff --git a/repos/base-foc/src/core/thread_start.cc b/repos/base-foc/src/core/thread_start.cc index b0eaa8ba3..215e2e424 100644 --- a/repos/base-foc/src/core/thread_start.cc +++ b/repos/base-foc/src/core/thread_start.cc @@ -61,7 +61,7 @@ void Thread::start() pt->pager(platform_specific()->core_pager()); - l4_utcb_tcr_u(foc_utcb)->user[UTCB_TCR_BADGE] = (unsigned long) pt->gate().local.idx(); + l4_utcb_tcr_u(foc_utcb)->user[UTCB_TCR_BADGE] = (unsigned long) pt->gate().local.data(); l4_utcb_tcr_u(foc_utcb)->user[UTCB_TCR_THREAD_OBJ] = (addr_t)this; pt->start((void *)_thread_start, stack_top()); diff --git a/repos/base-foc/src/include/base/internal/cap_alloc.h b/repos/base-foc/src/include/base/internal/cap_alloc.h index ec8d9f329..7b995af1a 100644 --- a/repos/base-foc/src/include/base/internal/cap_alloc.h +++ b/repos/base-foc/src/include/base/internal/cap_alloc.h @@ -14,12 +14,15 @@ #ifndef _INCLUDE__BASE__CAP_ALLOC_H_ #define _INCLUDE__BASE__CAP_ALLOC_H_ -#include +/* Genode includes */ #include #include #include #include +/* base-internal includes */ +#include + namespace Genode { /** @@ -117,8 +120,8 @@ namespace Genode { } } - addr_t idx_to_kcap(Cap_index *idx) { - return ((T*)idx - &_indices[0]) << Fiasco::L4_CAP_SHIFT; + addr_t idx_to_kcap(Cap_index const *idx) const { + return ((T const *)idx - &_indices[0]) << Fiasco::L4_CAP_SHIFT; } Cap_index* kcap_to_idx(addr_t kcap) { diff --git a/repos/base-foc/include/base/cap_map.h b/repos/base-foc/src/include/base/internal/cap_map.h similarity index 82% rename from repos/base-foc/include/base/cap_map.h rename to repos/base-foc/src/include/base/internal/cap_map.h index c6571e4d0..d8b2311de 100644 --- a/repos/base-foc/include/base/cap_map.h +++ b/repos/base-foc/src/include/base/internal/cap_map.h @@ -35,50 +35,12 @@ #include #include -namespace Genode -{ - /** - * A Cap_index represents a single mapping of the global capability id - * to the address in the local capability space. - * - * The address of the Cap_index determines the location in the - * (platform-specific) capability space of the process. Therefore it - * shouldn't be copied around, but only referenced by - * e.g. Native_capability. - */ - class Cap_index : public Avl_node, - Noncopyable - { - private: +/* base-internal includes */ +#include - enum { INVALID_ID = -1, UNUSED = 0 }; +namespace Genode { - uint8_t _ref_cnt; /* reference counter */ - uint16_t _id; /* global capability id */ - - public: - - Cap_index() : _ref_cnt(0), _id(INVALID_ID) { } - - bool valid() const { return _id != INVALID_ID; } - bool used() const { return _id != UNUSED; } - uint16_t id() const { return _id; } - void id(uint16_t id) { _id = id; } - uint8_t inc(); - uint8_t dec(); - addr_t kcap(); - - void* operator new (size_t size, Cap_index* idx) { return idx; } - void operator delete (void* idx) { memset(idx, 0, sizeof(Cap_index)); } - - - /************************ - ** Avl node interface ** - ************************/ - - bool higher(Cap_index *n); - Cap_index *find_by_id(uint16_t id); - }; + typedef Native_capability::Data Cap_index; /** @@ -129,7 +91,7 @@ namespace Genode * * \param idx pointer to the Cap_index object in question */ - virtual addr_t idx_to_kcap(Cap_index *idx) = 0; + virtual addr_t idx_to_kcap(Cap_index const *idx) const = 0; /** * Get the Cap_index object of a specific location diff --git a/repos/base-foc/src/include/base/internal/capability_data.h b/repos/base-foc/src/include/base/internal/capability_data.h new file mode 100644 index 000000000..c151cc3bf --- /dev/null +++ b/repos/base-foc/src/include/base/internal/capability_data.h @@ -0,0 +1,63 @@ +/* + * \brief Internal capability representation + * \author Norman Feske + * \author Stefan Kalkowski + * \date 2016-06-22 + */ + +/* + * 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__BASE__INTERNAL__CAPABILITY_DATA_H_ +#define _INCLUDE__BASE__INTERNAL__CAPABILITY_DATA_H_ + +/* Genode includes */ +#include + +/** + * A Native_capability::Data object represents a single mapping of the global + * capability id to the address in the local capability space. + * + * The address of the data object determines the location in the + * (platform-specific) capability space of the component. Therefore it + * shouldn't be copied around, but only referenced by e.g. Native_capability. + */ +class Genode::Native_capability::Data : public Avl_node, Noncopyable +{ + private: + + enum { INVALID_ID = -1, UNUSED = 0 }; + + uint8_t _ref_cnt; /* reference counter */ + uint16_t _id; /* global capability id */ + + public: + + Data() : _ref_cnt(0), _id(INVALID_ID) { } + + bool valid() const { return _id != INVALID_ID; } + bool used() const { return _id != UNUSED; } + uint16_t id() const { return _id; } + void id(uint16_t id) { _id = id; } + uint8_t inc(); + uint8_t dec(); + addr_t kcap() const; + + void* operator new (size_t size, Data* idx) { return idx; } + void operator delete (void* idx) { memset(idx, 0, sizeof(Data)); } + + + /************************ + ** Avl node interface ** + ************************/ + + bool higher(Data *n); + Data *find_by_id(uint16_t id); +}; + +#endif /* _INCLUDE__BASE__INTERNAL__CAPABILITY_DATA_H_ */ + diff --git a/repos/base-foc/src/include/base/internal/parent_cap.h b/repos/base-foc/src/include/base/internal/parent_cap.h index 9da1776fc..f7e53b582 100644 --- a/repos/base-foc/src/include/base/internal/parent_cap.h +++ b/repos/base-foc/src/include/base/internal/parent_cap.h @@ -24,6 +24,7 @@ /* base-internal includes */ #include +#include namespace Genode { @@ -43,7 +44,7 @@ namespace Genode { i = cap_map()->insert(local_name, Fiasco::PARENT_CAP); } - return reinterpret_cap_cast(Native_capability(i)); + return reinterpret_cap_cast(Native_capability(*i)); } } diff --git a/repos/base-foc/src/lib/base/cap_map.cc b/repos/base-foc/src/lib/base/cap_map.cc index d1f823269..47974fb8c 100644 --- a/repos/base-foc/src/lib/base/cap_map.cc +++ b/repos/base-foc/src/lib/base/cap_map.cc @@ -14,19 +14,15 @@ */ /* Genode includes */ -#include -#include - #include +#include /* base-internal includes */ #include +#include /* kernel includes */ -namespace Fiasco { -#include -#include -} +#include /*********************** @@ -50,7 +46,7 @@ Genode::Cap_index* Genode::Cap_index::find_by_id(Genode::uint16_t id) } -Genode::addr_t Genode::Cap_index::kcap() { +Genode::addr_t Genode::Cap_index::kcap() const { return cap_idx_alloc()->idx_to_kcap(this); } @@ -181,3 +177,28 @@ Genode::Capability_map* Genode::cap_map() static Genode::Capability_map map; return ↦ } + + +/********************** + ** Capability_space ** + **********************/ + +Fiasco::l4_cap_idx_t Genode::Capability_space::alloc_kcap() +{ + return cap_idx_alloc()->alloc_range(1)->kcap(); +} + + +void Genode::Capability_space::free_kcap(Fiasco::l4_cap_idx_t kcap) +{ + Genode::Cap_index* idx = Genode::cap_idx_alloc()->kcap_to_idx(kcap); + Genode::cap_idx_alloc()->free(idx, 1); +} + + +Fiasco::l4_cap_idx_t Genode::Capability_space::kcap(Native_capability cap) +{ + if (cap.data() == nullptr) + Genode::raw("Native_capability data is NULL!"); + return cap.data()->kcap(); +} diff --git a/repos/base-foc/src/lib/base/cap_map_remove.cc b/repos/base-foc/src/lib/base/cap_map_remove.cc index 90edcbf30..34599adba 100644 --- a/repos/base-foc/src/lib/base/cap_map_remove.cc +++ b/repos/base-foc/src/lib/base/cap_map_remove.cc @@ -13,7 +13,7 @@ * under the terms of the GNU General Public License version 2. */ -#include +#include void Genode::Capability_map::remove(Genode::Cap_index* i) { diff --git a/repos/base-foc/src/lib/base/capability.cc b/repos/base-foc/src/lib/base/capability.cc new file mode 100644 index 000000000..2daec69f8 --- /dev/null +++ b/repos/base-foc/src/lib/base/capability.cc @@ -0,0 +1,72 @@ +/* + * \brief Capability lifetime management + * \author Norman Feske + * \date 2015-05-06 + */ + +/* + * 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. + */ + +/* Fiasco includes */ +namespace Fiasco { +#include +} + +/* base-internal includes */ +#include +#include + +using namespace Genode; + + +Native_capability::Native_capability() { } + + +void Native_capability::_inc() +{ + if (_data) + _data->inc(); +} + + +void Native_capability::_dec() +{ + if (_data && !_data->dec()) + cap_map()->remove(_data); +} + + +long Native_capability::local_name() const +{ + return _data ? _data->id() : 0; +} + + +bool Native_capability::valid() const +{ + return (_data != 0) && _data->valid(); +} + + +Native_capability::Raw Native_capability::raw() const +{ + return { (unsigned long)local_name(), 0, 0, 0 }; +} + + +void Native_capability::print(Genode::Output &out) const +{ + using Genode::print; + + print(out, "cap<"); + if (_data) { + print(out, "kcap=", Hex(_data->kcap()), ",key=", (unsigned)_data->id()); + } else { + print(out, "invalid"); + } + print(out, ">"); +} diff --git a/repos/base-foc/src/lib/base/ipc.cc b/repos/base-foc/src/lib/base/ipc.cc index 242a9c121..8abe4dcbc 100644 --- a/repos/base-foc/src/lib/base/ipc.cc +++ b/repos/base-foc/src/lib/base/ipc.cc @@ -32,6 +32,7 @@ #include /* for 'thread_get_my_native_id()' */ #include #include +#include /* Fiasco.OC includes */ namespace Fiasco { @@ -168,8 +169,8 @@ static unsigned long extract_msg_from_utcb(l4_msgtag_t tag, */ for (unsigned i = 0; i < num_caps; i++) { if (caps[i].valid) { - rcv_msg.insert(Native_capability(cap_map()->insert_map(caps[i].badge, - caps[i].sel))); + rcv_msg.insert(Native_capability(*cap_map()->insert_map(caps[i].badge, + caps[i].sel))); } else { rcv_msg.insert(Native_capability()); } @@ -200,7 +201,7 @@ static l4_msgtag_t copy_msgbuf_to_utcb(Msgbuf_base &snd_msg, if (!cap.valid()) continue; - if (!l4_msgtag_label(l4_task_cap_valid(L4_BASE_TASK_CAP, cap.dst()))) + if (!l4_msgtag_label(l4_task_cap_valid(L4_BASE_TASK_CAP, cap.data()->kcap()))) cap = Native_capability(); } @@ -217,7 +218,7 @@ static l4_msgtag_t copy_msgbuf_to_utcb(Msgbuf_base &snd_msg, if (cap.valid()) { caps[i].valid = true; caps[i].badge = cap.local_name(); - caps[i].sel = cap.dst(); + caps[i].sel = cap.data()->kcap(); } } @@ -285,8 +286,11 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst, rcv_cap_sel += L4_CAP_SIZE; } + if (!dst.valid()) + throw Genode::Ipc_error(); + l4_msgtag_t const reply_tag = - l4_ipc_call(dst.dst(), l4_utcb(), call_tag, L4_IPC_NEVER); + l4_ipc_call(dst.data()->kcap(), l4_utcb(), call_tag, L4_IPC_NEVER); if (l4_ipc_error(reply_tag, l4_utcb()) == L4_IPC_RECANCELED) throw Genode::Blocking_canceled(); @@ -370,10 +374,40 @@ Genode::Rpc_request Genode::ipc_reply_wait(Reply_capability const &last_caller, Ipc_server::Ipc_server() : - Native_capability((Cap_index*)Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE]) + Native_capability(*(Cap_index*)Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE]) { Thread::myself()->native_thread().rcv_window.init(); } Ipc_server::~Ipc_server() { } + + +/******************** + ** Receive_window ** + ********************/ + +Receive_window::~Receive_window() +{ + if (_rcv_idx_base) + cap_idx_alloc()->free(_rcv_idx_base, MAX_CAPS_PER_MSG); +} + + +void Receive_window::init() +{ + _rcv_idx_base = cap_idx_alloc()->alloc_range(MAX_CAPS_PER_MSG); +} + + +addr_t Receive_window::rcv_cap_sel_base() +{ + return _rcv_idx_base->kcap(); +} + + +addr_t Receive_window::rcv_cap_sel(unsigned i) +{ + return rcv_cap_sel_base() + i*Fiasco::L4_CAP_SIZE; +} + diff --git a/repos/base-foc/src/lib/base/signal_source_client.cc b/repos/base-foc/src/lib/base/signal_source_client.cc new file mode 100644 index 000000000..060c19e2c --- /dev/null +++ b/repos/base-foc/src/lib/base/signal_source_client.cc @@ -0,0 +1,77 @@ +/* + * \brief Fiasco.OC-specific signal-source client interface + * \author Norman Feske + * \author Stefan Kalkowski + * \date 2010-02-03 + */ + +/* + * 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. + */ + +/* Genode includes */ +#include +#include +#include + +/* base-internal includes */ +#include +#include + +/* Fiasco includes */ +namespace Fiasco { +#include +} + +using namespace Genode; + + +Signal_source_client::Signal_source_client(Capability cap) +: + Rpc_client(static_cap_cast(cap)) +{ + using namespace Fiasco; + + /* request mapping of semaphore capability selector */ + _sem = call(); + + l4_msgtag_t tag = l4_irq_attach(_sem.data()->kcap(), 0, + Thread::myself()->native_thread().kcap); + if (l4_error(tag)) + Genode::raw("l4_irq_attach failed with ", l4_error(tag)); +} + + +Signal_source_client::~Signal_source_client() +{ + Fiasco::l4_irq_detach(_sem.data()->kcap()); +} + + +__attribute__((optimize("-fno-omit-frame-pointer"))) +__attribute__((noinline)) +Signal_source_client::Signal Signal_source_client::wait_for_signal() +{ + using namespace Fiasco; + + Signal signal; + do { + + /* block on semaphore until signal context was submitted */ + l4_irq_receive(_sem.data()->kcap(), L4_IPC_NEVER); + + /* + * The following request will return immediately and either + * return a valid or a null signal. The latter may happen in + * the case a submitted signal context was destroyed (by the + * submitter) before we have a chance to raise our request. + */ + signal = call(); + + } while (!signal.imprint()); + + return signal; +} diff --git a/repos/base-foc/src/lib/base/spin_lock.cc b/repos/base-foc/src/lib/base/spin_lock.cc index eacb70f41..36eec1252 100644 --- a/repos/base-foc/src/lib/base/spin_lock.cc +++ b/repos/base-foc/src/lib/base/spin_lock.cc @@ -13,10 +13,8 @@ * under the terms of the GNU General Public License version 2. */ -/* Genode includes */ -#include - /* base-internal includes */ +#include #include diff --git a/repos/base-foc/src/lib/base/thread_bootstrap.cc b/repos/base-foc/src/lib/base/thread_bootstrap.cc index 14fa7c38e..2f6cca2bc 100644 --- a/repos/base-foc/src/lib/base/thread_bootstrap.cc +++ b/repos/base-foc/src/lib/base/thread_bootstrap.cc @@ -20,6 +20,7 @@ /* base-internal includes */ #include +#include /***************************** diff --git a/repos/base-foc/src/lib/base/thread_start.cc b/repos/base-foc/src/lib/base/thread_start.cc index 271831830..1a8170cb9 100644 --- a/repos/base-foc/src/lib/base/thread_start.cc +++ b/repos/base-foc/src/lib/base/thread_start.cc @@ -23,6 +23,7 @@ /* base-internal includes */ #include +#include /* Fiasco includes */ namespace Fiasco { diff --git a/repos/base-foc/src/test/cap_integrity/main.cc b/repos/base-foc/src/test/cap_integrity/main.cc index e1e23d2df..761a23ad3 100644 --- a/repos/base-foc/src/test/cap_integrity/main.cc +++ b/repos/base-foc/src/test/cap_integrity/main.cc @@ -13,8 +13,13 @@ * under the terms of the GNU General Public License version 2. */ +/* Genode includes */ #include #include +#include + +/* base-internal includes */ +#include /* cap_idx_alloc */ using namespace Genode; using namespace Fiasco; @@ -26,7 +31,7 @@ int main(int argc, char **argv) enum { COUNT = 1000 }; Cap_index* idx = cap_idx_alloc()->alloc_range(COUNT); - Fiasco::l4_cap_idx_t tid = env()->ram_session_cap().dst(); + Fiasco::l4_cap_idx_t tid = Capability_space::kcap(env()->ram_session_cap()); /* try the first 1000 local name IDs */ for (int local_name = 0; local_name < COUNT; local_name++, idx++) { @@ -36,7 +41,7 @@ int main(int argc, char **argv) idx->kcap() | L4_ITEM_MAP); Log_session_capability log_session_cap = - reinterpret_cap_cast(Native_capability(idx)); + reinterpret_cap_cast(Native_capability(*idx)); Log_session_client log_session_client(log_session_cap); try { log_session_client.write("test message"); diff --git a/repos/base-foc/src/test/cap_integrity/target.mk b/repos/base-foc/src/test/cap_integrity/target.mk index 403543f96..8b836382e 100644 --- a/repos/base-foc/src/test/cap_integrity/target.mk +++ b/repos/base-foc/src/test/cap_integrity/target.mk @@ -1,4 +1,5 @@ REQUIRES = foc TARGET = test-cap_integrity SRC_CC = main.cc +INC_DIR += $(REP_DIR)/src/include LIBS = base diff --git a/repos/base-hw/include/base/native_capability.h b/repos/base-hw/include/base/native_capability.h deleted file mode 100644 index c21d298c4..000000000 --- a/repos/base-hw/include/base/native_capability.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * \brief Native capability of base-hw - * \author Stefan Kalkowski - * \date 2015-05-15 - */ - -/* - * 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__BASE__NATIVE_CAPABILITY_H_ -#define _INCLUDE__BASE__NATIVE_CAPABILITY_H_ - -/* Genode includes */ -#include -#include - -namespace Genode { class Native_capability; } - - -class Genode::Native_capability -{ - public: - - using Dst = Kernel::capid_t; - - private: - - Dst _dst; - - void _inc() const; - void _dec() const; - - public: - - struct Raw { }; - - /** - * Create an invalid capability - */ - Native_capability() : _dst(Kernel::cap_id_invalid()) { } - - /** - * Create a capability out of a kernel's capability id - */ - Native_capability(Kernel::capid_t dst) : _dst(dst) { _inc(); } - - /** - * Create a capability from another one - */ - Native_capability(const Native_capability &o) : _dst(o._dst) { _inc(); } - - ~Native_capability() { _dec(); } - - /** - * Returns true if it is a valid capability otherwise false - */ - bool valid() const { return (_dst != Kernel::cap_id_invalid()); } - - - /***************** - ** Accessors ** - *****************/ - - addr_t local_name() const { return _dst; } - Dst dst() const { return _dst; } - - - /************************** - ** Operator overloads ** - **************************/ - - bool operator==(const Native_capability &o) const { - return _dst == _dst; } - - Native_capability& operator=(const Native_capability &o) - { - if (this == &o) return *this; - _dec(); - _dst = o._dst; - _inc(); - return *this; - } - - Raw raw() const { return Raw(); } -}; - -#endif /* _INCLUDE__BASE__NATIVE_CAPABILITY_H_ */ diff --git a/repos/base-hw/src/core/capability.cc b/repos/base-hw/src/core/capability.cc index 6165eee90..71bad5dca 100644 --- a/repos/base-hw/src/core/capability.cc +++ b/repos/base-hw/src/core/capability.cc @@ -10,8 +10,29 @@ * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. */ -#include -void Genode::Native_capability::_inc() const { } +#include -void Genode::Native_capability::_dec() const { } +using namespace Genode; + + +Native_capability::Native_capability() { } + + +void Native_capability::_inc() { } +void Native_capability::_dec() { } + + +long Native_capability::local_name() const +{ + return (long)_data; +} + + +bool Native_capability::valid() const +{ + return (addr_t)_data != Kernel::cap_id_invalid(); +} + + +Native_capability::Raw Native_capability::raw() const { return { 0, 0, 0, 0 }; } diff --git a/repos/base-hw/src/core/include/kernel/configuration.h b/repos/base-hw/src/core/include/kernel/configuration.h index 8400e650a..74efdaae1 100644 --- a/repos/base-hw/src/core/include/kernel/configuration.h +++ b/repos/base-hw/src/core/include/kernel/configuration.h @@ -14,6 +14,8 @@ #ifndef _CORE__INCLUDE__KERNEL__CONFIGURATION_H_ #define _CORE__INCLUDE__KERNEL__CONFIGURATION_H_ +#include + namespace Kernel { enum { diff --git a/repos/base-hw/src/core/include/object.h b/repos/base-hw/src/core/include/object.h index 69560fd2b..f5398cc11 100644 --- a/repos/base-hw/src/core/include/object.h +++ b/repos/base-hw/src/core/include/object.h @@ -14,13 +14,17 @@ #ifndef _CORE__INCLUDE__OBJECT_H_ #define _CORE__INCLUDE__OBJECT_H_ -#include -#include -#include +/* Genode includes */ #include -namespace Genode -{ +/* base-internal includes */ +#include + +/* base-hw includes */ +#include +#include + +namespace Genode { /** * Represents a kernel object in core * @@ -51,9 +55,11 @@ class Genode::Kernel_object */ template Kernel_object(bool syscall, ARGS &&... args) - : _cap(syscall ? T::syscall_create(&_data, args...) - : Kernel::cap_id_invalid()) { - if (!syscall) construct_at(&_data, args...); } + : _cap(Capability_space::import(syscall ? T::syscall_create(&_data, args...) + : Kernel::cap_id_invalid())) + { + if (!syscall) construct_at(&_data, args...); + } ~Kernel_object() { T::syscall_destroy(kernel_object()); } @@ -66,7 +72,7 @@ class Genode::Kernel_object bool create(ARGS &&... args) { if (_cap.valid()) return false; - _cap = T::syscall_create(&_data, args...); + _cap = Capability_space::import(T::syscall_create(&_data, args...)); return _cap.valid(); } }; diff --git a/repos/base-hw/src/core/include/platform_pd.h b/repos/base-hw/src/core/include/platform_pd.h index 9b1e69f71..3b5695f38 100644 --- a/repos/base-hw/src/core/include/platform_pd.h +++ b/repos/base-hw/src/core/include/platform_pd.h @@ -40,7 +40,7 @@ namespace Genode { class Platform_thread; /* forward declaration */ - class Capability_space; + class Cap_space; /** * Platform specific part of a Genode protection domain @@ -128,7 +128,7 @@ class Hw::Address_space : public Genode::Address_space }; -class Genode::Capability_space +class Genode::Cap_space { private: @@ -142,7 +142,7 @@ class Genode::Capability_space public: - Capability_space(); + Cap_space(); Cap_slab & capability_slab() { return _slab; } @@ -151,7 +151,7 @@ class Genode::Capability_space class Genode::Platform_pd : public Hw::Address_space, - public Genode::Capability_space, + public Genode::Cap_space, public Kernel_object { private: diff --git a/repos/base-hw/src/core/include/rpc_cap_factory.h b/repos/base-hw/src/core/include/rpc_cap_factory.h index 4db2f2b67..552e1e87d 100644 --- a/repos/base-hw/src/core/include/rpc_cap_factory.h +++ b/repos/base-hw/src/core/include/rpc_cap_factory.h @@ -20,11 +20,15 @@ #include #include #include +#include /* core-local includes */ #include #include +/* base-internal includes */ +#include + namespace Genode { class Rpc_cap_factory; } @@ -86,10 +90,11 @@ class Genode::Rpc_cap_factory construct_at(obj); /* create kernel object via syscall */ - obj->cap = Kernel::new_obj(obj->data, ep.dst()); + Kernel::capid_t capid = Kernel::new_obj(obj->data, Capability_space::capid(ep)); + obj->cap = Capability_space::import(capid); if (!obj->cap.valid()) { - PWRN("Invalid entrypoint %u for allocating a capability!", - ep.dst()); + raw("Invalid entrypoint ", (addr_t)Capability_space::capid(ep), + " for allocating a capability!"); destroy(&_slab, obj); return Native_capability(); } @@ -104,7 +109,7 @@ class Genode::Rpc_cap_factory Lock::Guard guard(_lock); for (Kobject * obj = _list.first(); obj; obj = obj->next()) { - if (obj->cap.dst() == cap.dst()) { + if (obj->cap.data() == cap.data()) { Kernel::delete_obj(obj->data); _list.remove(obj); destroy(&_slab, obj); diff --git a/repos/base-hw/src/core/include/spec/x86_64/muen/vm_session_component.h b/repos/base-hw/src/core/include/spec/x86_64/muen/vm_session_component.h index cf74c2581..b019d6b70 100644 --- a/repos/base-hw/src/core/include/spec/x86_64/muen/vm_session_component.h +++ b/repos/base-hw/src/core/include/spec/x86_64/muen/vm_session_component.h @@ -50,7 +50,7 @@ class Genode::Vm_session_component void exception_handler(Signal_context_capability handler) { - if (!create(&_state, handler.dst(), nullptr)) + if (!create(&_state, Capability_space::capid(handler), nullptr)) PWRN("Cannot instantiate vm kernel object, " "invalid signal context?"); } diff --git a/repos/base-hw/src/core/include/util.h b/repos/base-hw/src/core/include/util.h index 9704d862c..3a39eec79 100644 --- a/repos/base-hw/src/core/include/util.h +++ b/repos/base-hw/src/core/include/util.h @@ -21,6 +21,9 @@ /* base-internal includes */ #include +/* base-hw includes */ +#include + namespace Genode { struct Native_region diff --git a/repos/base-hw/src/core/irq_session_component.cc b/repos/base-hw/src/core/irq_session_component.cc index 670859492..8794af7b8 100644 --- a/repos/base-hw/src/core/irq_session_component.cc +++ b/repos/base-hw/src/core/irq_session_component.cc @@ -20,6 +20,9 @@ #include #include +/* base-internal includes */ +#include + using namespace Genode; @@ -47,7 +50,8 @@ void Irq_session_component::sigh(Signal_context_capability cap) _sig_cap = cap; - if (Kernel::new_irq((addr_t)&_kernel_object, _irq_number, _sig_cap.dst())) + if (Kernel::new_irq((addr_t)&_kernel_object, _irq_number, + Capability_space::capid(_sig_cap))) PWRN("invalid signal handler for IRQ %u", _irq_number); } diff --git a/repos/base-hw/src/core/pager.cc b/repos/base-hw/src/core/pager.cc index 837563a47..b108be7b3 100644 --- a/repos/base-hw/src/core/pager.cc +++ b/repos/base-hw/src/core/pager.cc @@ -19,6 +19,9 @@ #include #include +/* base-internal includes */ +#include + using namespace Genode; @@ -65,7 +68,7 @@ void Ipc_pager::set_reply_mapping(Mapping m) { _mapping = m; } void Pager_object::wake_up() { using Object = Kernel_object; - Kernel::ack_signal(Object::_cap.dst()); + Kernel::ack_signal(Capability_space::capid(Object::_cap)); } void Pager_object::start_paging(Kernel::Signal_receiver * receiver) diff --git a/repos/base-hw/src/core/platform_pd.cc b/repos/base-hw/src/core/platform_pd.cc index bd6c2b9f9..c2c473d8c 100644 --- a/repos/base-hw/src/core/platform_pd.cc +++ b/repos/base-hw/src/core/platform_pd.cc @@ -103,15 +103,14 @@ Hw::Address_space::~Address_space() } -/************************************* - ** Capability_space implementation ** - *************************************/ +/****************************** + ** Cap_space implementation ** + ******************************/ -Capability_space::Capability_space() -: _slab(nullptr, &_initial_sb) { } +Cap_space::Cap_space() : _slab(nullptr, &_initial_sb) { } -void Capability_space::upgrade_slab(Allocator &alloc) +void Cap_space::upgrade_slab(Allocator &alloc) { for (;;) { void *block = nullptr; diff --git a/repos/base-hw/src/core/platform_thread.cc b/repos/base-hw/src/core/platform_thread.cc index 3e1af2bd3..78e5a99c1 100644 --- a/repos/base-hw/src/core/platform_thread.cc +++ b/repos/base-hw/src/core/platform_thread.cc @@ -22,6 +22,7 @@ /* base-internal includes */ #include +#include /* kernel includes */ #include @@ -171,10 +172,10 @@ int Platform_thread::start(void * const ip, void * const sp) /* reset capability counter */ utcb->cap_cnt(0); - utcb->cap_add(_cap.dst()); + utcb->cap_add(Capability_space::capid(_cap)); if (_main_thread) { - utcb->cap_add(_pd->parent().dst()); - utcb->cap_add(_utcb.dst()); + utcb->cap_add(Capability_space::capid(_pd->parent())); + utcb->cap_add(Capability_space::capid(_utcb)); } Kernel::start_thread(kernel_object(), cpu, _pd->kernel_pd(), _utcb_core_addr); @@ -187,7 +188,8 @@ void Platform_thread::pager(Pager_object * const pager) using namespace Kernel; if (route_thread_event(kernel_object(), Thread_event_id::FAULT, - pager ? pager->cap().dst() : cap_id_invalid())) + pager ? Capability_space::capid(pager->cap()) + : cap_id_invalid())) PERR("failed to set pager object for thread %s", label()); _pager = pager; diff --git a/repos/base-hw/src/core/region_map_support.cc b/repos/base-hw/src/core/region_map_support.cc index 29997b5f8..e370f7ea6 100644 --- a/repos/base-hw/src/core/region_map_support.cc +++ b/repos/base-hw/src/core/region_map_support.cc @@ -20,6 +20,8 @@ #include #include +/* base-internal includes */ + using namespace Genode; @@ -45,7 +47,7 @@ void Pager_entrypoint::entry() while (1) { /* receive fault */ - if (Kernel::await_signal(_cap.dst())) continue; + if (Kernel::await_signal(Capability_space::capid(_cap))) continue; Untyped_capability cap = (*(Pager_object**)Thread::myself()->utcb()->data())->cap(); diff --git a/repos/base-hw/src/core/spec/arm_v7/trustzone/vm_session_component.cc b/repos/base-hw/src/core/spec/arm_v7/trustzone/vm_session_component.cc index a4377e4cf..4ffb813ee 100644 --- a/repos/base-hw/src/core/spec/arm_v7/trustzone/vm_session_component.cc +++ b/repos/base-hw/src/core/spec/arm_v7/trustzone/vm_session_component.cc @@ -20,7 +20,9 @@ using namespace Genode; void Vm_session_component::exception_handler(Signal_context_capability handler) { - if (!create((void*)_ds.core_local_addr(), handler.dst(), nullptr)) { + if (!create((void*)_ds.core_local_addr(), Capability_space::capid(handler), + nullptr)) + { PWRN("Cannot instantiate vm kernel object twice," "or invalid signal context?"); } diff --git a/repos/base-hw/src/core/spec/arm_v7/virtualization/vm_session_component.cc b/repos/base-hw/src/core/spec/arm_v7/virtualization/vm_session_component.cc index 4dcbf5b5a..22b5013c5 100644 --- a/repos/base-hw/src/core/spec/arm_v7/virtualization/vm_session_component.cc +++ b/repos/base-hw/src/core/spec/arm_v7/virtualization/vm_session_component.cc @@ -28,7 +28,7 @@ void Vm_session_component::exception_handler(Signal_context_capability handler) Core_mem_allocator * cma = static_cast(platform()->core_mem_alloc()); - if (!create((void*)_ds.core_local_addr(), handler.dst(), + if (!create((void*)_ds.core_local_addr(), Capability_space::capid(handler), cma->phys_addr(_table))) PWRN("Cannot instantiate vm kernel object, invalid signal context?"); } diff --git a/repos/base-hw/src/core/thread_start.cc b/repos/base-hw/src/core/thread_start.cc index 1a297936e..ade5500fe 100644 --- a/repos/base-hw/src/core/thread_start.cc +++ b/repos/base-hw/src/core/thread_start.cc @@ -69,5 +69,5 @@ void Thread::_init_platform_thread(size_t, Type type) max(sizeof(Native_utcb) / get_page_size(), (size_t)1)); /* adjust initial object state in case of a main thread */ - native_thread().cap = Hw::_main_thread_cap.dst(); + native_thread().cap = Hw::_main_thread_cap; } diff --git a/repos/base-hw/src/include/base/internal/capability_space.h b/repos/base-hw/src/include/base/internal/capability_space.h new file mode 100644 index 000000000..d981428bc --- /dev/null +++ b/repos/base-hw/src/include/base/internal/capability_space.h @@ -0,0 +1,40 @@ +/* + * \brief Capability helper + * \author Norman Feske + * \date 2016-06-22 + */ + +/* + * 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__BASE__INTERNAL__CAPABILITY_SPACE_H_ +#define _INCLUDE__BASE__INTERNAL__CAPABILITY_SPACE_H_ + +/* Genode includes */ +#include + +/* base-hw includes */ +#include + +namespace Genode { namespace Capability_space { + + /** + * Return kernel capability selector of Genode capability + */ + static inline Kernel::capid_t capid(Native_capability const &cap) + { + addr_t const index = (addr_t)cap.data(); + return index; + } + + static inline Native_capability import(Kernel::capid_t capid) + { + return Native_capability(*(Native_capability::Data *)(addr_t)capid); + } +} } + +#endif /* _INCLUDE__BASE__INTERNAL__CAPABILITY_SPACE_H_ */ diff --git a/repos/base-hw/src/include/base/internal/lock_helper.h b/repos/base-hw/src/include/base/internal/lock_helper.h index 44e49a684..79bf69cb5 100644 --- a/repos/base-hw/src/include/base/internal/lock_helper.h +++ b/repos/base-hw/src/include/base/internal/lock_helper.h @@ -17,9 +17,11 @@ /* Genode includes */ #include -namespace Hw { - extern Genode::Untyped_capability _main_thread_cap; -} +/* base-internal includes */ +#include + +namespace Hw { extern Genode::Untyped_capability _main_thread_cap; } + /** * Yield execution time-slice of current thread @@ -34,7 +36,8 @@ static inline void thread_yield() { static inline Kernel::capid_t native_thread_id(Genode::Thread * const t) { - return t ? t->native_thread().cap.dst() : Hw::_main_thread_cap.dst(); + using Genode::Capability_space::capid; + return t ? capid(t->native_thread().cap) : capid(Hw::_main_thread_cap); } diff --git a/repos/base-hw/src/lib/base/capability.cc b/repos/base-hw/src/lib/base/capability.cc index 02d664a97..ba9e16980 100644 --- a/repos/base-hw/src/lib/base/capability.cc +++ b/repos/base-hw/src/lib/base/capability.cc @@ -17,24 +17,63 @@ /* base-internal includes */ #include -static volatile int spinlock = SPINLOCK_UNLOCKED; -static Genode::uint8_t ref_counter[1 << (sizeof(Kernel::capid_t)*8)]; +/* kernel includes */ +#include -void Genode::Native_capability::_inc() const +using namespace Genode; + +static volatile int spinlock = SPINLOCK_UNLOCKED; + +static uint8_t ref_counter[1 << (sizeof(Kernel::capid_t)*8)]; + + +Native_capability::Native_capability() { } + + +void Native_capability::_inc() { if (!valid()) return; spinlock_lock(&spinlock); - ref_counter[_dst]++; + ref_counter[(addr_t)_data]++; spinlock_unlock(&spinlock); } -void Genode::Native_capability::_dec() const +void Native_capability::_dec() { if (!valid()) return; spinlock_lock(&spinlock); - if (!--ref_counter[_dst]) { Kernel::delete_cap(_dst); } + if (!--ref_counter[(addr_t)_data]) { Kernel::delete_cap((addr_t)_data); } spinlock_unlock(&spinlock); } + + +long Native_capability::local_name() const +{ + return (long)_data; +} + + +bool Native_capability::valid() const +{ + return (addr_t)_data != Kernel::cap_id_invalid(); +} + + +Native_capability::Raw Native_capability::raw() const { return { 0, 0, 0, 0 }; } + + +void Native_capability::print(Genode::Output &out) const +{ + using Genode::print; + + print(out, "cap<"); + if (_data) { + print(out, (addr_t)_data); + } else { + print(out, "invalid"); + } + print(out, ">"); +} diff --git a/repos/base-hw/src/lib/base/ipc.cc b/repos/base-hw/src/lib/base/ipc.cc index 33c622695..8603d6469 100644 --- a/repos/base-hw/src/lib/base/ipc.cc +++ b/repos/base-hw/src/lib/base/ipc.cc @@ -25,6 +25,7 @@ #include #include #include +#include /* base-hw includes */ #include @@ -44,7 +45,7 @@ static inline void copy_msg_to_utcb(Msgbuf_base const &snd_msg, Native_utcb &utc snd_msg.used_caps()); for (unsigned i = 0; i < num_caps; i++) - utcb.cap_set(i, snd_msg.cap(i).dst()); + utcb.cap_set(i, Capability_space::capid(snd_msg.cap(i))); utcb.cap_cnt(num_caps); @@ -68,9 +69,9 @@ static inline void copy_utcb_to_msg(Native_utcb const &utcb, Msgbuf_base &rcv_ms utcb.cap_cnt()); for (unsigned i = 0; i < num_caps; i++) { - rcv_msg.cap(i) = utcb.cap_get(i); + rcv_msg.cap(i) = Capability_space::import(utcb.cap_get(i)); if (rcv_msg.cap(i).valid()) - Kernel::ack_cap(rcv_msg.cap(i).dst()); + Kernel::ack_cap(Capability_space::capid(rcv_msg.cap(i))); } rcv_msg.used_caps(num_caps); @@ -100,8 +101,7 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst, copy_msg_to_utcb(snd_msg, *Thread::myself()->utcb()); - switch (Kernel::send_request_msg(dst.dst(), - rcv_caps)) { + switch (Kernel::send_request_msg(Capability_space::capid(dst), rcv_caps)) { case -1: throw Blocking_canceled(); case -2: throw Allocator::Out_of_memory(); default: diff --git a/repos/base-hw/src/lib/base/signal.cc b/repos/base-hw/src/lib/base/signal.cc index e47b5e128..6d058fb86 100644 --- a/repos/base-hw/src/lib/base/signal.cc +++ b/repos/base-hw/src/lib/base/signal.cc @@ -20,9 +20,7 @@ /* base-internal includes */ #include - -/* base-hw includes */ -#include +#include using namespace Genode; @@ -54,7 +52,7 @@ void Signal_transmitter::submit(unsigned cnt) { Trace::Signal_submit trace_event(cnt); } - Kernel::submit_signal(_context.dst(), cnt); + Kernel::submit_signal(Capability_space::capid(_context), cnt); } @@ -85,7 +83,7 @@ void Signal_receiver::_platform_destructor() void Signal_receiver::_platform_begin_dissolve(Signal_context * const c) { - Kernel::kill_signal_context(c->_cap.dst()); + Kernel::kill_signal_context(Capability_space::capid(c->_cap)); } void Signal_receiver::_platform_finish_dissolve(Signal_context *) { } @@ -119,7 +117,7 @@ Signal_context_capability Signal_receiver::manage(Signal_context * const c) void Signal_receiver::block_for_signal() { /* wait for a signal */ - if (Kernel::await_signal(_cap.dst())) { + if (Kernel::await_signal(Capability_space::capid(_cap))) { PERR("failed to receive signal"); return; } @@ -135,7 +133,7 @@ void Signal_receiver::block_for_signal() context->_curr_signal = Signal::Data(context, num); } /* end kernel-aided life-time management */ - Kernel::ack_signal(data->context->_cap.dst()); + Kernel::ack_signal(Capability_space::capid(data->context->_cap)); } diff --git a/repos/base-hw/src/lib/base/thread_bootstrap.cc b/repos/base-hw/src/lib/base/thread_bootstrap.cc index df683f1d9..a308e5118 100644 --- a/repos/base-hw/src/lib/base/thread_bootstrap.cc +++ b/repos/base-hw/src/lib/base/thread_bootstrap.cc @@ -20,9 +20,7 @@ /* base-internal includes */ #include #include - -/* base-hw includes */ -#include +#include using namespace Genode; @@ -47,10 +45,13 @@ void prepare_init_main_thread() * before the UTCB gets polluted by the following function calls. */ Native_utcb * utcb = Thread::myself()->utcb(); - _parent_cap = utcb->cap_get(Native_utcb::PARENT); - Untyped_capability ds_cap(utcb->cap_get(Native_utcb::UTCB_DATASPACE)); + _parent_cap = Capability_space::import(utcb->cap_get(Native_utcb::PARENT)); + + Untyped_capability ds_cap = + Capability_space::import(utcb->cap_get(Native_utcb::UTCB_DATASPACE)); _main_thread_utcb_ds = reinterpret_cap_cast(ds_cap); - _main_thread_cap = utcb->cap_get(Native_utcb::THREAD_MYSELF); + + _main_thread_cap = Capability_space::import(utcb->cap_get(Native_utcb::THREAD_MYSELF)); } @@ -76,5 +77,8 @@ void Thread::_thread_start() Genode::sleep_forever(); } -void Thread::_thread_bootstrap() { - native_thread().cap = myself()->utcb()->cap_get(Native_utcb::THREAD_MYSELF); } +void Thread::_thread_bootstrap() +{ + Kernel::capid_t capid = myself()->utcb()->cap_get(Native_utcb::THREAD_MYSELF); + native_thread().cap = Capability_space::import(capid); +} diff --git a/repos/base-linux/include/base/native_capability.h b/repos/base-linux/include/base/native_capability.h deleted file mode 100644 index 512d15788..000000000 --- a/repos/base-linux/include/base/native_capability.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * \brief Native capability type - * \author Norman Feske - * \date 2007-10-15 - */ - -/* - * Copyright (C) 2007-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__BASE__NATIVE_CAPABILITY_H_ -#define _INCLUDE__BASE__NATIVE_CAPABILITY_H_ - -#include -#include -#include - -namespace Genode { - - struct Cap_dst_policy - { - struct Dst - { - int socket; - - /** - * Default constructor creates invalid destination - */ - Dst() : socket(-1) { } - - explicit Dst(int socket) : socket(socket) { } - }; - - static bool valid(Dst id) { return id.socket != -1; } - static Dst invalid() { return Dst(); } - static void copy(void* dst, Native_capability_tpl* src); - }; - - typedef Native_capability_tpl Native_capability; -} - -#endif /* _INCLUDE__BASE__NATIVE_CAPABILITY_H_ */ diff --git a/repos/base-linux/lib/mk/base-common.mk b/repos/base-linux/lib/mk/base-common.mk index 2fa17ca2d..c45aaddcf 100644 --- a/repos/base-linux/lib/mk/base-common.mk +++ b/repos/base-linux/lib/mk/base-common.mk @@ -12,3 +12,4 @@ SRC_CC += region_map_mmap.cc debug.cc SRC_CC += signal_submit.cc SRC_CC += rpc_dispatch_loop.cc SRC_CC += thread_env.cc +SRC_CC += capability.cc diff --git a/repos/base-linux/lib/mk/base.mk b/repos/base-linux/lib/mk/base.mk index 372407127..fa6bb32e2 100644 --- a/repos/base-linux/lib/mk/base.mk +++ b/repos/base-linux/lib/mk/base.mk @@ -8,4 +8,5 @@ include $(REP_DIR)/lib/mk/base.inc LIBS += startup SRC_CC += thread.cc thread_myself.cc thread_linux.cc +SRC_CC += capability_space.cc capability_raw.cc diff --git a/repos/base-linux/lib/mk/lx_hybrid.mk b/repos/base-linux/lib/mk/lx_hybrid.mk index 36183ac68..7a598d992 100644 --- a/repos/base-linux/lib/mk/lx_hybrid.mk +++ b/repos/base-linux/lib/mk/lx_hybrid.mk @@ -1,4 +1,4 @@ -SRC_CC += lx_hybrid.cc new_delete.cc +SRC_CC += lx_hybrid.cc new_delete.cc capability_space.cc vpath new_delete.cc $(BASE_DIR)/src/lib/cxx vpath lx_hybrid.cc $(REP_DIR)/src/lib/lx_hybrid diff --git a/repos/base-linux/src/core/include/core_env.h b/repos/base-linux/src/core/include/core_env.h index b656d187e..e5bf0b090 100644 --- a/repos/base-linux/src/core/include/core_env.h +++ b/repos/base-linux/src/core/include/core_env.h @@ -210,8 +210,6 @@ namespace Genode { PWRN("%s:%u not implemented", __FILE__, __LINE__); return Cpu_session_capability(); } - - void reload_parent_cap(Capability::Dst, long) { } }; diff --git a/repos/base-linux/src/core/include/dataspace_component.h b/repos/base-linux/src/core/include/dataspace_component.h index c0c26c448..3ca5e4b39 100644 --- a/repos/base-linux/src/core/include/dataspace_component.h +++ b/repos/base-linux/src/core/include/dataspace_component.h @@ -25,6 +25,9 @@ #include #include +/* base-internal includes */ +#include + namespace Genode { /** @@ -122,9 +125,10 @@ namespace Genode { Untyped_capability fd() { - typedef Untyped_capability::Dst Dst; - enum { DUMMY_LOCAL_NAME = 0 }; - return Untyped_capability(Dst(_fd), DUMMY_LOCAL_NAME); + Untyped_capability fd_cap = + Capability_space::import(Rpc_destination(_fd), Rpc_obj_key()); + + return fd_cap; } }; } diff --git a/repos/base-linux/src/core/include/rpc_cap_factory.h b/repos/base-linux/src/core/include/rpc_cap_factory.h new file mode 100644 index 000000000..fd1514523 --- /dev/null +++ b/repos/base-linux/src/core/include/rpc_cap_factory.h @@ -0,0 +1,39 @@ +/* + * \brief RPC capability factory + * \author Norman Feske + * \date 2016-01-19 + */ + +/* + * 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__RPC_CAP_FACTORY_H_ +#define _CORE__INCLUDE__RPC_CAP_FACTORY_H_ + +#include +#include +#include + +namespace Genode { class Rpc_cap_factory; } + +class Genode::Rpc_cap_factory +{ + private: + + static Native_capability _alloc(Rpc_cap_factory *owner, + Native_capability ep); + + public: + + Rpc_cap_factory(Allocator &md_alloc) { } + + Native_capability alloc(Native_capability ep); + + void free(Native_capability cap); +}; + +#endif /* _CORE__INCLUDE__RPC_CAP_FACTORY_H_ */ diff --git a/repos/base-linux/src/core/native_cpu_component.cc b/repos/base-linux/src/core/native_cpu_component.cc index f4e905d35..b19c00560 100644 --- a/repos/base-linux/src/core/native_cpu_component.cc +++ b/repos/base-linux/src/core/native_cpu_component.cc @@ -15,6 +15,9 @@ #include #include +/* base-internal includes */ +#include + using namespace Genode; @@ -30,10 +33,8 @@ Untyped_capability Native_cpu_component::server_sd(Thread_capability thread_cap) auto lambda = [] (Cpu_thread_component *thread) { if (!thread) return Untyped_capability(); - enum { DUMMY_LOCAL_NAME = 0 }; - typedef Native_capability::Dst Dst; - return Untyped_capability(Dst(thread->platform_thread().server_sd()), - DUMMY_LOCAL_NAME); + return Capability_space::import(Rpc_destination(thread->platform_thread().server_sd()), + Rpc_obj_key()); }; return _thread_ep.apply(thread_cap, lambda); } @@ -44,10 +45,8 @@ Untyped_capability Native_cpu_component::client_sd(Thread_capability thread_cap) auto lambda = [] (Cpu_thread_component *thread) { if (!thread) return Untyped_capability(); - enum { DUMMY_LOCAL_NAME = 0 }; - typedef Native_capability::Dst Dst; - return Untyped_capability(Dst(thread->platform_thread().client_sd()), - DUMMY_LOCAL_NAME); + return Capability_space::import(Rpc_destination(thread->platform_thread().client_sd()), + Rpc_obj_key()); }; return _thread_ep.apply(thread_cap, lambda); } diff --git a/repos/base-linux/src/core/native_pd_component.cc b/repos/base-linux/src/core/native_pd_component.cc index b2f3e84e5..b46f0fd76 100644 --- a/repos/base-linux/src/core/native_pd_component.cc +++ b/repos/base-linux/src/core/native_pd_component.cc @@ -22,6 +22,7 @@ /* base-internal includes */ #include +#include /* Linux includes */ #include @@ -117,7 +118,8 @@ void Native_pd_component::_start(Dataspace_component &ds) char buf[4096]; int num_bytes = 0; - while ((num_bytes = lx_read(ds.fd().dst().socket, buf, sizeof(buf))) != 0) + int const fd_socket = Capability_space::ipc_cap_data(ds.fd()).dst.socket; + while ((num_bytes = lx_read(fd_socket, buf, sizeof(buf))) != 0) lx_write(tmp_binary_fd, buf, num_bytes); lx_close(tmp_binary_fd); @@ -167,7 +169,7 @@ void Native_pd_component::_start(Dataspace_component &ds) * pointer, all arguments are embedded within the 'execve_args' struct. */ Execve_args arg(filename, argv_buf, env, - _pd_session._parent.dst().socket); + Capability_space::ipc_cap_data(_pd_session._parent).dst.socket); _pid = lx_create_process((int (*)(void *))_exec_child, stack + STACK_SIZE - sizeof(umword_t), &arg); diff --git a/repos/base-linux/src/core/platform.cc b/repos/base-linux/src/core/platform.cc index 41496cc11..9ba8ae68d 100644 --- a/repos/base-linux/src/core/platform.cc +++ b/repos/base-linux/src/core/platform.cc @@ -18,6 +18,7 @@ /* base-internal includes */ #include #include +#include /* local includes */ #include "platform.h" @@ -206,7 +207,8 @@ int Region_map_mmap::_dataspace_fd(Capability ds_cap) if (!core_env()->entrypoint()->is_myself()) { /* release Region_map_mmap::_lock during RPC */ _lock.unlock(); - int socket = Linux_dataspace_client(ds_cap).fd().dst().socket; + Untyped_capability fd_cap = Linux_dataspace_client(ds_cap).fd(); + int socket = Capability_space::ipc_cap_data(fd_cap).dst.socket; _lock.lock(); return socket; } @@ -223,7 +225,7 @@ int Region_map_mmap::_dataspace_fd(Capability ds_cap) * dataspace, the descriptor would unexpectedly be closed again. */ return core_env()->entrypoint()->apply(lx_ds_cap, [] (Linux_dataspace *ds) { - return ds ? lx_dup(ds->fd().dst().socket) : -1; }); + return ds ? lx_dup(Capability_space::ipc_cap_data(ds->fd()).dst.socket) : -1; }); } diff --git a/repos/base-linux/src/core/ram_session_support.cc b/repos/base-linux/src/core/ram_session_support.cc index a77452cae..98058b6e6 100644 --- a/repos/base-linux/src/core/ram_session_support.cc +++ b/repos/base-linux/src/core/ram_session_support.cc @@ -21,6 +21,9 @@ #include #include +/* base-internal includes */ +#include + /* Linux syscall bindings */ #include @@ -55,7 +58,7 @@ void Ram_session_component::_export_ram_ds(Dataspace_component *ds) void Ram_session_component::_revoke_ram_ds(Dataspace_component *ds) { - int const fd = ds->fd().dst().socket; + int const fd = Capability_space::ipc_cap_data(ds->fd()).dst.socket; if (fd != -1) lx_close(fd); } diff --git a/repos/base-linux/src/core/rom_session_component.cc b/repos/base-linux/src/core/rom_session_component.cc index 47ec3ec76..f5fe3e0cc 100644 --- a/repos/base-linux/src/core/rom_session_component.cc +++ b/repos/base-linux/src/core/rom_session_component.cc @@ -24,6 +24,9 @@ #include #include +/* base-internal includes */ +#include + /* local includes */ #include "rom_session_component.h" @@ -44,7 +47,7 @@ Rom_session_component::~Rom_session_component() { _ds_ep->dissolve(&_ds); - int const fd = _ds.fd().dst().socket; + int const fd = Capability_space::ipc_cap_data(_ds.fd()).dst.socket; if (fd != -1) lx_close(fd); } diff --git a/repos/base-linux/src/core/target.mk b/repos/base-linux/src/core/target.mk index 12e4d0bbc..a36f6d821 100644 --- a/repos/base-linux/src/core/target.mk +++ b/repos/base-linux/src/core/target.mk @@ -19,7 +19,8 @@ SRC_CC = main.cc \ dataspace_component.cc \ native_pd_component.cc \ native_cpu_component.cc \ - rpc_cap_factory.cc \ + capability_space.cc \ + rpc_cap_factory_l4.cc \ core_rpc_cap_alloc.cc \ io_mem_session_component.cc \ signal_source_component.cc \ @@ -47,7 +48,8 @@ vpath cpu_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_support.cc $(GEN_CORE_DIR) vpath cpu_thread_component.cc $(GEN_CORE_DIR) vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) -vpath rpc_cap_factory.cc $(GEN_CORE_DIR) +vpath capability_space.cc $(GEN_CORE_DIR) +vpath rpc_cap_factory_l4.cc $(GEN_CORE_DIR) vpath platform_services.cc $(GEN_CORE_DIR) vpath signal_source_component.cc $(GEN_CORE_DIR) vpath trace_session_component.cc $(GEN_CORE_DIR) diff --git a/repos/base-linux/src/include/base/internal/local_capability.h b/repos/base-linux/src/include/base/internal/local_capability.h index 9fa5b63d5..158b201c8 100644 --- a/repos/base-linux/src/include/base/internal/local_capability.h +++ b/repos/base-linux/src/include/base/internal/local_capability.h @@ -14,15 +14,24 @@ * under the terms of the GNU General Public License version 2. */ -#ifndef _INCLUDE__BASE__LOCAL_CAPABILITY_H_ -#define _INCLUDE__BASE__LOCAL_CAPABILITY_H_ +#ifndef _INCLUDE__BASE__INTERNAL__LOCAL_CAPABILITY_H_ +#define _INCLUDE__BASE__INTERNAL__LOCAL_CAPABILITY_H_ -#include +#include namespace Genode { template class Local_capability; + + /** + * Return true if argument is a local capability + */ + static inline bool local(Untyped_capability const &cap) + { + return Capability_space::ipc_cap_data(cap).dst.socket == -1; + } } + /** * Local capability referring to a specific RPC interface * @@ -44,7 +53,9 @@ class Genode::Local_capability * \return a capability that represents the local object. */ static Capability local_cap(RPC_INTERFACE* ptr) { - Untyped_capability cap(Cap_dst_policy::Dst(), (long)ptr); + Untyped_capability cap = + Capability_space::import(invalid_rpc_destination(), + Rpc_obj_key((long)ptr)); return reinterpret_cap_cast(cap); } /** @@ -57,4 +68,4 @@ class Genode::Local_capability return reinterpret_cast(c.local_name()); } }; -#endif /* _INCLUDE__BASE__LOCAL_CAPABILITY_H_ */ +#endif /* _INCLUDE__BASE__INTERNAL__LOCAL_CAPABILITY_H_ */ diff --git a/repos/base-linux/src/include/base/internal/rpc_destination.h b/repos/base-linux/src/include/base/internal/rpc_destination.h new file mode 100644 index 000000000..7bf76ddb7 --- /dev/null +++ b/repos/base-linux/src/include/base/internal/rpc_destination.h @@ -0,0 +1,41 @@ +/* + * \brief RPC destination type + * \author Norman Feske + * \date 2016-03-11 + */ + +/* + * 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__BASE__INTERNAL__RPC_DESTINATION_H_ +#define _INCLUDE__BASE__INTERNAL__RPC_DESTINATION_H_ + +#include + +namespace Genode { + + struct Rpc_destination + { + int socket = -1; + + explicit Rpc_destination(int socket) : socket(socket) { } + + Rpc_destination() { } + }; + + static inline Rpc_destination invalid_rpc_destination() + { + return Rpc_destination(); + } + + static void print(Output &out, Rpc_destination const &dst) + { + Genode::print(out, "socket=", dst.socket); + } +} + +#endif /* _INCLUDE__BASE__INTERNAL__RPC_DESTINATION_H_ */ diff --git a/repos/base-linux/src/lib/base/capability_raw.cc b/repos/base-linux/src/lib/base/capability_raw.cc new file mode 100644 index 000000000..854a870ea --- /dev/null +++ b/repos/base-linux/src/lib/base/capability_raw.cc @@ -0,0 +1,31 @@ +/* + * \brief Capability + * \author Norman Feske + * \date 2016-06-16 + */ + +/* + * 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. + */ + +#include + +/* base-internal includes */ +#include + +using namespace Genode; + + +Native_capability::Raw Native_capability::raw() const +{ + /* + * On Linux, we don't pass information as a 'raw' representation to + * child components. So this function remains unused. We still need + * to provide it to prevent link errors of noux, which relies on this + * function for implementing 'fork' (not supported on base-linux). + */ + return { { 0, 0, 0, 0 } }; +} diff --git a/repos/base-linux/src/lib/base/ipc.cc b/repos/base-linux/src/lib/base/ipc.cc index d1fd3f102..6ef14bc04 100644 --- a/repos/base-linux/src/lib/base/ipc.cc +++ b/repos/base-linux/src/lib/base/ipc.cc @@ -24,6 +24,7 @@ #include #include #include +#include /* Linux includes */ #include @@ -33,6 +34,19 @@ using namespace Genode; +namespace { + + struct Pid + { + int value; + + Pid() : value(lx_getpid()) { } + + void print(Output &out) const { Genode::print(out, "[", value, "]"); } + }; +} + + /* * The request message layout is: * @@ -60,12 +74,21 @@ struct Protocol_header /* badges of the transferred capability arguments */ unsigned long badges[Msgbuf_base::MAX_CAPS_PER_MSG]; - enum { INVALID_BADGE = ~0UL }; + enum { INVALID_BADGE = ~1UL }; void *msg_start() { return &protocol_word; } }; +/* + * The INVALID_BADGE must be different from the representation of an + * invalid RPC object key because this key value is used by manually + * created NON-RPC-object capabilities (client_sd, server_sd, dataspace fd). + */ +static_assert((int)Protocol_header::INVALID_BADGE != (int)Rpc_obj_key::INVALID, + "ambigious INVALID_BADGE"); + + /****************************** ** File-descriptor registry ** ******************************/ @@ -242,8 +265,11 @@ static void insert_sds_into_message(Message &msg, Native_capability const &cap = snd_msgbuf.cap(i); if (cap.valid()) { - msg.marshal_socket(cap.dst().socket); - header.badges[i] = cap.local_name(); + Capability_space::Ipc_cap_data cap_data = + Capability_space::ipc_cap_data(cap); + + msg.marshal_socket(cap_data.dst.socket); + header.badges[i] = cap_data.rpc_obj_key.value(); } else { header.badges[i] = Protocol_header::INVALID_BADGE; } @@ -277,7 +303,8 @@ static void extract_sds_from_message(unsigned start_index, int const associated_sd = Genode::ep_sd_registry()->try_associate(sd, id); - buf.insert(Native_capability(Cap_dst_policy::Dst(associated_sd), badge)); + buf.insert(Capability_space::import(Rpc_destination(associated_sd), + Rpc_obj_key(badge))); if ((associated_sd >= 0) && (associated_sd != sd)) { @@ -374,10 +401,13 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst, /* marshal capabilities contained in 'snd_msgbuf' */ insert_sds_into_message(snd_msg, snd_header, snd_msgbuf); - int const send_ret = lx_sendmsg(dst.dst().socket, snd_msg.msg(), 0); + int const dst_socket = Capability_space::ipc_cap_data(dst).dst.socket; + + int const send_ret = lx_sendmsg(dst_socket, snd_msg.msg(), 0); if (send_ret < 0) { - PRAW("[%d] lx_sendmsg to sd %d failed with %d in lx_call()", - lx_getpid(), dst.dst().socket, send_ret); + raw(Pid(), " lx_sendmsg to sd ", dst_socket, + " failed with ", send_ret, " in lx_call()"); + for (;;); throw Genode::Ipc_error(); } @@ -414,7 +444,9 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst, void Genode::ipc_reply(Native_capability caller, Rpc_exception_code exc, Msgbuf_base &snd_msg) { - try { lx_reply(caller.dst().socket, exc, snd_msg); } catch (Ipc_error) { } + int const reply_socket = Capability_space::ipc_cap_data(caller).dst.socket; + + try { lx_reply(reply_socket, exc, snd_msg); } catch (Ipc_error) { } } @@ -425,7 +457,7 @@ Genode::Rpc_request Genode::ipc_reply_wait(Reply_capability const &last_caller, { /* when first called, there was no request yet */ if (last_caller.valid() && exc.value != Rpc_exception_code::INVALID_OBJECT) - lx_reply(last_caller.dst().socket, exc, reply_msg); + lx_reply(Capability_space::ipc_cap_data(last_caller).dst.socket, exc, reply_msg); /* * Block infinitely if called from the main thread. This may happen if the @@ -464,15 +496,15 @@ Genode::Rpc_request Genode::ipc_reply_wait(Reply_capability const &last_caller, /* start at offset 1 to skip the reply channel */ extract_sds_from_message(1, msg, header, request_msg); - typedef Native_capability::Dst Dst; - return Rpc_request(Native_capability(Dst(reply_socket), ~0UL), badge); + return Rpc_request(Capability_space::import(Rpc_destination(reply_socket), + Rpc_obj_key()), badge); } } Ipc_server::Ipc_server() : - Native_capability(Dst(-1), 0) + Native_capability(Capability_space::import(Rpc_destination(), Rpc_obj_key())) { /* * If 'thread' is 0, the constructor was called by the main thread. By @@ -498,7 +530,8 @@ Ipc_server::Ipc_server() /* override capability initialization */ *static_cast(this) = - Native_capability(Native_capability::Dst(socket_pair.client_sd), 0); + Capability_space::import(Rpc_destination(socket_pair.client_sd), + Rpc_obj_key()); } diff --git a/repos/base-linux/src/lib/base/platform_env.cc b/repos/base-linux/src/lib/base/platform_env.cc index ba0f3f2a5..7e5cbeaa7 100644 --- a/repos/base-linux/src/lib/base/platform_env.cc +++ b/repos/base-linux/src/lib/base/platform_env.cc @@ -22,6 +22,7 @@ #include #include #include +#include using namespace Genode; @@ -32,16 +33,18 @@ using namespace Genode; size_t Region_map_mmap::_dataspace_size(Dataspace_capability ds) { - if (ds.valid()) - return Dataspace_client(ds).size(); + if (local(ds)) + return Local_capability::deref(ds)->size(); + + return Dataspace_client(ds).size(); - return Local_capability::deref(ds)->size(); } int Region_map_mmap::_dataspace_fd(Dataspace_capability ds) { - return Linux_dataspace_client(ds).fd().dst().socket; + Untyped_capability fd_cap = Linux_dataspace_client(ds).fd(); + return Capability_space::ipc_cap_data(fd_cap).dst.socket; } @@ -126,12 +129,13 @@ static unsigned long get_env_ulong(const char *key) static Parent_capability obtain_parent_cap() { - long local_name = get_env_ulong("parent_local_name"); + long const local_name = get_env_ulong("parent_local_name"); - /* produce typed capability manually */ - typedef Native_capability::Dst Dst; - Dst const dst(PARENT_SOCKET_HANDLE); - return reinterpret_cap_cast(Native_capability(dst, local_name)); + Untyped_capability parent_cap = + Capability_space::import(Rpc_destination(PARENT_SOCKET_HANDLE), + Rpc_obj_key(local_name)); + + return reinterpret_cap_cast(parent_cap); } @@ -178,8 +182,10 @@ namespace Genode { Thread *thread = Thread::myself(); if (thread) { - socket_pair.server_sd = native_cpu.server_sd(thread->cap()).dst().socket; - socket_pair.client_sd = native_cpu.client_sd(thread->cap()).dst().socket; + Untyped_capability server_cap = native_cpu.server_sd(thread->cap()); + Untyped_capability client_cap = native_cpu.client_sd(thread->cap()); + socket_pair.server_sd = Capability_space::ipc_cap_data(server_cap).dst.socket; + socket_pair.client_sd = Capability_space::ipc_cap_data(client_cap).dst.socket; thread->native_thread().socket_pair = socket_pair; } return socket_pair; diff --git a/repos/base-linux/src/lib/base/region_map_mmap.cc b/repos/base-linux/src/lib/base/region_map_mmap.cc index a8aba7b74..11e83ddf4 100644 --- a/repos/base-linux/src/lib/base/region_map_mmap.cc +++ b/repos/base-linux/src/lib/base/region_map_mmap.cc @@ -53,7 +53,7 @@ using namespace Genode; static bool is_sub_rm_session(Dataspace_capability ds) { - if (ds.valid()) + if (ds.valid() && !local(ds)) return false; return Local_capability::deref(ds) != 0; diff --git a/repos/base-nova/include/base/native_capability.h b/repos/base-nova/include/base/native_capability.h deleted file mode 100644 index 182185401..000000000 --- a/repos/base-nova/include/base/native_capability.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * \brief Platform-specific capability type - * \author Norman Feske - * \author Alexander Boettcher - * \date 2009-10-02 - */ - -/* - * 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__BASE__NATIVE_CAPABILITY_H_ - -/* Genode includes */ -#include -#include -#include - -/* NOVA includes */ -#include - -namespace Genode { - - class Native_capability - { - public: - - typedef Nova::Obj_crd Dst; - - struct Raw { }; - - private: - - struct _Raw - { - Dst dst; - - _Raw() : dst() { } - - _Raw(addr_t sel, unsigned rights) - : dst(sel, 0, rights) { } - } _cap; - - addr_t _rcv_window; - - enum { INVALID_INDEX = ~0UL }; - - protected: - - inline void _inc() const - { - Cap_index idx(cap_map()->find(local_name())); - idx.inc(); - } - - inline void _dec() const - { - Cap_index idx(cap_map()->find(local_name())); - idx.dec(); - } - - public: - - /** - * Constructors - */ - - Native_capability() - : _cap(), _rcv_window(INVALID_INDEX) {} - - explicit - Native_capability(addr_t sel, unsigned rights = 0x1f) - { - if (sel == INVALID_INDEX) - _cap = _Raw(); - else { - _cap = _Raw(sel, rights); - _inc(); - } - - _rcv_window = INVALID_INDEX; - } - - Native_capability(const Native_capability &o) - : _cap(o._cap), _rcv_window(o._rcv_window) - { if (valid()) _inc(); } - - ~Native_capability() { if (valid()) _dec(); } - - /** - * Overloaded comparison operator - */ - bool operator==(const Native_capability &o) const { - return local_name() == o.local_name(); } - - /** - * Copy constructor - */ - Native_capability& operator= - (const Native_capability &o) - { - if (this == &o) - return *this; - - if (valid()) _dec(); - - _cap = o._cap; - _rcv_window = o._rcv_window; - - if (valid()) _inc(); - - return *this; - } - - /** - * Check whether the selector of the Native_cap and - * the capability type is valid. - */ - bool valid() const { return !_cap.dst.is_null(); } - - Dst dst() const { return _cap.dst; } - - /** - * Return the local_name. On NOVA it is the same as the - * destination value. - */ - addr_t local_name() const - { - if (valid()) - return _cap.dst.base(); - else - return INVALID_INDEX; - } - - /** - * Set one specific cap selector index as receive - * window for the next IPC. This can be used to make - * sure that the to be received mapped capability will - * be placed at a specific index. - */ - void rcv_window(addr_t rcv) { _rcv_window = rcv; } - - /** - * Return the selector of the rcv_window. - */ - addr_t rcv_window() const { return _rcv_window; } - - /** - * Return an invalid Dst object - */ - static Dst invalid() { return Dst(); } - - /** - * Return a invalid Native_capability - */ - static Native_capability invalid_cap() - { - return Native_capability(); - } - - Raw raw() const { return Raw(); } - }; -} - -#endif /* _INCLUDE__BASE__NATIVE_CAPABILITY_H_ */ diff --git a/repos/base-nova/include/base/cap_map.h b/repos/base-nova/include/nova/cap_map.h similarity index 89% rename from repos/base-nova/include/base/cap_map.h rename to repos/base-nova/include/nova/cap_map.h index 3b5231b0b..67e8444b6 100644 --- a/repos/base-nova/include/base/cap_map.h +++ b/repos/base-nova/include/nova/cap_map.h @@ -3,6 +3,9 @@ * \author Alexander Boettcher * \date 2013-08-26 * + * This header is public to allow user-level VMMs to manually allocate windows + * of consecutive selectors (for virtualization event portals) in the + * component's capability space. */ /* @@ -12,8 +15,8 @@ * under the terms of the GNU General Public License version 2. */ -#ifndef _INCLUDE__BASE__CAP_MAP_H_ -#define _INCLUDE__BASE__CAP_MAP_H_ +#ifndef _INCLUDE__NOVA__CAP_MAP_H_ +#define _INCLUDE__NOVA__CAP_MAP_H_ /* Genode includes */ #include @@ -126,4 +129,4 @@ namespace Genode { Capability_map *cap_map(); } -#endif /* _INCLUDE__BASE__CAP_MAP_H_ */ +#endif /* _INCLUDE__NOVA__CAP_MAP_H_ */ diff --git a/repos/base-nova/include/nova/capability_space.h b/repos/base-nova/include/nova/capability_space.h new file mode 100644 index 000000000..d498b1ee5 --- /dev/null +++ b/repos/base-nova/include/nova/capability_space.h @@ -0,0 +1,47 @@ +/* + * \brief Capability helper + * \author Norman Feske + * \date 2016-06-27 + */ + +/* + * 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__NOVA__CAPABILITY_SPACE_H_ +#define _INCLUDE__NOVA__CAPABILITY_SPACE_H_ + +/* Genode includes */ +#include + +/* NOVA includes */ +#include + +namespace Genode { namespace Capability_space { + + enum { INVALID_INDEX = ~0UL }; + + typedef Nova::Crd Ipc_cap_data; + + static inline Nova::Crd crd(Native_capability const &cap) + { + /* + * We store the 'Nova::Crd' value in place of the 'Data' pointer. + */ + addr_t value = (addr_t)cap.data(); + Nova::Crd crd = *(Nova::Crd *)&value; + return crd; + } + + static inline Native_capability import(addr_t sel, unsigned rights = 0x1f) + { + Nova::Obj_crd const crd = (sel == INVALID_INDEX) + ? Nova::Obj_crd() : Nova::Obj_crd(sel, 0, rights); + return Native_capability(*(Native_capability::Data *)crd.value()); + } +} } + +#endif /* _INCLUDE__NOVA__CAPABILITY_SPACE_H_ */ diff --git a/repos/base-nova/include/nova/native_thread.h b/repos/base-nova/include/nova/native_thread.h index 83bf68466..520c44727 100644 --- a/repos/base-nova/include/nova/native_thread.h +++ b/repos/base-nova/include/nova/native_thread.h @@ -34,7 +34,23 @@ struct Genode::Native_thread addr_t initial_ip; /* initial IP of local thread */ /* receive window for capability selectors received at the server side */ - Receive_window rcv_window; + Receive_window server_rcv_window; + + /* + * Designated selector to populate with the result of an IPC call + * + * By default, the client-side receive window for delegated selectors + * is automatically allocated within the component's selector space. + * However, in special cases such as during the initialization of a + * user-level VMM (ports/include/vmm/vcpu_dispatcher.h), the targeted + * selector is defined manually. The 'client_rcv_sel' provides the + * hook for such a manual allocation. If it contains a valid selector + * value, the value is used as the basis of the receive window of an + * 'ipc_call'. + */ + addr_t client_rcv_sel = INVALID_INDEX; + + void reset_client_rcv_sel() { client_rcv_sel = INVALID_INDEX; } Native_capability pager_cap; diff --git a/repos/base-nova/include/nova/receive_window.h b/repos/base-nova/include/nova/receive_window.h index 3ce750904..5206fbef3 100644 --- a/repos/base-nova/include/nova/receive_window.h +++ b/repos/base-nova/include/nova/receive_window.h @@ -126,24 +126,12 @@ struct Genode::Receive_window /** * Return received portal-capability selector */ - void rcv_pt_sel(Native_capability &cap) - { - if (_rcv_pt_sel_cnt >= _rcv_pt_sel_max) { - cap = Native_capability(); - return; - } - - /* return only received or translated caps */ - cap = Native_capability(_rcv_pt_sel[_rcv_pt_sel_cnt++].sel); - } + void rcv_pt_sel(Native_capability &cap); /** * Return true if receive window must be re-initialized */ - bool rcv_invalid() const - { - return _rcv_pt_base == INVALID_INDEX; - } + bool rcv_invalid() const; unsigned num_received_caps() const { return _rcv_pt_sel_max; } @@ -167,56 +155,7 @@ struct Genode::Receive_window * \result 'true' - receive window must be re-initialized * 'false' - portal selectors has been kept */ - bool rcv_cleanup(bool keep, unsigned short const new_max = MAX_CAP_ARGS) - { - /* mark used mapped capabilities as used to prevent freeing */ - bool reinit = false; - for (unsigned i = 0; i < _rcv_pt_sel_cnt; i++) { - if (!_rcv_pt_sel[i].del) - continue; - - /* should never happen */ - if (_rcv_pt_sel[i].sel < _rcv_pt_base || - (_rcv_pt_sel[i].sel >= _rcv_pt_base + MAX_CAP_ARGS)) - nova_die(); - - _rcv_pt_cap_free [_rcv_pt_sel[i].sel - _rcv_pt_base] = USED_CAP; - - reinit = true; - } - - /* if old receive window was smaller, we need to re-init */ - for (unsigned i = 0; !reinit && i < new_max; i++) - if (_rcv_pt_cap_free[i] == FREE_INVALID) - reinit = true; - - _rcv_pt_sel_cnt = 0; - _rcv_pt_sel_max = 0; - - /* we can keep the cap selectors if none was used */ - if (keep && !reinit) { - for (unsigned i = 0; i < MAX_CAP_ARGS; i++) { - /* revoke received caps which are unused */ - if (_rcv_pt_cap_free[i] == UNUSED_CAP) - Nova::revoke(Nova::Obj_crd(_rcv_pt_base + i, 0), true); - - /* free rest of indexes if new_max is smaller then last window */ - if (i >= new_max && _rcv_pt_cap_free[i] == FREE_SEL) - cap_map()->remove(_rcv_pt_base + i, 0, false); - } - - return false; - } - - /* decrease ref count if valid selector */ - for (unsigned i = 0; i < MAX_CAP_ARGS; i++) { - if (_rcv_pt_cap_free[i] == FREE_INVALID) - continue; - cap_map()->remove(_rcv_pt_base + i, 0, _rcv_pt_cap_free[i] != FREE_SEL); - } - - return true; - } + bool rcv_cleanup(bool keep, unsigned short const new_max = MAX_CAP_ARGS); /** * Initialize receive window for portal capability @@ -234,39 +173,7 @@ struct Genode::Receive_window * fresh receive window and clears 'rcv_invalid'. */ bool prepare_rcv_window(Nova::Utcb &utcb, - addr_t rcv_window = INVALID_INDEX) - { - /* open maximal translate window */ - utcb.crd_xlt = Nova::Obj_crd(0, ~0UL); - - /* use receive window if specified */ - if (rcv_window != INVALID_INDEX) { - /* cleanup if receive window already used */ - if (!rcv_invalid()) rcv_cleanup(false); - - _rcv_pt_base = rcv_window; - - /* open receive window */ - utcb.crd_rcv = Nova::Obj_crd(_rcv_pt_base, _rcv_wnd_log2); - return true; - } - - /* allocate receive window if necessary, otherwise use old one */ - if (rcv_invalid() || rcv_cleanup(true, 1U << _rcv_wnd_log2)) - { - _rcv_pt_base = cap_map()->insert(_rcv_wnd_log2); - - if (_rcv_pt_base == INVALID_INDEX) { - /* no mappings can be received */ - utcb.crd_rcv = Nova::Obj_crd(); - return false; - } - } - - /* open receive window */ - utcb.crd_rcv = Nova::Obj_crd(_rcv_pt_base, _rcv_wnd_log2); - return true; - } + addr_t rcv_window = INVALID_INDEX); /** * Post IPC processing. diff --git a/repos/base-nova/include/signal_source/client.h b/repos/base-nova/include/signal_source/client.h index 26ebbbcbe..2a2662a6b 100644 --- a/repos/base-nova/include/signal_source/client.h +++ b/repos/base-nova/include/signal_source/client.h @@ -31,6 +31,7 @@ /* NOVA includes */ #include #include +#include namespace Genode { @@ -53,9 +54,9 @@ namespace Genode { { /* request mapping of semaphore capability selector */ Thread * myself = Thread::myself(); - request_signal_sm_cap(Native_capability(myself->native_thread().ec_sel + 1), + request_signal_sm_cap(Capability_space::import(myself->native_thread().ec_sel + 1), myself->native_thread().exc_pt_sel + Nova::PT_SEL_STARTUP); - _sem = Native_capability(myself->native_thread().exc_pt_sel + Nova::PT_SEL_STARTUP); + _sem = Capability_space::import(myself->native_thread().exc_pt_sel + Nova::PT_SEL_STARTUP); call(_sem); } diff --git a/repos/base-nova/lib/mk/base-common.mk b/repos/base-nova/lib/mk/base-common.mk index 66b1c3cc9..3656e3a9e 100644 --- a/repos/base-nova/lib/mk/base-common.mk +++ b/repos/base-nova/lib/mk/base-common.mk @@ -12,3 +12,4 @@ SRC_CC += signal_submit.cc SRC_CC += thread.cc thread_myself.cc SRC_CC += stack.cc SRC_CC += cap_map.cc +SRC_CC += capability.cc diff --git a/repos/base-nova/lib/mk/core.inc b/repos/base-nova/lib/mk/core.inc new file mode 100644 index 000000000..1067180d5 --- /dev/null +++ b/repos/base-nova/lib/mk/core.inc @@ -0,0 +1,6 @@ +SRC_CC += pager.cc + +INC_DIR = $(REP_DIR)/src/core/include \ + $(BASE_DIR)/src/core/include \ + $(REP_DIR)/src/include \ + $(BASE_DIR)/src/include diff --git a/repos/base-nova/lib/mk/spec/x86_32/core.mk b/repos/base-nova/lib/mk/spec/x86_32/core.mk index 827c104a4..2f6dfad37 100644 --- a/repos/base-nova/lib/mk/spec/x86_32/core.mk +++ b/repos/base-nova/lib/mk/spec/x86_32/core.mk @@ -1,7 +1,3 @@ -SRC_CC += pager.cc - -INC_DIR = $(REP_DIR)/src/core/include \ - $(BASE_DIR)/src/core/include \ - $(BASE_DIR)/src/include +include $(REP_DIR)/lib/mk/core.inc vpath %.cc $(REP_DIR)/src/core/spec/x86_32 diff --git a/repos/base-nova/lib/mk/spec/x86_64/core.mk b/repos/base-nova/lib/mk/spec/x86_64/core.mk index d6fc61fbb..b51370fb7 100644 --- a/repos/base-nova/lib/mk/spec/x86_64/core.mk +++ b/repos/base-nova/lib/mk/spec/x86_64/core.mk @@ -1,6 +1,3 @@ -SRC_CC += pager.cc - -INC_DIR = $(REP_DIR)/src/core/include \ - $(BASE_DIR)/src/include +include $(REP_DIR)/lib/mk/core.inc vpath %.cc $(REP_DIR)/src/core/spec/x86_64 diff --git a/repos/base-nova/src/core/include/imprint_badge.h b/repos/base-nova/src/core/include/imprint_badge.h index f574c540a..af338bc18 100644 --- a/repos/base-nova/src/core/include/imprint_badge.h +++ b/repos/base-nova/src/core/include/imprint_badge.h @@ -14,6 +14,9 @@ #ifndef _CORE__INCLUDE__IMPRINT_BADGE_H_ #define _CORE__INCLUDE__IMPRINT_BADGE_H_ +/* NOVA includes */ +#include + static inline bool imprint_badge(unsigned long pt_sel, unsigned long badge) { using namespace Nova; diff --git a/repos/base-nova/src/core/include/pager.h b/repos/base-nova/src/core/include/pager.h index e2052743e..9e67e5f84 100644 --- a/repos/base-nova/src/core/include/pager.h +++ b/repos/base-nova/src/core/include/pager.h @@ -21,6 +21,9 @@ #include #include +/* NOVA includes */ +#include + /* core-local includes */ #include #include diff --git a/repos/base-nova/src/core/include/signal_broker.h b/repos/base-nova/src/core/include/signal_broker.h index 8b6d0ecd5..72fce06e7 100644 --- a/repos/base-nova/src/core/include/signal_broker.h +++ b/repos/base-nova/src/core/include/signal_broker.h @@ -17,6 +17,9 @@ /* Genode includes */ #include +/* NOVA includes */ +#include + /* core-local includes */ #include #include @@ -85,7 +88,7 @@ class Genode::Signal_broker return Signal_context_capability(); } - Native_capability si(cap_map()->insert()); + Native_capability si = Capability_space::import(cap_map()->insert()); Signal_context_capability cap = reinterpret_cap_cast(si); uint8_t res = Nova::create_si(cap.local_name(), __core_pd_sel, imprint, diff --git a/repos/base-nova/src/core/pager.cc b/repos/base-nova/src/core/pager.cc index ebbf6ab0e..65508bb4d 100644 --- a/repos/base-nova/src/core/pager.cc +++ b/repos/base-nova/src/core/pager.cc @@ -29,6 +29,7 @@ /* NOVA includes */ #include #include /* map_local */ +#include static bool verbose_oom = false; @@ -126,7 +127,8 @@ void Pager_object::_page_fault_handler(addr_t pager_obj) ret); Native_capability pager_cap = obj->Object_pool::Entry::cap(); - revoke(pager_cap.dst()); + + revoke(Capability_space::crd(pager_cap).base()); revoke(Obj_crd(obj->exc_pt_sel_client(), NUM_INITIAL_PT_LOG2)); @@ -917,7 +919,8 @@ Pager_capability Pager_entrypoint::manage(Pager_object *obj) PWRN("invalid CPU parameter used in pager object"); return Pager_capability(); } - Native_capability pager_thread_cap(pager_threads[use_cpu]->native_thread().ec_sel); + Native_capability pager_thread_cap = + Capability_space::import(pager_threads[use_cpu]->native_thread().ec_sel); /* request creation of portal bind to pager thread */ Native_capability cap_session = @@ -946,7 +949,7 @@ void Pager_entrypoint::dissolve(Pager_object *obj) _cap_factory.free(pager_obj); /* revoke cap selector locally */ - revoke(pager_obj.dst(), true); + revoke(Capability_space::crd(pager_obj), true); /* remove object from pool */ remove(obj); diff --git a/repos/base-nova/src/core/platform_thread.cc b/repos/base-nova/src/core/platform_thread.cc index b3e7a2d32..0981d5f93 100644 --- a/repos/base-nova/src/core/platform_thread.cc +++ b/repos/base-nova/src/core/platform_thread.cc @@ -114,7 +114,8 @@ int Platform_thread::start(void *ip, void *sp) if (!vcpu()) { pd_utcb = stack_area_virtual_base() + stack_virtual_size() - get_page_size(); - addr_t remap_src[] = { _pd->parent_pt_sel(), _pager->Object_pool::Entry::cap().local_name() }; + addr_t remap_src[] = { _pd->parent_pt_sel(), + (unsigned long)_pager->Object_pool::Entry::cap().local_name() }; addr_t remap_dst[] = { PT_SEL_PARENT, PT_SEL_MAIN_PAGER }; /* remap exception portals for first thread */ diff --git a/repos/base-nova/src/core/rpc_cap_factory.cc b/repos/base-nova/src/core/rpc_cap_factory.cc index 68727371c..bd6cb4eee 100644 --- a/repos/base-nova/src/core/rpc_cap_factory.cc +++ b/repos/base-nova/src/core/rpc_cap_factory.cc @@ -15,6 +15,9 @@ #include #include +/* NOVA includes */ +#include + using namespace Genode; @@ -31,14 +34,14 @@ Native_capability Rpc_cap_factory::alloc(Native_capability ep, addr_t entry, add /* create cap object */ Cap_object * pt_cap = new (&_slab) Cap_object(pt_sel); if (!pt_cap) - return Native_capability::invalid_cap(); + return Native_capability(); _list.insert(pt_cap); /* create portal */ uint8_t const res = create_pt(pt_sel, pd_sel, ec_sel, Mtd(mtd), entry); if (res == NOVA_OK) - return Native_capability(pt_sel); + return Capability_space::import(pt_sel); PERR("cap_session - cap=%lx:%lx addr=%lx mtd=%lx xpt=%lx res=%u", ec_sel, ep.local_name(), entry, mtd, pt_sel, res); @@ -49,7 +52,7 @@ Native_capability Rpc_cap_factory::alloc(Native_capability ep, addr_t entry, add /* cleanup unused selectors */ cap_map()->remove(pt_sel, 0, false); - return Native_capability::invalid_cap(); + return Native_capability(); } @@ -60,7 +63,7 @@ void Rpc_cap_factory::free(Native_capability cap) Lock::Guard guard(_lock); for (Cap_object *obj = _list.first(); obj ; obj = obj->next()) { - if (cap.local_name() == obj->_cap_sel) { + if (cap.local_name() == (long)obj->_cap_sel) { Nova::revoke(Nova::Obj_crd(obj->_cap_sel, 0)); cap_map()->remove(obj->_cap_sel, 0, false); diff --git a/repos/base-nova/src/include/base/internal/ipc.h b/repos/base-nova/src/include/base/internal/ipc.h index 3b046d92d..d152f49d2 100644 --- a/repos/base-nova/src/include/base/internal/ipc.h +++ b/repos/base-nova/src/include/base/internal/ipc.h @@ -17,6 +17,7 @@ /* NOVA includes */ #include #include +#include /** * Copy message registers from UTCB to destination message buffer @@ -108,7 +109,7 @@ static inline bool copy_msgbuf_to_utcb(Nova::Utcb &utcb, for (unsigned i = 0; i < snd_msg.used_caps(); i++) { Native_capability const &cap = snd_msg.cap(i); - Nova::Obj_crd crd(cap.local_name(), 0, cap.dst().rights()); + Nova::Crd const crd = Capability_space::crd(cap); if (crd.base() == ~0UL) continue; diff --git a/repos/base-nova/src/include/base/internal/parent_cap.h b/repos/base-nova/src/include/base/internal/parent_cap.h index 8629eaceb..1513e193c 100644 --- a/repos/base-nova/src/include/base/internal/parent_cap.h +++ b/repos/base-nova/src/include/base/internal/parent_cap.h @@ -22,7 +22,7 @@ #include /* NOVA includes */ -#include +#include namespace Genode { @@ -30,7 +30,7 @@ namespace Genode { static inline Parent_capability parent_cap() { return reinterpret_cap_cast( - Native_capability(Nova::PT_SEL_PARENT)); + Capability_space::import(Nova::PT_SEL_PARENT)); } } diff --git a/repos/base-nova/src/lib/base/cap_map.cc b/repos/base-nova/src/lib/base/cap_map.cc index 6217eb6e9..b46a7da87 100644 --- a/repos/base-nova/src/lib/base/cap_map.cc +++ b/repos/base-nova/src/lib/base/cap_map.cc @@ -11,12 +11,12 @@ * under the terms of the GNU General Public License version 2. */ -#include - +/* Genode includes */ #include -/* base-nova specific include */ +/* NOVA includes */ #include +#include using namespace Genode; diff --git a/repos/base-nova/src/lib/base/capability.cc b/repos/base-nova/src/lib/base/capability.cc new file mode 100644 index 000000000..ca776beb9 --- /dev/null +++ b/repos/base-nova/src/lib/base/capability.cc @@ -0,0 +1,78 @@ +/* + * \brief Capability lifetime management + * \author Norman Feske + * \date 2015-05-06 + */ + +/* + * 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. + */ + +#include + +/* base-internal includes */ +#include + +/* NOVA includes */ +#include +#include + +using namespace Genode; + + +Native_capability::Native_capability() +{ + *this = Capability_space::import(Capability_space::INVALID_INDEX); +} + + +void Native_capability::_inc() +{ + Cap_index idx(cap_map()->find(local_name())); + idx.inc(); +} + + +void Native_capability::_dec() +{ + Cap_index idx(cap_map()->find(local_name())); + idx.dec(); +} + + +long Native_capability::local_name() const +{ + if (valid()) + return Capability_space::crd(*this).base(); + else + return Capability_space::INVALID_INDEX; +} + + +bool Native_capability::valid() const +{ + return _data != nullptr; +} + + +Native_capability::Raw Native_capability::raw() const +{ + return { 0, 0, 0, 0 }; +} + + +void Native_capability::print(Genode::Output &out) const +{ + using Genode::print; + + print(out, "cap<"); + if (_data) { + print(out, local_name()); + } else { + print(out, "invalid"); + } + print(out, ">"); +} diff --git a/repos/base-nova/src/lib/base/ipc.cc b/repos/base-nova/src/lib/base/ipc.cc index 6e9da3e6d..fa4894ca7 100644 --- a/repos/base-nova/src/lib/base/ipc.cc +++ b/repos/base-nova/src/lib/base/ipc.cc @@ -19,6 +19,9 @@ /* base-internal includes */ #include +/* NOVA includes */ +#include + using namespace Genode; @@ -43,7 +46,8 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst, rcv_window.rcv_wnd(log2_max); } - Nova::Utcb &utcb = *(Nova::Utcb *)Thread::myself()->utcb(); + Thread * const myself = Thread::myself(); + Nova::Utcb &utcb = *(Nova::Utcb *)myself->utcb(); /* the protocol value is unused as the badge is delivered by the kernel */ if (!copy_msgbuf_to_utcb(utcb, snd_msg, 0)) { @@ -51,8 +55,15 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst, throw Ipc_error(); } + /* + * Determine manually defined selector for receiving the call result. + * See the comment in 'base-nova/include/nova/native_thread.h'. + */ + addr_t const manual_rcv_sel = myself ? myself->native_thread().client_rcv_sel + : Receive_window::INVALID_INDEX; + /* if we can't setup receive window, die in order to recognize the issue */ - if (!rcv_window.prepare_rcv_window(utcb, dst.rcv_window())) + if (!rcv_window.prepare_rcv_window(utcb, manual_rcv_sel)) /* printf doesn't work here since for IPC also rcv_prepare* is used */ nova_die(); @@ -64,7 +75,7 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst, utcb.set_msg_word(0); /* track potentially received caps and invalidate unused caps slots */ - rcv_window.post_ipc(utcb, dst.rcv_window()); + rcv_window.post_ipc(utcb, manual_rcv_sel); if (res != Nova::NOVA_OK) return Rpc_exception_code(Rpc_exception_code::INVALID_OBJECT); @@ -75,3 +86,112 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst, return Rpc_exception_code(copy_utcb_to_msgbuf(utcb, rcv_window, rcv_msg)); } + + +/******************** + ** Receive_window ** + ********************/ + +void Receive_window::rcv_pt_sel(Native_capability &cap) +{ + if (_rcv_pt_sel_cnt >= _rcv_pt_sel_max) { + cap = Native_capability(); + return; + } + + /* return only received or translated caps */ + cap = Capability_space::import(_rcv_pt_sel[_rcv_pt_sel_cnt++].sel); +} + + +bool Receive_window::rcv_invalid() const +{ + return _rcv_pt_base == Capability_space::INVALID_INDEX; +} + + +bool Receive_window::rcv_cleanup(bool keep, unsigned short const new_max) +{ + /* mark used mapped capabilities as used to prevent freeing */ + bool reinit = false; + for (unsigned i = 0; i < _rcv_pt_sel_cnt; i++) { + if (!_rcv_pt_sel[i].del) + continue; + + /* should never happen */ + if (_rcv_pt_sel[i].sel < _rcv_pt_base || + (_rcv_pt_sel[i].sel >= _rcv_pt_base + MAX_CAP_ARGS)) + nova_die(); + + _rcv_pt_cap_free [_rcv_pt_sel[i].sel - _rcv_pt_base] = USED_CAP; + + reinit = true; + } + + /* if old receive window was smaller, we need to re-init */ + for (unsigned i = 0; !reinit && i < new_max; i++) + if (_rcv_pt_cap_free[i] == FREE_INVALID) + reinit = true; + + _rcv_pt_sel_cnt = 0; + _rcv_pt_sel_max = 0; + + /* we can keep the cap selectors if none was used */ + if (keep && !reinit) { + for (unsigned i = 0; i < MAX_CAP_ARGS; i++) { + /* revoke received caps which are unused */ + if (_rcv_pt_cap_free[i] == UNUSED_CAP) + Nova::revoke(Nova::Obj_crd(_rcv_pt_base + i, 0), true); + + /* free rest of indexes if new_max is smaller then last window */ + if (i >= new_max && _rcv_pt_cap_free[i] == FREE_SEL) + cap_map()->remove(_rcv_pt_base + i, 0, false); + } + + return false; + } + + /* decrease ref count if valid selector */ + for (unsigned i = 0; i < MAX_CAP_ARGS; i++) { + if (_rcv_pt_cap_free[i] == FREE_INVALID) + continue; + cap_map()->remove(_rcv_pt_base + i, 0, _rcv_pt_cap_free[i] != FREE_SEL); + } + + return true; +} + + +bool Receive_window::prepare_rcv_window(Nova::Utcb &utcb, addr_t rcv_window) +{ + /* open maximal translate window */ + utcb.crd_xlt = Nova::Obj_crd(0, ~0UL); + + /* use receive window if specified */ + if (rcv_window != INVALID_INDEX) { + /* cleanup if receive window already used */ + if (!rcv_invalid()) rcv_cleanup(false); + + _rcv_pt_base = rcv_window; + + /* open receive window */ + utcb.crd_rcv = Nova::Obj_crd(_rcv_pt_base, _rcv_wnd_log2); + return true; + } + + /* allocate receive window if necessary, otherwise use old one */ + if (rcv_invalid() || rcv_cleanup(true, 1U << _rcv_wnd_log2)) + { + _rcv_pt_base = cap_map()->insert(_rcv_wnd_log2); + + if (_rcv_pt_base == INVALID_INDEX) { + /* no mappings can be received */ + utcb.crd_rcv = Nova::Obj_crd(); + return false; + } + } + + /* open receive window */ + utcb.crd_rcv = Nova::Obj_crd(_rcv_pt_base, _rcv_wnd_log2); + return true; +} diff --git a/repos/base-nova/src/lib/base/rpc_entrypoint.cc b/repos/base-nova/src/lib/base/rpc_entrypoint.cc index 8c79254ac..3407f0d2b 100644 --- a/repos/base-nova/src/lib/base/rpc_entrypoint.cc +++ b/repos/base-nova/src/lib/base/rpc_entrypoint.cc @@ -23,7 +23,6 @@ #include /* NOVA includes */ -#include #include #include @@ -42,7 +41,7 @@ Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj) /* _ec_sel is invalid until thread gets started */ if (native_thread().ec_sel != Native_thread::INVALID_INDEX) - ec_cap = Native_capability(native_thread().ec_sel); + ec_cap = Capability_space::import(native_thread().ec_sel); else ec_cap = _thread_cap; @@ -127,7 +126,7 @@ void Rpc_entrypoint::_activation_entry() Rpc_entrypoint &ep = *static_cast(Thread::myself()); Nova::Utcb &utcb = *(Nova::Utcb *)Thread::myself()->utcb(); - Receive_window &rcv_window = ep.native_thread().rcv_window; + Receive_window &rcv_window = ep.native_thread().server_rcv_window; rcv_window.post_ipc(utcb); /* handle ill-formed message */ @@ -146,7 +145,7 @@ void Rpc_entrypoint::_activation_entry() Rpc_exception_code exc = Rpc_exception_code(Rpc_exception_code::INVALID_OBJECT); /* in case of a portal cleanup call we are done here - just reply */ - if (ep._cap.local_name() == id_pt) { + if (ep._cap.local_name() == (long)id_pt) { if (!rcv_window.prepare_rcv_window(utcb)) PWRN("out of capability selectors for handling server requests"); @@ -224,12 +223,13 @@ Rpc_entrypoint::Rpc_entrypoint(Pd_session *pd_session, size_t stack_size, Thread::start(); /* create cleanup portal */ - _cap = _alloc_rpc_cap(_pd_session, Native_capability(native_thread().ec_sel), + _cap = _alloc_rpc_cap(_pd_session, + Capability_space::import(native_thread().ec_sel), (addr_t)_activation_entry); if (!_cap.valid()) throw Cpu_session::Thread_creation_failed(); - Receive_window &rcv_window = Thread::native_thread().rcv_window; + Receive_window &rcv_window = Thread::native_thread().server_rcv_window; /* prepare portal receive window of new thread */ if (!rcv_window.prepare_rcv_window(*(Nova::Utcb *)&_stack->utcb())) diff --git a/repos/base-nova/src/lib/base/signal_submit.cc b/repos/base-nova/src/lib/base/signal_submit.cc index 668615ff0..3c2df933d 100644 --- a/repos/base-nova/src/lib/base/signal_submit.cc +++ b/repos/base-nova/src/lib/base/signal_submit.cc @@ -16,6 +16,9 @@ #include #include +/* NOVA includes */ +#include + using namespace Genode; diff --git a/repos/base-nova/src/lib/base/stack.cc b/repos/base-nova/src/lib/base/stack.cc index 9e549d321..a768ce6e0 100644 --- a/repos/base-nova/src/lib/base/stack.cc +++ b/repos/base-nova/src/lib/base/stack.cc @@ -26,8 +26,8 @@ #include #include -/* base-nova includes */ -#include +/* NOVA includes */ +#include using namespace Genode; diff --git a/repos/base-nova/src/lib/base/thread_start.cc b/repos/base-nova/src/lib/base/thread_start.cc index ffcb6de30..cee4bec8a 100644 --- a/repos/base-nova/src/lib/base/thread_start.cc +++ b/repos/base-nova/src/lib/base/thread_start.cc @@ -29,6 +29,8 @@ /* NOVA includes */ #include #include +#include +#include using namespace Genode; @@ -80,7 +82,8 @@ void Thread::_init_platform_thread(size_t weight, Type type) if (type == MAIN || type == REINITIALIZED_MAIN) { _thread_cap = env()->parent()->main_thread_cap(); - Genode::Native_capability pager_cap(Nova::PT_SEL_MAIN_PAGER); + Genode::Native_capability pager_cap = + Capability_space::import(Nova::PT_SEL_MAIN_PAGER); native_thread().exc_pt_sel = 0; native_thread().ec_sel = Nova::PT_SEL_MAIN_EC; diff --git a/repos/base-nova/src/test/platform/ipc.cc b/repos/base-nova/src/test/platform/ipc.cc index c3a819e49..eb4967c6a 100644 --- a/repos/base-nova/src/test/platform/ipc.cc +++ b/repos/base-nova/src/test/platform/ipc.cc @@ -44,7 +44,7 @@ long Test::cap_void_manual(Genode::Native_capability dst, if (!arg1.valid()) return Genode::Rpc_exception_code::INVALID_OBJECT; - Nova::Obj_crd crd(arg1.local_name(), 0, arg1.dst().rights()); + Nova::Crd crd = Genode::Capability_space::crd(arg1); if (!utcb->append_item(crd, 0, false, false, false)) return Genode::Rpc_exception_code::INVALID_OBJECT; diff --git a/repos/base-nova/src/test/platform/main.cc b/repos/base-nova/src/test/platform/main.cc index f911ab658..c6d6d2e41 100644 --- a/repos/base-nova/src/test/platform/main.cc +++ b/repos/base-nova/src/test/platform/main.cc @@ -49,8 +49,8 @@ void test_translate() long rpc = Test::cap_void_manual(session_cap, session_cap, local_name); if (rpc != Genode::Rpc_exception_code::SUCCESS || - local_name == session_cap.local_name() || - local_name == Native_thread::INVALID_INDEX) + local_name == (addr_t)session_cap.local_name() || + local_name == (addr_t)Native_thread::INVALID_INDEX) { failed ++; PERR("%s: ipc call failed %lx", __func__, rpc); @@ -58,12 +58,12 @@ void test_translate() return; } - Genode::Native_capability copy1(local_name); + Genode::Native_capability copy1 = Capability_space::import(local_name); rpc = Test::cap_void_manual(session_cap, copy1, local_name); if (rpc != Genode::Rpc_exception_code::SUCCESS || - local_name == copy1.local_name() || - local_name == Native_thread::INVALID_INDEX) + local_name == (addr_t)copy1.local_name() || + local_name == (addr_t)Native_thread::INVALID_INDEX) { failed ++; PERR("%s: ipc call failed %lx", __func__, rpc); @@ -71,7 +71,7 @@ void test_translate() return; } - Genode::Native_capability copy2(local_name); + Genode::Native_capability copy2 = Capability_space::import(local_name); PINF("delegation session_cap->copy1->copy2 0x%lx->0x%lx->0x%lx", session_cap.local_name(), copy1.local_name(), copy2.local_name()); @@ -144,8 +144,8 @@ void test_revoke() long rpc = Test::cap_void_manual(session_cap, session_cap, local_name); if (rpc != Genode::Rpc_exception_code::SUCCESS || - local_name == session_cap.local_name() || - local_name == Native_thread::INVALID_INDEX) + local_name == (addr_t)session_cap.local_name() || + local_name == (addr_t)Native_thread::INVALID_INDEX) { failed ++; PERR("test_revoke ipc call failed %lx", rpc); @@ -153,12 +153,12 @@ void test_revoke() return; } - Genode::Native_capability copy_session_cap(local_name); + Genode::Native_capability copy_session_cap = Capability_space::import(local_name); rpc = Test::cap_void_manual(copy_session_cap, copy_session_cap, local_name); if (rpc != Genode::Rpc_exception_code::SUCCESS || - local_name == copy_session_cap.local_name() || - local_name == Native_thread::INVALID_INDEX) + local_name == (addr_t)copy_session_cap.local_name() || + local_name == (addr_t)Native_thread::INVALID_INDEX) { failed ++; PERR("test_revoke ipc call failed %lx", rpc); @@ -178,8 +178,8 @@ void test_revoke() Nova::Obj_crd crd_ses(copy_session_cap.local_name(), 0); res = Nova::lookup(crd_ses); - if (res != Nova::NOVA_OK || crd_ses.base() != copy_session_cap.local_name() || crd_ses.type() != 3 || - crd_ses.order() != 0) { + if (res != Nova::NOVA_OK || crd_ses.base() != (addr_t)copy_session_cap.local_name() + || crd_ses.type() != 3 || crd_ses.order() != 0) { failed ++; PERR("%u - lookup call failed err=%x is_null=%u", __LINE__, res, crd_ses.is_null()); ep.dissolve(&component); @@ -222,13 +222,13 @@ void test_revoke() * as used before by copy_session_cap */ Genode::Thread * myself = Genode::Thread::myself(); - Genode::Native_capability pager_cap(myself->native_thread().ec_sel + 1); + Genode::Native_capability pager_cap = Capability_space::import(myself->native_thread().ec_sel + 1); request_event_portal(pager_cap, copy_session_cap.local_name(), 0, 0); /* check whether the requested cap before is valid and placed well */ crd_ses = Nova::Obj_crd(copy_session_cap.local_name(), 0); res = Nova::lookup(crd_ses); - if (res != Nova::NOVA_OK || crd_ses.base() != copy_session_cap.local_name() || + if (res != Nova::NOVA_OK || crd_ses.base() != (addr_t)copy_session_cap.local_name() || crd_ses.type() != 3 || crd_ses.order() != 0) { failed ++; PERR("%u - lookup call failed err=%x is_null=%u", __LINE__, res, crd_ses.is_null()); diff --git a/repos/base-nova/src/test/platform/server.h b/repos/base-nova/src/test/platform/server.h index dfd0c87a3..45e283fbc 100644 --- a/repos/base-nova/src/test/platform/server.h +++ b/repos/base-nova/src/test/platform/server.h @@ -21,6 +21,10 @@ #include #include +/* NOVA includes */ +#include +#include + namespace Test { struct Session; struct Client; @@ -115,4 +119,4 @@ inline Genode::addr_t Test::Component::leak_utcb_address() { return reinterpret_cast(Genode::Thread::myself()->utcb()); } inline Genode::Native_capability Test::Component::cap_cap(Genode::addr_t cap) { - return Genode::Native_capability(cap); } + return Genode::Capability_space::import(cap); } diff --git a/repos/base-okl4/include/base/native_capability.h b/repos/base-okl4/include/base/native_capability.h deleted file mode 100644 index faa839f38..000000000 --- a/repos/base-okl4/include/base/native_capability.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * \brief Native capability type - * \author Norman Feske - * \date 2008-07-26 - */ - -/* - * Copyright (C) 2008-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__BASE__NATIVE_CAPABILITY_H_ -#define _INCLUDE__BASE__NATIVE_CAPABILITY_H_ - -#include -#include - -namespace Okl4 { extern "C" { -#include -} } - -namespace Genode { - - struct Cap_dst_policy - { - typedef Okl4::L4_ThreadId_t Dst; - static bool valid(Dst tid) { return !Okl4::L4_IsNilThread(tid); } - static Dst invalid() { return Okl4::L4_nilthread; } - static void copy(void* dst, Native_capability_tpl* src); - }; - - typedef Native_capability_tpl Native_capability; -} - -#endif /* _INCLUDE__BASE__NATIVE_CAPABILITY_H_ */ diff --git a/repos/base-okl4/include/base/thread_state.h b/repos/base-okl4/include/base/thread_state.h deleted file mode 100644 index ecbe2c0e5..000000000 --- a/repos/base-okl4/include/base/thread_state.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * \brief Thread state - * \author Stefan Kalkowski - * \date 2007-07-30 - * - * This file contains the OKL4 specific part of the thread state. - */ - -/* - * Copyright (C) 2007-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__BASE__THREAD_STATE_H_ -#define _INCLUDE__BASE__THREAD_STATE_H_ - -namespace Okl4 { extern "C" { -#include -} } - -#include - -namespace Genode { - - struct Thread_state : Thread_state_base - { - Okl4::L4_ThreadId_t tid; /* OKL4 specific thread id */ - }; -} - -#endif /* _INCLUDE__BASE__THREAD_STATE_H_ */ diff --git a/repos/base-okl4/lib/mk/base-common.mk b/repos/base-okl4/lib/mk/base-common.mk index 256326a15..9d03d7f92 100644 --- a/repos/base-okl4/lib/mk/base-common.mk +++ b/repos/base-okl4/lib/mk/base-common.mk @@ -8,9 +8,7 @@ include $(BASE_DIR)/lib/mk/base-common.inc LIBS += startup -SRC_CC += cap_copy.cc +SRC_CC += capability.cc capability_raw.cc SRC_CC += signal_submit.cc SRC_CC += rpc_dispatch_loop.cc SRC_CC += thread.cc thread_bootstrap.cc thread_myself.cc - -vpath cap_copy.cc $(BASE_DIR)/src/lib/startup diff --git a/repos/base-okl4/lib/mk/base.mk b/repos/base-okl4/lib/mk/base.mk index a32c7ebd7..eec5dc939 100644 --- a/repos/base-okl4/lib/mk/base.mk +++ b/repos/base-okl4/lib/mk/base.mk @@ -2,3 +2,4 @@ include $(BASE_DIR)/lib/mk/base.inc SRC_CC += thread_start.cc SRC_CC += cache.cc +SRC_CC += capability_space.cc diff --git a/repos/base-okl4/src/core/include/rpc_cap_factory.h b/repos/base-okl4/src/core/include/rpc_cap_factory.h new file mode 100644 index 000000000..fd1514523 --- /dev/null +++ b/repos/base-okl4/src/core/include/rpc_cap_factory.h @@ -0,0 +1,39 @@ +/* + * \brief RPC capability factory + * \author Norman Feske + * \date 2016-01-19 + */ + +/* + * 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__RPC_CAP_FACTORY_H_ +#define _CORE__INCLUDE__RPC_CAP_FACTORY_H_ + +#include +#include +#include + +namespace Genode { class Rpc_cap_factory; } + +class Genode::Rpc_cap_factory +{ + private: + + static Native_capability _alloc(Rpc_cap_factory *owner, + Native_capability ep); + + public: + + Rpc_cap_factory(Allocator &md_alloc) { } + + Native_capability alloc(Native_capability ep); + + void free(Native_capability cap); +}; + +#endif /* _CORE__INCLUDE__RPC_CAP_FACTORY_H_ */ diff --git a/repos/base-okl4/src/core/pager.cc b/repos/base-okl4/src/core/pager.cc index 3df81be42..defdfef66 100644 --- a/repos/base-okl4/src/core/pager.cc +++ b/repos/base-okl4/src/core/pager.cc @@ -22,6 +22,7 @@ /* base-internal includes */ #include #include +#include namespace Okl4 { extern "C" { #include @@ -156,5 +157,5 @@ void Ipc_pager::acknowledge_wakeup() Untyped_capability Pager_entrypoint::_pager_object_cap(unsigned long badge) { - return Untyped_capability(native_thread().l4id, badge); + return Capability_space::import(native_thread().l4id, Rpc_obj_key(badge)); } diff --git a/repos/base-okl4/src/core/pager_object.cc b/repos/base-okl4/src/core/pager_object.cc index bb3adab87..da81e6684 100644 --- a/repos/base-okl4/src/core/pager_object.cc +++ b/repos/base-okl4/src/core/pager_object.cc @@ -14,6 +14,9 @@ /* core includes */ #include +/* base-internal includes */ +#include + /* OKL4 includes */ namespace Okl4 { extern "C" { #include @@ -40,7 +43,7 @@ void Pager_object::wake_up() L4_LoadMR(1, 0); /* fault address */ L4_LoadMR(2, (unsigned long)this); /* instruction pointer */ - L4_Call(cap().dst()); + L4_Call(Capability_space::ipc_cap_data(cap()).dst); } diff --git a/repos/base-okl4/src/core/platform_thread.cc b/repos/base-okl4/src/core/platform_thread.cc index 1a96061a3..a3168e01a 100644 --- a/repos/base-okl4/src/core/platform_thread.cc +++ b/repos/base-okl4/src/core/platform_thread.cc @@ -24,6 +24,9 @@ #include #include +/* base-internal includes */ +#include + /* OKL4 includes */ namespace Okl4 { extern "C" { #include @@ -50,7 +53,11 @@ int Platform_thread::start(void *ip, void *sp, unsigned int cpu_no) _thread_id); L4_SpaceId_t space_id = L4_SpaceId(space_no); L4_ThreadId_t scheduler = L4_rootserver; - L4_ThreadId_t pager = _pager ? _pager->cap().dst() : L4_nilthread; + + L4_ThreadId_t pager = _pager + ? Capability_space::ipc_cap_data(_pager->cap()).dst + : L4_nilthread; + L4_ThreadId_t exception_handler = pager; L4_Word_t resources = 0; L4_Word_t utcb_size_per_task = L4_GetUtcbSize()*(1 << Thread_id_bits::THREAD); diff --git a/repos/base-okl4/src/core/spec/x86/platform_thread_x86.cc b/repos/base-okl4/src/core/spec/x86/platform_thread_x86.cc index 2bf59faed..fdcd6728b 100644 --- a/repos/base-okl4/src/core/spec/x86/platform_thread_x86.cc +++ b/repos/base-okl4/src/core/spec/x86/platform_thread_x86.cc @@ -26,7 +26,6 @@ using namespace Okl4; Thread_state Platform_thread::state() { Thread_state s; - s.tid = _l4_thread_id; L4_Copy_regs_to_mrs(_l4_thread_id); diff --git a/repos/base-okl4/src/core/target.inc b/repos/base-okl4/src/core/target.inc index b1c4111e1..df81d3e48 100644 --- a/repos/base-okl4/src/core/target.inc +++ b/repos/base-okl4/src/core/target.inc @@ -12,6 +12,7 @@ SRC_CC += stack_area.cc \ cpu_session_component.cc \ cpu_session_support.cc \ cpu_thread_component.cc \ + capability_space.cc \ dataspace_component.cc \ default_log.cc \ dump_alloc.cc \ @@ -25,7 +26,7 @@ SRC_CC += stack_area.cc \ pd_session_component.cc \ pd_upgrade_ram_quota.cc \ pd_assign_pci.cc \ - rpc_cap_factory.cc \ + rpc_cap_factory_l4.cc \ platform.cc \ platform_pd.cc \ platform_services.cc \ @@ -50,10 +51,11 @@ vpath rom_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_support.cc $(GEN_CORE_DIR) vpath cpu_thread_component.cc $(GEN_CORE_DIR) +vpath capability_space.cc $(GEN_CORE_DIR) +vpath rpc_cap_factory_l4.cc $(GEN_CORE_DIR) vpath pd_session_component.cc $(GEN_CORE_DIR) vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) vpath pd_assign_pci.cc $(GEN_CORE_DIR) -vpath rpc_cap_factory.cc $(GEN_CORE_DIR) vpath region_map_component.cc $(GEN_CORE_DIR) vpath io_mem_session_component.cc $(GEN_CORE_DIR) vpath io_mem_session_support.cc $(GEN_CORE_DIR) diff --git a/repos/base-okl4/src/include/base/internal/parent_cap.h b/repos/base-okl4/src/include/base/internal/parent_cap.h new file mode 100644 index 000000000..d8fa0a4f7 --- /dev/null +++ b/repos/base-okl4/src/include/base/internal/parent_cap.h @@ -0,0 +1,40 @@ +/* + * \brief Interface to obtain the parent capability for the component + * \author Norman Feske + * \date 2015-05-12 + */ + +/* + * Copyright (C) 2015-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__BASE__INTERNAL__PARENT_CAP_H_ +#define _INCLUDE__BASE__INTERNAL__PARENT_CAP_H_ + +/* Genode includes */ +#include + +/* base-internal includes */ +#include +#include + + +namespace Genode { + + static inline Parent_capability parent_cap() + { + Native_capability::Raw &raw = *(Native_capability::Raw *)&_parent_cap; + + Okl4::L4_ThreadId_t tid; + tid.raw = raw.v[0]; + + Native_capability cap = Capability_space::import(tid, Rpc_obj_key(raw.v[1])); + + return reinterpret_cap_cast(cap); + } +} + +#endif /* _INCLUDE__BASE__INTERNAL__PARENT_CAP_H_ */ diff --git a/repos/base-okl4/src/include/base/internal/rpc_destination.h b/repos/base-okl4/src/include/base/internal/rpc_destination.h new file mode 100644 index 000000000..19a5be466 --- /dev/null +++ b/repos/base-okl4/src/include/base/internal/rpc_destination.h @@ -0,0 +1,39 @@ +/* + * \brief RPC destination type + * \author Norman Feske + * \date 2016-03-11 + */ + +/* + * 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__BASE__INTERNAL__RPC_DESTINATION_H_ +#define _INCLUDE__BASE__INTERNAL__RPC_DESTINATION_H_ + +/* OKL4 includes */ +namespace Okl4 { +#include +} + +namespace Genode { + + typedef Okl4::L4_ThreadId_t Rpc_destination; + + static inline Rpc_destination invalid_rpc_destination() + { + Okl4::L4_ThreadId_t tid; + tid.raw = 0; + return tid; + } + + static void print(Output &out, Rpc_destination const &dst) + { + Genode::print(out, "tid=", Hex(dst.raw)); + } +} + +#endif /* _INCLUDE__BASE__INTERNAL__RPC_DESTINATION_H_ */ diff --git a/repos/base-okl4/src/lib/base/capability_raw.cc b/repos/base-okl4/src/lib/base/capability_raw.cc new file mode 100644 index 000000000..90222e4dc --- /dev/null +++ b/repos/base-okl4/src/lib/base/capability_raw.cc @@ -0,0 +1,28 @@ +/* + * \brief Capability + * \author Norman Feske + * \date 2016-06-16 + */ + +/* + * 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. + */ + +#include + +/* base-internal includes */ +#include + +using namespace Genode; + + +Native_capability::Raw Native_capability::raw() const +{ + Capability_space::Ipc_cap_data const cap_data = + Capability_space::ipc_cap_data(*this); + + return { { cap_data.dst.raw, cap_data.rpc_obj_key.value(), 0, 0 } }; +} diff --git a/repos/base-okl4/src/lib/base/ipc.cc b/repos/base-okl4/src/lib/base/ipc.cc index a846afaa4..ba192dd78 100644 --- a/repos/base-okl4/src/lib/base/ipc.cc +++ b/repos/base-okl4/src/lib/base/ipc.cc @@ -13,40 +13,26 @@ /* Genode includes */ #include +#include #include #include /* base-internal includes */ #include #include +#include /* OKL4 includes */ namespace Okl4 { extern "C" { #include #include #include -#include } } using namespace Genode; using namespace Okl4; -/*************** - ** Utilities ** - ***************/ - -/** - * Print string, bypassing Genode's LOG mechanism - * - * This function is used in conditions where Genode's base mechanisms may fail. - */ -static void kdb_emergency_print(const char *s) -{ - for (; s && *s; s++) - Okl4::L4_KDB_PrintChar(*s); -} - /* * Message layout within the UTCB * @@ -85,7 +71,18 @@ static L4_Word_t extract_msg_from_utcb(L4_MsgTag_t rcv_tag, Msgbuf_base &rcv_msg L4_ThreadId_t tid; L4_StoreMR(3 + 2*i, &tid.raw); L4_StoreMR(3 + 2*i + 1, &local_name); - rcv_msg.insert(Native_capability(tid, local_name)); + + Rpc_obj_key const rpc_obj_key(local_name); + bool const cap_valid = tid.raw != 0UL; + + Native_capability cap; + if (cap_valid) { + cap = Capability_space::lookup(rpc_obj_key); + if (!cap.valid()) + cap = Capability_space::import(tid, rpc_obj_key); + } + + rcv_msg.insert(cap); } unsigned const data_start_idx = 3 + 2*num_caps; @@ -120,7 +117,7 @@ static void copy_msg_to_utcb(Msgbuf_base const &snd_msg, L4_Word_t local_name) unsigned const num_msg_words = num_data_words + num_header_words; if (num_msg_words >= L4_GetMessageRegisters()) { - kdb_emergency_print("Message does not fit into UTCB message registers\n"); + raw("Message does not fit into UTCB message registers"); L4_LoadMR(0, 0); return; } @@ -134,8 +131,19 @@ static void copy_msg_to_utcb(Msgbuf_base const &snd_msg, L4_Word_t local_name) L4_LoadMR(2, snd_msg.used_caps()); for (unsigned i = 0; i < snd_msg.used_caps(); i++) { - L4_LoadMR(3 + i*2, snd_msg.cap(i).dst().raw); - L4_LoadMR(3 + i*2 + 1, snd_msg.cap(i).local_name()); + + Native_capability cap = snd_msg.cap(i); + if (cap.valid()) { + Capability_space::Ipc_cap_data const cap_data = + Capability_space::ipc_cap_data(snd_msg.cap(i)); + + L4_LoadMR(3 + i*2, (L4_Word_t)cap_data.dst.raw); + L4_LoadMR(3 + i*2 + 1, (L4_Word_t)cap_data.rpc_obj_key.value()); + } else { + L4_LoadMR(3 + i*2, (L4_Word_t)0UL); + L4_LoadMR(3 + i*2 + 1, (L4_Word_t)0UL); + } + } L4_LoadMRs(num_header_words, num_data_words, (L4_Word_t *)snd_msg.data()); @@ -150,12 +158,15 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst, Msgbuf_base &snd_msg, Msgbuf_base &rcv_msg, size_t) { + Capability_space::Ipc_cap_data const dst_data = + Capability_space::ipc_cap_data(dst); + /* copy call message to the UTCBs message registers */ - copy_msg_to_utcb(snd_msg, dst.local_name()); + copy_msg_to_utcb(snd_msg, dst_data.rpc_obj_key.value()); L4_Accept(L4_UntypedWordsAcceptor); - L4_MsgTag_t rcv_tag = L4_Call(dst.dst()); + L4_MsgTag_t rcv_tag = L4_Call(dst_data.dst); enum { ERROR_MASK = 0xe, ERROR_CANCELED = 3 << 1 }; if (L4_IpcFailed(rcv_tag) && @@ -163,7 +174,7 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst, throw Genode::Blocking_canceled(); if (L4_IpcFailed(rcv_tag)) { - kdb_emergency_print("Ipc failed\n"); + raw("Ipc failed"); return Rpc_exception_code(Rpc_exception_code::INVALID_OBJECT); } @@ -183,7 +194,7 @@ void Genode::ipc_reply(Native_capability caller, Rpc_exception_code exc, copy_msg_to_utcb(snd_msg, exc.value); /* perform non-blocking IPC send operation */ - L4_MsgTag_t rcv_tag = L4_Reply(caller.dst()); + L4_MsgTag_t rcv_tag = L4_Reply(Capability_space::ipc_cap_data(caller).dst); if (L4_IpcFailed(rcv_tag)) PERR("ipc error in _reply - gets ignored"); @@ -204,7 +215,8 @@ Genode::Rpc_request Genode::ipc_reply_wait(Reply_capability const &last_caller, /* copy reply to the UTCBs message registers */ copy_msg_to_utcb(reply_msg, exc.value); - rcv_tag = L4_ReplyWait(last_caller.dst(), &caller); + rcv_tag = L4_ReplyWait(Capability_space::ipc_cap_data(last_caller).dst, + &caller); } else { rcv_tag = L4_Wait(&caller); } @@ -212,7 +224,7 @@ Genode::Rpc_request Genode::ipc_reply_wait(Reply_capability const &last_caller, /* copy request message from the UTCBs message registers */ unsigned long const badge = extract_msg_from_utcb(rcv_tag, request_msg); - return Rpc_request(Native_capability(caller, 0), badge); + return Rpc_request(Capability_space::import(caller, Rpc_obj_key()), badge); } @@ -231,7 +243,10 @@ static inline Okl4::L4_ThreadId_t thread_get_my_global_id() } -Ipc_server::Ipc_server() : Native_capability(thread_get_my_global_id(), 0) { } +Ipc_server::Ipc_server() +: + Native_capability(Capability_space::import(thread_get_my_global_id(), Rpc_obj_key())) +{ } Ipc_server::~Ipc_server() { } diff --git a/repos/base-pistachio/include/base/native_capability.h b/repos/base-pistachio/include/base/native_capability.h deleted file mode 100644 index 8bec3c24f..000000000 --- a/repos/base-pistachio/include/base/native_capability.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * \brief Native capability type on Pistachio - * \author Norman Feske - * \date 2008-07-26 - */ - -/* - * Copyright (C) 2008-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__BASE__NATIVE_CAPABILITY_H_ -#define _INCLUDE__BASE__NATIVE_CAPABILITY_H_ - -#include -#include - -namespace Pistachio { -#include -} - -namespace Genode { - - struct Cap_dst_policy - { - typedef Pistachio::L4_ThreadId_t Dst; - static bool valid(Dst tid) { return !Pistachio::L4_IsNilThread(tid); } - static Dst invalid() - { - using namespace Pistachio; - return L4_nilthread; - } - static void copy(void* dst, Native_capability_tpl* src); - }; - - typedef Native_capability_tpl Native_capability; -} - -#endif /* _INCLUDE__BASE__NATIVE_CAPABILITY_H_ */ diff --git a/repos/base-pistachio/lib/mk/base-common.mk b/repos/base-pistachio/lib/mk/base-common.mk index 6730a5da9..28a975ee3 100644 --- a/repos/base-pistachio/lib/mk/base-common.mk +++ b/repos/base-pistachio/lib/mk/base-common.mk @@ -8,12 +8,10 @@ include $(BASE_DIR)/lib/mk/base-common.inc LIBS += startup syscall -SRC_CC += cap_copy.cc +SRC_CC += capability.cc capability_raw.cc SRC_CC += signal_submit.cc SRC_CC += rpc_dispatch_loop.cc SRC_CC += thread.cc thread_bootstrap.cc thread_myself.cc # suppress warning caused by Pistachio's 'l4/message.h' CC_WARN += -Wno-array-bounds - -vpath cap_copy.cc $(BASE_DIR)/src/lib/startup diff --git a/repos/base-pistachio/lib/mk/base.mk b/repos/base-pistachio/lib/mk/base.mk index a32c7ebd7..eec5dc939 100644 --- a/repos/base-pistachio/lib/mk/base.mk +++ b/repos/base-pistachio/lib/mk/base.mk @@ -2,3 +2,4 @@ include $(BASE_DIR)/lib/mk/base.inc SRC_CC += thread_start.cc SRC_CC += cache.cc +SRC_CC += capability_space.cc diff --git a/repos/base-pistachio/src/core/include/rpc_cap_factory.h b/repos/base-pistachio/src/core/include/rpc_cap_factory.h new file mode 100644 index 000000000..fd1514523 --- /dev/null +++ b/repos/base-pistachio/src/core/include/rpc_cap_factory.h @@ -0,0 +1,39 @@ +/* + * \brief RPC capability factory + * \author Norman Feske + * \date 2016-01-19 + */ + +/* + * 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__RPC_CAP_FACTORY_H_ +#define _CORE__INCLUDE__RPC_CAP_FACTORY_H_ + +#include +#include +#include + +namespace Genode { class Rpc_cap_factory; } + +class Genode::Rpc_cap_factory +{ + private: + + static Native_capability _alloc(Rpc_cap_factory *owner, + Native_capability ep); + + public: + + Rpc_cap_factory(Allocator &md_alloc) { } + + Native_capability alloc(Native_capability ep); + + void free(Native_capability cap); +}; + +#endif /* _CORE__INCLUDE__RPC_CAP_FACTORY_H_ */ diff --git a/repos/base-pistachio/src/core/pager.cc b/repos/base-pistachio/src/core/pager.cc index cfeb6d204..ec0a810cb 100644 --- a/repos/base-pistachio/src/core/pager.cc +++ b/repos/base-pistachio/src/core/pager.cc @@ -17,8 +17,9 @@ /* base-internal includes */ #include +#include -/* Core includes */ +/* core includes */ #include #include @@ -142,5 +143,5 @@ void Ipc_pager::acknowledge_wakeup() Untyped_capability Pager_entrypoint::_pager_object_cap(unsigned long badge) { - return Untyped_capability(native_thread().l4id, badge); + return Capability_space::import(native_thread().l4id, Rpc_obj_key(badge)); } diff --git a/repos/base-pistachio/src/core/pager_object.cc b/repos/base-pistachio/src/core/pager_object.cc index 0165684d5..b925a1588 100644 --- a/repos/base-pistachio/src/core/pager_object.cc +++ b/repos/base-pistachio/src/core/pager_object.cc @@ -14,6 +14,9 @@ /* core includes */ #include +/* base-internal includes */ +#include + /* Pistachio includes */ namespace Pistachio { #include @@ -40,7 +43,7 @@ void Pager_object::wake_up() L4_LoadMR(1, 0); /* fault address */ L4_LoadMR(2, (unsigned long)this); /* instruction pointer */ - L4_Call(cap().dst()); + L4_Call(Capability_space::ipc_cap_data(cap()).dst); } diff --git a/repos/base-pistachio/src/core/platform.cc b/repos/base-pistachio/src/core/platform.cc index b5ec20ea5..23cab3cfb 100644 --- a/repos/base-pistachio/src/core/platform.cc +++ b/repos/base-pistachio/src/core/platform.cc @@ -21,6 +21,7 @@ /* base-internal includes */ #include #include +#include /* core includes */ #include @@ -206,7 +207,7 @@ Platform::Sigma0::Sigma0() : Pager_object(Cpu_session_capability(), Thread_capability(), 0, Affinity::Location()) { - cap(Native_capability(Pistachio::get_sigma0(), 0)); + cap(Capability_space::import(Pistachio::get_sigma0(), Rpc_obj_key())); } @@ -225,7 +226,7 @@ Platform::Core_pager::Core_pager(Platform_pd *core_pd) Platform_thread::pager(sigma0()); core_pd->bind_thread(this); - cap(Native_capability(native_thread_id(), 0)); + cap(Capability_space::import(native_thread_id(), Rpc_obj_key())); /* stack begins at the top end of the '_core_pager_stack' array */ void *sp = (void *)&_core_pager_stack[PAGER_STACK_ELEMENTS - 1]; diff --git a/repos/base-pistachio/src/core/platform_thread.cc b/repos/base-pistachio/src/core/platform_thread.cc index d34bbc64a..084c4d462 100644 --- a/repos/base-pistachio/src/core/platform_thread.cc +++ b/repos/base-pistachio/src/core/platform_thread.cc @@ -15,6 +15,9 @@ #include #include +/* base-internal includes */ +#include + /* core includes */ #include #include @@ -64,7 +67,9 @@ Affinity::Location Platform_thread::affinity() const int Platform_thread::start(void *ip, void *sp) { L4_ThreadId_t thread = _l4_thread_id; - L4_ThreadId_t pager = _pager ? _pager->cap().dst() : L4_nilthread; + L4_ThreadId_t pager = _pager + ? Capability_space::ipc_cap_data(_pager->cap()).dst + : L4_nilthread; /* XXX should always be the root task */ L4_ThreadId_t preempter = L4_Myself(); diff --git a/repos/base-pistachio/src/core/target.inc b/repos/base-pistachio/src/core/target.inc index ff81129f6..91bd4edc8 100644 --- a/repos/base-pistachio/src/core/target.inc +++ b/repos/base-pistachio/src/core/target.inc @@ -11,6 +11,7 @@ SRC_CC = stack_area.cc \ cpu_session_component.cc \ cpu_session_platform.cc \ cpu_thread_component.cc \ + capability_space.cc \ dataspace_component.cc \ default_log.cc \ dump_alloc.cc \ @@ -21,7 +22,7 @@ SRC_CC = stack_area.cc \ main.cc \ multiboot_info.cc \ pd_session_component.cc \ - rpc_cap_factory.cc \ + rpc_cap_factory_l4.cc \ pd_assign_pci.cc \ pd_upgrade_ram_quota.cc \ pager.cc \ @@ -52,10 +53,11 @@ vpath cpu_session_component.cc $(GEN_CORE_DIR) vpath cpu_session_support.cc $(GEN_CORE_DIR) vpath cpu_thread_component.cc $(GEN_CORE_DIR) vpath pd_session_component.cc $(GEN_CORE_DIR) -vpath rpc_cap_factory.cc $(GEN_CORE_DIR) vpath pd_assign_pci.cc $(GEN_CORE_DIR) vpath pd_upgrade_ram_quota.cc $(GEN_CORE_DIR) vpath region_map_component.cc $(GEN_CORE_DIR) +vpath rpc_cap_factory_l4.cc $(GEN_CORE_DIR) +vpath capability_space.cc $(GEN_CORE_DIR) vpath io_mem_session_component.cc $(GEN_CORE_DIR) vpath io_mem_session_support.cc $(GEN_CORE_DIR) vpath signal_source_component.cc $(GEN_CORE_DIR) diff --git a/repos/base-pistachio/src/include/base/internal/parent_cap.h b/repos/base-pistachio/src/include/base/internal/parent_cap.h new file mode 100644 index 000000000..913e3c6fb --- /dev/null +++ b/repos/base-pistachio/src/include/base/internal/parent_cap.h @@ -0,0 +1,40 @@ +/* + * \brief Interface to obtain the parent capability for the component + * \author Norman Feske + * \date 2015-05-12 + */ + +/* + * Copyright (C) 2015-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__BASE__INTERNAL__PARENT_CAP_H_ +#define _INCLUDE__BASE__INTERNAL__PARENT_CAP_H_ + +/* Genode includes */ +#include + +/* base-internal includes */ +#include +#include + + +namespace Genode { + + static inline Parent_capability parent_cap() + { + Native_capability::Raw &raw = *(Native_capability::Raw *)&_parent_cap; + + Pistachio::L4_ThreadId_t tid; + tid.raw = raw.v[0]; + + Native_capability cap = Capability_space::import(tid, Rpc_obj_key(raw.v[1])); + + return reinterpret_cap_cast(cap); + } +} + +#endif /* _INCLUDE__BASE__INTERNAL__PARENT_CAP_H_ */ diff --git a/repos/base-pistachio/src/include/base/internal/rpc_destination.h b/repos/base-pistachio/src/include/base/internal/rpc_destination.h new file mode 100644 index 000000000..d69fa1601 --- /dev/null +++ b/repos/base-pistachio/src/include/base/internal/rpc_destination.h @@ -0,0 +1,39 @@ +/* + * \brief RPC destination type + * \author Norman Feske + * \date 2016-03-11 + */ + +/* + * 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__BASE__INTERNAL__RPC_DESTINATION_H_ +#define _INCLUDE__BASE__INTERNAL__RPC_DESTINATION_H_ + +/* Pistachio includes */ +namespace Pistachio { +#include +} + +namespace Genode { + + typedef Pistachio::L4_ThreadId_t Rpc_destination; + + static inline Rpc_destination invalid_rpc_destination() + { + Pistachio::L4_ThreadId_t tid; + tid.raw = 0; + return tid; + } + + static void print(Output &out, Rpc_destination const &dst) + { + Genode::print(out, "tid=", Hex(dst.raw)); + } +} + +#endif /* _INCLUDE__BASE__INTERNAL__RPC_DESTINATION_H_ */ diff --git a/repos/base-pistachio/src/lib/base/capability_raw.cc b/repos/base-pistachio/src/lib/base/capability_raw.cc new file mode 100644 index 000000000..90222e4dc --- /dev/null +++ b/repos/base-pistachio/src/lib/base/capability_raw.cc @@ -0,0 +1,28 @@ +/* + * \brief Capability + * \author Norman Feske + * \date 2016-06-16 + */ + +/* + * 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. + */ + +#include + +/* base-internal includes */ +#include + +using namespace Genode; + + +Native_capability::Raw Native_capability::raw() const +{ + Capability_space::Ipc_cap_data const cap_data = + Capability_space::ipc_cap_data(*this); + + return { { cap_data.dst.raw, cap_data.rpc_obj_key.value(), 0, 0 } }; +} diff --git a/repos/base-pistachio/src/lib/base/ipc.cc b/repos/base-pistachio/src/lib/base/ipc.cc index ae07e5c8b..414321ab7 100644 --- a/repos/base-pistachio/src/lib/base/ipc.cc +++ b/repos/base-pistachio/src/lib/base/ipc.cc @@ -13,39 +13,24 @@ */ /* Genode includes */ -#include +#include #include #include #include /* base-internal includes */ #include +#include /* Pistachio includes */ namespace Pistachio { #include #include -#include } using namespace Genode; using namespace Pistachio; -#define VERBOSE_IPC 0 -#if VERBOSE_IPC - -/* Just a printf wrapper for now. */ -#define IPCDEBUG(msg, ...) { \ - if (L4_Myself().raw == 0xf4001) { \ - (void)printf("IPC (thread = 0x%x) " msg, \ - L4_ThreadNo(Pistachio::L4_Myself()) \ - , ##__VA_ARGS__); \ - } else {} -} -#else -#define IPCDEBUG(...) -#endif - /** * Assert that we got 1 untyped word and 2 typed words @@ -64,13 +49,13 @@ static inline void check_ipc_result(L4_MsgTag_t result, L4_Word_t error_code) * Provide diagnostic information on unexpected conditions */ if (L4_IpcFailed(result)) { - PERR("Error in thread %08lx. IPC failed.", L4_Myself().raw); + raw("Error in thread ", Hex(L4_Myself().raw), ". IPC failed."); throw Genode::Ipc_error(); } if (L4_UntypedWords(result) < 2) { - PERR("Error in thread %08lx. Expected at leat two untyped words, but got %lu.\n", - L4_Myself().raw, L4_UntypedWords(result)); + raw("Error in thread ", Hex(L4_Myself().raw), ". " + "Expected at leat two untyped words, but got ", L4_UntypedWords(result), ".\n"); throw Genode::Ipc_error(); } } @@ -90,9 +75,21 @@ static void extract_caps(L4_Msg_t &msg, Msgbuf_base &rcv_msg) L4_ThreadId_t tid; tid.raw = L4_Get(&msg, 2 + i*2); - L4_Word_t const local_name = L4_Get(&msg, 2 + i*2 + 1); + Rpc_obj_key const rpc_obj_key(L4_Get(&msg, 2 + i*2 + 1)); - rcv_msg.insert(Native_capability(tid, local_name)); + bool const cap_valid = tid.raw != 0UL; + + Native_capability cap; + + if (cap_valid) { + + cap = Capability_space::lookup(rpc_obj_key); + + if (!cap.valid()) + cap = Capability_space::import(tid, rpc_obj_key); + } + + rcv_msg.insert(cap); } } @@ -109,8 +106,19 @@ static void prepare_send(L4_Word_t protocol_value, L4_Msg_t &msg, L4_Append(&msg, (L4_Word_t)snd_msg.used_caps()); for (unsigned i = 0; i < snd_msg.used_caps(); i++) { - L4_Append(&msg, (L4_Word_t)snd_msg.cap(i).dst().raw); - L4_Append(&msg, (L4_Word_t)snd_msg.cap(i).local_name()); + + Native_capability cap = snd_msg.cap(i); + + if (cap.valid()) { + Capability_space::Ipc_cap_data const cap_data = + Capability_space::ipc_cap_data(snd_msg.cap(i)); + + L4_Append(&msg, (L4_Word_t)cap_data.dst.raw); + L4_Append(&msg, (L4_Word_t)cap_data.rpc_obj_key.value()); + } else { + L4_Append(&msg, (L4_Word_t)0UL); + L4_Append(&msg, (L4_Word_t)0UL); + } } L4_Append(&msg, L4_StringItem(snd_msg.data_size(), snd_msg.data())); @@ -139,11 +147,14 @@ Rpc_exception_code Genode::ipc_call(Native_capability dst, L4_MsgBuffer_t msgbuf; prepare_receive(msgbuf, rcv_msg); + Capability_space::Ipc_cap_data const dst_data = + Capability_space::ipc_cap_data(dst); + /* prepare sending parameters */ L4_Msg_t msg; - prepare_send(dst.local_name(), msg, snd_msg); + prepare_send(dst_data.rpc_obj_key.value(), msg, snd_msg); - L4_MsgTag_t result = L4_Call(dst.dst()); + L4_MsgTag_t result = L4_Call(dst_data.dst); L4_Clear(&msg); L4_Store(result, &msg); @@ -166,9 +177,9 @@ void Genode::ipc_reply(Native_capability caller, Rpc_exception_code exc, L4_Msg_t msg; prepare_send(exc.value, msg, snd_msg); - L4_MsgTag_t result = L4_Reply(caller.dst()); + L4_MsgTag_t result = L4_Reply(Capability_space::ipc_cap_data(caller).dst); if (L4_IpcFailed(result)) - PERR("ipc error in _reply, ignored"); + raw("ipc error in _reply, ignored"); snd_msg.reset(); } @@ -198,7 +209,8 @@ Genode::Rpc_request Genode::ipc_reply_wait(Reply_capability const &last_caller, prepare_send(exc.value, reply_l4_msg, reply_msg); /* send reply and wait for new request message */ - request_tag = L4_Ipc(last_caller.dst(), L4_anythread, + request_tag = L4_Ipc(Capability_space::ipc_cap_data(last_caller).dst, + L4_anythread, L4_Timeouts(L4_ZeroTime, L4_Never), &caller); if (!L4_IpcFailed(request_tag)) @@ -221,11 +233,14 @@ Genode::Rpc_request Genode::ipc_reply_wait(Reply_capability const &last_caller, extract_caps(msg, request_msg); unsigned long const badge = L4_Get(&msg, 0); - return Rpc_request(Native_capability(caller, 0), badge); + return Rpc_request(Capability_space::import(caller, Rpc_obj_key()), badge); } -Ipc_server::Ipc_server() : Native_capability(Pistachio::L4_Myself(), 0) { } +Ipc_server::Ipc_server() +: + Native_capability(Capability_space::import(Pistachio::L4_Myself(), Rpc_obj_key())) +{ } Ipc_server::~Ipc_server() { } diff --git a/repos/base-sel4/include/base/native_capability.h b/repos/base-sel4/include/base/native_capability.h deleted file mode 100644 index 3b27cb70f..000000000 --- a/repos/base-sel4/include/base/native_capability.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * \brief Platform-specific capability type - * \author Norman Feske - * \date 2014-10-14 - */ - -/* - * Copyright (C) 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__BASE__NATIVE_CAPABILITY_H_ -#define _INCLUDE__BASE__NATIVE_CAPABILITY_H_ - -#include - -namespace Genode { - - class Native_capability - { - public: - - /* - * Platform-specific raw information of the capability that is - * transferred as-is when the capability is delegated. - */ - struct Raw { long v[4]; }; - - /** - * Forward declaration of the platform-specific internal capability - * representation - */ - class Data; - - private: - - Data *_data = nullptr; - - protected: - - void _inc(); - void _dec(); - - public: - - /** - * Default constructor creates an invalid capability - */ - Native_capability() { } - - /** - * Copy constructor - */ - Native_capability(const Native_capability &other) - : _data(other._data) { _inc(); } - - /** - * Construct capability manually - * - * This constructor is used internally. - * - * \noapi - */ - Native_capability(Data &data) : _data(&data) { _inc(); } - - /** - * Destructor - */ - ~Native_capability() { _dec(); } - - Data const *data() const { return _data; } - - /** - * Overloaded comparision operator - */ - bool operator == (const Native_capability &o) const - { - return _data == o._data; - } - - Native_capability& operator = (const Native_capability &o) - { - if (this == &o) - return *this; - - _dec(); - _data = o._data; - _inc(); - return *this; - } - - long local_name() const; - - bool valid() const; - - Raw raw() const { return { { 0, 0, 0, 0 } }; } - }; -} - -#endif /* _INCLUDE__BASE__NATIVE_CAPABILITY_H_ */ diff --git a/repos/base-sel4/lib/mk/base-common.inc b/repos/base-sel4/lib/mk/base-common.inc index 4a23a090c..3bf9e2a48 100644 --- a/repos/base-sel4/lib/mk/base-common.inc +++ b/repos/base-sel4/lib/mk/base-common.inc @@ -11,4 +11,4 @@ LIBS += startup syscall SRC_CC += signal_submit.cc SRC_CC += rpc_dispatch_loop.cc SRC_CC += thread.cc thread_myself.cc thread_bootstrap.cc -SRC_CC += capability.cc +SRC_CC += capability.cc capability_raw.cc diff --git a/repos/base-sel4/src/include/base/internal/capability_space_sel4.h b/repos/base-sel4/src/include/base/internal/capability_space_sel4.h index 83a59e88e..bad118067 100644 --- a/repos/base-sel4/src/include/base/internal/capability_space_sel4.h +++ b/repos/base-sel4/src/include/base/internal/capability_space_sel4.h @@ -37,6 +37,8 @@ namespace Genode { explicit Cap_sel(addr_t value) : _value(value) { } addr_t value() const { return _value; } + + void print(Output &out) const { Genode::print(out, "sel=", _value); } }; } @@ -56,6 +58,8 @@ namespace Genode { namespace Capability_space { Ipc_cap_data(Rpc_obj_key rpc_obj_key, unsigned sel) : rpc_obj_key(rpc_obj_key), sel(sel) { } + + void print(Output &out) const { Genode::print(out, sel, ",", rpc_obj_key); } }; /** @@ -111,7 +115,7 @@ namespace Genode * First, core must keep track of all capabilities of the system. Hence, its * capability space must be dimensioned larger. * - * Second, core has to maintain the information about the CAP session that + * Second, core has to maintain the information about the PD session that * was used to allocate the capability to prevent misbehaving clients from * freeing capabilities allocated from another component. This information * is part of the core-specific 'Native_capability::Data' structure. @@ -251,6 +255,11 @@ class Genode::Capability_space_sel4 return data.rpc_obj_key(); } + void print(Output &out, Data const &data) const + { + ipc_cap_data(data).print(out); + } + Capability_space::Ipc_cap_data ipc_cap_data(Data const &data) const { return { rpc_obj_key(data), sel(data) }; diff --git a/repos/base-sel4/src/lib/base/capability_raw.cc b/repos/base-sel4/src/lib/base/capability_raw.cc new file mode 100644 index 000000000..4189764af --- /dev/null +++ b/repos/base-sel4/src/lib/base/capability_raw.cc @@ -0,0 +1,25 @@ +/* + * \brief Capability + * \author Norman Feske + * \date 2016-06-16 + */ + +/* + * 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. + */ + +#include + +using namespace Genode; + + +Native_capability::Raw Native_capability::raw() const +{ + /* + * On seL4, there is no raw data representation of capabilities. + */ + return { { 0, 0, 0, 0 } }; +} diff --git a/repos/base-sel4/src/lib/base/capability_space.cc b/repos/base-sel4/src/lib/base/capability_space.cc index c2d3fe7a3..ee056fa47 100644 --- a/repos/base-sel4/src/lib/base/capability_space.cc +++ b/repos/base-sel4/src/lib/base/capability_space.cc @@ -122,6 +122,12 @@ Rpc_obj_key Capability_space::rpc_obj_key(Native_capability::Data const &data) } +void Capability_space::print(Output &out, Native_capability::Data const &data) +{ + return local_capability_space().print(out, data); +} + + Capability_space::Ipc_cap_data Capability_space::ipc_cap_data(Native_capability const &cap) { return local_capability_space().ipc_cap_data(*cap.data()); diff --git a/repos/base/include/base/native_capability.h b/repos/base/include/base/native_capability.h new file mode 100644 index 000000000..5e02a15e8 --- /dev/null +++ b/repos/base/include/base/native_capability.h @@ -0,0 +1,105 @@ +/* + * \brief Capability type + * \author Norman Feske + * \date 2016-07-15 + */ + +/* + * 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__BASE__NATIVE_CAPABILITY_H_ +#define _INCLUDE__BASE__NATIVE_CAPABILITY_H_ + +#include +#include + +namespace Genode { class Native_capability; } + + +class Genode::Native_capability +{ + public: + + /* + * Platform-specific raw information of the capability that is + * transferred as-is when the capability is delegated. + */ + struct Raw { unsigned long v[4]; }; + + /** + * Forward declaration of the platform-specific internal capability + * representation + */ + class Data; + + private: + + Data *_data = nullptr; + + protected: + + void _inc(); + void _dec(); + + public: + + /** + * Default constructor creates an invalid capability + */ + Native_capability(); + + /** + * Copy constructor + */ + Native_capability(const Native_capability &other) + : _data(other._data) { _inc(); } + + /** + * Construct capability manually + * + * This constructor is used internally. + * + * \noapi + */ + Native_capability(Data &data) : _data(&data) { _inc(); } + + /** + * Destructor + */ + ~Native_capability() { _dec(); } + + Data const *data() const { return _data; } + + /** + * Overloaded comparision operator + */ + bool operator == (const Native_capability &o) const + { + return _data == o._data; + } + + Native_capability& operator = (const Native_capability &o) + { + if (this == &o) + return *this; + + _dec(); + _data = o._data; + _inc(); + return *this; + } + + long local_name() const; + + bool valid() const; + + Raw raw() const; + + void print(Output &) const; +}; + +#endif /* _INCLUDE__BASE__NATIVE_CAPABILITY_H_ */ diff --git a/repos/base/include/base/output.h b/repos/base/include/base/output.h index 0ef3158d5..5ab087ea6 100644 --- a/repos/base/include/base/output.h +++ b/repos/base/include/base/output.h @@ -173,6 +173,15 @@ namespace Genode { { obj.print(output); } + + /** + * Print a variable number of arguments + */ + template + static inline void print(Output &output, HEAD const &head, TAIL... tail) + { + Output::out_args(output, head, tail...); + } } #endif /* _INCLUDE__BASE__OUTPUT_H_ */ diff --git a/repos/base/src/core/capability_space.cc b/repos/base/src/core/capability_space.cc new file mode 100644 index 000000000..48c40cb02 --- /dev/null +++ b/repos/base/src/core/capability_space.cc @@ -0,0 +1,100 @@ +/* + * \brief Instance of the (Genode) capability space for non-core components + * \author Norman Feske + * \date 2015-05-11 + */ + +/* + * 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. + */ + +/* base includes */ +#include +#include + +/* base-internal includes */ +#include + + +/** + * Definition of capability meta data + */ +struct Genode::Native_capability::Data : Capability_data +{ + Rpc_destination dst = invalid_rpc_destination(); + + Data(Rpc_destination dst, Rpc_obj_key key) + : Capability_data(key), dst(dst) { } + + Data() { } +}; + + +using namespace Genode; + + +/** + * Singleton instance of component-local capability space + */ +namespace { + + struct Local_capability_space + : + Capability_space_tpl<64*1024, Native_capability::Data> + { }; + + static Local_capability_space &local_capability_space() + { + static Local_capability_space capability_space; + return capability_space; + } +} + + +/****************************************************** + ** Implementation of the Capability_space interface ** + ******************************************************/ + +void Capability_space::dec_ref(Native_capability::Data &data) +{ + local_capability_space().dec_ref(data); +} + + +void Capability_space::inc_ref(Native_capability::Data &data) +{ + local_capability_space().inc_ref(data); +} + + +Rpc_obj_key Capability_space::rpc_obj_key(Native_capability::Data const &data) +{ + return local_capability_space().rpc_obj_key(data); +} + + +Capability_space::Ipc_cap_data Capability_space::ipc_cap_data(Native_capability const &cap) +{ + return local_capability_space().ipc_cap_data(*cap.data()); +} + + +Native_capability Capability_space::lookup(Rpc_obj_key rpc_obj_key) +{ + return local_capability_space().lookup(rpc_obj_key); +} + + +Native_capability Capability_space::import(Rpc_destination dst, Rpc_obj_key key) +{ + return local_capability_space().import(dst, key); +} + + +void Capability_space::print(Output &out, Native_capability::Data const &data) +{ + local_capability_space().print(out, data); +} diff --git a/repos/base-sel4/src/core/include/core_capability_space.h b/repos/base/src/core/include/core_capability_space.h similarity index 100% rename from repos/base-sel4/src/core/include/core_capability_space.h rename to repos/base/src/core/include/core_capability_space.h diff --git a/repos/base/src/core/rpc_cap_factory_l4.cc b/repos/base/src/core/rpc_cap_factory_l4.cc new file mode 100644 index 000000000..b040c8e16 --- /dev/null +++ b/repos/base/src/core/rpc_cap_factory_l4.cc @@ -0,0 +1,53 @@ +/* + * \brief RPC capability factory + * \author Norman Feske + * \date 2016-01-19 + */ + +/* + * 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 includes */ +#include +#include + +/* base-internal include */ +#include +#include + +using namespace Genode; + + +static unsigned unique_id_cnt; + + +Native_capability Rpc_cap_factory::_alloc(Rpc_cap_factory *owner, + Native_capability ep) +{ + if (!ep.valid()) { + PWRN("Invalid entrypoint capability"); + return Native_capability(); + } + + Rpc_obj_key const rpc_obj_key(++unique_id_cnt); + + /* combine thread ID of 'ep' with new unique ID */ + Capability_space::Ipc_cap_data cap_data = + Capability_space::ipc_cap_data(ep); + + return Capability_space::import(cap_data.dst, rpc_obj_key); +} + + +Native_capability Rpc_cap_factory::alloc(Native_capability ep) +{ + return Rpc_cap_factory::_alloc(this, ep); +} + + +void Rpc_cap_factory::free(Native_capability cap) { } + diff --git a/repos/base-sel4/src/include/base/internal/capability_data.h b/repos/base/src/include/base/internal/capability_data.h similarity index 100% rename from repos/base-sel4/src/include/base/internal/capability_data.h rename to repos/base/src/include/base/internal/capability_data.h diff --git a/repos/base-sel4/src/include/base/internal/capability_space.h b/repos/base/src/include/base/internal/capability_space.h similarity index 80% rename from repos/base-sel4/src/include/base/internal/capability_space.h rename to repos/base/src/include/base/internal/capability_space.h index dde982e6c..5b7165777 100644 --- a/repos/base-sel4/src/include/base/internal/capability_space.h +++ b/repos/base/src/include/base/internal/capability_space.h @@ -35,17 +35,22 @@ namespace Genode { namespace Capability_space { /** * Increment reference counter */ - void dec_ref(Native_capability::Data &data); + void dec_ref(Native_capability::Data &); /** * Decrement reference counter */ - void inc_ref(Native_capability::Data &data); + void inc_ref(Native_capability::Data &); /** * Obtain RPC object key */ - Rpc_obj_key rpc_obj_key(Native_capability::Data const &data); + Rpc_obj_key rpc_obj_key(Native_capability::Data const &); + + /** + * Print internal capability representation + */ + void print(Output &, Native_capability::Data const &); } } #endif /* _INCLUDE__BASE__INTERNAL__CAPABILITY_SPACE_H_ */ diff --git a/repos/base/src/include/base/internal/capability_space_tpl.h b/repos/base/src/include/base/internal/capability_space_tpl.h new file mode 100644 index 000000000..60087c770 --- /dev/null +++ b/repos/base/src/include/base/internal/capability_space_tpl.h @@ -0,0 +1,213 @@ +/* + * \brief Capability-space management for traditional L4 kernels and Linux + * \author Norman Feske + * \date 2016-06-15 + * + * On traditional L4 kernels, a capability is represented by the thread ID + * of the invoked entrypoint thread and a globally unique RPC object key. + * On Linux, a capability is represented by a socket descriptor and an RPC + * object key. The thread ID respectively socket descriptor refer to the + * recipient of an RPC call (RPC destination). + */ + +/* + * 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__BASE__INTERNAL__CAPABILITY_SPACE_TPL_H_ +#define _INCLUDE__BASE__INTERNAL__CAPABILITY_SPACE_TPL_H_ + +/* base includes */ +#include +#include +#include +#include + +/* base-internal includes */ +#include +#include + +namespace Genode { template class Capability_space_tpl; } + + +/** + * Platform-specific supplement to the generic 'Capability_space' interface + */ +namespace Genode { namespace Capability_space { + + /** + * Information needed to transfer capability via the kernel's IPC mechanism + */ + struct Ipc_cap_data + { + Rpc_destination dst; + Rpc_obj_key rpc_obj_key; + + Ipc_cap_data(Rpc_destination dst, Rpc_obj_key rpc_obj_key) + : dst(dst), rpc_obj_key(rpc_obj_key) { } + + void print(Output &out) const { Genode::print(out, dst, ",", rpc_obj_key); } + }; + + /** + * Retrieve IPC data for given capability + */ + Ipc_cap_data ipc_cap_data(Native_capability const &cap); + + Native_capability lookup(Rpc_obj_key); + + Native_capability import(Rpc_destination, Rpc_obj_key); +} } + + +/** + * Capability space template + * + * The capability space of core and non-core components differ in two ways. + * + * First, core must keep track of all capabilities of the system. Hence, its + * capability space must be dimensioned larger. + * + * Second, core has to maintain the information about the PD session that + * was used to allocate the capability to prevent misbehaving clients from + * freeing capabilities allocated from another component. This information + * is part of the core-specific 'Native_capability::Data' structure. + */ +template +class Genode::Capability_space_tpl +{ + private: + + typedef CAP_DATA Data; + + /** + * Supplement Native_capability::Data with the meta data needed to + * manage it in an AVL tree + */ + struct Tree_managed_data : Data, Avl_node + { + template + Tree_managed_data(ARGS... args) : Data(args...) { } + + Tree_managed_data() { } + + bool higher(Tree_managed_data *data) + { + return data->rpc_obj_key().value() > rpc_obj_key().value(); + } + + Tree_managed_data *find_by_key(Rpc_obj_key key) + { + if (key.value() == rpc_obj_key().value()) return this; + + Tree_managed_data *data = + this->child(key.value() > rpc_obj_key().value()); + + return data ? data->find_by_key(key) : nullptr; + } + }; + + Tree_managed_data _caps_data[NUM_CAPS]; + Bit_allocator _alloc; + Avl_tree _tree; + Lock mutable _lock; + + /** + * Calculate index into _caps_data for capability data object + */ + unsigned _index(Data const &data) const + { + addr_t const offset = (addr_t)&data - (addr_t)_caps_data; + return offset / sizeof(_caps_data[0]); + } + + Data *_lookup(Rpc_obj_key key) const + { + Lock::Guard guard(_lock); + + if (!_tree.first()) + return nullptr; + + return _tree.first()->find_by_key(key); + } + + public: + + /** + * Create Genode capability + * + * The arguments are passed to the constructor of the + * 'Native_capability::Data' type. + */ + template + Native_capability::Data &create_capability(ARGS... args) + { + Lock::Guard guard(_lock); + + addr_t const index = _alloc.alloc(); + + _caps_data[index] = Tree_managed_data(args...); + + if (_caps_data[index].rpc_obj_key().valid()) + _tree.insert(&_caps_data[index]); + + return _caps_data[index]; + } + + void dec_ref(Data &data) + { + Lock::Guard guard(_lock); + + if (data.dec_ref() == 0) { + + if (data.rpc_obj_key().valid()) + _tree.remove(static_cast(&data)); + + _alloc.free(_index(data)); + data = Tree_managed_data(); + } + } + + void inc_ref(Data &data) + { + Lock::Guard guard(_lock); + + if (data.inc_ref() == 255) + PERR("cap ref count overflow"); + } + + Rpc_obj_key rpc_obj_key(Data const &data) const + { + return data.rpc_obj_key(); + } + + void print(Output &out, Data const &data) const + { + ipc_cap_data(data).print(out); + } + + Capability_space::Ipc_cap_data ipc_cap_data(Data const &data) const + { + if (&data == nullptr) { + raw("ipc_cap_data nullptr"); + for (;;); + } + return { data.dst, data.rpc_obj_key() }; + } + + Native_capability lookup(Rpc_obj_key rpc_obj_key) + { + Native_capability::Data *data = _lookup(rpc_obj_key); + return data ? Native_capability(*data) : Native_capability(); + } + + Native_capability import(Rpc_destination dst, Rpc_obj_key key) + { + return Native_capability(create_capability(dst, key)); + } +}; + +#endif /* _INCLUDE__BASE__INTERNAL__CAPABILITY_SPACE_TPL_H_ */ diff --git a/repos/base-sel4/src/include/base/internal/rpc_obj_key.h b/repos/base/src/include/base/internal/rpc_obj_key.h similarity index 54% rename from repos/base-sel4/src/include/base/internal/rpc_obj_key.h rename to repos/base/src/include/base/internal/rpc_obj_key.h index e1dfb22ac..9535230d6 100644 --- a/repos/base-sel4/src/include/base/internal/rpc_obj_key.h +++ b/repos/base/src/include/base/internal/rpc_obj_key.h @@ -16,6 +16,7 @@ /* base includes */ #include +#include namespace Genode { struct Rpc_obj_key; } @@ -28,16 +29,27 @@ class Genode::Rpc_obj_key private: - uint32_t _value = INVALID; + addr_t _value = INVALID; public: Rpc_obj_key() { } - explicit Rpc_obj_key(uint32_t value) : _value(value) { } + explicit Rpc_obj_key(addr_t value) : _value(value) { } - bool valid() const { return _value != INVALID; } - uint32_t value() const { return _value; } + bool valid() const { return _value != INVALID; } + addr_t value() const { return _value; } + + void print(Output &out) const + { + /* + * We print the value as signed long to make 'INVALID' or platform- + * specific low-level codes like 'Protocol_header::INVALID_BADGE' + * on Linux) easily recognizable. Such codes appear as negative + * numbers. + */ + Genode::print(out, "key=", (long)_value); + } }; #endif /* _INCLUDE__BASE__INTERNAL__RPC_OBJ_KEY_H_ */ diff --git a/repos/base-sel4/src/lib/base/capability.cc b/repos/base/src/lib/base/capability.cc similarity index 71% rename from repos/base-sel4/src/lib/base/capability.cc rename to repos/base/src/lib/base/capability.cc index f6197b1dc..200db63b6 100644 --- a/repos/base-sel4/src/lib/base/capability.cc +++ b/repos/base/src/lib/base/capability.cc @@ -11,15 +11,15 @@ * under the terms of the GNU General Public License version 2. */ -/* base includes */ -#include - /* base-internal includes */ #include using namespace Genode; +Native_capability::Native_capability() { } + + void Native_capability::_inc() { if (_data) @@ -42,6 +42,20 @@ long Native_capability::local_name() const bool Native_capability::valid() const { - return _data != 0; + return _data != nullptr; +} + + +void Native_capability::print(Output &out) const +{ + using Genode::print; + + print(out, "cap<"); + if (_data) { + Capability_space::print(out, *_data); + } else { + print(out, "invalid"); + } + print(out, ">"); } diff --git a/repos/base/src/lib/base/capability_space.cc b/repos/base/src/lib/base/capability_space.cc new file mode 100644 index 000000000..d7907f5a0 --- /dev/null +++ b/repos/base/src/lib/base/capability_space.cc @@ -0,0 +1,100 @@ +/* + * \brief Instance of the (Genode) capability space for non-core components + * \author Norman Feske + * \date 2015-05-11 + */ + +/* + * 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. + */ + +/* base includes */ +#include +#include + +/* base-internal includes */ +#include + + +/** + * Definition of capability meta data + */ +struct Genode::Native_capability::Data : Capability_data +{ + Rpc_destination dst = invalid_rpc_destination(); + + Data(Rpc_destination dst, Rpc_obj_key key) + : Capability_data(key), dst(dst) { } + + Data() { } +}; + + +using namespace Genode; + + +/** + * Singleton instance of component-local capability space + */ +namespace { + + struct Local_capability_space + : + Capability_space_tpl<4*1024, Native_capability::Data> + { }; + + static Local_capability_space &local_capability_space() + { + static Local_capability_space capability_space; + return capability_space; + } +} + + +/****************************************************** + ** Implementation of the Capability_space interface ** + ******************************************************/ + +void Capability_space::dec_ref(Native_capability::Data &data) +{ + local_capability_space().dec_ref(data); +} + + +void Capability_space::inc_ref(Native_capability::Data &data) +{ + local_capability_space().inc_ref(data); +} + + +Rpc_obj_key Capability_space::rpc_obj_key(Native_capability::Data const &data) +{ + return local_capability_space().rpc_obj_key(data); +} + + +Capability_space::Ipc_cap_data Capability_space::ipc_cap_data(Native_capability const &cap) +{ + return local_capability_space().ipc_cap_data(*cap.data()); +} + + +Native_capability Capability_space::lookup(Rpc_obj_key rpc_obj_key) +{ + return local_capability_space().lookup(rpc_obj_key); +} + + +Native_capability Capability_space::import(Rpc_destination dst, Rpc_obj_key key) +{ + return local_capability_space().import(dst, key); +} + + +void Capability_space::print(Output &out, Native_capability::Data const &data) +{ + local_capability_space().print(out, data); +} diff --git a/repos/os/src/drivers/timer/spec/hw/platform_timer.h b/repos/os/src/drivers/timer/spec/hw/platform_timer.h index d0aad7fa8..24957d38f 100644 --- a/repos/os/src/drivers/timer/spec/hw/platform_timer.h +++ b/repos/os/src/drivers/timer/spec/hw/platform_timer.h @@ -38,12 +38,25 @@ class Platform_timer unsigned long mutable _last_timeout_us; time_t const _max_timeout_us; + /** + * Return kernel capability selector of Genode capability + * + * This function is normally framework-internal and defined in + * 'base/internal/capability_space.h'. + */ + static inline Kernel::capid_t _capid(Genode::Native_capability const &cap) + { + Genode::addr_t const index = (Genode::addr_t)cap.data(); + return index; + } + public: Platform_timer() : - _sigid(_sigrec.manage(&_sigctx).dst()), _curr_time_us(0), - _last_timeout_us(0), _max_timeout_us(Kernel::timeout_max_us()) + _sigid(_capid(_sigrec.manage(&_sigctx))), + _curr_time_us(0), _last_timeout_us(0), + _max_timeout_us(Kernel::timeout_max_us()) { PINF("Maximum timeout %lu us", _max_timeout_us); if (max_timeout() < min_timeout()) { diff --git a/repos/os/src/test/timer/main.cc b/repos/os/src/test/timer/main.cc index a8c9d85e0..204fd5471 100644 --- a/repos/os/src/test/timer/main.cc +++ b/repos/os/src/test/timer/main.cc @@ -17,7 +17,7 @@ #include #include -enum { STACK_SIZE = 4096 }; +enum { STACK_SIZE = 1024*sizeof(long) }; class Timer_client : public Genode::List::Element, Timer::Connection, Genode::Thread_deprecated diff --git a/repos/ports-foc/src/lib/l4lx/genode_block.cc b/repos/ports-foc/src/lib/l4lx/genode_block.cc index f1dafb7ba..54cd3d81d 100644 --- a/repos/ports-foc/src/lib/l4lx/genode_block.cc +++ b/repos/ports-foc/src/lib/l4lx/genode_block.cc @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -116,9 +117,13 @@ namespace { Genode::strncpy(_name, label, sizeof(_name)); } + Fiasco::l4_cap_idx_t irq_cap() + { + return Genode::Capability_space::kcap(_irq_cap); + } + Req_cache *cache() { return &_cache; } Block::Connection *session() { return &_session; } - Fiasco::l4_cap_idx_t irq_cap() { return _irq_cap.dst(); } Genode::Signal_context *context() { return &_tx; } Genode::size_t block_size() { return _blk_size; } Genode::size_t block_count() { return _blk_cnt; } diff --git a/repos/ports-foc/src/lib/l4lx/genode_net.cc b/repos/ports-foc/src/lib/l4lx/genode_net.cc index 48efac87e..375d137f8 100644 --- a/repos/ports-foc/src/lib/l4lx/genode_net.cc +++ b/repos/ports-foc/src/lib/l4lx/genode_net.cc @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -153,9 +154,10 @@ extern "C" { native_cpu(L4lx::cpu_connection()->native_cpu()); static Genode::Native_capability cap = native_cpu.alloc_irq(); static Genode::Lock lock(Genode::Lock::LOCKED); - static Signal_thread th(cap.dst(), &lock); + static Fiasco::l4_cap_idx_t const kcap = Genode::Capability_space::kcap(cap); + static Signal_thread th(kcap, &lock); lock.lock(); - return cap.dst(); + return kcap; } diff --git a/repos/ports-foc/src/lib/l4lx/genode_terminal.cc b/repos/ports-foc/src/lib/l4lx/genode_terminal.cc index 45f2232d0..24f1e1e97 100644 --- a/repos/ports-foc/src/lib/l4lx/genode_terminal.cc +++ b/repos/ports-foc/src/lib/l4lx/genode_terminal.cc @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -100,9 +101,10 @@ extern "C" { native_cpu(L4lx::cpu_connection()->native_cpu()); static Genode::Native_capability cap = native_cpu.alloc_irq(); + l4_cap_idx_t const kcap = Genode::Capability_space::kcap(cap); if (!signal_thread) - signal_thread = new (Genode::env()->heap()) Signal_thread(cap.dst()); - return cap.dst(); + signal_thread = new (Genode::env()->heap()) Signal_thread(kcap); + return kcap; } diff --git a/repos/ports-foc/src/lib/l4lx/include/dataspace.h b/repos/ports-foc/src/lib/l4lx/include/dataspace.h index 20b680308..e7c3d3a44 100644 --- a/repos/ports-foc/src/lib/l4lx/include/dataspace.h +++ b/repos/ports-foc/src/lib/l4lx/include/dataspace.h @@ -16,16 +16,12 @@ /* Genode includes */ #include -#include #include #include #include #include #include - -namespace Fiasco { -#include -} +#include namespace L4lx { @@ -86,10 +82,10 @@ namespace L4lx { public: Single_dataspace(const char* name, - Genode::size_t size, - Genode::Dataspace_capability ds, + Genode::size_t size, + Genode::Dataspace_capability ds, Fiasco::l4_cap_idx_t ref = - Genode::cap_idx_alloc()->alloc_range(1)->kcap()) + Genode::Capability_space::alloc_kcap()) : Dataspace(name, size, ref), _cap(ds) {} Genode::Dataspace_capability cap() { return _cap; } diff --git a/repos/ports-foc/src/lib/l4lx/include/task.h b/repos/ports-foc/src/lib/l4lx/include/task.h index 738658767..6eb46199a 100644 --- a/repos/ports-foc/src/lib/l4lx/include/task.h +++ b/repos/ports-foc/src/lib/l4lx/include/task.h @@ -51,7 +51,8 @@ namespace L4lx { /* remap task cap to given cap slot */ l4_task_map(L4_BASE_TASK_CAP, L4_BASE_TASK_CAP, - l4_obj_fpage(_cap.dst(), 0, L4_FPAGE_RWX), + l4_obj_fpage(Genode::Capability_space::kcap(_cap), + 0, L4_FPAGE_RWX), _ref | L4_ITEM_MAP); } diff --git a/repos/ports-foc/src/lib/l4lx/include/vcpu.h b/repos/ports-foc/src/lib/l4lx/include/vcpu.h index 8ac17beb6..102e87b39 100644 --- a/repos/ports-foc/src/lib/l4lx/include/vcpu.h +++ b/repos/ports-foc/src/lib/l4lx/include/vcpu.h @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/repos/ports-foc/src/lib/l4lx/l4_re_c_util_cap.cc b/repos/ports-foc/src/lib/l4lx/l4_re_c_util_cap.cc index 704d8b5ce..5d7651d11 100644 --- a/repos/ports-foc/src/lib/l4lx/l4_re_c_util_cap.cc +++ b/repos/ports-foc/src/lib/l4lx/l4_re_c_util_cap.cc @@ -13,7 +13,7 @@ /* Genode includes */ #include -#include +#include namespace Fiasco { #include @@ -28,7 +28,7 @@ extern "C" { l4_cap_idx_t l4re_util_cap_alloc(void) { - l4_cap_idx_t ret = Genode::cap_idx_alloc()->alloc_range(1)->kcap(); + l4_cap_idx_t ret = Genode::Capability_space::alloc_kcap(); if (DEBUG) PDBG("ret=%lx", ret); diff --git a/repos/ports-foc/src/lib/l4lx/l4lx_task.cc b/repos/ports-foc/src/lib/l4lx/l4lx_task.cc index de4ee2fc7..d1326dba7 100644 --- a/repos/ports-foc/src/lib/l4lx/l4lx_task.cc +++ b/repos/ports-foc/src/lib/l4lx/l4lx_task.cc @@ -13,7 +13,7 @@ /* Genode includes */ #include -#include +#include #include #include @@ -67,8 +67,7 @@ int l4lx_task_number_free(l4_cap_idx_t task) { Linux::Irq_guard guard; - Genode::Cap_index* idx = Genode::cap_idx_alloc()->kcap_to_idx(task); - Genode::cap_idx_alloc()->free(idx, 1); + Genode::Capability_space::free_kcap(task); return 0; } @@ -89,7 +88,7 @@ int l4lx_task_get_new_task(l4_cap_idx_t parent_id, { Linux::Irq_guard guard; - *id = Genode::cap_idx_alloc()->alloc_range(1)->kcap(); + *id = Genode::Capability_space::alloc_kcap(); return 0; } diff --git a/repos/ports-foc/src/lib/l4lx/l4lx_thread.cc b/repos/ports-foc/src/lib/l4lx/l4lx_thread.cc index 62c098fa5..0ff0dd53b 100644 --- a/repos/ports-foc/src/lib/l4lx/l4lx_thread.cc +++ b/repos/ports-foc/src/lib/l4lx/l4lx_thread.cc @@ -106,7 +106,8 @@ void l4lx_thread_alloc_irq(l4_cap_idx_t c) Genode::Native_capability cap = native_cpu.alloc_irq(); l4_task_map(L4_BASE_TASK_CAP, L4_BASE_TASK_CAP, - l4_obj_fpage(cap.dst(), 0, L4_FPAGE_RWX), c | L4_ITEM_MAP); + l4_obj_fpage(Genode::Capability_space::kcap(cap), 0, L4_FPAGE_RWX), + c | L4_ITEM_MAP); } l4lx_thread_t l4lx_thread_create(L4_CV void (*thread_func)(void *data), diff --git a/repos/ports-foc/src/lib/l4lx/l4x_pagefault.cc b/repos/ports-foc/src/lib/l4lx/l4x_pagefault.cc index d9470b3df..504fd36f1 100644 --- a/repos/ports-foc/src/lib/l4lx/l4x_pagefault.cc +++ b/repos/ports-foc/src/lib/l4lx/l4x_pagefault.cc @@ -94,9 +94,10 @@ Fiasco::l4_cap_idx_t genode_balloon_irq_cap() static Genode::Foc_native_cpu_client native_cpu(L4lx::cpu_connection()->native_cpu()); static Genode::Native_capability cap = native_cpu.alloc_irq(); static Genode::Lock lock(Genode::Lock::LOCKED); - static Signal_thread th(cap.dst(), &lock); + static Fiasco::l4_cap_idx_t kcap = Genode::Capability_space::kcap(cap); + static Signal_thread th(kcap, &lock); lock.lock(); - return cap.dst(); + return kcap; } diff --git a/repos/ports-foc/src/lib/l4lx/startup.cc b/repos/ports-foc/src/lib/l4lx/startup.cc index e415c217c..bd2f3c966 100644 --- a/repos/ports-foc/src/lib/l4lx/startup.cc +++ b/repos/ports-foc/src/lib/l4lx/startup.cc @@ -120,7 +120,7 @@ static void prepare_l4re_env() env->scheduler = L4_BASE_SCHEDULER_CAP; env->mem_alloc = L4_INVALID_CAP; env->log = L4_INVALID_CAP; - env->main_thread = main_thread_cap.dst(); + env->main_thread = Genode::Capability_space::kcap(main_thread_cap); env->rm = Fiasco::THREAD_AREA_BASE + Fiasco::THREAD_PAGER_CAP; } diff --git a/repos/ports/include/vmm/vcpu_dispatcher.h b/repos/ports/include/vmm/vcpu_dispatcher.h index 37fdc5143..a82d4ee25 100644 --- a/repos/ports/include/vmm/vcpu_dispatcher.h +++ b/repos/ports/include/vmm/vcpu_dispatcher.h @@ -17,6 +17,7 @@ /* Genode includes */ #include #include +#include namespace Vmm { @@ -108,18 +109,20 @@ class Vmm::Vcpu_dispatcher : public T */ void (*entry)() = &_portal_entry; - /* Create the portal at the desired selector index */ - _native_pd.rcv_window(exc_base + EV); - - Native_capability thread_cap(T::native_thread().ec_sel); + /* create the portal at the desired selector index (EV) */ + Native_capability thread_cap = + Capability_space::import(T::native_thread().ec_sel); Untyped_capability handler = retry( [&] () { + /* manually define selector used for RPC result */ + Thread::myself()->native_thread().client_rcv_sel = exc_base + EV; return _native_pd.alloc_rpc_cap(thread_cap, (addr_t)entry, mtd.value()); }, [&] () { + Thread::myself()->native_thread().reset_client_rcv_sel(); Pd_session_client *client = dynamic_cast(&_pd); @@ -127,7 +130,10 @@ class Vmm::Vcpu_dispatcher : public T env()->parent()->upgrade(*client, "ram_quota=16K"); }); - return handler.valid() && (exc_base + EV == handler.local_name()); + /* revert selector allocation to automatic mode of operation */ + Thread::myself()->native_thread().reset_client_rcv_sel(); + + return handler.valid() && (exc_base + EV == (addr_t)handler.local_name()); } /** diff --git a/repos/ports/include/vmm/vcpu_thread.h b/repos/ports/include/vmm/vcpu_thread.h index 23d78d5db..149d3a11a 100644 --- a/repos/ports/include/vmm/vcpu_thread.h +++ b/repos/ports/include/vmm/vcpu_thread.h @@ -15,7 +15,6 @@ #define _INCLUDE__VMM__VCPU_THREAD_H_ /* Genode includes */ -#include #include #include #include @@ -26,6 +25,7 @@ /* NOVA includes */ #include +#include namespace Vmm { diff --git a/repos/ports/src/noux/main.cc b/repos/ports/src/noux/main.cc index 46f229f04..3ff0c3c75 100644 --- a/repos/ports/src/noux/main.cc +++ b/repos/ports/src/noux/main.cc @@ -66,7 +66,8 @@ extern void init_network(); namespace Noux { using namespace Genode; - class Timeout_scheduler : Thread_deprecated<4096>, public Alarm_scheduler + class Timeout_scheduler : Thread_deprecated<1024*sizeof(long)>, + public Alarm_scheduler { private: Timer::Connection _timer;