diff --git a/base-foc/include/base/cap_alloc.h b/base-foc/include/base/cap_alloc.h new file mode 100644 index 000000000..2aa2aaed5 --- /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 000000000..61529ac35 --- /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 9d0b1adb1..000000000 --- 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 414872fe9..7fdfed480 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 6f1225e89..d9d4e3a2b 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 75917cdf1..8ef131595 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 cb49ee33d..1d5d45466 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 680b082fc..5e891ce43 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 eef8cc150..495d7c8e0 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 000000000..e69de29bb diff --git a/base-foc/lib/mk/env.mk b/base-foc/lib/mk/env.mk index 733c424d0..8b689c483 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 6c85c3682..9a9abfc51 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 000000000..d7b4387ea --- /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 000000000..c63d21c99 --- /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 836da6a9f..000000000 --- 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 00081157a..2c6a76ac0 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 8f8a1454b..aac576eb8 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 3eb900d0e..41f06494e 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 399be8169..e2c7a3b14 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 f9dd3c376..3bf4bc91e 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 ad6257a63..3342c889d 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 ea4f19ca6..f1109a7c2 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 b86ba2750..4703bc768 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 76053fbeb..cc6f20db4 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 000000000..1f05d2aa8 --- /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 000000000..3a6a0a5e4 --- /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 000000000..3f0fede07 --- /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 c0a25050f..9134f7ece 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 26730e17a..02f7e6b76 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 ae2b3b887..947707505 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 590c65ca0..37ba924e3 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 bfe47fe10..bbdc670bf 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 9f7353aa9..72e8bb14d 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 f4778b4e2..07dfdf454 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 d811d910b..69c05fa0e 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 3fdfe1e5c..f2c2fa9c3 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 1ab623c79..14e9f19a3 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 f57d58a55..d859db836 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 e448ca581..a3670320a 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 f16193570..c0ac260f4 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 f1ab115c0..062412083 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 9dc9e7cda..4688fa53f 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 26ba02061..743d93ec8 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 d1fbeeba3..7b887aca9 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 f203ef352..ece56ebb3 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 37597c966..79029a68b 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 ab51c0531..28a8d483e 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; }