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