diff --git a/base-nova/include/base/native_types.h b/base-nova/include/base/native_types.h
index d7a3081a99..f923f745ec 100644
--- a/base-nova/include/base/native_types.h
+++ b/base-nova/include/base/native_types.h
@@ -1,6 +1,7 @@
/*
* \brief Platform-specific type definitions
* \author Norman Feske
+ * \author Alexander Boettcher
* \date 2009-10-02
*/
@@ -26,8 +27,6 @@ namespace Genode {
struct Native_thread
{
addr_t ec_sel; /* NOVA cap selector for execution context */
- addr_t sc_sel; /* NOVA cap selector for scheduling context */
- addr_t rs_sel; /* NOVA cap selector for running semaphore */
addr_t pd_sel; /* NOVA cap selector of protection domain */
addr_t exc_pt_sel; /* base of event portal window */
};
@@ -36,11 +35,11 @@ namespace Genode {
inline bool operator == (Native_thread_id t1, Native_thread_id t2)
{
- return (t1.ec_sel == t2.ec_sel) && (t1.rs_sel == t2.rs_sel);
- }
+ return (t1.ec_sel == t2.ec_sel) && (t1.pd_sel == t2.pd_sel);
+ }
inline bool operator != (Native_thread_id t1, Native_thread_id t2)
{
- return (t1.ec_sel != t2.ec_sel) && (t1.rs_sel != t2.rs_sel);
+ return (t1.ec_sel != t2.ec_sel) && (t1.pd_sel != t2.pd_sel);
}
class Native_utcb
diff --git a/base-nova/include/base/sleep.h b/base-nova/include/base/sleep.h
index 82b498f7e0..f096ca6fae 100644
--- a/base-nova/include/base/sleep.h
+++ b/base-nova/include/base/sleep.h
@@ -1,6 +1,7 @@
/*
* \brief Lay back and relax
* \author Norman Feske
+ * \author Alexander Boettcher
* \date 2010-02-01
*/
@@ -15,19 +16,23 @@
#define _INCLUDE__BASE__SLEEP_H_
/* Genode includes */
-#include
#include
/* NOVA includes */
#include
+extern int main_thread_running_semaphore();
+
namespace Genode {
__attribute__((noreturn)) inline void sleep_forever()
{
- int sleep_sm_sel = cap_selector_allocator()->alloc();
- Nova::create_sm(sleep_sm_sel, Cap_selector_allocator::pd_sel(), 0);
- while (1) Nova::sm_ctrl(sleep_sm_sel, Nova::SEMAPHORE_DOWN);
+ using namespace Nova;
+
+ Thread_base *myself = Thread_base::myself();
+ addr_t sem = myself ? myself->tid().exc_pt_sel + SM_SEL_EC :
+ main_thread_running_semaphore();
+ while (1) { Nova::sm_ctrl(sem, Nova::SEMAPHORE_DOWNZERO); }
}
}
diff --git a/base-nova/include/nova/syscall-generic.h b/base-nova/include/nova/syscall-generic.h
index b5e4b6f9ab..e23ead81e5 100644
--- a/base-nova/include/nova/syscall-generic.h
+++ b/base-nova/include/nova/syscall-generic.h
@@ -2,6 +2,7 @@
* \brief Syscall bindings for the NOVA microhypervisor
* \author Norman Feske
* \author Sebastian Sumpf
+ * \author Alexander Boettcher
* \date 2009-12-27
*/
@@ -499,6 +500,9 @@ namespace Nova {
PT_SEL_PARENT = 0x1a, /* convention on Genode */
PT_SEL_STARTUP = 0x1e,
PD_SEL = 0x1b,
+ PD_SEL_CAP_LOCK = 0x1c, /* convention on Genode */
+ SM_SEL_EC_MAIN = 0x1c, /* convention on Genode */
+ SM_SEL_EC = 0x1d, /* convention on Genode */
};
}
diff --git a/base-nova/src/base/env/cap_sel_alloc.cc b/base-nova/src/base/env/cap_sel_alloc.cc
index 614cd4a680..03a328304a 100644
--- a/base-nova/src/base/env/cap_sel_alloc.cc
+++ b/base-nova/src/base/env/cap_sel_alloc.cc
@@ -2,6 +2,7 @@
* \brief Capability-selector allocator
* \author Norman Feske
* \author Sebastian Sumpf
+ * \author Alexander Boettcher
* \date 2010-01-19
*
* This is a NOVA-specific addition to the process environment.
@@ -41,7 +42,7 @@ class Alloc_lock
{
private:
- int _sm_cap;
+ addr_t _sm_cap;
public:
@@ -50,10 +51,7 @@ class Alloc_lock
*
* \param sm_cap capability selector for the used semaphore
*/
- Alloc_lock(int sm_cap) : _sm_cap(sm_cap)
- {
- Nova::create_sm(_sm_cap, __local_pd_sel, 1);
- }
+ Alloc_lock() : _sm_cap(Nova::PD_SEL_CAP_LOCK) { }
void lock() { Nova::sm_ctrl(_sm_cap, Nova::SEMAPHORE_DOWN); }
@@ -66,7 +64,7 @@ class Alloc_lock
*/
static Alloc_lock *alloc_lock()
{
- static Alloc_lock alloc_lock_inst(__first_free_cap_selector);
+ static Alloc_lock alloc_lock_inst;
return &alloc_lock_inst;
}
diff --git a/base-nova/src/base/env/main_thread.cc b/base-nova/src/base/env/main_thread.cc
index 7f5b600691..3570a204ba 100644
--- a/base-nova/src/base/env/main_thread.cc
+++ b/base-nova/src/base/env/main_thread.cc
@@ -1,6 +1,7 @@
/*
* \brief Information about the main thread
* \author Norman Feske
+ * \author Alexander Boettcher
* \date 2010-01-19
*/
@@ -13,8 +14,6 @@
/* Genode includes */
#include
-#include
-#include
/* NOVA includes */
#include
@@ -30,14 +29,4 @@ Nova::mword_t __main_thread_utcb;
Native_utcb *main_thread_utcb() { return (Native_utcb *)__main_thread_utcb; }
-int main_thread_running_semaphore()
-{
- static int sm;
- if (!sm) {
- sm = cap_selector_allocator()->alloc();
- int res = Nova::create_sm(sm, Cap_selector_allocator::pd_sel(), 0);
- if (res)
- PERR("create_sm returned %d", res);
- }
- return sm;
-}
+addr_t main_thread_running_semaphore() { return Nova::SM_SEL_EC; }
diff --git a/base-nova/src/base/lock/lock_helper.h b/base-nova/src/base/lock/lock_helper.h
index 0c375550cc..d7241fdff9 100644
--- a/base-nova/src/base/lock/lock_helper.h
+++ b/base-nova/src/base/lock/lock_helper.h
@@ -1,6 +1,7 @@
/*
* \brief Helper functions for the Lock implementation
* \author Norman Feske
+ * \author Alexander Boettcher
* \date 2009-10-02
*
* For documentation about the interface, please revisit the 'base-pistachio'
@@ -17,6 +18,7 @@
/* Genode includes */
#include
#include
+#include
/* NOVA includes */
#include
@@ -32,7 +34,10 @@ extern int main_thread_running_semaphore();
* use the thread library. If the thread library is not used, 'myself' can only
* be called by the main thread, for which 'myself' is defined as zero.
*/
-Genode::Thread_base * __attribute__((weak)) Genode::Thread_base::myself() { return 0; }
+Genode::Thread_base * __attribute__((weak)) Genode::Thread_base::myself()
+{
+ return 0;
+}
static inline void thread_yield() { }
@@ -40,8 +45,9 @@ static inline void thread_yield() { }
static bool thread_check_stopped_and_restart(Genode::Native_thread_id tid)
{
- int sem = tid.rs_sel == 0 ? main_thread_running_semaphore()
- : tid.rs_sel;
+ Genode::addr_t sem = tid.pd_sel == 0 ?
+ main_thread_running_semaphore() :
+ tid.exc_pt_sel + Nova::SM_SEL_EC;
Nova::sm_ctrl(sem, Nova::SEMAPHORE_UP);
return true;
@@ -51,13 +57,13 @@ static bool thread_check_stopped_and_restart(Genode::Native_thread_id tid)
static inline Genode::Native_thread_id thread_get_my_native_id()
{
/*
- * We encode the main thread as tid { 0, 0, 0 } because we cannot
+ * We encode the main thread as tid { 0, 0 } because we cannot
* call 'main_thread_running_semaphore()' here.
*/
Genode::Thread_base *myself = Genode::Thread_base::myself();
if (myself == 0) {
- Genode::Native_thread_id main_tid = { 0, 0, 0 };
+ Genode::Native_thread_id main_tid = { 0, 0 };
return main_tid;
} else
return myself->tid();
@@ -66,14 +72,14 @@ static inline Genode::Native_thread_id thread_get_my_native_id()
static inline Genode::Native_thread_id thread_invalid_id()
{
- Genode::Native_thread_id tid = { 0, 0, ~0UL };
+ Genode::Native_thread_id tid = { 0, ~0UL };
return tid;
}
static inline bool thread_id_valid(Genode::Native_thread_id tid)
{
- return tid.rs_sel != ~0UL;
+ return tid.pd_sel != ~0UL;
}
@@ -82,7 +88,15 @@ static inline void thread_switch_to(Genode::Native_thread_id tid) { }
static inline void thread_stop_myself()
{
- Genode::Thread_base *myself = Genode::Thread_base::myself();
- int sem = myself ? myself->tid().rs_sel : main_thread_running_semaphore();
- Nova::sm_ctrl(sem, Nova::SEMAPHORE_DOWNZERO);
+ using namespace Genode;
+ using namespace Nova;
+
+ addr_t sem;
+ Thread_base *myself = Thread_base::myself();
+ if (myself)
+ sem = myself->tid().exc_pt_sel + SM_SEL_EC;
+ else
+ sem = main_thread_running_semaphore();
+
+ sm_ctrl(sem, SEMAPHORE_DOWNZERO);
}
diff --git a/base-nova/src/base/pager/pager.cc b/base-nova/src/base/pager/pager.cc
index ce2defa032..5528940f07 100644
--- a/base-nova/src/base/pager/pager.cc
+++ b/base-nova/src/base/pager/pager.cc
@@ -2,6 +2,7 @@
* \brief Pager framework
* \author Norman Feske
* \author Sebastian Sumpf
+ * \author Alexander Boettcher
* \date 2010-01-25
*/
@@ -61,9 +62,6 @@ void Pager_object::_startup_handler()
Pager_object *obj = static_cast(Thread_base::myself());
Utcb *utcb = (Utcb *)Thread_base::myself()->utcb();
-// printf("start new pager object with EIP=0x%p, ESP=0x%p\n",
-// (void *)obj->_initial_eip, (void *)obj->_initial_esp);
-
utcb->eip = obj->_initial_eip;
utcb->esp = obj->_initial_esp;
utcb->mtd = Mtd::EIP | Mtd::ESP;
@@ -78,14 +76,21 @@ void Pager_object::_invoke_handler()
Pager_object *obj = static_cast(Thread_base::myself());
/* send single portal as reply */
- addr_t event = utcb->msg[0];
+ addr_t event = utcb->msg_words() != 1 ? 0 : utcb->msg[0];
utcb->mtd = 0;
utcb->set_msg_word(0);
- if (event == PT_SEL_STARTUP || event == PT_SEL_PAGE_FAULT) {
+ if (event == PT_SEL_STARTUP || event == PT_SEL_PAGE_FAULT ||
+ event == SM_SEL_EC) {
+ /**
+ * Caller is requesting the SM cap of main thread
+ * this object is paging - it is stored at SM_SEL_EC_MAIN
+ */
+ if (event == SM_SEL_EC) event = SM_SEL_EC_MAIN;
+
bool res = utcb->append_item(Obj_crd(obj->exc_pt_sel() + event,
0), 0);
- /* one item ever fits on the UTCB */
+ /* one item ever fits on the UTCB */
(void)res;
}
@@ -127,7 +132,7 @@ Pager_object::Pager_object(unsigned long badge)
reinterpret_cast(_invoke_handler));
if (res)
PERR("could not create pager cleanup portal, error = %u\n",
- res);
+ res);
}
Pager_object::~Pager_object()
diff --git a/base-nova/src/base/server/server.cc b/base-nova/src/base/server/server.cc
index 62cb84510a..3b1baeb9f5 100644
--- a/base-nova/src/base/server/server.cc
+++ b/base-nova/src/base/server/server.cc
@@ -2,6 +2,7 @@
* \brief NOVA-specific support code for the server-side RPC API
* \author Norman Feske
* \author Sebastian Sumpf
+ * \author Alexander Boettcher
* \date 2010-01-13
*/
@@ -92,6 +93,7 @@ void Rpc_entrypoint::_activation_entry()
#else
addr_t id_pt; asm volatile ("" : "=a" (id_pt));
#endif
+
/* retrieve portal id from eax */
Rpc_entrypoint *ep = static_cast(Thread_base::myself());
@@ -217,6 +219,8 @@ Rpc_entrypoint::Rpc_entrypoint(Cap_session *cap_session, size_t stack_size,
Nova::PT_SEL_STARTUP);
request_event_portal(pager_cap, _tid.exc_pt_sel,
Nova::PT_SEL_PAGE_FAULT);
+ request_event_portal(pager_cap, _tid.exc_pt_sel,
+ Nova::SM_SEL_EC);
/**
* Request native thread cap, _thread_cap only a token.
diff --git a/base-nova/src/base/thread/thread_nova.cc b/base-nova/src/base/thread/thread_nova.cc
index 2a60aab8e4..00e59d787e 100644
--- a/base-nova/src/base/thread/thread_nova.cc
+++ b/base-nova/src/base/thread/thread_nova.cc
@@ -2,6 +2,7 @@
* \brief NOVA-specific implementation of the Thread API
* \author Norman Feske
* \author Sebastian Sumpf
+ * \author Alexander Boettcher
* \date 2010-01-19
*/
@@ -53,7 +54,6 @@ void Thread_base::_init_platform_thread()
* running semaphore and exception handler portals.
*/
_tid.ec_sel = ~0UL;
- _tid.rs_sel = cap_selector_allocator()->alloc();
_tid.pd_sel = cap_selector_allocator()->pd_sel();
_tid.exc_pt_sel = cap_selector_allocator()->alloc(NUM_INITIAL_PT_LOG2);
@@ -66,33 +66,29 @@ void Thread_base::_init_platform_thread()
env()->pd_session()->bind_thread(_thread_cap);
/* create new pager object and assign it to the new thread */
- Pager_capability pager_cap = env()->rm_session()->add_client(_thread_cap);
+ Pager_capability pager_cap =
+ env()->rm_session()->add_client(_thread_cap);
env()->cpu_session()->set_pager(_thread_cap, pager_cap);
- /* create running semaphore required for locking */
- uint8_t res = create_sm(_tid.rs_sel, _tid.pd_sel, 0);
- if (res != NOVA_OK) {
- PERR("create_sm returned %u", res);
- throw Cpu_session::Thread_creation_failed();
- }
-
}
void Thread_base::_deinit_platform_thread()
{
-// Nova::revoke(Nova::Obj_crd(_tid.ec_sel, 0));
- Nova::revoke(Nova::Obj_crd(_tid.rs_sel, 0));
- Nova::revoke(Nova::Obj_crd(_tid.exc_pt_sel, Nova::NUM_INITIAL_PT_LOG2));
+ using namespace Nova;
-// cap_selector_allocator()->free(_tid.ec_sel, 0);
- cap_selector_allocator()->free(_tid.rs_sel, 0);
- cap_selector_allocator()->free(_tid.exc_pt_sel, Nova::NUM_INITIAL_PT_LOG2);
+ if (_tid.ec_sel != ~0UL) {
+ revoke(Obj_crd(_tid.ec_sel, 0));
+ cap_selector_allocator()->free(_tid.ec_sel, 0);
+ }
+
+ revoke(Obj_crd(_tid.exc_pt_sel, NUM_INITIAL_PT_LOG2));
+ cap_selector_allocator()->free(_tid.exc_pt_sel, NUM_INITIAL_PT_LOG2);
/* revoke utcb */
- Nova::Rights rwx(true, true, true);
+ Rights rwx(true, true, true);
addr_t utcb = reinterpret_cast(&_context->utcb);
- Nova::revoke(Nova::Mem_crd(utcb >> 12, 0, rwx));
+ revoke(Mem_crd(utcb >> 12, 0, rwx));
/* de-announce thread */
env()->cpu_session()->kill_thread(_thread_cap);
@@ -131,6 +127,7 @@ void Thread_base::start()
/* request exception portals */
request_event_portal(pager_cap, _tid.exc_pt_sel, PT_SEL_STARTUP);
request_event_portal(pager_cap, _tid.exc_pt_sel, PT_SEL_PAGE_FAULT);
+ request_event_portal(pager_cap, _tid.exc_pt_sel, SM_SEL_EC);
/* request creation of SC to let thread run*/
env()->cpu_session()->resume(_thread_cap);
@@ -139,5 +136,5 @@ void Thread_base::start()
void Thread_base::cancel_blocking()
{
- Nova::sm_ctrl(_tid.rs_sel, Nova::SEMAPHORE_UP);
+ Nova::sm_ctrl(_tid.exc_pt_sel + Nova::SM_SEL_EC, Nova::SEMAPHORE_UP);
}
diff --git a/base-nova/src/core/platform.cc b/base-nova/src/core/platform.cc
index 8901d564fc..53f1809e9c 100644
--- a/base-nova/src/core/platform.cc
+++ b/base-nova/src/core/platform.cc
@@ -2,6 +2,7 @@
* \brief Platform interface implementation
* \author Norman Feske
* \author Sebastian Sumpf
+ * \author Alexander Boettcher
* \date 2009-10-02
*/
@@ -16,6 +17,7 @@
#include
#include
#include
+#include
/* core includes */
#include
@@ -140,7 +142,7 @@ static void page_fault_handler()
static void init_core_page_fault_handler()
{
/* create echo EC */
- enum {
+ enum {
STACK_SIZE = 4*1024,
CPU_NO = 0,
GLOBAL = false,
@@ -185,6 +187,10 @@ Platform::Platform() :
/* set core pd selector */
__local_pd_sel = hip->sel_exc;
+ /* create lock used by capability allocator */
+ Nova::create_sm(Nova::PD_SEL_CAP_LOCK, __local_pd_sel, 1);
+ Nova::create_sm(Nova::SM_SEL_EC, __local_pd_sel, 0);
+
/* locally map the whole I/O port range */
enum { ORDER_64K = 16 };
map_local_one_to_one(__main_thread_utcb, Io_crd(0, ORDER_64K));
diff --git a/base-nova/src/core/platform_thread.cc b/base-nova/src/core/platform_thread.cc
index 9655950156..0bbe46d391 100644
--- a/base-nova/src/core/platform_thread.cc
+++ b/base-nova/src/core/platform_thread.cc
@@ -2,6 +2,7 @@
* \brief Thread facility
* \author Norman Feske
* \author Sebastian Sumpf
+ * \author Alexander Boettcher
* \date 2009-10-02
*/
@@ -65,15 +66,30 @@ int Platform_thread::start(void *ip, void *sp, addr_t exc_base)
return -3;
}
+ /**
+ * Create semaphore required for Genode locking.
+ * It is created at the root pager exception base +
+ * SM_SEL_EC_MAIN and can be later on requested by the thread
+ * the same way as STARTUP and PAGEFAULT portal.
+ */
+ uint8_t res = Nova::create_sm(_pager->exc_pt_sel() +
+ SM_SEL_EC_MAIN,
+ _pd->pd_sel(), 0);
+ if (res != Nova::NOVA_OK) {
+ PERR("creation of semaphore for new thread failed %u",
+ res);
+ return -4;
+ }
+
/* ip == 0 means that caller will use the thread as worker */
bool thread_global = ip;
- uint8_t res = create_ec(_sel_ec(), _pd->pd_sel(), _cpu_no,
- utcb, initial_sp,
- exc_base, thread_global);
+ res = create_ec(_sel_ec(), _pd->pd_sel(), _cpu_no, utcb,
+ initial_sp, exc_base, thread_global);
+
if (res)
PERR("creation of new thread failed %u", res);
- return res ? -4 : 0;
+ return res ? -5 : 0;
}
/*
@@ -82,51 +98,75 @@ int Platform_thread::start(void *ip, void *sp, addr_t exc_base)
*/
_pager->initial_esp(PD_UTCB + get_page_size());
- /* locally map parent portal to initial portal window */
- int res = map_local((Nova::Utcb *)Thread_base::myself()->utcb(),
- Obj_crd(_pd->parent_pt_sel(), 0),
- Obj_crd(_pager->exc_pt_sel() + PT_SEL_PARENT, 0));
- if (res) {
- PERR("could not locally remap parent portal");
- return -5;
+ addr_t pd_sel = cap_selector_allocator()->pd_sel();
+ addr_t exc_base_sel = cap_selector_allocator()->alloc(Nova::NUM_INITIAL_PT_LOG2);
+ addr_t sm_alloc_sel = exc_base_sel + PD_SEL_CAP_LOCK;
+ addr_t sm_ec_sel = exc_base_sel + SM_SEL_EC;
+
+ addr_t remap_src[] = { _pager->exc_pt_sel() + PT_SEL_PAGE_FAULT,
+ _pd->parent_pt_sel(),
+ _pager->exc_pt_sel() + PT_SEL_STARTUP };
+ addr_t remap_dst[] = { PT_SEL_PAGE_FAULT,
+ PT_SEL_PARENT,
+ PT_SEL_STARTUP };
+
+ for (unsigned i = 0; i < sizeof(remap_dst)/sizeof(remap_dst[0]); i++) {
+ /* locally map portals to initial portal window */
+ if (map_local((Nova::Utcb *)Thread_base::myself()->utcb(),
+ Obj_crd(remap_src[i], 0),
+ Obj_crd(exc_base_sel + remap_dst[i], 0))) {
+ PERR("could not remap portal %lx->%lx",
+ remap_src[i], remap_dst[i]);
+ return -6;
+ }
}
- Obj_crd initial_pts(_pager->exc_pt_sel(), Nova::NUM_INITIAL_PT_LOG2,
- 1 << 4);
+ /* Create lock for cap allocator selector */
+ uint8_t res = Nova::create_sm(sm_alloc_sel, pd_sel, 1);
+ if (res != Nova::NOVA_OK) {
+ PERR("could not create semaphore for capability allocator");
+ return -7;
+ }
+ /* Create lock for EC used by lock_helper */
+ res = Nova::create_sm(sm_ec_sel, pd_sel, 0);
+ if (res != Nova::NOVA_OK) {
+ PERR("could not create semaphore for new thread");
+ return -8;
+ }
- addr_t pd_sel = cap_selector_allocator()->pd_sel();
- addr_t pd0_sel = _pager->exc_pt_sel() + Nova::PD_SEL;
+ /* Create task */
+ addr_t pd0_sel = cap_selector_allocator()->alloc();
_pd->assign_pd(pd0_sel);
+ Obj_crd initial_pts(exc_base_sel, Nova::NUM_INITIAL_PT_LOG2);
res = create_pd(pd0_sel, pd_sel, initial_pts);
if (res) {
PERR("create_pd returned %d", res);
- return -6;
+ return -9;
}
+ /* Create first thread in task */
enum { THREAD_GLOBAL = true };
res = create_ec(_sel_ec(), pd0_sel, _cpu_no, PD_UTCB, 0, 0,
THREAD_GLOBAL);
if (res) {
PERR("create_ec returned %d", res);
- return -7;
+ return -10;
}
+ /* Let the thread run */
res = create_sc(_sel_sc(), pd0_sel, _sel_ec(), Qpd());
if (res) {
PERR("create_sc returned %d", res);
- return -8;
+ return -11;
}
return 0;
}
-void Platform_thread::pause()
-{
- PDBG("not implemented");
-}
+void Platform_thread::pause() { PDBG("not implemented"); }
void Platform_thread::resume()
@@ -148,16 +188,11 @@ int Platform_thread::state(Thread_state *state_dst)
void Platform_thread::cancel_blocking() { PWRN("not implemented"); }
-unsigned long Platform_thread::pager_object_badge()
-const
-{
- return ~0UL;
-}
+unsigned long Platform_thread::pager_object_badge() const { return ~0UL; }
Platform_thread::Platform_thread(const char *name, unsigned, int thread_id)
-: _pd(0), _id_base(cap_selector_allocator()->alloc(1)),
- _cpu_no(0) { }
+: _pd(0), _id_base(cap_selector_allocator()->alloc(1)), _cpu_no(0) { }
Platform_thread::~Platform_thread()
diff --git a/base-nova/src/core/thread_start.cc b/base-nova/src/core/thread_start.cc
index 191215998d..67b99c008d 100644
--- a/base-nova/src/core/thread_start.cc
+++ b/base-nova/src/core/thread_start.cc
@@ -2,6 +2,7 @@
* \brief NOVA-specific implementation of the Thread API for core
* \author Norman Feske
* \author Sebastian Sumpf
+ * \author Alexander Boettcher
* \date 2010-01-19
*/
@@ -42,22 +43,23 @@ void Thread_base::_init_platform_thread()
addr_t pd_sel = Platform_pd::pd_core_sel();
/* create running semaphore required for locking */
- uint8_t res = Nova::create_sm(_tid.rs_sel, _tid.pd_sel, 0);
- if (res)
+ addr_t rs_sel =_tid.exc_pt_sel + SM_SEL_EC;
+ uint8_t res = create_sm(rs_sel, _tid.pd_sel, 0);
+ if (res != NOVA_OK) {
PERR("create_sm returned %u", res);
+ throw Cpu_session::Thread_creation_failed();
+ }
addr_t sp = reinterpret_cast(&_context->stack[-4]);
addr_t utcb = reinterpret_cast(&_context->utcb);
/* create local EC */
enum { CPU_NO = 0, GLOBAL = false };
- res = Nova::create_ec(_tid.ec_sel, Cap_selector_allocator::pd_sel(),
- CPU_NO, utcb, sp,
- _tid.exc_pt_sel, GLOBAL);
- if (res) {
+ res = create_ec(_tid.ec_sel, Cap_selector_allocator::pd_sel(), CPU_NO,
+ utcb, sp, _tid.exc_pt_sel, GLOBAL);
+ if (res != NOVA_OK) {
PERR("%p - create_ec returned %d", this, res);
- PERR("valid thread %x %lx:%lx", _thread_cap.valid(),
- _thread_cap.dst()._sel, _thread_cap.local_name());
+ throw Cpu_session::Thread_creation_failed();
}
}
@@ -65,12 +67,11 @@ void Thread_base::_init_platform_thread()
void Thread_base::_deinit_platform_thread()
{
unmap_local(Nova::Obj_crd(_tid.ec_sel, 0));
- unmap_local(Nova::Obj_crd(_tid.rs_sel, 0));
unmap_local(Nova::Obj_crd(_tid.exc_pt_sel, Nova::NUM_INITIAL_PT_LOG2));
cap_selector_allocator()->free(_tid.ec_sel, 0);
- cap_selector_allocator()->free(_tid.rs_sel, 0);
- cap_selector_allocator()->free(_tid.exc_pt_sel, Nova::NUM_INITIAL_PT_LOG2);
+ cap_selector_allocator()->free(_tid.exc_pt_sel,
+ Nova::NUM_INITIAL_PT_LOG2);
/* revoke utcb */
Nova::Rights rwx(true, true, true);
@@ -88,5 +89,7 @@ void Thread_base::start()
void Thread_base::cancel_blocking()
{
- Nova::sm_ctrl(_tid.rs_sel, Nova::SEMAPHORE_UP);
+ using namespace Nova;
+
+ sm_ctrl(_tid.exc_pt_sel + SM_SEL_EC, SEMAPHORE_UP);
}