144 lines
2.8 KiB
C++
144 lines
2.8 KiB
C++
/*
|
|
* \brief Thread facility
|
|
* \author Norman Feske
|
|
* \author Sebastian Sumpf
|
|
* \date 2009-10-02
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2009-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 <base/printf.h>
|
|
#include <base/cap_sel_alloc.h>
|
|
#include <base/ipc_pager.h>
|
|
|
|
/* core includes */
|
|
#include <platform_thread.h>
|
|
#include <platform_pd.h>
|
|
#include <util.h>
|
|
#include <nova_util.h>
|
|
|
|
/* NOVA includes */
|
|
#include <nova/syscalls.h>
|
|
|
|
using namespace Genode;
|
|
|
|
|
|
/*********************
|
|
** Platform thread **
|
|
*********************/
|
|
|
|
void Platform_thread::set_cpu(unsigned int cpu_no)
|
|
{
|
|
PERR("not yet implemented");
|
|
}
|
|
|
|
|
|
int Platform_thread::start(void *ip, void *sp, unsigned int cpu_no)
|
|
{
|
|
using namespace Nova;
|
|
|
|
if (!_pager) {
|
|
PERR("pager undefined");
|
|
return -1;
|
|
}
|
|
|
|
enum { PD_EC_CPU_NO = 0, PD_UTCB = 0x6000000 };
|
|
|
|
_pager->initial_eip((addr_t)ip);
|
|
|
|
if (!_is_main_thread || !_pd) {
|
|
_pager->initial_esp((addr_t)sp);
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* For the first thread of a new PD, use the initial stack pointer for
|
|
* reporting the thread's UTCB address.
|
|
*/
|
|
_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");
|
|
|
|
Obj_crd initial_pts(_pager->exc_pt_sel(), Nova::NUM_INITIAL_PT_LOG2);
|
|
|
|
|
|
int pd_sel = cap_selector_allocator()->pd_sel();
|
|
int pd0_sel = _pager->exc_pt_sel() + Nova::PD_SEL;
|
|
_pd->assign_pd(pd0_sel);
|
|
|
|
res = create_pd(pd0_sel, pd_sel, initial_pts);
|
|
if (res)
|
|
PERR("create_pd returned %d", res);
|
|
|
|
int ec_sel = cap_selector_allocator()->alloc();
|
|
int sc_sel = cap_selector_allocator()->alloc();
|
|
|
|
enum { THREAD_GLOBAL = true };
|
|
res = create_ec(ec_sel, pd0_sel, PD_EC_CPU_NO, PD_UTCB, 0, 0,
|
|
THREAD_GLOBAL);
|
|
if (res)
|
|
PDBG("create_ec returned %d", res);
|
|
|
|
res = create_sc(sc_sel, pd0_sel, ec_sel, Qpd());
|
|
if (res)
|
|
PERR("create_sc returned %d", res);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
void Platform_thread::pause()
|
|
{
|
|
PDBG("not implemented");
|
|
}
|
|
|
|
|
|
void Platform_thread::resume()
|
|
{
|
|
PDBG("not implemented");
|
|
}
|
|
|
|
|
|
int Platform_thread::state(Thread_state *state_dst)
|
|
{
|
|
PWRN("not implemented");
|
|
return -1;
|
|
}
|
|
|
|
|
|
void Platform_thread::cancel_blocking() { PWRN("not implemented"); }
|
|
|
|
|
|
unsigned long Platform_thread::pager_object_badge()
|
|
const
|
|
{
|
|
return _pd ? ((_pd->id() << 16) || _id) : ~0;
|
|
}
|
|
|
|
|
|
static int id_cnt;
|
|
|
|
|
|
Platform_thread::Platform_thread(const char *name, unsigned, addr_t, int thread_id)
|
|
: _pd(0), _id(++id_cnt) { }
|
|
|
|
|
|
Platform_thread::~Platform_thread()
|
|
{
|
|
using namespace Nova;
|
|
|
|
if (_is_main_thread)
|
|
revoke(Obj_crd(_pd->pd_sel(), 0));
|
|
}
|