diff --git a/repos/base-sel4/include/base/ipc_msgbuf.h b/repos/base-sel4/include/base/ipc_msgbuf.h
index 380b6d5e25..d38db66b6d 100644
--- a/repos/base-sel4/include/base/ipc_msgbuf.h
+++ b/repos/base-sel4/include/base/ipc_msgbuf.h
@@ -1,11 +1,11 @@
/*
- * \brief seL4-specific layout of IPC message buffer
+ * \brief IPC message buffer layout
* \author Norman Feske
- * \date 2014-10-14
+ * \date 2015-05-10
*/
/*
- * Copyright (C) 2014 Genode Labs GmbH
+ * 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.
@@ -14,99 +14,133 @@
#ifndef _INCLUDE__BASE__IPC_MSGBUF_H_
#define _INCLUDE__BASE__IPC_MSGBUF_H_
+#include
+
namespace Genode {
- /**
- * IPC message buffer layout
- */
- class Msgbuf_base
- {
- public:
-
- enum { MAX_CAPS_PER_MSG = 8 };
-
- protected:
-
- /*
- * Capabilities to be transferred
- */
- int _caps[MAX_CAPS_PER_MSG];
- Genode::size_t _used_caps;
- Genode::size_t _read_cap_index;
-
- /**
- * Maximum size of plain-data message payload
- */
- Genode::size_t _size;
-
- /**
- * Actual size of plain-data message payload
- */
- Genode::size_t _used_size;
-
- char _msg_start[]; /* symbol marks start of message buffer data */
-
- /*
- * No member variables are allowed beyond this point!
- */
-
- public:
-
- char buf[];
-
- Msgbuf_base() { reset_caps(); }
-
- /**
- * Return size of message buffer
- */
- inline Genode::size_t size() const { return _size; };
-
- /**
- * Return address of message buffer
- */
- inline void *addr() { return &_msg_start[0]; };
-
- void reset_caps() { _used_caps = 0; _read_cap_index = 0; }
-
- bool append_cap(int cap)
- {
- if (_used_caps == MAX_CAPS_PER_MSG)
- return false;
-
- _caps[_used_caps++] = cap;
- return true;
- }
-
- int read_cap()
- {
- if (_read_cap_index == _used_caps)
- return -1;
-
- return _caps[_read_cap_index++];
- }
-
- size_t used_caps() const { return _used_caps; }
-
- int cap(unsigned index) const
- {
- return index < _used_caps ? _caps[index] : -1;
- }
- };
-
-
- /**
- * Pump up IPC message buffer to specified buffer size
- */
- template
- class Msgbuf : public Msgbuf_base
- {
- public:
-
- char buf[BUF_SIZE];
-
- Msgbuf() { _size = BUF_SIZE; }
- };
+ class Msgbuf_base;
+ template struct Msgbuf;
}
+class Genode::Msgbuf_base
+{
+ public:
+
+ enum { MAX_CAPS_PER_MSG = 3 };
+
+ protected:
+
+ /*
+ * Resolve ambiguity if the header is included from a libc-using
+ * program.
+ */
+ typedef Genode::size_t size_t;
+
+ /*
+ * Capabilities to be transferred
+ */
+ Native_capability _caps[MAX_CAPS_PER_MSG];
+ size_t _used_caps = 0;
+ size_t _read_cap_index = 0;
+
+ /**
+ * Maximum size of plain-data message payload
+ */
+ size_t const _size;
+
+ /**
+ * Actual size of plain-data message payload
+ */
+ size_t _used_size = 0;
+
+ char _msg_start[]; /* symbol marks start of message buffer data */
+
+ /*
+ * No member variables are allowed beyond this point!
+ */
+
+ Msgbuf_base(size_t size) : _size(size) { }
+
+ public:
+
+ char buf[];
+
+ /**
+ * Return size of message buffer
+ */
+ size_t size() const { return _size; };
+
+ void reset_caps()
+ {
+ for (Genode::size_t i = 0; i < _used_caps; i++)
+ _caps[i] = Native_capability();
+
+ _used_caps = 0;
+ }
+
+ void reset_read_cap_index()
+ {
+ _read_cap_index = 0;
+ }
+
+ /**
+ * Return pointer to start of message-buffer content
+ */
+ void const *data() const { return &_msg_start[0]; };
+ void *data() { return &_msg_start[0]; };
+
+ /**
+ * Exception type
+ */
+ class Too_many_caps : public Exception { };
+
+ /**
+ * Called from '_marshal_capability'
+ */
+ void append_cap(Native_capability const &cap)
+ {
+ if (_used_caps == MAX_CAPS_PER_MSG)
+ throw Too_many_caps();
+
+ _caps[_used_caps++] = cap;
+ }
+
+ /**
+ * Called from '_unmarshal_capability'
+ */
+ Native_capability extract_cap()
+ {
+ if (_read_cap_index == _used_caps)
+ return Native_capability();
+
+ return _caps[_read_cap_index++];
+ }
+
+ /**
+ * Return number of marshalled capabilities
+ */
+ size_t used_caps() const { return _used_caps; }
+
+ Native_capability &cap(unsigned index)
+ {
+ return _caps[index];
+ }
+};
+
+
+template
+struct Genode::Msgbuf : Msgbuf_base
+{
+ /**
+ * Pump up IPC message buffer to specified buffer size
+ *
+ * XXX remove padding of 16
+ */
+ char buf[BUF_SIZE + 16];
+
+ Msgbuf() : Msgbuf_base(BUF_SIZE) { }
+};
+
+
#endif /* _INCLUDE__BASE__IPC_MSGBUF_H_ */
diff --git a/repos/base-sel4/src/base/env/capability_space.cc b/repos/base-sel4/src/base/env/capability_space.cc
index bb43309f59..d1019937d6 100644
--- a/repos/base-sel4/src/base/env/capability_space.cc
+++ b/repos/base-sel4/src/base/env/capability_space.cc
@@ -82,3 +82,38 @@ 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)
+{
+ Native_capability::Data *data = local_capability_space().lookup(rpc_obj_key);
+
+ return data ? Native_capability(*data) : Native_capability();
+}
+
+
+unsigned Capability_space::alloc_rcv_sel()
+{
+ PDBG("not implemented");
+ for (;;);
+ return 0;
+}
+
+
+void Capability_space::reset_sel(unsigned sel)
+{
+ PDBG("not implemented");
+}
+
+
+Native_capability Capability_space::import(Ipc_cap_data ipc_cap_data)
+{
+ PDBG("not implemented");
+
+ return Native_capability();
+}
diff --git a/repos/base-sel4/src/base/internal/capability_space_sel4.h b/repos/base-sel4/src/base/internal/capability_space_sel4.h
index 1785204611..af0701360d 100644
--- a/repos/base-sel4/src/base/internal/capability_space_sel4.h
+++ b/repos/base-sel4/src/base/internal/capability_space_sel4.h
@@ -22,7 +22,7 @@
#include
#include
-namespace Genode { template class Capability_space_sel4; }
+namespace Genode { template class Capability_space_sel4; }
/**
@@ -37,6 +37,9 @@ namespace Genode { namespace Capability_space {
{
Rpc_obj_key rpc_obj_key;
unsigned sel;
+
+ Ipc_cap_data(Rpc_obj_key rpc_obj_key, unsigned sel)
+ : rpc_obj_key(rpc_obj_key), sel(sel) { }
};
/**
@@ -49,6 +52,23 @@ namespace Genode { namespace Capability_space {
*/
unsigned alloc_rcv_sel();
+ /**
+ * Delete selector but retain allocation
+ *
+ * This function is used when a delegated capability selector is replaced
+ * with an already known selector. The delegated selector is discarded.
+ */
+ void reset_sel(unsigned sel);
+
+ /**
+ * Lookup capability by its RPC object key
+ */
+ Native_capability lookup(Rpc_obj_key key);
+
+ /**
+ * Import capability into the component's capability space
+ */
+ Native_capability import(Ipc_cap_data ipc_cap_data);
} }
@@ -65,7 +85,7 @@ namespace Genode { namespace Capability_space {
* freeing capabilities allocated from another component. This information
* is part of the core-specific 'Native_capability::Data' structure.
*/
-template
+template
class Genode::Capability_space_sel4
{
public:
@@ -73,10 +93,10 @@ class Genode::Capability_space_sel4
/*
* The capability space consists of two parts. The lower part is
* populated with statically-defined capabilities whereas the upper
- * part is dynamically managed by the component. The 'NUM_STATIC_CAPS'
- * defines the size of the first part.
+ * part is dynamically managed by the component. The
+ * 'NUM_CORE_MANAGED_CAPS' defines the size of the first part.
*/
- enum { NUM_STATIC_CAPS = 1024 };
+ enum { NUM_CORE_MANAGED_CAPS = _NUM_CORE_MANAGED_CAPS };
private:
@@ -111,7 +131,7 @@ class Genode::Capability_space_sel4
Tree_managed_data _caps_data[NUM_CAPS];
Avl_tree _tree;
- Lock _lock;
+ Lock mutable _lock;
/**
* Calculate index into _caps_data for capability data object
@@ -125,9 +145,9 @@ class Genode::Capability_space_sel4
/**
* Return true if capability is locally managed by the component
*/
- bool _is_dynamic(Data &data) const
+ bool _is_core_managed(Data &data) const
{
- return _index(data) >= NUM_STATIC_CAPS;
+ return _index(data) < NUM_CORE_MANAGED_CAPS;
}
void _remove(Native_capability::Data &data)
@@ -180,7 +200,7 @@ class Genode::Capability_space_sel4
{
Lock::Guard guard(_lock);
- if (_is_dynamic(data) && !data.dec_ref()) {
+ if (!_is_core_managed(data) && !data.dec_ref()) {
PDBG("remove cap");
_remove(data);
}
@@ -190,8 +210,9 @@ class Genode::Capability_space_sel4
{
Lock::Guard guard(_lock);
- if (_is_dynamic(data))
+ if (!_is_core_managed(data)) {
data.inc_ref();
+ }
}
Rpc_obj_key rpc_obj_key(Data const &data) const
@@ -203,6 +224,16 @@ class Genode::Capability_space_sel4
{
return { rpc_obj_key(data), sel(data) };
}
+
+ Data *lookup(Rpc_obj_key key) const
+ {
+ Lock::Guard guard(_lock);
+
+ if (!_tree.first())
+ return nullptr;
+
+ return _tree.first()->find_by_key(key);
+ }
};
diff --git a/repos/base-sel4/src/base/ipc/ipc.cc b/repos/base-sel4/src/base/ipc/ipc.cc
index 0204b15f94..3390c3bd3a 100644
--- a/repos/base-sel4/src/base/ipc/ipc.cc
+++ b/repos/base-sel4/src/base/ipc/ipc.cc
@@ -19,7 +19,8 @@
#include
/* base-internal includes */
-#include
+#include
+#include
/* seL4 includes */
#include
@@ -27,19 +28,216 @@
using namespace Genode;
+/**
+ * Message-register definitions
+ */
+enum {
+ MR_IDX_NUM_CAPS = 0,
+ MR_IDX_CAPS = 1,
+ MR_IDX_DATA = MR_IDX_CAPS + Msgbuf_base::MAX_CAPS_PER_MSG,
+};
+
+
+/**
+ * Convert Genode::Msgbuf_base content into seL4 message
+ *
+ * \param msg source message buffer
+ * \param data_length size of message data in bytes
+ */
+static seL4_MessageInfo_t new_seL4_message(Msgbuf_base &msg,
+ size_t const data_length)
+{
+ /*
+ * Supply capabilities to kernel IPC message
+ */
+ seL4_SetMR(MR_IDX_NUM_CAPS, msg.used_caps());
+ size_t sel4_sel_cnt = 0;
+ for (size_t i = 0; i < msg.used_caps(); i++) {
+
+ Native_capability &cap = msg.cap(i);
+
+ if (cap.valid()) {
+ Capability_space::Ipc_cap_data const ipc_cap_data =
+ Capability_space::ipc_cap_data(cap);
+
+ seL4_SetMR(MR_IDX_CAPS + i, ipc_cap_data.rpc_obj_key.value());
+ seL4_SetCap(sel4_sel_cnt++, ipc_cap_data.sel);
+ } else {
+ seL4_SetMR(MR_IDX_CAPS + i, Rpc_obj_key::INVALID);
+ }
+ }
+
+ /*
+ * Pad unused capability slots with invalid capabilities to avoid
+ * leakage of any information that happens to be in the IPC buffer.
+ */
+ for (size_t i = msg.used_caps(); i < Msgbuf_base::MAX_CAPS_PER_MSG; i++)
+ seL4_SetMR(MR_IDX_CAPS + i, Rpc_obj_key::INVALID);
+
+ /*
+ * Allocate and define receive selector
+ */
+ Native_thread &thread = Thread_base::myself()->tid();
+
+ if (!thread.rcv_sel)
+ thread.rcv_sel = Capability_space::alloc_rcv_sel();
+
+ /*
+ * Supply data payload
+ */
+ size_t const num_data_mwords =
+ align_natural(data_length) / sizeof(umword_t);
+
+ umword_t const *src = (umword_t const *)msg.data();
+ for (size_t i = 0; i < num_data_mwords; i++)
+ seL4_SetMR(MR_IDX_DATA + i, *src++);
+
+ seL4_MessageInfo_t const msg_info =
+ seL4_MessageInfo_new(0, 0, sel4_sel_cnt,
+ MR_IDX_DATA + num_data_mwords);
+ return msg_info;
+}
+
+
+/**
+ * Convert seL4 message into Genode::Msgbuf_base
+ */
+static void decode_seL4_message(umword_t badge,
+ seL4_MessageInfo_t const &msg_info,
+ Msgbuf_base &dst_msg)
+{
+ /*
+ * Extract Genode capabilities from seL4 IPC message
+ */
+ dst_msg.reset_caps();
+ size_t const num_caps = seL4_GetMR(MR_IDX_NUM_CAPS);
+ size_t curr_sel4_cap_idx = 0;
+
+ for (size_t i = 0; i < num_caps; i++) {
+
+ Rpc_obj_key const rpc_obj_key(seL4_GetMR(MR_IDX_CAPS + i));
+
+ if (!rpc_obj_key.valid()) {
+ dst_msg.append_cap(Native_capability());
+ continue;
+ }
+
+ /*
+ * RPC object key as contained in the message data is valid.
+ */
+
+ unsigned const unwrapped =
+ seL4_MessageInfo_get_capsUnwrapped(msg_info) &
+ (1 << curr_sel4_cap_idx);
+
+ /* distinguish unwrapped from delegated cap */
+ if (unwrapped) {
+
+ /*
+ * Received unwrapped capability
+ *
+ * This means that the capability argument belongs to our endpoint.
+ * So it is already present within the capability space.
+ */
+
+ unsigned const arg_badge =
+ seL4_CapData_Badge_get_Badge(seL4_GetBadge(curr_sel4_cap_idx));
+
+ if (arg_badge != rpc_obj_key.value()) {
+ PWRN("argument badge (%d) != RPC object key (%d)",
+ arg_badge, rpc_obj_key.value());
+ }
+
+ Native_capability arg_cap = Capability_space::lookup(rpc_obj_key);
+
+ dst_msg.append_cap(arg_cap);
+
+ } else {
+
+ /*
+ * Received delegated capability
+ *
+ * We have either received a capability that is foreign to us,
+ * or an alias for a capability that we already posses. The
+ * latter can happen in the following circumstances:
+ *
+ * - We forwarded a selector that was created by another
+ * component. We cannot re-identify such a capability when
+ * handed back because seL4's badge mechanism works only for
+ * capabilities belonging to the IPC destination endpoint.
+ *
+ * - We received a selector on the IPC reply path, where seL4's
+ * badge mechanism is not in effect.
+ */
+
+ bool const delegated = seL4_MessageInfo_get_extraCaps(msg_info);
+
+ ASSERT(delegated);
+
+ Native_thread &thread = Thread_base::myself()->tid();
+
+ Native_capability arg_cap = Capability_space::lookup(rpc_obj_key);
+
+ if (arg_cap.valid()) {
+
+ /*
+ * Discard the received selector and keep using the already
+ * present one.
+ *
+ * XXX We'd need to find out if both the received and the
+ * looked-up selector refer to the same endpoint.
+ * Unfortunaltely, seL4 lacks such a comparison operation.
+ */
+
+ Capability_space::reset_sel(thread.rcv_sel);
+
+ dst_msg.append_cap(arg_cap);
+
+ } else {
+
+ Capability_space::Ipc_cap_data const
+ ipc_cap_data(rpc_obj_key, thread.rcv_sel);
+
+ dst_msg.append_cap(Capability_space::import(ipc_cap_data));
+
+ /*
+ * Since we keep using the received selector, we need to
+ * allocate a fresh one for the next incoming delegation.
+ */
+ thread.rcv_sel = Capability_space::alloc_rcv_sel();
+ }
+ }
+ curr_sel4_cap_idx++;
+ }
+
+ /*
+ * Extract message data payload
+ */
+
+ umword_t *dst = (umword_t *)dst_msg.data();
+ for (size_t i = 0; i < seL4_MessageInfo_get_length(msg_info); i++)
+ *dst++ = seL4_GetMR(MR_IDX_DATA + i);
+
+ /*
+ * Store RPC object key of invoked object to be picked up by server.cc
+ */
+ *(long *)dst_msg.data() = badge;
+}
+
+
/*****************************
** IPC marshalling support **
*****************************/
void Ipc_ostream::_marshal_capability(Native_capability const &cap)
{
- PDBG("not implemented");
+ _snd_msg->append_cap(cap);
}
void Ipc_istream::_unmarshal_capability(Native_capability &cap)
{
- PDBG("not implemented");
+ cap = _rcv_msg->extract_cap();
}
@@ -49,16 +247,15 @@ void Ipc_istream::_unmarshal_capability(Native_capability &cap)
void Ipc_ostream::_send()
{
- PDBG("not implemented");
+ ASSERT(false);
_write_offset = sizeof(umword_t);
}
-
Ipc_ostream::Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg)
:
- Ipc_marshaller((char *)snd_msg->addr(), snd_msg->size()),
+ Ipc_marshaller((char *)snd_msg->data(), snd_msg->size()),
_snd_msg(snd_msg), _dst(dst)
{
_write_offset = sizeof(umword_t);
@@ -71,19 +268,13 @@ Ipc_ostream::Ipc_ostream(Native_capability dst, Msgbuf_base *snd_msg)
void Ipc_istream::_wait()
{
- PDBG("not implemented");
-
- for (;;)
- seL4_Yield();
-
-
- _read_offset = sizeof(umword_t);
+ ASSERT(false);
}
Ipc_istream::Ipc_istream(Msgbuf_base *rcv_msg)
:
- Ipc_unmarshaller((char *)rcv_msg->addr(), rcv_msg->size()),
+ Ipc_unmarshaller((char *)rcv_msg->data(), rcv_msg->size()),
_rcv_msg(rcv_msg)
{
_read_offset = sizeof(umword_t);
@@ -99,7 +290,20 @@ Ipc_istream::~Ipc_istream() { }
void Ipc_client::_call()
{
- PDBG("not implemented");
+ if (!Ipc_ostream::_dst.valid()) {
+ PERR("Trying to invoke an invalid capability, stop.");
+ kernel_debugger_panic("IPC destination is invalid");
+ }
+
+ seL4_MessageInfo_t const request_msg_info =
+ new_seL4_message(*_snd_msg, _write_offset);
+
+ unsigned const dst_sel = Capability_space::ipc_cap_data(_dst).sel;
+
+ seL4_MessageInfo_t const reply_msg_info =
+ seL4_Call(dst_sel, request_msg_info);
+
+ decode_seL4_message(0, reply_msg_info, *_rcv_msg);
_write_offset = _read_offset = sizeof(umword_t);
}
@@ -125,29 +329,19 @@ void Ipc_server::_prepare_next_reply_wait()
/* receive buffer offset */
_read_offset = sizeof(umword_t);
+
+ _rcv_msg->reset_read_cap_index();
+ _snd_msg->reset_caps();
}
void Ipc_server::_wait()
{
- /* wait for new server request */
- PDBG("called, do seL4_Wait");
-
+ seL4_Word badge = Rpc_obj_key::INVALID;
seL4_MessageInfo_t const msg_info =
- seL4_Wait(Thread_base::myself()->tid().ep_sel, nullptr);
- PDBG("returned from seL4_Wait, call seL4_Reply");
+ seL4_Wait(Thread_base::myself()->tid().ep_sel, &badge);
- PDBG("msg_info: got unwrapped %d", seL4_MessageInfo_get_capsUnwrapped(msg_info));
- PDBG(" got extra caps %d", seL4_MessageInfo_get_extraCaps(msg_info));
- PDBG(" label %d", seL4_MessageInfo_get_label(msg_info));
-
- if (seL4_MessageInfo_get_capsUnwrapped(msg_info)) {
- PDBG(" badge %d", seL4_CapData_Badge_get_Badge(seL4_GetBadge(0)));
- }
-
- for (;;)
- seL4_Yield();
-// try { Ipc_istream::_wait(); } catch (Blocking_canceled) { }
+ decode_seL4_message(badge, msg_info, *_rcv_msg);
_prepare_next_reply_wait();
}
@@ -155,18 +349,30 @@ void Ipc_server::_wait()
void Ipc_server::_reply()
{
- try { _send(); } catch (Ipc_error) { }
-
- _prepare_next_reply_wait();
+ ASSERT(false);
}
void Ipc_server::_reply_wait()
{
- if (_reply_needed)
- _reply();
+ if (!_reply_needed) {
- _wait();
+ _wait();
+
+ } else {
+
+ seL4_Word badge = Rpc_obj_key::INVALID;
+ seL4_MessageInfo_t const reply_msg_info =
+ new_seL4_message(*_snd_msg, _write_offset);
+
+ seL4_MessageInfo_t const request_msg_info =
+ seL4_ReplyWait(Thread_base::myself()->tid().ep_sel,
+ reply_msg_info, &badge);
+
+ decode_seL4_message(badge, request_msg_info, *_rcv_msg);
+ }
+
+ _prepare_next_reply_wait();
}
@@ -176,5 +382,6 @@ Ipc_server::Ipc_server(Msgbuf_base *snd_msg,
Ipc_istream(rcv_msg), Ipc_ostream(Native_capability(), snd_msg),
_reply_needed(false)
{
- *static_cast(this) = Native_capability(Capability_space::create_ep_cap(*Thread_base::myself()));
+ *static_cast(this) =
+ Native_capability(Capability_space::create_ep_cap(*Thread_base::myself()));
}
diff --git a/repos/base-sel4/src/base/server/server.cc b/repos/base-sel4/src/base/server/server.cc
index 4b7e286aa1..0d7d3daf29 100644
--- a/repos/base-sel4/src/base/server/server.cc
+++ b/repos/base-sel4/src/base/server/server.cc
@@ -64,9 +64,6 @@ void Rpc_entrypoint::entry()
/* set default return value */
srv.ret(Ipc_client::ERR_INVALID_OBJECT);
- /* check whether capability's label fits global id */
- PDBG("not implemented");
-
/* atomically lookup and lock referenced object */
Object_pool::Guard curr_obj(lookup_and_lock(srv.badge()));
if (!curr_obj)
diff --git a/repos/base-sel4/src/core/capability_space.cc b/repos/base-sel4/src/core/capability_space.cc
index 112c461fc2..14f0ce27b0 100644
--- a/repos/base-sel4/src/core/capability_space.cc
+++ b/repos/base-sel4/src/core/capability_space.cc
@@ -61,7 +61,7 @@ namespace {
struct Local_capability_space
:
- Capability_space_sel4<1UL << Core_cspace::NUM_CORE_SEL_LOG2,
+ Capability_space_sel4<1UL << Core_cspace::NUM_CORE_SEL_LOG2, 0UL,
Native_capability::Data>
{ };
@@ -163,7 +163,34 @@ Capability_space::Ipc_cap_data Capability_space::ipc_cap_data(Native_capability
}
+Native_capability Capability_space::lookup(Rpc_obj_key rpc_obj_key)
+{
+ Native_capability::Data *data = local_capability_space().lookup(rpc_obj_key);
+
+ return data ? Native_capability(*data) : Native_capability();
+}
+
+
unsigned Capability_space::alloc_rcv_sel()
{
return platform_specific()->alloc_core_rcv_sel();
}
+
+
+void Capability_space::reset_sel(unsigned sel)
+{
+ return platform_specific()->reset_sel(sel);
+}
+
+
+Native_capability Capability_space::import(Ipc_cap_data ipc_cap_data)
+{
+ /* imported capabilities are not associated with a CAP session */
+ Cap_session const *cap_session = nullptr;
+
+ Native_capability::Data &data =
+ local_capability_space().create_capability(ipc_cap_data.sel, cap_session,
+ ipc_cap_data.rpc_obj_key);
+
+ return Native_capability(data);
+}
diff --git a/repos/base-sel4/src/core/include/platform.h b/repos/base-sel4/src/core/include/platform.h
index 01cda78e61..6d9d23cef4 100644
--- a/repos/base-sel4/src/core/include/platform.h
+++ b/repos/base-sel4/src/core/include/platform.h
@@ -138,6 +138,7 @@ class Genode::Platform : public Platform_generic
unsigned alloc_core_sel();
unsigned alloc_core_rcv_sel();
+ void reset_sel(unsigned sel);
void free_core_sel(unsigned sel);
void wait_for_exit();
diff --git a/repos/base-sel4/src/core/platform.cc b/repos/base-sel4/src/core/platform.cc
index 463d0f3b83..3eeabfdf03 100644
--- a/repos/base-sel4/src/core/platform.cc
+++ b/repos/base-sel4/src/core/platform.cc
@@ -272,12 +272,18 @@ unsigned Platform::alloc_core_rcv_sel()
{
unsigned rcv_sel = alloc_core_sel();
- seL4_SetCapReceivePath(_core_cnode.sel(), rcv_sel, 0);
+ seL4_SetCapReceivePath(_core_cnode.sel(), rcv_sel, _core_cnode.size_log2());
return rcv_sel;
}
+void Platform::reset_sel(unsigned sel)
+{
+ _core_cnode.remove(sel);
+}
+
+
void Platform::free_core_sel(unsigned sel)
{
Lock::Guard guard(_core_sel_alloc_lock);