diff --git a/base-foc/include/base/cap_alloc.h b/base-foc/include/base/cap_alloc.h
new file mode 100644
index 0000000000..2aa2aaed5a
--- /dev/null
+++ b/base-foc/include/base/cap_alloc.h
@@ -0,0 +1,127 @@
+/*
+ * \brief Capability index allocator for Fiasco.OC.
+ * \author Stefan Kalkowski
+ * \date 2012-02-16
+ */
+
+/*
+ * Copyright (C) 2012 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__CAP_ALLOC_H_
+#define _INCLUDE__BASE__CAP_ALLOC_H_
+
+#include
+#include
+
+namespace Genode {
+
+ /**
+ * Cap_index_allocator_tpl implements the Cap_index_allocator for Fiasco.OC.
+ *
+ * It's designed as a template because we need two distinguished versions
+ * for core and non-core processes with respect to dimensioning. Moreover,
+ * core needs more information within a Cap_index object, than the base
+ * class provides.
+ *
+ * \param T Cap_index specialization to use
+ * \param SZ size of Cap_index array used by the allocator
+ */
+ template
+ class Cap_index_allocator_tpl : public Cap_index_allocator
+ {
+ private:
+
+ Spin_lock _lock; /* used very early in initialization,
+ where normal lock isn't feasible */
+
+ enum {
+ /* everything above START_IDX is managed by core */
+ START_IDX = Fiasco::USER_BASE_CAP >> Fiasco::L4_CAP_SHIFT
+ };
+
+ protected:
+
+ unsigned char _data[SZ*sizeof(T)];
+ T* _indices;
+
+ public:
+
+ Cap_index_allocator_tpl() : _indices(reinterpret_cast(&_data)) {
+ memset(&_data, 0, sizeof(_data)); }
+
+
+ /***********************************
+ ** Cap_index_allocator interface **
+ ***********************************/
+
+ Cap_index* alloc(size_t cnt)
+ {
+ Lock_guard guard(_lock);
+
+ /*
+ * iterate through array and find unused, consecutive entries
+ */
+ for (unsigned i = START_IDX, j = 0; (i+cnt) < SZ; i+=j+1, j=0) {
+ for (; j < cnt; j++)
+ if (_indices[i+j].used())
+ break;
+
+ /* if we found a fitting hole, initialize the objects */
+ if (j == cnt) {
+ for (j = 0; j < cnt; j++)
+ new (&_indices[i+j]) T();
+ return &_indices[i];
+ }
+ }
+ return 0;
+ }
+
+ Cap_index* alloc(addr_t addr, size_t cnt)
+ {
+ Lock_guard guard(_lock);
+
+ /*
+ * construct the Cap_index pointer from the given
+ * address in capability space
+ */
+ T* obj = reinterpret_cast(kcap_to_idx(addr));
+ T* ret = obj;
+
+ /* check whether the consecutive entries are in range and unused */
+ for (size_t i = 0; i < cnt; i++, obj++) {
+ if (obj < &_indices[0] || obj >= &_indices[SZ])
+ throw Index_out_of_bounds();
+ if (obj->used())
+ throw Region_conflict();
+ new (obj) T();
+ }
+ return ret;
+ }
+
+ void free(Cap_index* idx, size_t cnt)
+ {
+ Lock_guard guard(_lock);
+
+ T* obj = static_cast(idx);
+ for (size_t i = 0; i < cnt; obj++, i++) {
+ /* range check given pointer address */
+ if (obj < &_indices[0] || obj >= &_indices[SZ])
+ throw Index_out_of_bounds();
+ delete obj;
+ }
+ }
+
+ addr_t idx_to_kcap(Cap_index *idx) {
+ return ((T*)idx - &_indices[0]) << Fiasco::L4_CAP_SHIFT;
+ }
+
+ Cap_index* kcap_to_idx(addr_t kcap) {
+ return &_indices[kcap >> Fiasco::L4_CAP_SHIFT]; }
+ };
+}
+
+#endif /* _INCLUDE__BASE__CAP_ALLOC_H_ */
diff --git a/base-foc/include/base/cap_map.h b/base-foc/include/base/cap_map.h
new file mode 100644
index 0000000000..61529ac35a
--- /dev/null
+++ b/base-foc/include/base/cap_map.h
@@ -0,0 +1,252 @@
+/*
+ * \brief Mapping of Genode's capability names to kernel capabilities.
+ * \author Stefan Kalkowski
+ * \date 2012-02-16
+ *
+ * Although kernels like Fiasco.OC and NOVA provide capability mechanisms
+ * to us, which should prevent the usage of global names, there is no
+ * efficient way to retrieve a capability a process owns, when it gets the
+ * same capability delivered again via IPC from another thread. But in some
+ * use-cases in Genode this is essential (e.g. parent getting a close-session
+ * request from a child). Moreover, we waste a lot of slots in the
+ * capability-space of the process for one and the same kernel-object.
+ * That's why we introduce a map of Genode's global capability names to the
+ * process-local addresses in the capability-space.
+ *
+ * TODO: should be moved to the generic part of the framework, and used by
+ * NOVA too.
+ */
+
+/*
+ * Copyright (C) 2012 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__CAP_MAP_H_
+#define _INCLUDE__BASE__CAP_MAP_H_
+
+/* Genode includes */
+#include
+#include
+#include
+#include
+#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:
+
+ enum { INVALID_ID = -1, UNUSED = 0 };
+
+ uint16_t _id; /* global capability id */
+
+ public:
+
+ Cap_index() : _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; }
+ 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);
+ };
+
+
+ /**
+ * Allocator for Cap_index objects.
+ *
+ * This is just an interface, as the real allocator has to be
+ * implemented platform-specific.
+ */
+ class Cap_index_allocator: Noncopyable
+ {
+ public:
+
+ class Index_out_of_bounds : public Exception { };
+ class Region_conflict : public Exception { };
+
+ virtual ~Cap_index_allocator() {}
+
+ /**
+ * Allocate a range of Cap_index objects
+ *
+ * \param cnt number of objects to allocate
+ * \return pointer to first allocated object, or zero if
+ * out of entries
+ */
+ virtual Cap_index* alloc(size_t cnt) = 0;
+
+ /**
+ * Allocate a range of Cap_index objects at a specific
+ * point in the capability space
+ *
+ * \param kcap address in capability space
+ * \param cnt number of objects to allocate
+ * \throw Index_out_of_bounds if address is out of scope
+ * \throw Region_conflict if capability space entry is used
+ * \return pointer to first allocated object,
+ * or zero if out of entries
+ */
+ virtual Cap_index* alloc(addr_t kcap, size_t cnt) = 0;
+
+ /**
+ * Free a range of Cap_index objects
+ *
+ * \param idx pointer to first object in range
+ * \param cnt number of objects to free
+ * \throw Index_out_of_bounds if address is out of scope
+ */
+ virtual void free(Cap_index *idx, size_t cnt) = 0;
+
+ /**
+ * Get the Cap_index object's address in capability space
+ *
+ * \param idx pointer to the Cap_index object in question
+ */
+ virtual addr_t idx_to_kcap(Cap_index *idx) = 0;
+
+ /**
+ * Get the Cap_index object of a specific location
+ * in the capability space
+ *
+ * \param kcap the address in the capability space
+ */
+ virtual Cap_index* kcap_to_idx(addr_t kcap) = 0;
+ };
+
+
+ /**
+ * Get the global Cap_index_allocator of the process.
+ */
+ Cap_index_allocator *cap_idx_alloc();
+
+
+ /**
+ * Low-level spin-lock to protect Cap_index_allocator and the Cap_map
+ *
+ * We cannot use a normal Genode lock because this lock is used by code
+ * executed prior the initialization of Genode
+ */
+ class Spin_lock
+ {
+ private:
+
+ volatile int _spinlock;
+
+ public:
+
+ /**
+ * Constructor
+ */
+ Spin_lock();
+
+ void lock();
+ void unlock();
+
+ /**
+ * Lock guard
+ */
+ typedef Genode::Lock_guard Guard;
+ };
+
+
+ class Native_capability;
+
+
+ /**
+ * The Capability_map is an AVL-tree of Cap_index objects that can be
+ * found via the global capability id
+ *
+ * It is used to re-find capabilities whenever a capability gets
+ * transfered to a process, so that we can re-use an existing one
+ * to save entries in the capability space, and prevent leaks of
+ * them.
+ */
+ class Capability_map : Noncopyable
+ {
+ private:
+
+ Avl_tree _tree;
+ Spin_lock _lock;
+
+ public:
+
+ /**
+ * Find an existing Cap_index via a capability id
+ *
+ * \param id the global capability id
+ * \return pointer of Cap_index when found, otherwise zero
+ */
+ Cap_index* find(int id);
+
+ /**
+ * Create and insert a new Cap_index with a specific capability id
+ *
+ * Allocation of the Cap_index is done via the global
+ * Cap_index_allocator, which might throw exceptions that aren't
+ * caught by this method
+ *
+ * \param id the global capability id
+ * \return pointer to the new Cap_index object, or zero
+ * when allocation failed
+ */
+ Cap_index* insert(int id);
+
+
+ /**
+ * Create and insert a new Cap_index with a specific capability id,
+ * and location in capability space
+ *
+ * Allocation of the Cap_index is done via the global
+ * Cap_index_allocator, which might throw exceptions that aren't
+ * caught by this method
+ *
+ * \param id the global capability id
+ * \param kcap address in capability space
+ * \return pointer to the new Cap_index object, or zero
+ * when allocation failed
+ */
+ Cap_index* insert(int id, addr_t kcap);
+
+ /**
+ * Remove a Cap_index object
+ *
+ * \param i pointer to Cap_index object to remove
+ */
+ void remove(Cap_index* i);
+ };
+
+
+ /**
+ * Get the global Capability_map of the process.
+ */
+ Capability_map *cap_map();
+}
+
+#endif /* _INCLUDE__BASE__CAP_MAP_H_ */
diff --git a/base-foc/include/base/cap_sel_alloc.h b/base-foc/include/base/cap_sel_alloc.h
deleted file mode 100644
index 9d0b1adb16..0000000000
--- a/base-foc/include/base/cap_sel_alloc.h
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * \brief Interface for process-local capability-selector allocation
- * \author Norman Feske
- * \author Stefan Kalkowski
- * \date 2010-01-19
- *
- * This interface is Fiasco-specific and not part of the Genode API. It should
- * only be used internally by the framework or by Fiasco-specific code. The
- * implementation of the interface is part of the environment library.
- *
- * This implementation is borrowed by the nova-platform equivalent.
- * (TODO: merge it)
- */
-
-/*
- * Copyright (C) 2010-2012 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__CAP_SEL_ALLOC_H_
-#define _INCLUDE__BASE__CAP_SEL_ALLOC_H_
-
-/* Genode includes */
-#include
-#include
-#include
-#include
-#include
-#include
-
-/* Fiasco.OC includes */
-namespace Fiasco {
-#include
-#include
-}
-
-namespace Genode
-{
- class Capability_allocator
- {
- protected:
-
- Capability_allocator() {}
- virtual ~Capability_allocator() {}
-
- public:
-
- /**
- * Allocate range of capability selectors
- *
- * \param num_caps_log2 number of capability selectors. By default,
- * the function returns a single capability selector.
- * \return first capability selector of allocated range,
- * or 0 if allocation failed
- */
- virtual addr_t alloc(size_t num_caps = 1) = 0;
-
-
- /**
- * Allocate or find a capability selector
- *
- * \param id Genode's global capability id we're looking for
- * \return return a previously allocated cap-selector associated
- * with the given id, or a new one, that is associated
- * with the id from now on.
- */
- virtual addr_t alloc_id(unsigned id) = 0;
-
- /**
- * Release range of capability selectors
- *
- * \param cap first capability selector of range
- * \param num_caps_log2 number of capability selectors to free.
- */
- virtual void free(addr_t cap, size_t num_caps = 1) = 0;
- };
-
-
- Capability_allocator* cap_alloc();
-
-
- /**
- * Low-level spin-lock to protect the allocator
- *
- * We cannot use a normal Genode lock because this lock is used by code
- * executed prior the initialization of Genode.
- */
- class Spin_lock
- {
- private:
-
- volatile int _spinlock;
-
- public:
-
- /**
- * Constructor
- */
- Spin_lock();
-
- void lock();
- void unlock();
-
- /**
- * Lock guard
- */
- typedef Genode::Lock_guard Guard;
- };
-
-
-
- template
- class Capability_allocator_tpl : public Capability_allocator
- {
- private:
-
- /**
- * Node in the capability cache,
- * associates global cap ids with kernel-capabilities.
- */
- class Cap_node : public Avl_node
- {
- private:
-
- friend class Capability_allocator_tpl;
-
- unsigned long _id;
- addr_t _kcap;
-
- public:
-
- Cap_node() : _id(0), _kcap(0) {}
- Cap_node(unsigned long id, addr_t kcap)
- : _id(id), _kcap(kcap) {}
-
- bool higher(Cap_node *n) {
- return n->_id > _id; }
-
- Cap_node *find_by_id(unsigned long id)
- {
- if (_id == id) return this;
-
- Cap_node *n = Avl_node::child(id > _id);
- return n ? n->find_by_id(id) : 0;
- }
-
-
- unsigned long id() const { return _id; }
- addr_t kcap() const { return _kcap; }
- bool valid() const { return _id || _kcap; }
- };
-
-
- addr_t _cap_idx; /* start cap-selector */
- Cap_node _data[SZ]; /* cache-nodes backing store */
- Avl_tree _tree; /* cap cache */
- Spin_lock _lock;
-
- public:
-
- /**
- * Constructor
- */
- Capability_allocator_tpl() : _cap_idx(Fiasco::USER_BASE_CAP) { }
-
-
- /************************************
- ** Capability_allocator interface **
- ************************************/
-
- addr_t alloc(size_t num_caps)
- {
- Spin_lock::Guard guard(_lock);
-
- int ret_base = _cap_idx;
- _cap_idx += num_caps * Fiasco::L4_CAP_SIZE;
- return ret_base;
- }
-
- addr_t alloc_id(unsigned id)
- {
- _lock.lock();
- Cap_node *n = _tree.first();
- if (n)
- n = n->find_by_id(id);
- _lock.unlock();
-
- if (n) {
- return n->kcap();
- }
-
- addr_t kcap = alloc(1);
-
- _lock.lock();
- for (unsigned i = 0; i < SZ; i++)
- if (!_data[i].valid()) {
- _data[i]._id = id;
- _data[i]._kcap = kcap;
- _tree.insert(&_data[i]);
- break;
- }
- _lock.unlock();
- return kcap;
- }
-
- void free(addr_t cap, size_t num_caps)
- {
- Spin_lock::Guard guard(_lock);
-
- for (unsigned i = 0; i < SZ; i++)
- if (!_data[i]._kcap == cap) {
- _tree.remove(&_data[i]);
- _data[i]._kcap = 0;
- _data[i]._id = 0;
- break;
- }
- }
- };
-}
-
-#endif /* _INCLUDE__BASE__CAP_SEL_ALLOC_H_ */
-
diff --git a/base-foc/include/base/ipc.h b/base-foc/include/base/ipc.h
index 414872fe94..7fdfed4803 100644
--- a/base-foc/include/base/ipc.h
+++ b/base-foc/include/base/ipc.h
@@ -24,9 +24,14 @@ namespace Fiasco {
inline void Genode::Ipc_ostream::_marshal_capability(Genode::Native_capability const &cap)
{
- long unique_id = cap.local_name();
- _write_to_buf(unique_id);
- if (unique_id)
+ bool local = cap.local();
+ long id = local ? (long)cap.local() : cap.local_name();
+
+ _write_to_buf(local);
+ _write_to_buf(id);
+
+ /* only transfer kernel-capability if it's no local capability and valid */
+ if (!local && id)
_snd_msg->snd_append_cap_sel(cap.dst());
}
@@ -35,24 +40,48 @@ inline void Genode::Ipc_istream::_unmarshal_capability(Genode::Native_capability
{
using namespace Fiasco;
- /* extract Genode internal capability label from message buffer */
- long unique_id = 0;
- _read_from_buf(unique_id);
+ bool local = false;
+ long id = 0;
- if (!unique_id) {
+ /* extract capability id from message buffer, and whether it's a local cap */
+ _read_from_buf(local);
+ _read_from_buf(id);
+
+ /* if it's a local capability, the pointer is marshalled in the id */
+ if (local) {
+ cap = Capability::local_cap((Native_capability*)id);
+ return;
+ }
+
+ /* if id is zero an invalid capability was tranfered */
+ if (!id) {
cap = Native_capability();
return;
}
- /* allocate new cap slot and grant cap to it out of receive window */
- Genode::addr_t cap_sel = cap_alloc()->alloc_id(unique_id);
- l4_msgtag_t tag = l4_task_cap_valid(L4_BASE_TASK_CAP, cap_sel);
- if (!tag.label()) {
- l4_task_map(L4_BASE_TASK_CAP, L4_BASE_TASK_CAP,
- l4_obj_fpage(_rcv_msg->rcv_cap_sel(), 0, L4_FPAGE_RWX),
- cap_sel | L4_ITEM_MAP | L4_MAP_ITEM_GRANT);
+ /* we received a valid, non-local capability, maybe we already own it? */
+ Cap_index *i = cap_map()->find(id);
+ bool map = false;
+ if (i) {
+ /**
+ * If we've a dead capability in our database, which is already
+ * revoked, its id might be reused.
+ */
+ l4_msgtag_t tag = Fiasco::l4_task_cap_valid(L4_BASE_TASK_CAP, i->kcap());
+ if (!tag.label())
+ map = true;
+ } else {
+ /* insert the new capability in the map */
+ i = cap_map()->insert(id);
+ map = true;
}
- cap = Native_capability(cap_sel, unique_id);
+
+ /* map the received capability from the receive-buffer if necessary */
+ if (map)
+ l4_task_map(L4_BASE_TASK_CAP, L4_BASE_TASK_CAP,
+ l4_obj_fpage(_rcv_msg->rcv_cap_sel(), 0, L4_FPAGE_RWX),
+ i->kcap() | L4_ITEM_MAP | L4_MAP_ITEM_GRANT);
+ cap = Native_capability(i);
}
#endif /* _INCLUDE__BASE__IPC_H_ */
diff --git a/base-foc/include/base/ipc_msgbuf.h b/base-foc/include/base/ipc_msgbuf.h
index 6f1225e898..d9d4e3a2b4 100644
--- a/base-foc/include/base/ipc_msgbuf.h
+++ b/base-foc/include/base/ipc_msgbuf.h
@@ -18,7 +18,7 @@
#define _INCLUDE__BASE__IPC_MSGBUF_H_
/* Genode includes */
-#include
+#include
/* Fiasco.OC includes */
namespace Fiasco {
@@ -51,7 +51,7 @@ namespace Genode {
/**
* Base of capability receive window.
*/
- addr_t _rcv_cap_sel_base;
+ Cap_index* _rcv_idx_base;
/**
* Read counter for unmarshalling portal capability selectors
@@ -65,13 +65,15 @@ namespace Genode {
/**
* Constructor
*/
- Msgbuf_base()
- : _rcv_cap_sel_base(cap_alloc()->alloc(MAX_CAP_ARGS))
+ Msgbuf_base() : _rcv_idx_base(cap_idx_alloc()->alloc(MAX_CAP_ARGS))
{
rcv_reset();
snd_reset();
}
+ ~Msgbuf_base() {
+ cap_idx_alloc()->free(_rcv_idx_base, MAX_CAP_ARGS); }
+
/*
* Begin of actual message buffer
*/
@@ -121,7 +123,7 @@ namespace Genode {
/**
* Return address of capability receive window.
*/
- addr_t rcv_cap_sel_base() { return _rcv_cap_sel_base; }
+ addr_t rcv_cap_sel_base() { return _rcv_idx_base->kcap(); }
/**
* Reset capability receive window
@@ -134,7 +136,7 @@ namespace Genode {
* \return capability selector, or 0 if index is invalid
*/
addr_t rcv_cap_sel() {
- return _rcv_cap_sel_base + _rcv_cap_sel_cnt++ * Fiasco::L4_CAP_SIZE; }
+ return rcv_cap_sel_base() + _rcv_cap_sel_cnt++ * Fiasco::L4_CAP_SIZE; }
};
diff --git a/base-foc/include/base/ipc_pager.h b/base-foc/include/base/ipc_pager.h
index 75917cdf1b..8ef131595c 100644
--- a/base-foc/include/base/ipc_pager.h
+++ b/base-foc/include/base/ipc_pager.h
@@ -153,8 +153,8 @@ namespace Genode {
/**
* Set destination for next reply
*/
- void set_reply_dst(Native_capability pager_object) {
- _last = pager_object.dst(); }
+ void set_reply_dst(Native_thread t) {
+ _last = t; }
/**
* Answer call without sending a flex-page mapping
diff --git a/base-foc/include/base/native_types.h b/base-foc/include/base/native_types.h
index cb49ee33dc..1d5d454668 100644
--- a/base-foc/include/base/native_types.h
+++ b/base-foc/include/base/native_types.h
@@ -1,12 +1,13 @@
#ifndef _INCLUDE__BASE__NATIVE_TYPES_H_
#define _INCLUDE__BASE__NATIVE_TYPES_H_
-#include
+#include
namespace Fiasco {
#include
#include
#include
+#include
enum Cap_selectors {
TASK_CAP = L4_BASE_TASK_CAP,
@@ -24,29 +25,92 @@ namespace Fiasco {
UTCB_TCR_BADGE = 1,
UTCB_TCR_THREAD_OBJ = 2
};
+
+ struct Capability
+ {
+ static bool valid(l4_cap_idx_t idx) {
+ return !(idx & L4_INVALID_CAP_BIT) && idx != 0; }
+ };
+
}
namespace Genode {
- struct Cap_dst_policy
- {
- typedef Fiasco::l4_cap_idx_t Dst;
-
- static bool valid(Dst idx) {
- return !(idx & Fiasco::L4_INVALID_CAP_BIT) && idx != 0; }
-
- static Dst invalid() { return Fiasco::L4_INVALID_CAP;}
- static void copy(void* dst, Native_capability_tpl* src);
- };
-
typedef volatile int Native_lock;
typedef Fiasco::l4_cap_idx_t Native_thread_id;
typedef Fiasco::l4_cap_idx_t Native_thread;
typedef Fiasco::l4_cap_idx_t Native_task;
typedef Fiasco::l4_utcb_t* Native_utcb;
- typedef int Native_connection_state;
- typedef Native_capability_tpl Native_capability;
+
+ /**
+ * 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. Moreover, it might instead
+ * of a Cap_index reference some process-local object, and thereby
+ * implements a local capability.
+ */
+ class Native_capability
+ {
+ private:
+
+ Cap_index* _idx;
+ void* _ptr;
+
+ inline Native_thread_id _cap_sel() const
+ {
+ return _idx ? Native_thread_id(_idx->kcap())
+ : Native_thread_id();
+ }
+
+ protected:
+
+ /**
+ * Constructs a local capability, used by derived Capability
+ * class only
+ *
+ * \param ptr pointer to process-local object
+ */
+ Native_capability(void* ptr) : _idx(0), _ptr(ptr) { }
+
+ public:
+
+ /**
+ * Default constructor creates an invalid capability
+ */
+ Native_capability() : _idx(0), _ptr(0) { }
+
+ /**
+ * Construct capability manually
+ */
+ Native_capability(Cap_index* idx) : _idx(idx), _ptr(0) { }
+
+ /**
+ * 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 (_ptr) ? _ptr == o._ptr : _idx == o._idx; }
+
+
+ /*******************************************
+ ** Interface provided by all platforms **
+ *******************************************/
+
+ int local_name() const { return _idx ? _idx->id() : 0; }
+ Native_thread dst() const { return _cap_sel(); }
+ bool valid() const { return (_idx != 0) && _idx->valid(); }
+ void* local() const { return _ptr; }
+ void copy_to(void* dst) { *((int*)dst) = local_name(); }
+ };
+
+
+ typedef int Native_connection_state;
}
#endif /* _INCLUDE__BASE__NATIVE_TYPES_H_ */
diff --git a/base-foc/include/base/thread_state.h b/base-foc/include/base/thread_state.h
index 680b082fcc..5e891ce430 100644
--- a/base-foc/include/base/thread_state.h
+++ b/base-foc/include/base/thread_state.h
@@ -24,16 +24,20 @@ namespace Genode {
struct Thread_state : public Cpu_state
{
- Native_capability cap; /* capability selector with thread cap */
+ Native_thread kcap; /* thread's gate cap in its pd */
+ int id; /* id of gate capability */
+ Native_utcb utcb; /* thread's utcb in its pd */
unsigned exceptions; /* counts exceptions raised by the thread */
bool paused; /* indicates whether thread is stopped */
- bool in_exception; /* true if thread is currently in exception */
+ bool in_exception; /* true if thread is in exception */
Lock lock;
/**
* Constructor
*/
- Thread_state() : cap(), exceptions(0), paused(false) { }
+ Thread_state()
+ : kcap(Fiasco::L4_INVALID_CAP), id(0), utcb(0), exceptions(0),
+ paused(false), in_exception(false) { }
};
}
diff --git a/base-foc/include/signal_session/source_rpc_object.h b/base-foc/include/signal_session/source_rpc_object.h
index eef8cc1509..495d7c8e09 100644
--- a/base-foc/include/signal_session/source_rpc_object.h
+++ b/base-foc/include/signal_session/source_rpc_object.h
@@ -32,6 +32,9 @@ namespace Genode {
public:
+ Signal_source_rpc_object(Native_capability cap)
+ : _blocking_semaphore(cap) {}
+
Native_capability _request_semaphore() { return _blocking_semaphore; }
};
}
diff --git a/base-foc/lib/mk/cap_copy.mk b/base-foc/lib/mk/cap_copy.mk
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/base-foc/lib/mk/env.mk b/base-foc/lib/mk/env.mk
index 733c424d03..8b689c4831 100644
--- a/base-foc/lib/mk/env.mk
+++ b/base-foc/lib/mk/env.mk
@@ -1,10 +1,11 @@
-SRC_CC = env.cc context_area.cc cap_sel_alloc.cc \
+SRC_CC = env.cc context_area.cc cap_map.cc cap_alloc.cc \
reload_parent_cap.cc spin_lock.cc
LIBS = ipc heap log_console lock
INC_DIR += $(REP_DIR)/src/base/lock $(BASE_DIR)/src/base/lock
vpath env.cc $(BASE_DIR)/src/base/env
vpath context_area.cc $(BASE_DIR)/src/base/env
-vpath cap_sel_alloc.cc $(REP_DIR)/src/base/env
-vpath reload_parent_cap.cc $(BASE_DIR)/src/base/env
+vpath cap_map.cc $(REP_DIR)/src/base/env
+vpath cap_alloc.cc $(REP_DIR)/src/base/env
vpath spin_lock.cc $(REP_DIR)/src/base/env
+vpath reload_parent_cap.cc $(BASE_DIR)/src/base/env
diff --git a/base-foc/lib/mk/ipc.inc b/base-foc/lib/mk/ipc.inc
index 6c85c3682e..9a9abfc516 100644
--- a/base-foc/lib/mk/ipc.inc
+++ b/base-foc/lib/mk/ipc.inc
@@ -1,4 +1,4 @@
-LIBS = syscalls cap_copy
+LIBS = syscalls
SRC_CC += ipc.cc pager.cc
INC_DIR += $(REP_DIR)/src/base/lock
diff --git a/base-foc/src/base/env/cap_alloc.cc b/base-foc/src/base/env/cap_alloc.cc
new file mode 100644
index 0000000000..d7b4387ea7
--- /dev/null
+++ b/base-foc/src/base/env/cap_alloc.cc
@@ -0,0 +1,20 @@
+/*
+ * \brief Capability index allocator for Fiasco.OC non-core processes.
+ * \author Stefan Kalkowski
+ * \date 2012-02-16
+ */
+
+/*
+ * Copyright (C) 2012 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
+
+Genode::Cap_index_allocator* Genode::cap_idx_alloc()
+{
+ static Genode::Cap_index_allocator_tpl alloc;
+ return &alloc;
+}
diff --git a/base-foc/src/base/env/cap_map.cc b/base-foc/src/base/env/cap_map.cc
new file mode 100644
index 0000000000..c63d21c99d
--- /dev/null
+++ b/base-foc/src/base/env/cap_map.cc
@@ -0,0 +1,102 @@
+/*
+ * \brief Mapping of Genode's capability names to kernel capabilities.
+ * \author Stefan Kalkowski
+ * \date 2010-12-06
+ *
+ * This is a Fiasco.OC-specific addition to the process enviroment.
+ */
+
+/*
+ * Copyright (C) 2010-2012 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
+#include
+
+
+/***********************
+ ** Cap_index class **
+ ***********************/
+
+bool Genode::Cap_index::higher(Genode::Cap_index *n) { return n->_id > _id; }
+
+
+Genode::Cap_index* Genode::Cap_index::find_by_id(Genode::uint16_t id)
+{
+ using namespace Genode;
+
+ if (_id == id) return this;
+
+ Cap_index *n = Avl_node::child(id > _id);
+ return n ? n->find_by_id(id) : 0;
+}
+
+
+Genode::addr_t Genode::Cap_index::kcap() {
+ return cap_idx_alloc()->idx_to_kcap(this); }
+
+
+Genode::Cap_index* Genode::Capability_map::find(int id)
+{
+ using namespace Genode;
+
+ Lock_guard guard(_lock);
+
+ Cap_index* i = 0;
+ if (_tree.first())
+ i = _tree.first()->find_by_id(id);
+ return i;
+}
+
+
+/****************************
+ ** Capability_map class **
+ ****************************/
+
+Genode::Cap_index* Genode::Capability_map::insert(int id)
+{
+ using namespace Genode;
+
+ Lock_guard guard(_lock);
+
+ Cap_index *i = cap_idx_alloc()->alloc(1);
+ i->id(id);
+ _tree.insert(i);
+ return i;
+}
+
+
+Genode::Cap_index* Genode::Capability_map::insert(int id, addr_t kcap)
+{
+ using namespace Genode;
+
+ Lock_guard guard(_lock);
+
+ Cap_index *i = cap_idx_alloc()->alloc(kcap, 1);
+ i->id(id);
+ _tree.insert(i);
+ return i;
+}
+
+
+void Genode::Capability_map::remove(Genode::Cap_index* i)
+{
+ using namespace Genode;
+
+ Lock_guard guard(_lock);
+
+ if (i) {
+ _tree.remove(i);
+ cap_idx_alloc()->free(i,1);
+ }
+}
+
+
+Genode::Capability_map* Genode::cap_map()
+{
+ static Genode::Capability_map map;
+ return ↦
+}
diff --git a/base-foc/src/base/env/cap_sel_alloc.cc b/base-foc/src/base/env/cap_sel_alloc.cc
deleted file mode 100644
index 836da6a9fa..0000000000
--- a/base-foc/src/base/env/cap_sel_alloc.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * \brief Capability-selector allocator for non-core tasks.
- * \author Stefan Kalkowski
- * \date 2010-12-06
- *
- * This is a Fiasco.OC-specific addition to the process enviroment.
- */
-
-/*
- * Copyright (C) 2010-2012 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
-
-
-Genode::Capability_allocator* Genode::cap_alloc()
-{
- static Genode::Capability_allocator_tpl<4096> _alloc;
- return &_alloc;
-}
diff --git a/base-foc/src/base/env/spin_lock.cc b/base-foc/src/base/env/spin_lock.cc
index 00081157ac..2c6a76ac04 100644
--- a/base-foc/src/base/env/spin_lock.cc
+++ b/base-foc/src/base/env/spin_lock.cc
@@ -14,7 +14,7 @@
*/
/* Genode includes */
-#include
+#include
/* Lock implementation local include */
#include
diff --git a/base-foc/src/base/ipc/ipc.cc b/base-foc/src/base/ipc/ipc.cc
index 8f8a1454ba..aac576eb87 100644
--- a/base-foc/src/base/ipc/ipc.cc
+++ b/base-foc/src/base/ipc/ipc.cc
@@ -52,7 +52,7 @@ enum Debug {
};
-static bool ipc_error(l4_msgtag_t tag, bool print)
+static inline bool ipc_error(l4_msgtag_t tag, bool print)
{
int ipc_error = l4_ipc_error(tag, l4_utcb());
if (ipc_error) {
@@ -189,8 +189,7 @@ void Ipc_istream::_wait()
Ipc_istream::Ipc_istream(Msgbuf_base *rcv_msg)
:
Ipc_unmarshaller(&rcv_msg->buf[0], rcv_msg->size()),
- Native_capability(thread_get_my_native_id(),
- Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE]),
+ Native_capability(cap_map()->find(Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE])),
_rcv_msg(rcv_msg)
{
_read_offset = sizeof(l4_mword_t);
@@ -266,8 +265,7 @@ void Ipc_server::_reply()
{
l4_msgtag_t tag = copy_msgbuf_to_utcb(_snd_msg, _write_offset, _dst);
tag = l4_ipc_send(L4_SYSF_REPLY, l4_utcb(), tag, L4_IPC_SEND_TIMEOUT_0);
- if (ipc_error(tag, DEBUG_MSG))
- throw Ipc_error();
+ ipc_error(tag, DEBUG_MSG);
}
diff --git a/base-foc/src/base/ipc/pager.cc b/base-foc/src/base/ipc/pager.cc
index 3eb900d0e3..41f06494e3 100644
--- a/base-foc/src/base/ipc/pager.cc
+++ b/base-foc/src/base/ipc/pager.cc
@@ -98,7 +98,7 @@ void Ipc_pager::reply_and_wait_for_fault()
void Ipc_pager::acknowledge_wakeup()
{
- l4_cap_idx_t dst = Cap_dst_policy::valid(_last) ? _last : L4_SYSF_REPLY;
+ l4_cap_idx_t dst = Fiasco::Capability::valid(_last) ? _last : L4_SYSF_REPLY;
/* answer wakeup call from one of core's region-manager sessions */
l4_ipc_send(dst, l4_utcb(), l4_msgtag(0, 0, 0, 0), L4_IPC_SEND_TIMEOUT_0);
@@ -106,5 +106,5 @@ void Ipc_pager::acknowledge_wakeup()
Ipc_pager::Ipc_pager()
-: Native_capability(Thread_base::myself()->tid(), 0), _badge(0) { }
+: Native_capability(cap_map()->find(Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE])), _badge(0) { }
diff --git a/base-foc/src/base/lock/lock_helper.h b/base-foc/src/base/lock/lock_helper.h
index 399be8169a..e2c7a3b145 100644
--- a/base-foc/src/base/lock/lock_helper.h
+++ b/base-foc/src/base/lock/lock_helper.h
@@ -81,7 +81,7 @@ static inline Genode::Native_thread_id thread_invalid_id()
*/
static inline bool thread_id_valid(Genode::Native_thread_id tid)
{
- return Genode::Cap_dst_policy::valid(tid);
+ return Fiasco::Capability::valid(tid);
}
diff --git a/base-foc/src/base/pager/pager.cc b/base-foc/src/base/pager/pager.cc
index f9dd3c3763..3bf4bc91e1 100644
--- a/base-foc/src/base/pager/pager.cc
+++ b/base-foc/src/base/pager/pager.cc
@@ -78,7 +78,7 @@ void Pager_activation_base::entry()
PDBG("Could not resolve pf=%p ip=%p",
(void*)pager.fault_addr(), (void*)pager.fault_ip());
} else {
- pager.set_reply_dst(Native_capability(obj->badge(),0));
+ pager.set_reply_dst(obj->badge());
reply_pending = true;
continue;
}
@@ -101,7 +101,7 @@ void Pager_activation_base::entry()
}
/* send reply to the caller */
- pager.set_reply_dst(Native_capability());
+ pager.set_reply_dst(Native_thread());
pager.acknowledge_wakeup();
/* revert exception flag */
@@ -111,7 +111,7 @@ void Pager_activation_base::entry()
}
/* send wake up message to requested thread */
- pager.set_reply_dst(Native_capability(obj->badge(),0));
+ pager.set_reply_dst(obj->badge());
pager.acknowledge_wakeup();
break;
}
@@ -131,12 +131,12 @@ void Pager_activation_base::entry()
obj->state.in_exception = true;
/*
- * It might occur, that the thread raises an exception,
+ * It might occur that the thread raises an exception,
* after it already got resumed by the cpu_session, in
* that case we unblock it immediately.
*/
if (!obj->state.paused) {
- pager.set_reply_dst(Native_capability(obj->badge(),0));
+ pager.set_reply_dst(obj->badge());
reply_pending = true;
}
break;
diff --git a/base-foc/src/base/thread/thread_bootstrap.cc b/base-foc/src/base/thread/thread_bootstrap.cc
index ad6257a630..3342c889d0 100644
--- a/base-foc/src/base/thread/thread_bootstrap.cc
+++ b/base-foc/src/base/thread/thread_bootstrap.cc
@@ -11,31 +11,11 @@
* under the terms of the GNU General Public License version 2.
*/
-#include
-#include
#include
#include
-namespace Fiasco {
-#include
-}
-void Genode::Thread_base::_thread_bootstrap()
-{
- using namespace Genode;
- using namespace Fiasco;
-
- /* first, receive my own gate-capability and badge from starter thread */
- addr_t thread_base = 0;
- unsigned long my_badge = 0;
- Msgbuf<128> snd_msg, rcv_msg;
- Ipc_server srv(&snd_msg, &rcv_msg);
- srv >> IPC_WAIT >> thread_base >> my_badge << IPC_REPLY;
-
- /* store both values in user-defined section of the UTCB */
- l4_utcb_tcr()->user[UTCB_TCR_BADGE] = my_badge;
- l4_utcb_tcr()->user[UTCB_TCR_THREAD_OBJ] = thread_base;
-}
+void Genode::Thread_base::_thread_bootstrap() { }
void Genode::Thread_base::_thread_start()
diff --git a/base-foc/src/base/thread/thread_start.cc b/base-foc/src/base/thread/thread_start.cc
index ea4f19ca6c..f1109a7c29 100644
--- a/base-foc/src/base/thread/thread_start.cc
+++ b/base-foc/src/base/thread/thread_start.cc
@@ -18,17 +18,27 @@
#include
#include
+namespace Fiasco {
+#include
+}
+
using namespace Genode;
void Thread_base::_deinit_platform_thread()
{
+ using namespace Fiasco;
+
+ int id = l4_utcb_tcr_u(_context->utcb)->user[UTCB_TCR_BADGE];
env()->cpu_session()->kill_thread(_thread_cap);
+ cap_map()->remove(cap_map()->find(id));
}
void Thread_base::start()
{
+ using namespace Fiasco;
+
/* create thread at core */
char buf[48];
name(buf, sizeof(buf));
@@ -41,23 +51,20 @@ void Thread_base::start()
Pager_capability pager_cap = env()->rm_session()->add_client(_thread_cap);
env()->cpu_session()->set_pager(_thread_cap, pager_cap);
+ /* get gate-capability and badge of new thread */
+ Thread_state state;
+ env()->cpu_session()->state(_thread_cap, &state);
+ _tid = state.kcap;
+ _context->utcb = state.utcb;
+
+ l4_utcb_tcr_u(state.utcb)->user[UTCB_TCR_BADGE] = state.id;
+ l4_utcb_tcr_u(state.utcb)->user[UTCB_TCR_THREAD_OBJ] = (addr_t)this;
+ cap_map()->insert(state.id, state.kcap);
+
/* register initial IP and SP at core */
addr_t thread_sp = (addr_t)&_context->stack[-4];
thread_sp &= ~0xf; /* align initial stack to 16 byte boundary */
env()->cpu_session()->start(_thread_cap, (addr_t)_thread_start, thread_sp);
-
- /* get gate-capability and badge of new thread */
- Thread_state state;
- env()->cpu_session()->state(_thread_cap, &state);
- _tid = state.cap.dst();
-
- /*
- * send newly constructed thread, pointer to its Thread_base object,
- * and its badge
- */
- Msgbuf<128> snd_msg, rcv_msg;
- Ipc_client cli(state.cap, &snd_msg, &rcv_msg);
- cli << (addr_t)this << state.cap.local_name() << IPC_CALL;
}
diff --git a/base-foc/src/core/cap_session_component.cc b/base-foc/src/core/cap_session_component.cc
index b86ba2750a..4703bc7682 100644
--- a/base-foc/src/core/cap_session_component.cc
+++ b/base-foc/src/core/cap_session_component.cc
@@ -13,21 +13,88 @@
/* Genode includes */
#include
+#include
#include
/* core includes */
#include
+#include
+#include
#include
namespace Fiasco {
#include
#include
#include
+#include
#include
}
using namespace Genode;
+/***************************
+ ** Cap_index_allocator **
+ ***************************/
+
+Genode::Cap_index_allocator* Genode::cap_idx_alloc()
+{
+ static Genode::Cap_index_allocator_tpl alloc;
+ return &alloc;
+}
+
+
+/*******************
+ ** Cap_mapping **
+ *******************/
+
+Core_cap_index* Cap_mapping::_get_cap()
+{
+ int id = platform_specific()->cap_id_alloc()->alloc();
+ return reinterpret_cast(cap_map()->insert(id));
+}
+
+
+void Cap_mapping::map(Native_thread_id task)
+{
+ using namespace Fiasco;
+
+ if (!local || !Fiasco::Capability::valid(remote))
+ return;
+
+ l4_msgtag_t tag = l4_task_map(task, L4_BASE_TASK_CAP,
+ l4_obj_fpage(local->kcap(), 0, L4_FPAGE_RWX),
+ ((l4_cap_idx_t)remote) | L4_ITEM_MAP);
+ if (l4_msgtag_has_error(tag))
+ PERR("mapping cap failed");
+}
+
+
+void Cap_mapping::unmap()
+{
+ using namespace Fiasco;
+
+ l4_msgtag_t tag = l4_task_unmap(L4_BASE_TASK_CAP,
+ l4_obj_fpage(local->kcap(), 0, L4_FPAGE_RWX),
+ L4_FP_ALL_SPACES | L4_FP_DELETE_OBJ);
+ if (l4_msgtag_has_error(tag))
+ PERR("unmapping cap failed");
+}
+
+
+Cap_mapping::Cap_mapping(bool alloc, Native_thread_id r)
+: local(alloc ? _get_cap() : 0), remote(r) { }
+
+
+Cap_mapping::Cap_mapping(Core_cap_index* i, Native_thread_id r)
+: local(i), remote(r) { }
+
+
+Cap_mapping::~Cap_mapping()
+{
+ unmap();
+ cap_map()->remove(cap_map()->find(local->id()));
+}
+
/*****************************
** Cap_session_component **
@@ -40,55 +107,38 @@ Native_capability Cap_session_component::alloc(Cap_session_component *session,
if (!ep.valid()) {
PWRN("Invalid cap!");
- return Native_capability();
- }
-
- /*
- * maybe someone tries to fool us, proof whether cap exists in cap tree.
- *
- * Actually we should proof whether both capability selectors
- * point to the same object, but this isn't possible in fiasco.oc.
- */
- Capability_node *n = Capability_tree::tree()->find_by_badge(ep.local_name());
- if (!n) {
- PWRN("Unknown capability!");
return cap;
}
-
try {
using namespace Fiasco;
+ Core_cap_index* ref = reinterpret_cast(ep.idx());
+
/*
- * Allocate new badge, and ipc-gate and set badge as gate-label
+ * Allocate new id, and ipc-gate and set id as gate-label
*/
- unsigned long badge = Badge_allocator::allocator()->alloc();
- Native_thread gate = cap_alloc()->alloc_id(badge);
- l4_msgtag_t tag = l4_factory_create_gate(L4_BASE_FACTORY_CAP,
- gate,
- n->pt()->native_thread(),
- badge);
+ unsigned long id = platform_specific()->cap_id_alloc()->alloc();
+ Core_cap_index* idx =
+ reinterpret_cast(cap_map()->insert(id));
+ l4_msgtag_t tag = l4_factory_create_gate(L4_BASE_FACTORY_CAP,
+ idx->kcap(),
+ ref->pt()->thread().local->kcap(), id);
if (l4_msgtag_has_error(tag)) {
PERR("l4_factory_create_gate failed!");
- cap_alloc()->free(gate);
- Badge_allocator::allocator()->free(badge);
+ cap_map()->remove(idx);
+ platform_specific()->cap_id_alloc()->free(id);
return cap;
} else
/* set debugger-name of ipc-gate to thread's name */
- Fiasco::l4_debugger_set_object_name(gate, n->pt()->name());
-
- /*
- * Create new node in capability tree.
- *
- * TODO: don't use core_mem_alloc, but a session-specific allocator
- */
- Capability_node *new_node = new (platform()->core_mem_alloc())
- Capability_node(badge, session, n->pt(), gate);
- Capability_tree::tree()->insert(new_node);
- cap = Native_capability(gate, badge);
-
- } catch (Badge_allocator::Out_of_badges) {}
+ Fiasco::l4_debugger_set_object_name(idx->kcap(), ref->pt()->name());
+ idx->session(session);
+ idx->pt(ref->pt());
+ cap = Native_capability(idx);
+ } catch (Cap_id_allocator::Out_of_ids) {
+ PERR("Out of IDs");
+ }
return cap;
}
@@ -103,137 +153,62 @@ void Cap_session_component::free(Native_capability cap)
{
using namespace Fiasco;
- Capability_node *n = Capability_tree::tree()->find_by_badge(cap.local_name());
- if (!n)
+ if (!cap.valid())
return;
+ Core_cap_index* idx = reinterpret_cast(cap.idx());
+
/*
* check whether this cap_session has created the capability to delete.
- *
- * Actually we should proof whether both capability selectors
- * point to the same object, but this isn't possible in fiasco.oc.
*/
- if (n->cap_session() != this)
+ if (idx->session() != this)
return;
- Capability_tree::tree()->remove(n);
l4_msgtag_t tag = l4_task_unmap(L4_BASE_TASK_CAP,
- l4_obj_fpage(cap.dst(), 0, L4_FPAGE_RWX),
+ l4_obj_fpage(idx->kcap(), 0, L4_FPAGE_RWX),
L4_FP_ALL_SPACES | L4_FP_DELETE_OBJ);
if (l4_msgtag_has_error(tag))
- PERR("destruction of ipc-gate %lx failed!", (unsigned long) cap.dst());
+ PERR("destruction of ipc-gate %lx failed!", (unsigned long) idx->kcap());
- /* free badge _after_ invalidating all caps */
- Badge_allocator::allocator()->free(n->badge());
-
- /* free explicilty allocated cap-selector */
- cap_alloc()->free(n->gate());
-
- destroy(platform_specific()->core_mem_alloc(), n);
+ unsigned long id = idx->id();
+ cap_map()->remove(idx);
+ platform_specific()->cap_id_alloc()->free(id);
}
-/***********************
- ** Badge Allocator **
- ***********************/
+/*******************************
+ ** Capability ID Allocator **
+ *******************************/
-Badge_allocator::Badge_allocator()
-: _id_alloc(platform_specific()->core_mem_alloc())
+Cap_id_allocator::Cap_id_allocator(Allocator* alloc)
+: _id_alloc(alloc)
{
- _id_alloc.add_range(BADGE_OFFSET, BADGE_RANGE);
+ _id_alloc.add_range(CAP_ID_OFFSET, CAP_ID_RANGE);
}
-unsigned long Badge_allocator::alloc()
+unsigned long Cap_id_allocator::alloc()
{
Lock::Guard lock_guard(_lock);
- void *badge;
- if (_id_alloc.alloc(BADGE_OFFSET, &badge))
- return (unsigned long) badge;
- throw Out_of_badges();
+ void *id;
+ if (_id_alloc.alloc(CAP_ID_OFFSET, &id))
+ return (unsigned long) id;
+ throw Out_of_ids();
}
-void Badge_allocator::free(unsigned long badge)
+void Cap_id_allocator::free(unsigned long id)
{
Lock::Guard lock_guard(_lock);
- if (badge < BADGE_RANGE)
- _id_alloc.free((void*)(badge & BADGE_MASK), BADGE_OFFSET);
+ if (id < CAP_ID_RANGE)
+ _id_alloc.free((void*)(id & CAP_ID_MASK), CAP_ID_OFFSET);
}
-Badge_allocator* Badge_allocator::allocator()
+Genode::Cap_index_allocator* cap_idx_alloc()
{
- static Badge_allocator alloc;
- return &alloc;
-}
-
-
-/***********************
- ** Capability_node **
- ***********************/
-
-Capability_node::Capability_node(unsigned long badge,
- Cap_session_component *cap_session,
- Platform_thread *pt,
- Native_thread gate)
-: _badge(badge), _cap_session(cap_session), _pt(pt), _gate(gate) {}
-
-
-bool Capability_node::higher(Capability_node *n)
-{
- return n->_badge > _badge;
-}
-
-
-Capability_node* Capability_node::find_by_badge(unsigned long badge)
-{
- if (_badge == badge) return this;
-
- Capability_node *n = Avl_node::child(badge > _badge);
- return n ? n->find_by_badge(badge) : 0;
-}
-
-
-/***********************
- ** Capability_tree **
- ***********************/
-
-void Capability_tree::insert(Avl_node *node)
-{
- Lock::Guard lock_guard(_lock);
-
- Avl_tree::insert(node);
-}
-
-
-void Capability_tree::remove(Avl_node *node)
-{
- Lock::Guard lock_guard(_lock);
-
- Avl_tree::remove(node);
-}
-
-
-Capability_node* Capability_tree::find_by_badge(unsigned long badge)
-{
- Lock::Guard lock_guard(_lock);
-
- return first()->find_by_badge(badge);
-}
-
-
-Capability_tree* Capability_tree::tree()
-{
- static Capability_tree _tree;
- return &_tree;
-}
-
-
-Genode::Capability_allocator* Genode::cap_alloc()
-{
- static Genode::Capability_allocator_tpl<20*1024> _alloc;
+ static Genode::Cap_index_allocator_tpl _alloc;
return &_alloc;
}
diff --git a/base-foc/src/core/cpu_session_extension.cc b/base-foc/src/core/cpu_session_extension.cc
index 76053fbebb..cc6f20db4a 100644
--- a/base-foc/src/core/cpu_session_extension.cc
+++ b/base-foc/src/core/cpu_session_extension.cc
@@ -16,6 +16,7 @@
/* Core includes */
#include
+#include
/* Fiasco.OC includes */
namespace Fiasco {
@@ -35,7 +36,7 @@ void Genode::Cpu_session_component::enable_vcpu(Genode::Thread_capability thread
Cpu_thread_component *thread = _lookup_thread(thread_cap);
if (!thread) return;
- Native_thread tid = thread->platform_thread()->native_thread();
+ Native_thread tid = thread->platform_thread()->thread().local->kcap();
l4_msgtag_t tag = l4_thread_vcpu_control(tid, vcpu_state);
if (l4_msgtag_has_error(tag))
@@ -53,7 +54,7 @@ Genode::Cpu_session_component::native_cap(Genode::Thread_capability cap)
Cpu_thread_component *thread = _lookup_thread(cap);
if (!thread) return Native_capability();
- return thread->platform_thread()->thread_cap();
+ return Native_capability(thread->platform_thread()->thread().local);
}
@@ -61,11 +62,11 @@ Genode::Native_capability Genode::Cpu_session_component::alloc_irq()
{
using namespace Fiasco;
- Native_thread_id irq_cap(Genode::cap_alloc()->alloc());
- l4_msgtag_t res = l4_factory_create_irq(L4_BASE_FACTORY_CAP, irq_cap);
+ Cap_index* i = cap_map()->insert(platform_specific()->cap_id_alloc()->alloc());
+ l4_msgtag_t res = l4_factory_create_irq(L4_BASE_FACTORY_CAP, i->kcap());
if (l4_error(res))
PWRN("Allocation of irq object failed!");
- return Genode::Native_capability(irq_cap, Badge_allocator::allocator()->alloc());
+ return Genode::Native_capability(i);
}
@@ -78,7 +79,7 @@ void Genode::Cpu_session_component::single_step(Genode::Thread_capability thread
Cpu_thread_component *thread = _lookup_thread(thread_cap);
if (!thread) return;
- Native_thread tid = thread->platform_thread()->native_thread();
+ Native_thread tid = thread->platform_thread()->thread().local->kcap();
enum { THREAD_SINGLE_STEP = 0x40000 };
int flags = enable ? THREAD_SINGLE_STEP : 0;
diff --git a/base-foc/src/core/include/cap_id_alloc.h b/base-foc/src/core/include/cap_id_alloc.h
new file mode 100644
index 0000000000..1f05d2aa82
--- /dev/null
+++ b/base-foc/src/core/include/cap_id_alloc.h
@@ -0,0 +1,51 @@
+/*
+ * \brief Capability IDs allocation service
+ * \author Stefan Kalkowski
+ * \date 2012-02-22
+ */
+
+/*
+ * Copyright (C) 2012 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__CAP_IP_ALLOC_H_
+#define _CORE__INCLUDE__CAP_IP_ALLOC_H_
+
+/* Genode includes */
+#include
+#include
+#include
+#include
+
+namespace Genode {
+
+ class Cap_id_allocator
+ {
+ private:
+
+ enum {
+ CAP_ID_RANGE = ~0UL,
+ CAP_ID_MASK = ~3UL,
+ CAP_ID_NUM_MAX = CAP_ID_MASK >> 2,
+ CAP_ID_OFFSET = 1 << 2
+ };
+
+ Synchronized_range_allocator _id_alloc;
+ Lock _lock;
+
+ public:
+
+ class Out_of_ids : Exception {};
+
+
+ Cap_id_allocator(Allocator*);
+
+ unsigned long alloc();
+ void free(unsigned long id);
+ };
+}
+
+#endif /* _CORE__INCLUDE__CAP_IP_ALLOC_H_ */
diff --git a/base-foc/src/core/include/cap_index.h b/base-foc/src/core/include/cap_index.h
new file mode 100644
index 0000000000..3a6a0a5e43
--- /dev/null
+++ b/base-foc/src/core/include/cap_index.h
@@ -0,0 +1,50 @@
+/*
+ * \brief Core-specific capability index.
+ * \author Stefan Kalkowski
+ * \date 2012-02-22
+ */
+
+/*
+ * Copyright (C) 2012 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__CAP_INDEX_H_
+#define _CORE__INCLUDE__CAP_INDEX_H_
+
+/* Genode includes */
+#include
+
+/* Core includes */
+#include
+
+namespace Genode {
+
+ class Platform_thread;
+ class Core_cap_index : public Cap_index
+ {
+ private:
+
+ Cap_session_component *_session;
+ Platform_thread *_pt;
+ Native_thread _gate;
+
+ public:
+
+ Core_cap_index(Cap_session_component *session = 0,
+ Platform_thread *pt = 0,
+ Native_thread gate = Native_thread() )
+ : _session(session), _pt(pt), _gate(gate) {}
+
+ Cap_session_component *session() { return _session; }
+ Platform_thread *pt() { return _pt; }
+ Native_thread gate() { return _gate; }
+
+ void session(Cap_session_component* c) { _session = c; }
+ void pt(Platform_thread* t) { _pt = t; }
+ };
+}
+
+#endif /* _CORE__INCLUDE__CAP_INDEX_H_ */
diff --git a/base-foc/src/core/include/cap_mapping.h b/base-foc/src/core/include/cap_mapping.h
new file mode 100644
index 0000000000..3f0fede070
--- /dev/null
+++ b/base-foc/src/core/include/cap_mapping.h
@@ -0,0 +1,66 @@
+/*
+ * \brief Fiasco.OC specific capability mapping.
+ * \author Stefan Kalkowski
+ * \date 2012-02-22
+ */
+
+/*
+ * Copyright (C) 2012 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__CAP_MAPPING_H_
+#define _CORE__INCLUDE__CAP_MAPPING_H_
+
+/* core includes */
+#include
+#include
+
+namespace Genode {
+
+ /**
+ * A Cap_mapping embodies a capability of core, and its mapped
+ * copy in another protection domain.
+ */
+ class Cap_mapping : Noncopyable
+ {
+ private:
+
+ /**
+ * Helper function for construction purposes.
+ *
+ * Allocates a new capability id and Core_cap_index and inserts
+ * it in the Cap_map.
+ *
+ * \return pointer to newly constructed Core_cap_index object
+ */
+ inline Core_cap_index* _get_cap();
+
+ public:
+
+ Core_cap_index* local; /* reference to cap that is mapped */
+ Native_thread_id remote; /* index in cap-space of the other pd */
+
+ Cap_mapping(bool alloc=false,
+ Native_thread_id r = Fiasco::L4_INVALID_CAP);
+ Cap_mapping(Core_cap_index* i,
+ Native_thread_id r = Fiasco::L4_INVALID_CAP);
+ ~Cap_mapping();
+
+ /**
+ * Map the cap in local to corresponding task.
+ *
+ * \param task capability of task to map to
+ */
+ void map(Native_task task);
+
+ /**
+ * Unmap all child mappings
+ */
+ void unmap();
+ };
+}
+
+#endif /* _CORE__INCLUDE__CAP_MAPPING_H_ */
diff --git a/base-foc/src/core/include/cap_session_component.h b/base-foc/src/core/include/cap_session_component.h
index c0a25050f5..9134f7ecef 100644
--- a/base-foc/src/core/include/cap_session_component.h
+++ b/base-foc/src/core/include/cap_session_component.h
@@ -1,5 +1,5 @@
/*
- * \brief Capability allocation service
+ * \brief Capability session service
* \author Stefan Kalkowski
* \date 2011-01-13
*/
@@ -15,10 +15,6 @@
#define _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_
/* Genode includes */
-#include
-#include
-#include
-#include
#include
namespace Genode {
@@ -38,81 +34,6 @@ namespace Genode {
static Native_capability alloc(Cap_session_component *session,
Native_capability ep);
};
-
-
- class Badge_allocator
- {
- private:
-
- enum {
- BADGE_RANGE = ~0UL,
- BADGE_MASK = ~3UL,
- BADGE_NUM_MAX = BADGE_MASK >> 2,
- BADGE_OFFSET = 1 << 2
- };
-
- Synchronized_range_allocator _id_alloc;
- Lock _lock;
-
- Badge_allocator();
-
- public:
-
- class Out_of_badges : Exception {};
-
- unsigned long alloc();
- void free(unsigned long badge);
-
- static Badge_allocator* allocator();
- };
-
-
- class Platform_thread;
- class Capability_node : public Avl_node
- {
- private:
-
- unsigned long _badge;
- Cap_session_component *_cap_session;
- Platform_thread *_pt;
- Native_thread _gate;
-
- public:
-
- Capability_node(unsigned long badge,
- Cap_session_component *cap_session,
- Platform_thread *pt,
- Native_thread gate);
-
- bool higher(Capability_node *n);
-
- Capability_node *find_by_badge(unsigned long badge);
-
- unsigned long badge() { return _badge; }
- Cap_session_component *cap_session() { return _cap_session; }
- Platform_thread *pt() { return _pt; }
- Native_thread gate() { return _gate; }
- };
-
-
- class Capability_tree : public Avl_tree
- {
- private:
-
- Lock _lock;
-
- Capability_tree() {}
-
- public:
-
- void insert(Avl_node *node);
-
- void remove(Avl_node *node);
-
- Capability_node *find_by_badge(unsigned long badge);
-
- static Capability_tree* tree();
- };
}
#endif /* _CORE__INCLUDE__CAP_SESSION_COMPONENT_H_ */
diff --git a/base-foc/src/core/include/irq_session_component.h b/base-foc/src/core/include/irq_session_component.h
index 26730e17a0..02f7e6b768 100644
--- a/base-foc/src/core/include/irq_session_component.h
+++ b/base-foc/src/core/include/irq_session_component.h
@@ -32,8 +32,8 @@ namespace Genode {
{
private:
- Native_thread _cap;
- Semaphore _sem;
+ Cap_index* _cap;
+ Semaphore _sem;
public:
@@ -44,8 +44,8 @@ namespace Genode {
bool higher(Interrupt *n);
Interrupt* find_by_num(unsigned num);
- Native_thread capability() { return _cap; }
- Semaphore* semaphore() { return &_sem; }
+ Native_thread capability() { return _cap->kcap(); }
+ Semaphore* semaphore() { return &_sem; }
};
diff --git a/base-foc/src/core/include/platform.h b/base-foc/src/core/include/platform.h
index ae2b3b8875..9477075058 100644
--- a/base-foc/src/core/include/platform.h
+++ b/base-foc/src/core/include/platform.h
@@ -1,7 +1,8 @@
/*
- * \brief Fiasco platform
+ * \brief Fiasco.OC platform
* \author Christian Helmuth
* \author Norman Feske
+ * \author Stefan Kalkowski
* \date 2007-09-10
*/
@@ -15,13 +16,17 @@
#ifndef _CORE__INCLUDE__PLATFORM_H_
#define _CORE__INCLUDE__PLATFORM_H_
+/* Genode includes */
#include
#include
+#include
-#include "platform_generic.h"
-#include "platform_thread.h"
-#include "platform_pd.h"
-#include "multiboot.h"
+/* Core includes */
+#include
+#include
+#include
+#include
+#include
namespace Genode {
@@ -30,6 +35,19 @@ namespace Genode {
{
private:
+ /**
+ * Pager object representing the pager of core namely sigma0
+ */
+ struct Sigma0 : public Pager_object
+ {
+ /**
+ * Constructor
+ */
+ Sigma0(Cap_index*);
+
+ int pager(Ipc_pager &ps) { /* never called */ return -1; }
+ };
+
/*
* Shortcut for the type of allocator instances for physical resources
*/
@@ -41,13 +59,16 @@ namespace Genode {
Phys_allocator _io_port_alloc; /* I/O port allocator */
Phys_allocator _irq_alloc; /* IRQ allocator */
Phys_allocator _region_alloc; /* virtual memory allocator for core */
+ Cap_id_allocator _cap_id_alloc; /* capability id allocator */
Multiboot_info _mb_info; /* multiboot information */
Rom_fs _rom_fs; /* ROM file system */
Rom_module _kip_rom; /* ROM module for Fiasco KIP */
+ Sigma0 _sigma0;
addr_t _vm_start; /* begin of virtual memory */
size_t _vm_size; /* size of virtual memory */
+
/*
* We do not export any boot module loaded before FIRST_ROM.
*/
@@ -89,24 +110,6 @@ namespace Genode {
public:
- /**
- * Pager object representing the pager of core namely sigma0
- */
- struct Sigma0 : public Pager_object
- {
- /**
- * Constructor
- */
- Sigma0();
-
- int pager(Ipc_pager &ps) { /* never called */ return -1; }
- };
-
- /**
- * Return singleton instance of Sigma0 pager object
- */
- static Sigma0 *sigma0();
-
/**
* Core pager thread that handles core-internal page-faults
*/
@@ -115,7 +118,7 @@ namespace Genode {
/**
* Constructor
*/
- Core_pager(Platform_pd *core_pd);
+ Core_pager(Platform_pd *core_pd, Sigma0*);
int pager(Ipc_pager &ps) { /* never called */ return -1; }
};
@@ -145,15 +148,16 @@ namespace Genode {
** Generic platform interface **
********************************/
- Allocator *core_mem_alloc() { return &_ram_alloc; }
- Range_allocator *ram_alloc() { return &_ram_alloc; }
- Range_allocator *io_mem_alloc() { return &_io_mem_alloc; }
- Range_allocator *io_port_alloc() { return &_io_port_alloc; }
- Range_allocator *irq_alloc() { return &_irq_alloc; }
- Range_allocator *region_alloc() { return &_region_alloc; }
- addr_t vm_start() const { return _vm_start; }
- size_t vm_size() const { return _vm_size; }
- Rom_fs *rom_fs() { return &_rom_fs; }
+ Allocator *core_mem_alloc() { return &_ram_alloc; }
+ Range_allocator *ram_alloc() { return &_ram_alloc; }
+ Range_allocator *io_mem_alloc() { return &_io_mem_alloc; }
+ Range_allocator *io_port_alloc() { return &_io_port_alloc; }
+ Range_allocator *irq_alloc() { return &_irq_alloc; }
+ Range_allocator *region_alloc() { return &_region_alloc; }
+ Cap_id_allocator *cap_id_alloc() { return &_cap_id_alloc; }
+ addr_t vm_start() const { return _vm_start; }
+ size_t vm_size() const { return _vm_size; }
+ Rom_fs *rom_fs() { return &_rom_fs; }
void wait_for_exit();
};
diff --git a/base-foc/src/core/include/platform_pd.h b/base-foc/src/core/include/platform_pd.h
index 590c65ca0b..37ba924e36 100644
--- a/base-foc/src/core/include/platform_pd.h
+++ b/base-foc/src/core/include/platform_pd.h
@@ -18,12 +18,17 @@
#ifndef _CORE__INCLUDE__PLATFORM_PD_H_
#define _CORE__INCLUDE__PLATFORM_PD_H_
+/* Genode includes */
#include
#include
#include
#include
#include
+/* core includes */
+#include
+
+/* Fiasco.OC includes */
namespace Fiasco {
#include
}
@@ -42,38 +47,24 @@ namespace Genode {
THREAD_MAX * Thread_base::CONTEXT_VIRTUAL_SIZE)
};
- Native_task _l4_task_cap; /* L4 task capability slot */
- unsigned _badge;
- Native_capability _parent;
- bool _parent_cap_mapped;
- bool _task_cap_mapped;
+ Cap_mapping _task;
+ Cap_mapping _parent;
Platform_thread *_threads[THREAD_MAX];
- /**
- * Protection-domain creation
- *
- * The syscall parameter propagates if any L4 kernel function
- * should be used. We need the special case for the Core startup.
- */
- void _create_pd(bool syscall);
-
- /**
- * Protection domain destruction
- *
- * No special case for Core here - we just never call it.
- */
- void _destroy_pd();
-
public:
class Threads_exhausted : Exception {};
/**
- * Constructor
+ * Constructor for core.
*/
- Platform_pd(bool create = true,
- Native_task task_cap = Native_task());
+ Platform_pd(Core_cap_index*);
+
+ /**
+ * Constructor for all tasks except core.
+ */
+ Platform_pd();
/**
* Destructor
@@ -102,16 +93,12 @@ namespace Genode {
*/
int assign_parent(Native_capability parent);
- void map_task_cap();
- void map_parent_cap();
-
/*******************************
** Fiasco-specific Accessors **
*******************************/
- Native_task native_task() { return _l4_task_cap; }
- unsigned badge() { return _badge; }
- Native_thread parent_cap() { return _parent.dst(); }
+ Native_capability native_task() const {
+ return Native_capability(_task.local); }
};
}
diff --git a/base-foc/src/core/include/platform_thread.h b/base-foc/src/core/include/platform_thread.h
index bfe47fe106..bbdc670bf3 100644
--- a/base-foc/src/core/include/platform_thread.h
+++ b/base-foc/src/core/include/platform_thread.h
@@ -23,11 +23,7 @@
/* core includes */
#include
#include
-
-/* Fiasco includes */
-namespace Fiasco {
-#include
-}
+#include
namespace Genode {
@@ -38,22 +34,18 @@ namespace Genode {
friend class Platform_pd;
- bool _core_thread;
- unsigned _badge;
- Native_capability _thread_cap;
- Native_capability _gate_cap;
- Native_capability _remote_gate_cap;
- Native_thread _remote_pager_cap;
- Native_thread _irq_cap;
- Native_thread _remote_irq_cap;
- Capability_node _node;
- Native_utcb _utcb;
- char _name[32]; /* thread name that will be
- registered at the kernel
- debugger */
- Platform_pd *_platform_pd; /* protection domain thread
- is bound to */
- Pager_object *_pager;
+ bool _core_thread;
+ Cap_mapping _thread;
+ Cap_mapping _gate;
+ Cap_mapping _pager;
+ Cap_mapping _irq;
+ Native_utcb _utcb;
+ char _name[32]; /* thread name that will be
+ registered at the kernel
+ debugger */
+ Platform_pd *_platform_pd; /* protection domain thread
+ is bound to */
+ Pager_object *_pager_obj;
void _create_thread(void);
void _finalize_construction(const char *name, unsigned prio);
@@ -71,7 +63,8 @@ namespace Genode {
/**
* Constructor for core main-thread
*/
- Platform_thread(Native_thread cap, const char *name);
+ Platform_thread(Core_cap_index* thread,
+ Core_cap_index* irq, const char *name);
/**
* Constructor for core threads
@@ -112,10 +105,9 @@ namespace Genode {
/**
* This thread is about to be bound
*
- * \param cap final capability index
* \param pd platform pd, thread is bound to
*/
- void bind(/*Native_thread_id cap, */Platform_pd *pd);
+ void bind(Platform_pd *pd);
/**
* Unbind this thread
@@ -140,25 +132,25 @@ namespace Genode {
/**
* Return/set pager
*/
- Pager_object *pager() const { return _pager; }
+ Pager_object *pager() const { return _pager_obj; }
void pager(Pager_object *pager);
/**
* Return identification of thread when faulting
*/
unsigned long pager_object_badge() {
- return (unsigned long) _thread_cap.dst(); }
+ return (unsigned long) _thread.local->kcap(); }
/*******************************
** Fiasco-specific Accessors **
*******************************/
- Native_thread native_thread() const { return _thread_cap.dst(); }
- Native_capability thread_cap() const { return _thread_cap; }
- Native_capability gate() const { return _remote_gate_cap; }
- const char *name() const { return _name; }
- bool core_thread() const { return _core_thread; }
+ Cap_mapping& thread() { return _thread; }
+ Cap_mapping& gate() { return _gate; }
+ const char *name() const { return _name; }
+ bool core_thread() const { return _core_thread; }
+ Native_utcb utcb() const { return _utcb; }
};
}
diff --git a/base-foc/src/core/irq_session_component.cc b/base-foc/src/core/irq_session_component.cc
index 9f7353aa90..72e8bb14d4 100644
--- a/base-foc/src/core/irq_session_component.cc
+++ b/base-foc/src/core/irq_session_component.cc
@@ -1,6 +1,7 @@
/*
- * \brief Core implementation of IRQ sessions
+ * \brief Fiasco.OC-specific core implementation of IRQ sessions
* \author Christian Helmuth
+ * \author Stefan Kalkowski
* \date 2007-09-13
*
* FIXME ram quota missing
@@ -51,7 +52,8 @@ bool Irq_session_component::Interrupt::higher(Irq_session_component::Interrupt *
Irq_session_component::Interrupt::Interrupt()
-: _cap(cap_alloc()->alloc()), _sem(), number(0) {}
+: _cap(cap_map()->insert(platform_specific()->cap_id_alloc()->alloc())),
+ _sem(), number(0) {}
Native_thread Irq_session_component::Interrupt_handler::handler_cap()
diff --git a/base-foc/src/core/pd_session_extension.cc b/base-foc/src/core/pd_session_extension.cc
index f4778b4e20..07dfdf4548 100644
--- a/base-foc/src/core/pd_session_extension.cc
+++ b/base-foc/src/core/pd_session_extension.cc
@@ -19,4 +19,4 @@
Genode::Native_capability Genode::Pd_session_component::task_cap() {
- return Native_capability(_pd.native_task(), _pd.badge()); }
+ return _pd.native_task(); }
diff --git a/base-foc/src/core/platform.cc b/base-foc/src/core/platform.cc
index d811d910b5..69c05fa0e7 100644
--- a/base-foc/src/core/platform.cc
+++ b/base-foc/src/core/platform.cc
@@ -120,30 +120,23 @@ static void _core_pager_loop()
}
-Platform::Sigma0::Sigma0() : Pager_object(0)
+Platform::Sigma0::Sigma0(Cap_index* i) : Pager_object(0)
{
/*
* We use the Pager_object here in a slightly different manner,
* just to tunnel the pager cap to the Platform_thread::start method.
*/
- cap(reinterpret_cap_cast(Native_capability(Fiasco::L4_BASE_PAGER_CAP, 0)));
+ cap(reinterpret_cap_cast(Native_capability(i)));
}
-Platform::Sigma0 *Platform::sigma0()
-{
- static Sigma0 _sigma0;
- return &_sigma0;
-}
-
-
-Platform::Core_pager::Core_pager(Platform_pd *core_pd)
+Platform::Core_pager::Core_pager(Platform_pd *core_pd, Sigma0 *sigma0)
: Platform_thread("core.pager"), Pager_object(0)
{
- Platform_thread::pager(sigma0());
+ Platform_thread::pager(sigma0);
core_pd->bind_thread(this);
- cap(Native_capability(native_thread(), 0));
+ cap(thread().local);
/* stack begins at the top end of the '_core_pager_stack' array */
void *sp = (void *)&_core_pager_stack[PAGER_STACK_ELEMENTS - 1];
@@ -152,8 +145,8 @@ Platform::Core_pager::Core_pager(Platform_pd *core_pd)
using namespace Fiasco;
l4_thread_control_start();
- l4_thread_control_pager(native_thread());
- l4_thread_control_exc_handler(native_thread());
+ l4_thread_control_pager(thread().local->kcap());
+ l4_thread_control_exc_handler(thread().local->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!");
@@ -162,7 +155,7 @@ Platform::Core_pager::Core_pager(Platform_pd *core_pd)
Platform::Core_pager *Platform::core_pager()
{
- static Core_pager _core_pager(core_pd());
+ static Core_pager _core_pager(core_pd(), &_sigma0);
return &_core_pager;
}
@@ -447,7 +440,8 @@ void Platform::_setup_rom()
Platform::Platform() :
_ram_alloc(0), _io_mem_alloc(core_mem_alloc()),
_io_port_alloc(core_mem_alloc()), _irq_alloc(core_mem_alloc()),
- _region_alloc(core_mem_alloc())
+ _region_alloc(core_mem_alloc()), _cap_id_alloc(core_mem_alloc()),
+ _sigma0(cap_map()->insert(_cap_id_alloc.alloc(), Fiasco::L4_BASE_PAGER_CAP))
{
/*
* We must be single-threaded at this stage and so this is safe.
@@ -472,17 +466,25 @@ Platform::Platform() :
printf(":core ranges: "); _core_address_ranges().raw()->dump_addr_tree();
}
+ Core_cap_index* pdi =
+ reinterpret_cast(cap_map()->insert(_cap_id_alloc.alloc(), Fiasco::L4_BASE_TASK_CAP));
+ Core_cap_index* thi =
+ reinterpret_cast(cap_map()->insert(_cap_id_alloc.alloc(), Fiasco::L4_BASE_THREAD_CAP));
+ Core_cap_index* irqi =
+ reinterpret_cast(cap_map()->insert(_cap_id_alloc.alloc()));
+
/* setup pd object for core pd */
- _core_pd = new(core_mem_alloc()) Platform_pd(false, Fiasco::L4_BASE_TASK_CAP);
+ _core_pd = new(core_mem_alloc())
+ Platform_pd(reinterpret_cast(pdi));
/*
* We setup the thread object for thread0 in core pd using a special
* interface that allows us to specify the capability slot.
*/
Platform_thread *core_thread = new(core_mem_alloc())
- Platform_thread(Fiasco::L4_BASE_THREAD_CAP, "core.main");
+ Platform_thread(thi, irqi, "core.main");
- core_thread->pager(sigma0());
+ core_thread->pager(&_sigma0);
_core_pd->bind_thread(core_thread);
}
diff --git a/base-foc/src/core/platform_pd.cc b/base-foc/src/core/platform_pd.cc
index 3fdfe1e5c2..f2c2fa9c32 100644
--- a/base-foc/src/core/platform_pd.cc
+++ b/base-foc/src/core/platform_pd.cc
@@ -37,38 +37,6 @@ static addr_t core_utcb_base() {
}
-/****************************
- ** Private object members **
- ****************************/
-
-void Platform_pd::_create_pd(bool syscall)
-{
- if (!Cap_dst_policy::valid(_l4_task_cap))
- _l4_task_cap = cap_alloc()->alloc();
-
- if (syscall) {
- if (!_l4_task_cap)
- panic("no cap slot for pd creation available!");
-
- 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,
- _l4_task_cap, utcb_area);
-
- if (l4_msgtag_has_error(tag))
- panic("pd creation failed");
- }
-}
-
-
-void Platform_pd::_destroy_pd()
-{
- l4_task_unmap(L4_BASE_TASK_CAP,
- l4_obj_fpage(_l4_task_cap, 0, L4_FPAGE_RWX),
- L4_FP_ALL_SPACES | L4_FP_DELETE_OBJ);
-}
-
-
/***************************
** Public object members **
***************************/
@@ -86,10 +54,15 @@ int Platform_pd::bind_thread(Platform_thread *thread)
thread->_utcb =
reinterpret_cast(UTCB_AREA_START + i * L4_UTCB_OFFSET);
Native_thread cap_offset = THREADS_BASE_CAP + i * THREAD_CAP_SLOT;
- thread->_remote_gate_cap = Native_capability(cap_offset + THREAD_GATE_CAP,
- thread->_gate_cap.local_name());
- thread->_remote_pager_cap = cap_offset + THREAD_PAGER_CAP;
- thread->_remote_irq_cap = cap_offset + THREAD_IRQ_CAP;
+ thread->_gate.remote = cap_offset + THREAD_GATE_CAP;
+ thread->_pager.remote = cap_offset + THREAD_PAGER_CAP;
+ thread->_irq.remote = cap_offset + THREAD_IRQ_CAP;
+
+ /* if it's no core-thread we have to map parent and pager gate cap */
+ if (!thread->core_thread()) {
+ _task.map(_task.local->kcap());
+ _parent.map(_task.local->kcap());
+ }
/* inform thread about binding */
thread->bind(this);
@@ -116,49 +89,33 @@ void Platform_pd::unbind_thread(Platform_thread *thread)
int Platform_pd::assign_parent(Native_capability parent)
{
- if (_parent.valid()) return -1;
- _parent = parent;
+ if (!parent.valid()) return -1;
+ _parent.local = reinterpret_cast(parent.idx());
+ _parent.remote = PARENT_CAP;
return 0;
}
-void Platform_pd::map_parent_cap()
+Platform_pd::Platform_pd(Core_cap_index* i)
+: _task(i, TASK_CAP)
{
- if (!_parent_cap_mapped) {
- l4_msgtag_t tag = l4_task_map(_l4_task_cap, L4_BASE_TASK_CAP,
- l4_obj_fpage(_parent.dst(), 0, L4_FPAGE_RWX),
- PARENT_CAP | L4_ITEM_MAP);
- if (l4_msgtag_has_error(tag))
- PWRN("mapping parent cap failed");
-
- _parent_cap_mapped = true;
- }
+ for (unsigned i = 0; i < THREAD_MAX; i++)
+ _threads[i] = (Platform_thread*) 0;
}
-void Platform_pd::map_task_cap()
-{
- if (!_task_cap_mapped) {
- l4_msgtag_t tag = l4_task_map(_l4_task_cap, L4_BASE_TASK_CAP,
- l4_obj_fpage(_l4_task_cap, 0, L4_FPAGE_RWX),
- TASK_CAP | L4_ITEM_MAP);
- if (l4_msgtag_has_error(tag))
- PWRN("mapping task cap failed");
- _task_cap_mapped = true;
- }
-}
-
-
-Platform_pd::Platform_pd(bool create, Native_task task_cap)
-: _l4_task_cap(task_cap),
- _badge(create ? Badge_allocator::allocator()->alloc() : 0),
- _parent_cap_mapped(false),
- _task_cap_mapped(false)
+Platform_pd::Platform_pd()
+: _task(true, TASK_CAP)
{
for (unsigned i = 0; i < THREAD_MAX; i++)
_threads[i] = (Platform_thread*) 0;
- _create_pd(create);
+ 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->kcap(), utcb_area);
+ if (l4_msgtag_has_error(tag))
+ PERR("pd creation failed");
}
@@ -168,7 +125,4 @@ Platform_pd::~Platform_pd()
if (_threads[i])
_threads[i]->unbind();
}
-
- _destroy_pd();
- Badge_allocator::allocator()->free(_badge);
}
diff --git a/base-foc/src/core/platform_thread.cc b/base-foc/src/core/platform_thread.cc
index 1ab623c795..14e9f19a3e 100644
--- a/base-foc/src/core/platform_thread.cc
+++ b/base-foc/src/core/platform_thread.cc
@@ -38,30 +38,25 @@ using namespace Fiasco;
int Platform_thread::start(void *ip, void *sp)
{
- if (_pager && _platform_pd) {
- /* map pager cap */
- l4_msgtag_t tag = l4_task_map(_platform_pd->native_task(), L4_BASE_TASK_CAP,
- l4_obj_fpage(_pager->cap().dst(), 0, L4_FPAGE_RWX),
- _remote_pager_cap | L4_ITEM_MAP);
- if (l4_msgtag_has_error(tag))
- PWRN("mapping pager cap failed");
- }
+ /* map the pager cap */
+ if (_platform_pd)
+ _pager.map(_platform_pd->native_task().dst());
/* reserve utcb area and associate thread with this task */
l4_thread_control_start();
- l4_thread_control_pager(_remote_pager_cap);
- l4_thread_control_exc_handler(_remote_pager_cap);
- l4_thread_control_bind(_utcb, _platform_pd->native_task());
-
- l4_msgtag_t tag = l4_thread_control_commit(_thread_cap.dst());
+ l4_thread_control_pager(_pager.remote);
+ l4_thread_control_exc_handler(_pager.remote);
+ l4_thread_control_bind(_utcb, _platform_pd->native_task().dst());
+ l4_msgtag_t tag = l4_thread_control_commit(_thread.local->kcap());
if (l4_msgtag_has_error(tag)) {
PWRN("l4_thread_control_commit for %lx failed!",
- (unsigned long) _thread_cap.dst());
+ (unsigned long) _thread.local->kcap());
return -1;
}
/* set ip and sp and run the thread */
- tag = l4_thread_ex_regs(_thread_cap.dst(), (l4_addr_t) ip, (l4_addr_t) sp, 0);
+ tag = l4_thread_ex_regs(_thread.local->kcap(), (l4_addr_t) ip,
+ (l4_addr_t) sp, 0);
if (l4_msgtag_has_error(tag)) {
PWRN("l4_thread_ex_regs failed!");
return -1;
@@ -73,33 +68,33 @@ int Platform_thread::start(void *ip, void *sp)
void Platform_thread::pause()
{
- if (!_pager)
+ if (!_pager_obj)
return;
- _pager->state.lock.lock();
+ _pager_obj->state.lock.lock();
- if (_pager->state.paused == true) {
- _pager->state.lock.unlock();
+ if (_pager_obj->state.paused == true) {
+ _pager_obj->state.lock.unlock();
return;
}
- unsigned exc = _pager->state.exceptions;
- _pager->state.ip = ~0UL;
- _pager->state.sp = ~0UL;
+ unsigned exc = _pager_obj->state.exceptions;
+ _pager_obj->state.ip = ~0UL;
+ _pager_obj->state.sp = ~0UL;
l4_umword_t flags = L4_THREAD_EX_REGS_TRIGGER_EXCEPTION;
/* Mark thread to be stopped */
- _pager->state.paused = true;
+ _pager_obj->state.paused = true;
/*
* Force the thread to be paused to trigger an exception.
* 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_cap.dst(), &_pager->state.ip,
- &_pager->state.sp, &flags);
+ l4_thread_ex_regs_ret(_thread.local->kcap(), &_pager_obj->state.ip,
+ &_pager_obj->state.sp, &flags);
bool in_syscall = flags == 0;
- _pager->state.lock.unlock();
+ _pager_obj->state.lock.unlock();
/**
* Check whether the thread was in ongoing ipc, if so it won't raise
@@ -110,185 +105,157 @@ void Platform_thread::pause()
* Wait until the pager thread got an exception from
* the requested thread, and stored its thread state
*/
- while (exc == _pager->state.exceptions && !_pager->state.in_exception)
- l4_thread_switch(_thread_cap.dst());
+ while (exc == _pager_obj->state.exceptions && !_pager_obj->state.in_exception)
+ l4_thread_switch(_thread.local->kcap());
}
}
void Platform_thread::resume()
{
- if (!_pager)
+ if (!_pager_obj)
return;
- _pager->state.lock.lock();
+ _pager_obj->state.lock.lock();
/* Mark thread to be runable again */
- _pager->state.paused = false;
- _pager->state.lock.unlock();
+ _pager_obj->state.paused = false;
+ _pager_obj->state.lock.unlock();
/* Send a message to the exception handler, to unblock the client */
Msgbuf<16> snd, rcv;
- Ipc_client ipc_client(_pager->cap(), &snd, &rcv);
- ipc_client << _pager << IPC_CALL;
+ Ipc_client ipc_client(_pager_obj->cap(), &snd, &rcv);
+ ipc_client << _pager_obj << IPC_CALL;
}
void Platform_thread::bind(Platform_pd *pd)
{
- l4_msgtag_t tag;
- Native_task task = pd->native_task();
-
_platform_pd = pd;
-
- if (!_core_thread) {
- /* map parent and task cap if it doesn't happen already */
- _platform_pd->map_task_cap();
- _platform_pd->map_parent_cap();
- }
-
- if (_gate_cap.valid()) {
- /* map thread's gate cap */
- tag = l4_task_map(task, L4_BASE_TASK_CAP,
- l4_obj_fpage(_gate_cap.dst(), 0, L4_FPAGE_RWX),
- _remote_gate_cap.dst() | L4_ITEM_MAP);
- if (l4_msgtag_has_error(tag))
- PWRN("mapping thread's gate cap failed");
- }
-
- /* map thread's irq cap */
- tag = l4_task_map(task, L4_BASE_TASK_CAP,
- l4_obj_fpage(_irq_cap, 0, L4_FPAGE_RWX),
- _remote_irq_cap | L4_ITEM_MAP);
- if (l4_msgtag_has_error(tag))
- PWRN("mapping thread's irq cap failed");
+ _gate.map(pd->native_task().dst());
+ _irq.map(pd->native_task().dst());
}
void Platform_thread::unbind()
{
- l4_thread_ex_regs(_thread_cap.dst(), 0, 0, 0);
- l4_task_unmap(L4_BASE_TASK_CAP,
- l4_obj_fpage(_gate_cap.dst(), 0, L4_FPAGE_RWX),
- L4_FP_ALL_SPACES | L4_FP_DELETE_OBJ);
- l4_task_unmap(L4_BASE_TASK_CAP,
- l4_obj_fpage(_thread_cap.dst(), 0, L4_FPAGE_RWX),
- L4_FP_ALL_SPACES | L4_FP_DELETE_OBJ);
+ /* first set the thread as its own pager */
+ 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->kcap())))
+ PWRN("l4_thread_control_commit for %lx failed!",
+ (unsigned long) _thread.local->kcap());
+
+ /* now force it into a pagefault */
+ l4_thread_ex_regs(_thread.local->kcap(), 0, 0, L4_THREAD_EX_REGS_CANCEL);
+
_platform_pd = (Platform_pd*) 0;
}
-void Platform_thread::pager(Pager_object *pager)
+void Platform_thread::pager(Pager_object *pager_obj)
{
- _pager = pager;
+ _pager_obj = pager_obj;
+ _pager.local = reinterpret_cast(pager_obj->cap().idx());
}
int Platform_thread::state(Thread_state *state_dst)
{
- if (_pager)
- *state_dst = _pager->state;
+ if (_pager_obj)
+ *state_dst = _pager_obj->state;
+
+ state_dst->kcap = _gate.remote;
+ state_dst->id = _gate.local->id();
+ state_dst->utcb = _utcb;
- state_dst->cap = _remote_gate_cap;
return 0;
}
void Platform_thread::cancel_blocking()
{
- l4_irq_trigger(_irq_cap);
+ l4_irq_trigger(_irq.local->kcap());
}
void Platform_thread::_create_thread()
{
l4_msgtag_t tag = l4_factory_create_thread(L4_BASE_FACTORY_CAP,
- _thread_cap.dst());
+ _thread.local->kcap());
if (l4_msgtag_has_error(tag))
PERR("cannot create more thread kernel-objects!");
+
+ /* create initial gate for thread */
+ _gate.local = reinterpret_cast(Cap_session_component::alloc(0, _thread.local).idx());
}
void Platform_thread::_finalize_construction(const char *name, unsigned prio)
{
/* create irq for new thread */
- _irq_cap = cap_alloc()->alloc();
- l4_msgtag_t tag = l4_factory_create_irq(L4_BASE_FACTORY_CAP, _irq_cap);
+ l4_msgtag_t tag = l4_factory_create_irq(L4_BASE_FACTORY_CAP,
+ _irq.local->kcap());
if (l4_msgtag_has_error(tag))
PWRN("creating thread's irq failed");
/* attach thread to irq */
- tag = l4_irq_attach(_irq_cap, 0, _thread_cap.dst());
+ tag = l4_irq_attach(_irq.local->kcap(), 0, _thread.local->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_cap.dst(), name);
+ Fiasco::l4_debugger_set_object_name(_thread.local->kcap(), name);
/* set priority of thread */
prio = Cpu_session::scale_priority(DEFAULT_PRIORITY, prio);
l4_sched_param_t params = l4_sched_param(prio);
- l4_scheduler_run_thread(L4_BASE_SCHEDULER_CAP, _thread_cap.dst(), ¶ms);
+ l4_scheduler_run_thread(L4_BASE_SCHEDULER_CAP, _thread.local->kcap(),
+ ¶ms);
}
Platform_thread::Platform_thread(const char *name,
unsigned prio)
: _core_thread(false),
- _badge(Badge_allocator::allocator()->alloc()),
- _thread_cap(cap_alloc()->alloc_id(_badge),
- _badge),
- _node(_thread_cap.local_name(), 0, this, _thread_cap.dst()),
+ _thread(true),
+ _irq(true),
_utcb(0),
_platform_pd(0),
- _pager(0)
+ _pager_obj(0)
{
- /* register the thread capability */
- Capability_tree::tree()->insert(&_node);
-
+ _thread.local->pt(this);
_create_thread();
-
- /* create gate for new thread */
- _gate_cap = core_env()->cap_session()->alloc(_thread_cap);
-
_finalize_construction(name, prio);
}
-Platform_thread::Platform_thread(Native_thread cap, const char *name)
+Platform_thread::Platform_thread(Core_cap_index* thread,
+ Core_cap_index* irq, const char *name)
: _core_thread(true),
- _thread_cap(cap, -1),
- _node(_thread_cap.local_name(), 0, this, _thread_cap.dst()),
+ _thread(thread, L4_BASE_THREAD_CAP),
+ _irq(irq),
_utcb(0),
_platform_pd(0),
- _pager(0)
+ _pager_obj(0)
{
- /* register the thread capability */
- Capability_tree::tree()->insert(&_node);
-
+ _thread.local->pt(this);
_finalize_construction(name, 0);
}
Platform_thread::Platform_thread(const char *name)
: _core_thread(true),
- _badge(Badge_allocator::allocator()->alloc()),
- _thread_cap(cap_alloc()->alloc_id(_badge),
- _badge),
- _node(_thread_cap.local_name(), 0, this, _thread_cap.dst()),
+ _thread(true),
+ _irq(true),
_utcb(0),
_platform_pd(0),
- _pager(0)
+ _pager_obj(0)
{
- /* register the thread capability */
- Capability_tree::tree()->insert(&_node);
-
+ _thread.local->pt(this);
_create_thread();
-
- /* create gate for new thread */
- _gate_cap = Cap_session_component::alloc(0, _thread_cap);
-
_finalize_construction(name, 0);
}
@@ -301,9 +268,4 @@ Platform_thread::~Platform_thread()
*/
if (_platform_pd)
_platform_pd->unbind_thread(this);
-
- /* remove the thread capability */
- Capability_tree::tree()->remove(&_node);
- cap_alloc()->free(_thread_cap.dst());
- Badge_allocator::allocator()->free(_badge);
}
diff --git a/base-foc/src/core/signal_source_component.cc b/base-foc/src/core/signal_source_component.cc
index f57d58a55e..d859db836f 100644
--- a/base-foc/src/core/signal_source_component.cc
+++ b/base-foc/src/core/signal_source_component.cc
@@ -14,12 +14,11 @@
/* Genode includes */
#include
-#include
#include
/* core includes */
#include
-#include
+#include
namespace Fiasco {
#include
@@ -65,15 +64,13 @@ Signal_source::Signal Signal_source_component::wait_for_signal()
Signal_source_component::Signal_source_component(Rpc_entrypoint *ep)
-: _entrypoint(ep)
+: Signal_source_rpc_object(cap_map()->insert(platform_specific()->cap_id_alloc()->alloc())),
+ _entrypoint(ep)
{
using namespace Fiasco;
- unsigned long badge = Badge_allocator::allocator()->alloc();
- Native_thread_id irq = cap_alloc()->alloc_id(badge);
- l4_msgtag_t res = l4_factory_create_irq(L4_BASE_FACTORY_CAP, irq);
+ l4_msgtag_t res = l4_factory_create_irq(L4_BASE_FACTORY_CAP,
+ _blocking_semaphore.dst());
if (l4_error(res))
PERR("Allocation of irq object failed!");
-
- _blocking_semaphore = Native_capability(irq, badge);
}
diff --git a/base-foc/src/core/target.inc b/base-foc/src/core/target.inc
index e448ca5814..a3670320a6 100644
--- a/base-foc/src/core/target.inc
+++ b/base-foc/src/core/target.inc
@@ -30,6 +30,7 @@ SRC_CC = main.cc \
signal_source_component.cc \
dump_alloc.cc \
context_area.cc \
+ cap_map.cc \
cap_session_component.cc \
cpu_session_extension.cc \
pd_session_extension.cc \
@@ -55,5 +56,6 @@ vpath dump_alloc.cc $(GEN_CORE_DIR)
vpath context_area.cc $(GEN_CORE_DIR)
vpath thread.cc $(REP_DIR)/src/base/thread
vpath thread_bootstrap.cc $(REP_DIR)/src/base/thread
+vpath cap_map.cc $(REP_DIR)/src/base/env
vpath spin_lock.cc $(REP_DIR)/src/base/env
vpath %.cc $(REP_DIR)/src/core
diff --git a/base-foc/src/core/thread_start.cc b/base-foc/src/core/thread_start.cc
index f16193570c..c0ac260f4f 100644
--- a/base-foc/src/core/thread_start.cc
+++ b/base-foc/src/core/thread_start.cc
@@ -44,19 +44,16 @@ void Thread_base::start()
new(platform()->core_mem_alloc()) Platform_thread(_context->name);
platform_specific()->core_pd()->bind_thread(pt);
- _tid = pt->gate().dst();
- _thread_cap = reinterpret_cap_cast(pt->thread_cap());
-
+ _tid = pt->gate().remote;
+ _thread_cap =
+ reinterpret_cap_cast(Native_capability(pt->thread().local));
pt->pager(platform_specific()->core_pager());
- pt->start((void *)_thread_start, _context->stack);
- /*
- * send newly constructed thread, pointer to its Thread_base object,
- * and its badge
- */
- Msgbuf<128> snd_msg, rcv_msg;
- Ipc_client cli(_thread_cap, &snd_msg, &rcv_msg);
- cli << (addr_t)this << pt->gate().local_name() << IPC_CALL;
+ _context->utcb = pt->utcb();
+ l4_utcb_tcr_u(pt->utcb())->user[UTCB_TCR_BADGE] = pt->gate().local->id();
+ l4_utcb_tcr_u(pt->utcb())->user[UTCB_TCR_THREAD_OBJ] = (addr_t)this;
+
+ pt->start((void *)_thread_start, _context->stack);
}
diff --git a/base-foc/src/platform/_main_helper.h b/base-foc/src/platform/_main_helper.h
index f1ab115c0e..062412083f 100644
--- a/base-foc/src/platform/_main_helper.h
+++ b/base-foc/src/platform/_main_helper.h
@@ -16,14 +16,21 @@
/* Genode includes */
#include
+#include
+#include
namespace Fiasco {
#include
+#include
+}
+
+enum { MAIN_THREAD_CAP_ID = 1 };
+
+static void main_thread_bootstrap() {
+ Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE] = MAIN_THREAD_CAP_ID;
+ Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_THREAD_OBJ] = 0;
+ Genode::cap_map()->insert(MAIN_THREAD_CAP_ID, Fiasco::MAIN_THREAD_CAP);
}
-static void main_thread_bootstrap() {
- Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_THREAD_OBJ] = 0; }
-
-
#endif /* _PLATFORM___MAIN_HELPER_H_ */
diff --git a/base-foc/src/platform/_main_parent_cap.h b/base-foc/src/platform/_main_parent_cap.h
index 9dc9e7cda6..4688fa53f2 100644
--- a/base-foc/src/platform/_main_parent_cap.h
+++ b/base-foc/src/platform/_main_parent_cap.h
@@ -21,15 +21,10 @@ namespace Genode {
/**
* Return constructed parent capability
*/
- Parent_capability parent_cap()
- {
- Native_capability cap;
- memcpy(&cap, (void *)&_parent_cap, sizeof(cap));
-
- /* assemble parent capability from object ID and Fiasco cap */
- return reinterpret_cap_cast(
- Native_capability(Fiasco::PARENT_CAP, cap.local_name()));
- }
+ Parent_capability parent_cap() {
+ static Cap_index* i = cap_map()->insert(*((int*)&_parent_cap),
+ Fiasco::PARENT_CAP);
+ return reinterpret_cap_cast(Native_capability(i)); }
}
#endif /* _PLATFORM__MAIN_PARENT_CAP_H_ */
diff --git a/ports-foc/src/lib/l4lx/include/dataspace.h b/ports-foc/src/lib/l4lx/include/dataspace.h
index 26ba020617..743d93ec82 100644
--- a/ports-foc/src/lib/l4lx/include/dataspace.h
+++ b/ports-foc/src/lib/l4lx/include/dataspace.h
@@ -16,7 +16,7 @@
/* Genode includes */
#include
-#include
+#include
#include
namespace Fiasco {
@@ -50,7 +50,7 @@ namespace L4lx {
Genode::size_t size,
Genode::Dataspace_capability ds)
: _name(name), _size(size), _cap(ds),
- _ref(Genode::cap_alloc()->alloc()) {}
+ _ref(Genode::cap_idx_alloc()->alloc(1)->kcap()) {}
/***************
diff --git a/ports-foc/src/lib/l4lx/include/vcpu.h b/ports-foc/src/lib/l4lx/include/vcpu.h
index d1fbeeba3e..7b887aca96 100644
--- a/ports-foc/src/lib/l4lx/include/vcpu.h
+++ b/ports-foc/src/lib/l4lx/include/vcpu.h
@@ -18,6 +18,7 @@
#include
#include
#include
+#include
#include
namespace Fiasco {
@@ -35,30 +36,12 @@ namespace L4lx {
void (*_func)(void *data);
void *_data;
- Fiasco::l4_utcb_t *_utcb;
Genode::addr_t _vcpu_state;
static void _startup()
{
- using namespace Genode;
- using namespace Fiasco;
-
- /* receive thread_base object pointer, and store it in TLS */
- addr_t thread_base = 0;
- Msgbuf<128> snd_msg, rcv_msg;
- Ipc_server srv(&snd_msg, &rcv_msg);
- srv >> IPC_WAIT >> thread_base;
-
- l4_utcb_tcr()->user[UTCB_TCR_THREAD_OBJ] = thread_base;
-
- Vcpu* me = dynamic_cast(Thread_base::myself());
- me->_utcb = l4_utcb();
- l4_utcb_tcr()->user[0] = me->tid(); /* L4X_UTCB_TCR_ID */
-
- srv << IPC_REPLY;
-
/* start thread function */
- Vcpu* vcpu = reinterpret_cast(thread_base);
+ Vcpu* vcpu = reinterpret_cast(Genode::Thread_base::myself());
vcpu->entry();
}
@@ -79,12 +62,12 @@ namespace L4lx {
: Genode::Thread_base(name, stack_size),
_func(func),
_data(data),
- _utcb(0),
_vcpu_state(vcpu_state) { start(); }
void start()
{
using namespace Genode;
+ using namespace Fiasco;
/* create thread at core */
char buf[48];
@@ -99,6 +82,17 @@ namespace L4lx {
env()->rm_session()->add_client(_thread_cap);
vcpu_connection()->set_pager(_thread_cap, pager_cap);
+ /* get gate-capability and badge of new thread */
+ Thread_state state;
+ vcpu_connection()->state(_thread_cap, &state);
+ _tid = state.kcap;
+ _context->utcb = state.utcb;
+
+ l4_utcb_tcr_u(state.utcb)->user[UTCB_TCR_THREAD_OBJ] = (addr_t)this;
+ l4_utcb_tcr_u(state.utcb)->user[UTCB_TCR_BADGE] = state.id;
+ l4_utcb_tcr_u(state.utcb)->user[0] = state.kcap; /* L4X_UTCB_TCR_ID */
+ cap_map()->insert(state.id, state.kcap);
+
/* register initial IP and SP at core */
addr_t stack = (addr_t)&_context->stack[-4];
stack &= ~0xf; /* align initial stack to 16 byte boundary */
@@ -106,18 +100,9 @@ namespace L4lx {
if (_vcpu_state)
vcpu_connection()->enable_vcpu(_thread_cap, _vcpu_state);
-
- /* get gate-capability and badge of new thread */
- Thread_state state;
- vcpu_connection()->state(_thread_cap, &state);
- _tid = state.cap.dst();
-
- Msgbuf<128> snd_msg, rcv_msg;
- Ipc_client cli(state.cap, &snd_msg, &rcv_msg);
- cli << (addr_t)this << IPC_CALL;
}
- Fiasco::l4_utcb_t *utcb() { return _utcb; };
+ Fiasco::l4_utcb_t *utcb() { return _context->utcb; };
};
}
diff --git a/ports-foc/src/lib/l4lx/l4_re_c_util_cap.cc b/ports-foc/src/lib/l4lx/l4_re_c_util_cap.cc
index f203ef352b..ece56ebb39 100644
--- a/ports-foc/src/lib/l4lx/l4_re_c_util_cap.cc
+++ b/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_alloc()->alloc();
+ l4_cap_idx_t ret = Genode::cap_idx_alloc()->alloc(1)->kcap();
if (DEBUG)
PDBG("ret=%lx", ret);
diff --git a/ports-foc/src/lib/l4lx/l4lx_irq.cc b/ports-foc/src/lib/l4lx/l4lx_irq.cc
index 37597c9666..79029a68b5 100644
--- a/ports-foc/src/lib/l4lx/l4lx_irq.cc
+++ b/ports-foc/src/lib/l4lx/l4lx_irq.cc
@@ -14,7 +14,6 @@
/* Genode includes */
#include
#include
-#include
#include
#include
diff --git a/ports-foc/src/lib/l4lx/l4lx_task.cc b/ports-foc/src/lib/l4lx/l4lx_task.cc
index ab51c05315..28a8d483ed 100644
--- a/ports-foc/src/lib/l4lx/l4lx_task.cc
+++ b/ports-foc/src/lib/l4lx/l4lx_task.cc
@@ -13,7 +13,7 @@
/* Genode includes */
#include
-#include
+#include
#include
#include
@@ -65,7 +65,8 @@ l4_cap_idx_t l4lx_task_number_allocate(void)
*/
int l4lx_task_number_free(l4_cap_idx_t task)
{
- Genode::cap_alloc()->free(task);
+ Genode::Cap_index* idx = Genode::cap_idx_alloc()->kcap_to_idx(task);
+ Genode::cap_idx_alloc()->free(idx, 1);
return 0;
}
@@ -84,7 +85,7 @@ int l4lx_task_number_free(l4_cap_idx_t task)
int l4lx_task_get_new_task(l4_cap_idx_t parent_id,
l4_cap_idx_t *id)
{
- *id = Genode::cap_alloc()->alloc();
+ *id = Genode::cap_idx_alloc()->alloc(1)->kcap();
return 0;
}