mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-19 03:06:39 +00:00
NOVA: create sm solely in core
Any kernel objects are now created solely by core - namely pt, ec, sm and sc.
This commit is contained in:
parent
2f84fd0434
commit
b6ea5714d7
@ -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
|
||||
|
@ -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 <base/cap_sel_alloc.h>
|
||||
#include <base/thread.h>
|
||||
|
||||
/* NOVA includes */
|
||||
#include <nova/syscalls.h>
|
||||
|
||||
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); }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
};
|
||||
|
||||
}
|
||||
|
10
base-nova/src/base/env/cap_sel_alloc.cc
vendored
10
base-nova/src/base/env/cap_sel_alloc.cc
vendored
@ -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;
|
||||
}
|
||||
|
||||
|
15
base-nova/src/base/env/main_thread.cc
vendored
15
base-nova/src/base/env/main_thread.cc
vendored
@ -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 <base/native_types.h>
|
||||
#include <base/cap_sel_alloc.h>
|
||||
#include <base/printf.h>
|
||||
|
||||
/* NOVA includes */
|
||||
#include <nova/syscalls.h>
|
||||
@ -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; }
|
||||
|
@ -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 <base/native_types.h>
|
||||
#include <base/thread.h>
|
||||
#include <base/stdint.h>
|
||||
|
||||
/* NOVA includes */
|
||||
#include <nova/syscalls.h>
|
||||
@ -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);
|
||||
}
|
||||
|
@ -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<Pager_object *>(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<Pager_object *>(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<addr_t>(_invoke_handler));
|
||||
if (res)
|
||||
PERR("could not create pager cleanup portal, error = %u\n",
|
||||
res);
|
||||
res);
|
||||
}
|
||||
|
||||
Pager_object::~Pager_object()
|
||||
|
@ -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<Rpc_entrypoint *>(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.
|
||||
|
@ -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<addr_t>(&_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);
|
||||
}
|
||||
|
@ -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 <base/printf.h>
|
||||
#include <base/sleep.h>
|
||||
#include <base/thread.h>
|
||||
#include <base/cap_sel_alloc.h>
|
||||
|
||||
/* core includes */
|
||||
#include <core_parent.h>
|
||||
@ -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));
|
||||
|
@ -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()
|
||||
|
@ -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<addr_t>(&_context->stack[-4]);
|
||||
addr_t utcb = reinterpret_cast<addr_t>(&_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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user