mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-26 14:19:19 +00:00
parent
dc0ebba1ec
commit
da5d182ad3
@ -38,20 +38,6 @@ namespace Genode {
|
||||
static void copy(void* dst, Native_capability_tpl<Cap_dst_policy>* src);
|
||||
};
|
||||
|
||||
struct Native_thread
|
||||
{
|
||||
Fiasco::l4_threadid_t l4id;
|
||||
|
||||
/**
|
||||
* Only used in core
|
||||
*
|
||||
* For 'Thread' objects created within core, 'pt' points to
|
||||
* the physical thread object, which is going to be destroyed
|
||||
* on destruction of the 'Thread'.
|
||||
*/
|
||||
Platform_thread *pt;
|
||||
};
|
||||
|
||||
typedef Native_capability_tpl<Cap_dst_policy> Native_capability;
|
||||
typedef Fiasco::l4_threadid_t Native_connection_state;
|
||||
}
|
||||
|
@ -14,10 +14,13 @@
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
|
||||
/* Core includes */
|
||||
/* core includes */
|
||||
#include <ipc_pager.h>
|
||||
#include <pager.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/native_thread.h>
|
||||
|
||||
namespace Fiasco {
|
||||
#include <l4/sys/ipc.h>
|
||||
#include <l4/sys/syscalls.h>
|
||||
@ -80,5 +83,5 @@ void Ipc_pager::acknowledge_wakeup()
|
||||
|
||||
Untyped_capability Pager_entrypoint::_pager_object_cap(unsigned long badge)
|
||||
{
|
||||
return Untyped_capability(_tid.l4id, badge);
|
||||
return Untyped_capability(native_thread().l4id, badge);
|
||||
}
|
||||
|
@ -37,15 +37,15 @@ void Thread_base::_thread_start()
|
||||
void Thread_base::start()
|
||||
{
|
||||
/* create and start platform thread */
|
||||
_tid.pt = new(platform()->core_mem_alloc())
|
||||
native_thread().pt = new(platform()->core_mem_alloc())
|
||||
Platform_thread(0, _stack->name().string());
|
||||
|
||||
platform_specific()->core_pd()->bind_thread(_tid.pt);
|
||||
platform_specific()->core_pd()->bind_thread(native_thread().pt);
|
||||
|
||||
_tid.pt->pager(platform_specific()->core_pager());
|
||||
_tid.l4id = _tid.pt->native_thread_id();
|
||||
native_thread().pt->pager(platform_specific()->core_pager());
|
||||
native_thread().l4id = native_thread().pt->native_thread_id();
|
||||
|
||||
_tid.pt->start((void *)_thread_start, stack_top());
|
||||
native_thread().pt->start((void *)_thread_start, stack_top());
|
||||
}
|
||||
|
||||
|
||||
@ -60,5 +60,5 @@ void Thread_base::cancel_blocking()
|
||||
void Thread_base::_deinit_platform_thread()
|
||||
{
|
||||
/* destruct platform thread */
|
||||
destroy(platform()->core_mem_alloc(), _tid.pt);
|
||||
destroy(platform()->core_mem_alloc(), native_thread().pt);
|
||||
}
|
||||
|
41
repos/base-fiasco/src/include/base/internal/native_thread.h
Normal file
41
repos/base-fiasco/src/include/base/internal/native_thread.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* \brief Kernel-specific thread meta data
|
||||
* \author Norman Feske
|
||||
* \date 2016-03-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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__INTERNAL__NATIVE_THREAD_H_
|
||||
#define _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/stdint.h>
|
||||
|
||||
/* Fiasco includes */
|
||||
namespace Fiasco {
|
||||
#include <l4/sys/types.h>
|
||||
}
|
||||
|
||||
namespace Genode { struct Native_thread; }
|
||||
|
||||
struct Genode::Native_thread
|
||||
{
|
||||
Fiasco::l4_threadid_t l4id;
|
||||
|
||||
/**
|
||||
* Only used in core
|
||||
*
|
||||
* For 'Thread' objects created within core, 'pt' points to the physical
|
||||
* thread object, which is going to be destroyed on destruction of the
|
||||
* 'Thread'.
|
||||
*/
|
||||
Platform_thread *pt;
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_ */
|
@ -75,20 +75,11 @@ namespace Fiasco {
|
||||
static bool valid(l4_cap_idx_t idx) {
|
||||
return !(idx & L4_INVALID_CAP_BIT) && idx != 0; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
namespace Genode {
|
||||
|
||||
struct Native_thread
|
||||
{
|
||||
Fiasco::l4_cap_idx_t kcap = 0;
|
||||
|
||||
Native_thread() { }
|
||||
explicit Native_thread(Fiasco::l4_cap_idx_t kcap) : kcap(kcap) { }
|
||||
};
|
||||
|
||||
|
||||
typedef Fiasco::l4_cap_idx_t Native_task;
|
||||
|
||||
|
||||
|
39
repos/base-foc/include/foc/native_thread.h
Normal file
39
repos/base-foc/include/foc/native_thread.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* \brief Kernel-specific thread meta data
|
||||
* \author Norman Feske
|
||||
* \date 2016-03-11
|
||||
*
|
||||
* On most platforms, the 'Genode::Native_thread' type is private to the base
|
||||
* framework. However, on Fiasco.OC, we make the type publicly available to
|
||||
* expose the low-level thread-specific capability selectors to L4Linux.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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__FOC__NATIVE_THREAD_H_
|
||||
#define _INCLUDE__FOC__NATIVE_THREAD_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/stdint.h>
|
||||
|
||||
/* Fiasco.OC includes */
|
||||
namespace Fiasco {
|
||||
#include <l4/sys/types.h>
|
||||
}
|
||||
|
||||
namespace Genode { struct Native_thread; }
|
||||
|
||||
struct Genode::Native_thread
|
||||
{
|
||||
Fiasco::l4_cap_idx_t kcap = 0;
|
||||
|
||||
Native_thread() { }
|
||||
explicit Native_thread(Fiasco::l4_cap_idx_t kcap) : kcap(kcap) { }
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__FOC__NATIVE_THREAD_H_ */
|
@ -27,6 +27,9 @@
|
||||
#include <base/thread.h>
|
||||
#include <signal_source/foc_signal_source.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/native_thread.h>
|
||||
|
||||
namespace Fiasco {
|
||||
#include <l4/sys/irq.h>
|
||||
}
|
||||
@ -53,7 +56,7 @@ namespace Genode {
|
||||
_sem = call<Rpc_request_semaphore>();
|
||||
|
||||
l4_msgtag_t tag = l4_irq_attach(_sem.dst(), 0,
|
||||
Thread_base::myself()->tid().kcap);
|
||||
Thread_base::myself()->native_thread().kcap);
|
||||
if (l4_error(tag))
|
||||
PERR("l4_irq_attach failed with %ld!", l4_error(tag));
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ void Thread_base::_deinit_platform_thread()
|
||||
{
|
||||
using namespace Fiasco;
|
||||
|
||||
if (_tid.kcap && _thread_cap.valid()) {
|
||||
if (native_thread().kcap && _thread_cap.valid()) {
|
||||
Cap_index *i = (Cap_index*)l4_utcb_tcr_u(utcb()->foc_utcb)->user[UTCB_TCR_BADGE];
|
||||
cap_map()->remove(i);
|
||||
_cpu_session->kill_thread(_thread_cap);
|
||||
@ -62,7 +62,7 @@ void Thread_base::_init_platform_thread(size_t weight, Type type)
|
||||
return;
|
||||
}
|
||||
/* adjust values whose computation differs for a main thread */
|
||||
_tid.kcap = Fiasco::MAIN_THREAD_CAP;
|
||||
native_thread().kcap = Fiasco::MAIN_THREAD_CAP;
|
||||
_thread_cap = env()->parent()->main_thread_cap();
|
||||
|
||||
if (!_thread_cap.valid())
|
||||
@ -91,7 +91,7 @@ void Thread_base::start()
|
||||
Fiasco::l4_utcb_t * const foc_utcb = (Fiasco::l4_utcb_t *)state.utcb;
|
||||
utcb()->foc_utcb = foc_utcb;
|
||||
|
||||
_tid = Native_thread(state.kcap);
|
||||
native_thread() = Native_thread(state.kcap);
|
||||
|
||||
Cap_index *i = cap_map()->insert(state.id, state.kcap);
|
||||
l4_utcb_tcr_u(foc_utcb)->user[UTCB_TCR_BADGE] = (unsigned long) i;
|
||||
|
@ -17,6 +17,9 @@
|
||||
/* Genode includes */
|
||||
#include <base/cap_map.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/native_thread.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Platform_thread;
|
||||
|
@ -23,6 +23,9 @@
|
||||
#include <base/thread_state.h>
|
||||
#include <util/touch.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/native_thread.h>
|
||||
|
||||
/* Fiasco includes */
|
||||
namespace Fiasco {
|
||||
#include <l4/sys/types.h>
|
||||
|
@ -18,9 +18,12 @@
|
||||
#include <base/printf.h>
|
||||
#include <base/lock.h>
|
||||
|
||||
/* Core includes */
|
||||
/* core includes */
|
||||
#include <pager.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/native_thread.h>
|
||||
|
||||
/* Fiasco.OC includes */
|
||||
namespace Fiasco {
|
||||
#include <l4/sys/factory.h>
|
||||
|
@ -53,7 +53,7 @@ void Thread_base::start()
|
||||
|
||||
l4_utcb_t *foc_utcb = (l4_utcb_t *)(pt->utcb());
|
||||
|
||||
_tid = Native_thread(pt->gate().remote);
|
||||
native_thread() = Native_thread(pt->gate().remote);
|
||||
|
||||
utcb()->foc_utcb = foc_utcb;
|
||||
|
||||
|
@ -22,6 +22,9 @@
|
||||
#include <base/native_types.h>
|
||||
#include <base/thread.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/native_thread.h>
|
||||
|
||||
/* Fiasco.OC includes */
|
||||
namespace Fiasco {
|
||||
#include <l4/sys/kdebug.h>
|
||||
@ -48,7 +51,7 @@ static inline void thread_yield() { Fiasco::l4_thread_yield(); }
|
||||
static inline bool thread_check_stopped_and_restart(Genode::Thread_base *thread_base)
|
||||
{
|
||||
Fiasco::l4_cap_idx_t tid = thread_base ?
|
||||
thread_base->tid().kcap :
|
||||
thread_base->native_thread().kcap :
|
||||
Fiasco::MAIN_THREAD_CAP;
|
||||
Fiasco::l4_cap_idx_t irq = tid + Fiasco::THREAD_IRQ_CAP;
|
||||
Fiasco::l4_irq_trigger(irq);
|
||||
@ -62,7 +65,7 @@ static inline bool thread_check_stopped_and_restart(Genode::Thread_base *thread_
|
||||
static inline void thread_switch_to(Genode::Thread_base *thread_base)
|
||||
{
|
||||
Fiasco::l4_cap_idx_t tid = thread_base ?
|
||||
thread_base->tid().kcap :
|
||||
thread_base->native_thread().kcap :
|
||||
Fiasco::MAIN_THREAD_CAP;
|
||||
Fiasco::l4_thread_switch(tid);
|
||||
}
|
||||
@ -82,7 +85,7 @@ static void thread_stop_myself()
|
||||
|
||||
Genode::Thread_base *myself = Genode::Thread_base::myself();
|
||||
Fiasco::l4_cap_idx_t tid = myself ?
|
||||
myself->tid().kcap :
|
||||
myself->native_thread().kcap :
|
||||
Fiasco::MAIN_THREAD_CAP;
|
||||
Fiasco::l4_cap_idx_t irq = tid + THREAD_IRQ_CAP;
|
||||
l4_irq_receive(irq, L4_IPC_NEVER);
|
||||
|
14
repos/base-foc/src/include/base/internal/native_thread.h
Normal file
14
repos/base-foc/src/include/base/internal/native_thread.h
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* \brief Kernel-specific thread meta data
|
||||
* \author Norman Feske
|
||||
* \date 2016-03-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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 <foc/native_thread.h>
|
@ -15,32 +15,11 @@
|
||||
#ifndef _INCLUDE__BASE__NATIVE_TYPES_H_
|
||||
#define _INCLUDE__BASE__NATIVE_TYPES_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <kernel/log.h>
|
||||
#include <base/native_capability.h>
|
||||
#include <base/ipc_msgbuf.h>
|
||||
#include <base/printf.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
class Platform_thread;
|
||||
class Native_thread;
|
||||
|
||||
typedef int Native_connection_state;
|
||||
|
||||
/**
|
||||
* Coherent address region
|
||||
*/
|
||||
struct Native_region;
|
||||
}
|
||||
|
||||
|
||||
struct Genode::Native_thread
|
||||
{
|
||||
Platform_thread * platform_thread;
|
||||
Native_capability cap;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* _INCLUDE__BASE__NATIVE_TYPES_H_ */
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/native_utcb.h>
|
||||
#include <base/internal/native_thread.h>
|
||||
|
||||
/* base-hw includes */
|
||||
#include <kernel/interface.h>
|
||||
@ -85,7 +86,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_base::myself() ? Thread_base::myself()->tid().cap
|
||||
Native_capability(Thread_base::myself() ? Thread_base::myself()->native_thread().cap
|
||||
: Hw::_main_thread_cap),
|
||||
_rcv_msg(rcv_msg), _rcv_cs(-1)
|
||||
{ _read_offset = align_natural<unsigned>(RPC_OBJECT_ID_SIZE); }
|
||||
|
@ -77,4 +77,4 @@ void Thread_base::_thread_start()
|
||||
}
|
||||
|
||||
void Thread_base::_thread_bootstrap() {
|
||||
_tid.cap = myself()->utcb()->cap_get(Native_utcb::THREAD_MYSELF); }
|
||||
native_thread().cap = myself()->utcb()->cap_get(Native_utcb::THREAD_MYSELF); }
|
||||
|
@ -62,7 +62,7 @@ void Thread_base::_init_platform_thread(size_t weight, Type type)
|
||||
while (1) ;
|
||||
}
|
||||
/* adjust initial object state in case of a main thread */
|
||||
tid().cap = Hw::_main_thread_cap;
|
||||
native_thread().cap = Hw::_main_thread_cap;
|
||||
_thread_cap = env()->parent()->main_thread_cap();
|
||||
}
|
||||
|
||||
|
@ -37,28 +37,28 @@ namespace Hw { extern Untyped_capability _main_thread_cap; }
|
||||
void Thread_base::start()
|
||||
{
|
||||
/* start thread with stack pointer at the top of stack */
|
||||
if (_tid.platform_thread->start((void *)&_thread_start, stack_top()))
|
||||
if (native_thread().platform_thread->start((void *)&_thread_start, stack_top()))
|
||||
PERR("failed to start thread");
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::cancel_blocking()
|
||||
{
|
||||
_tid.platform_thread->cancel_blocking();
|
||||
native_thread().platform_thread->cancel_blocking();
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::_deinit_platform_thread()
|
||||
{
|
||||
/* destruct platform thread */
|
||||
destroy(platform()->core_mem_alloc(), _tid.platform_thread);
|
||||
destroy(platform()->core_mem_alloc(), native_thread().platform_thread);
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::_init_platform_thread(size_t, Type type)
|
||||
{
|
||||
if (type == NORMAL) {
|
||||
_tid.platform_thread = new (platform()->core_mem_alloc())
|
||||
native_thread().platform_thread = new (platform()->core_mem_alloc())
|
||||
Platform_thread(_stack->name().string(), &_stack->utcb());
|
||||
return;
|
||||
}
|
||||
@ -69,5 +69,5 @@ void Thread_base::_init_platform_thread(size_t, Type type)
|
||||
max(sizeof(Native_utcb) / get_page_size(), (size_t)1));
|
||||
|
||||
/* adjust initial object state in case of a main thread */
|
||||
tid().cap = Hw::_main_thread_cap.dst();
|
||||
native_thread().cap = Hw::_main_thread_cap.dst();
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ static inline void thread_yield() {
|
||||
static inline Kernel::capid_t
|
||||
native_thread_id(Genode::Thread_base * const t)
|
||||
{
|
||||
return t ? t->tid().cap.dst() : Hw::_main_thread_cap.dst();
|
||||
return t ? t->native_thread().cap.dst() : Hw::_main_thread_cap.dst();
|
||||
}
|
||||
|
||||
|
||||
|
33
repos/base-hw/src/include/base/internal/native_thread.h
Normal file
33
repos/base-hw/src/include/base/internal/native_thread.h
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* \brief Kernel-specific thread meta data
|
||||
* \author Norman Feske
|
||||
* \date 2016-03-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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__INTERNAL__NATIVE_THREAD_H_
|
||||
#define _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_
|
||||
|
||||
#include <base/stdint.h>
|
||||
#include <base/native_capability.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
struct Native_thread;
|
||||
class Platform_thread;
|
||||
}
|
||||
|
||||
|
||||
struct Genode::Native_thread
|
||||
{
|
||||
Platform_thread *platform_thread;
|
||||
Native_capability cap;
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_ */
|
@ -20,39 +20,6 @@
|
||||
|
||||
namespace Genode {
|
||||
|
||||
/**
|
||||
* Native thread contains more thread-local data than just the ID
|
||||
*/
|
||||
struct Native_thread
|
||||
{
|
||||
/*
|
||||
* Unfortunately, both - PID and TID - are needed for lx_tgkill()
|
||||
*/
|
||||
unsigned int tid = 0; /* Native thread ID type as returned by the
|
||||
'clone' system call */
|
||||
unsigned int pid = 0; /* process ID (resp. thread-group ID) */
|
||||
|
||||
bool is_ipc_server = false;
|
||||
|
||||
/**
|
||||
* Natively aligned memory location used in the lock implementation
|
||||
*/
|
||||
int futex_counter __attribute__((aligned(sizeof(Genode::addr_t)))) = 0;
|
||||
|
||||
struct Meta_data;
|
||||
|
||||
/**
|
||||
* Opaque pointer to additional thread-specific meta data
|
||||
*
|
||||
* This pointer is used by hybrid Linux/Genode programs to maintain
|
||||
* POSIX-thread-related meta data. For non-hybrid Genode programs, it
|
||||
* remains unused.
|
||||
*/
|
||||
Meta_data *meta_data = nullptr;
|
||||
|
||||
Native_thread() { }
|
||||
};
|
||||
|
||||
struct Cap_dst_policy
|
||||
{
|
||||
struct Dst
|
||||
|
@ -36,6 +36,7 @@
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/socket_descriptor_registry.h>
|
||||
#include <base/internal/native_thread.h>
|
||||
|
||||
/* Linux includes */
|
||||
#include <linux_syscalls.h>
|
||||
@ -509,7 +510,7 @@ Ipc_istream::~Ipc_istream()
|
||||
*/
|
||||
Thread_base *thread = Thread_base::myself();
|
||||
if (thread)
|
||||
thread->tid().is_ipc_server = false;
|
||||
thread->native_thread().is_ipc_server = false;
|
||||
}
|
||||
|
||||
destroy_server_socket_pair(_rcv_cs);
|
||||
@ -641,7 +642,7 @@ Ipc_server::Ipc_server(Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg)
|
||||
* may call 'sleep_forever()', which instantiates 'Ipc_server'.
|
||||
*/
|
||||
|
||||
if (thread && thread->tid().is_ipc_server) {
|
||||
if (thread && thread->native_thread().is_ipc_server) {
|
||||
PRAW("[%d] unexpected multiple instantiation of Ipc_server by one thread",
|
||||
lx_gettid());
|
||||
struct Ipc_server_multiple_instance { };
|
||||
@ -650,7 +651,7 @@ Ipc_server::Ipc_server(Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg)
|
||||
|
||||
if (thread) {
|
||||
_rcv_cs = server_socket_pair();
|
||||
thread->tid().is_ipc_server = true;
|
||||
thread->native_thread().is_ipc_server = true;
|
||||
}
|
||||
|
||||
/* override capability initialization performed by 'Ipc_istream' */
|
||||
|
@ -58,7 +58,7 @@ void Thread_base::_thread_start()
|
||||
/* inform core about the new thread and process ID of the new thread */
|
||||
Linux_cpu_session *cpu = dynamic_cast<Linux_cpu_session *>(thread->_cpu_session);
|
||||
if (cpu)
|
||||
cpu->thread_id(thread->cap(), thread->tid().pid, thread->tid().tid);
|
||||
cpu->thread_id(thread->cap(), thread->native_thread().pid, thread->native_thread().tid);
|
||||
|
||||
/* wakeup 'start' function */
|
||||
startup_lock().unlock();
|
||||
@ -84,7 +84,7 @@ void Thread_base::_init_platform_thread(size_t weight, Type type)
|
||||
return;
|
||||
}
|
||||
/* adjust initial object state for main threads */
|
||||
tid().futex_counter = main_thread_futex_counter;
|
||||
native_thread().futex_counter = main_thread_futex_counter;
|
||||
_thread_cap = env()->parent()->main_thread_cap();
|
||||
}
|
||||
|
||||
@ -106,7 +106,7 @@ void Thread_base::_deinit_platform_thread()
|
||||
for (;;) {
|
||||
|
||||
/* destroy thread locally */
|
||||
int ret = lx_tgkill(_tid.pid, _tid.tid, LX_SIGCANCEL);
|
||||
int ret = lx_tgkill(native_thread().pid, native_thread().tid, LX_SIGCANCEL);
|
||||
|
||||
if (ret < 0) break;
|
||||
|
||||
@ -138,8 +138,8 @@ void Thread_base::start()
|
||||
threadlib_initialized = true;
|
||||
}
|
||||
|
||||
_tid.tid = lx_create_thread(Thread_base::_thread_start, stack_top(), this);
|
||||
_tid.pid = lx_getpid();
|
||||
native_thread().tid = lx_create_thread(Thread_base::_thread_start, stack_top(), this);
|
||||
native_thread().pid = lx_getpid();
|
||||
|
||||
/* wait until the 'thread_start' function got entered */
|
||||
startup_lock().lock();
|
||||
|
@ -15,6 +15,9 @@
|
||||
#include <base/lock.h>
|
||||
#include <linux_dataspace/client.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/native_thread.h>
|
||||
|
||||
/* local includes */
|
||||
#include "platform.h"
|
||||
#include "core_env.h"
|
||||
@ -157,7 +160,7 @@ namespace Genode {
|
||||
|
||||
Native_connection_state server_socket_pair()
|
||||
{
|
||||
return create_server_socket_pair(Thread_base::myself()->tid().tid);
|
||||
return create_server_socket_pair(Thread_base::myself()->native_thread().tid);
|
||||
}
|
||||
|
||||
void destroy_server_socket_pair(Native_connection_state const &ncs)
|
||||
|
@ -15,6 +15,9 @@
|
||||
#include <base/thread.h>
|
||||
#include <base/sleep.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/native_thread.h>
|
||||
|
||||
/* Linux syscall bindings */
|
||||
#include <linux_syscalls.h>
|
||||
|
||||
@ -54,8 +57,8 @@ void Thread_base::_deinit_platform_thread() { }
|
||||
|
||||
void Thread_base::start()
|
||||
{
|
||||
_tid.tid = lx_create_thread(Thread_base::_thread_start, stack_top(), this);
|
||||
_tid.pid = lx_getpid();
|
||||
native_thread().tid = lx_create_thread(Thread_base::_thread_start, stack_top(), this);
|
||||
native_thread().pid = lx_getpid();
|
||||
}
|
||||
|
||||
|
||||
|
@ -41,7 +41,7 @@ static inline void thread_yield()
|
||||
static inline bool thread_check_stopped_and_restart(Genode::Thread_base *thread_base)
|
||||
{
|
||||
const int *futex_counter_ptr = thread_base ?
|
||||
&thread_base->tid().futex_counter :
|
||||
&thread_base->native_thread().futex_counter :
|
||||
&main_thread_futex_counter;
|
||||
return lx_futex(futex_counter_ptr, LX_FUTEX_WAKE, 1);
|
||||
}
|
||||
@ -62,7 +62,7 @@ static inline void thread_stop_myself()
|
||||
*/
|
||||
Genode::Thread_base *myself = Genode::Thread_base::myself();
|
||||
const int *futex_counter_ptr = myself ?
|
||||
&myself->tid().futex_counter :
|
||||
&myself->native_thread().futex_counter :
|
||||
&main_thread_futex_counter;
|
||||
lx_futex(futex_counter_ptr, LX_FUTEX_WAIT, 0);
|
||||
}
|
||||
|
51
repos/base-linux/src/include/base/internal/native_thread.h
Normal file
51
repos/base-linux/src/include/base/internal/native_thread.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* \brief Kernel-specific thread meta data
|
||||
* \author Norman Feske
|
||||
* \date 2016-03-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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__INTERNAL__NATIVE_THREAD_H_
|
||||
#define _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_
|
||||
|
||||
#include <base/stdint.h>
|
||||
|
||||
namespace Genode { struct Native_thread; }
|
||||
|
||||
struct Genode::Native_thread
|
||||
{
|
||||
/*
|
||||
* Unfortunately, both - PID and TID - are needed for lx_tgkill()
|
||||
*/
|
||||
unsigned int tid = 0; /* Native thread ID type as returned by the
|
||||
'clone' system call */
|
||||
unsigned int pid = 0; /* process ID (resp. thread-group ID) */
|
||||
|
||||
bool is_ipc_server = false;
|
||||
|
||||
/**
|
||||
* Natively aligned memory location used in the lock implementation
|
||||
*/
|
||||
int futex_counter __attribute__((aligned(sizeof(Genode::addr_t)))) = 0;
|
||||
|
||||
struct Meta_data;
|
||||
|
||||
/**
|
||||
* Opaque pointer to additional thread-specific meta data
|
||||
*
|
||||
* This pointer is used by hybrid Linux/Genode programs to maintain
|
||||
* POSIX-thread-related meta data. For non-hybrid Genode programs, it
|
||||
* remains unused.
|
||||
*/
|
||||
Meta_data *meta_data = nullptr;
|
||||
|
||||
Native_thread() { }
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_ */
|
@ -11,11 +11,14 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
//#include <base/crt0.h>
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
#include <linux_syscalls.h>
|
||||
#include <linux_cpu_session/linux_cpu_session.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/native_thread.h>
|
||||
|
||||
|
||||
extern "C" int raw_write_str(const char *str);
|
||||
|
||||
@ -134,8 +137,20 @@ static pthread_key_t tls_key()
|
||||
|
||||
namespace Genode {
|
||||
|
||||
/**
|
||||
* Meta data tied to the thread via the pthread TLS mechanism
|
||||
*/
|
||||
struct Native_thread::Meta_data
|
||||
{
|
||||
/**
|
||||
* Linux-specific thread meta data
|
||||
*
|
||||
* For non-hybrid programs, this information is located at the
|
||||
* 'Stack'. But the POSIX threads of hybrid programs have no 'Stack'
|
||||
* object. So we have to keep the meta data here.
|
||||
*/
|
||||
Native_thread native_thread;
|
||||
|
||||
/**
|
||||
* Filled out by 'thread_start' function in the stack of the new
|
||||
* thread
|
||||
@ -152,7 +167,10 @@ namespace Genode {
|
||||
*
|
||||
* \param thread associated 'Thread_base' object
|
||||
*/
|
||||
Meta_data(Thread_base *thread) : thread_base(thread) { }
|
||||
Meta_data(Thread_base *thread) : thread_base(thread)
|
||||
{
|
||||
native_thread.meta_data = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to block the constructor until the new thread has initialized
|
||||
@ -174,8 +192,8 @@ namespace Genode {
|
||||
virtual void joined() = 0;
|
||||
};
|
||||
|
||||
/*
|
||||
* Thread meta data for a thread created by Genode
|
||||
/**
|
||||
* Thread meta data for a thread created by Genode
|
||||
*/
|
||||
class Thread_meta_data_created : public Native_thread::Meta_data
|
||||
{
|
||||
@ -238,8 +256,8 @@ namespace Genode {
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Thread meta data for an adopted thread
|
||||
/**
|
||||
* Thread meta data for an adopted thread
|
||||
*/
|
||||
class Thread_meta_data_adopted : public Native_thread::Meta_data
|
||||
{
|
||||
@ -320,7 +338,7 @@ static void adopt_thread(Native_thread::Meta_data *meta_data)
|
||||
/*
|
||||
* Initialize thread meta data
|
||||
*/
|
||||
Native_thread &native_thread = meta_data->thread_base->tid();
|
||||
Native_thread &native_thread = meta_data->thread_base->native_thread();
|
||||
native_thread.tid = lx_gettid();
|
||||
native_thread.pid = lx_getpid();
|
||||
}
|
||||
@ -375,19 +393,18 @@ Thread_base *Thread_base::myself()
|
||||
* thread, which is not what we want. For the allocation, we use glibc
|
||||
* malloc because 'Genode::env()->heap()->alloc()' uses IPC.
|
||||
*
|
||||
* XXX Both the 'Thread_base' and 'Threadm_meta_data' objects are never
|
||||
* freed.
|
||||
* XXX Both the 'Thread_base' and 'Native_thread::Meta_data' objects are
|
||||
* never freed.
|
||||
*/
|
||||
Thread_base *thread = (Thread_base *)malloc(sizeof(Thread_base));
|
||||
memset(thread, 0, sizeof(*thread));
|
||||
Native_thread::Meta_data *meta_data = new Thread_meta_data_adopted(thread);
|
||||
|
||||
/*
|
||||
* Initialize 'Thread_base::_tid' using the default constructor of
|
||||
* 'Native_thread'. This marks the client and server sockets as
|
||||
* uninitialized and prompts the IPC framework to create those as needed.
|
||||
* Initialize 'Thread_base::_native_thread' to point to the default-
|
||||
* constructed 'Native_thread' (part of 'Meta_data').
|
||||
*/
|
||||
meta_data->thread_base->tid() = Native_thread();
|
||||
meta_data->thread_base->_native_thread = &meta_data->native_thread;
|
||||
adopt_thread(meta_data);
|
||||
|
||||
return thread;
|
||||
@ -399,37 +416,42 @@ void Thread_base::start()
|
||||
/*
|
||||
* Unblock thread that is supposed to slumber in 'thread_start'.
|
||||
*/
|
||||
_tid.meta_data->started();
|
||||
native_thread().meta_data->started();
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::join()
|
||||
{
|
||||
_tid.meta_data->wait_for_join();
|
||||
native_thread().meta_data->wait_for_join();
|
||||
}
|
||||
|
||||
|
||||
Native_thread &Thread_base::native_thread() { return *_native_thread; }
|
||||
|
||||
|
||||
Thread_base::Thread_base(size_t weight, const char *name, size_t stack_size,
|
||||
Type type, Cpu_session * cpu_sess)
|
||||
: _cpu_session(cpu_sess)
|
||||
{
|
||||
_tid.meta_data = new (env()->heap()) Thread_meta_data_created(this);
|
||||
Native_thread::Meta_data *meta_data =
|
||||
new (env()->heap()) Thread_meta_data_created(this);
|
||||
|
||||
int const ret = pthread_create(&_tid.meta_data->pt, 0, thread_start,
|
||||
_tid.meta_data);
|
||||
_native_thread = &meta_data->native_thread;
|
||||
|
||||
int const ret = pthread_create(&meta_data->pt, 0, thread_start, meta_data);
|
||||
if (ret) {
|
||||
PERR("pthread_create failed (returned %d, errno=%d)",
|
||||
ret, errno);
|
||||
destroy(env()->heap(), _tid.meta_data);
|
||||
destroy(env()->heap(), meta_data);
|
||||
throw Out_of_stack_space();
|
||||
}
|
||||
|
||||
_tid.meta_data->wait_for_construction();
|
||||
native_thread().meta_data->wait_for_construction();
|
||||
|
||||
Linux_cpu_session *cpu = cpu_session(_cpu_session);
|
||||
|
||||
_thread_cap = cpu->create_thread(weight, name);
|
||||
cpu->thread_id(_thread_cap, _tid.pid, _tid.tid);
|
||||
cpu->thread_id(_thread_cap, native_thread().pid, native_thread().tid);
|
||||
}
|
||||
|
||||
|
||||
@ -447,22 +469,22 @@ void Thread_base::cancel_blocking()
|
||||
|
||||
Thread_base::~Thread_base()
|
||||
{
|
||||
bool const needs_join = (pthread_cancel(_tid.meta_data->pt) == 0);
|
||||
bool const needs_join = (pthread_cancel(native_thread().meta_data->pt) == 0);
|
||||
|
||||
if (needs_join) {
|
||||
int const ret = pthread_join(_tid.meta_data->pt, 0);
|
||||
int const ret = pthread_join(native_thread().meta_data->pt, 0);
|
||||
if (ret)
|
||||
PWRN("pthread_join unexpectedly returned with %d (errno=%d)",
|
||||
ret, errno);
|
||||
}
|
||||
|
||||
Thread_meta_data_created *meta_data =
|
||||
dynamic_cast<Thread_meta_data_created *>(_tid.meta_data);
|
||||
dynamic_cast<Thread_meta_data_created *>(native_thread().meta_data);
|
||||
|
||||
if (meta_data)
|
||||
destroy(env()->heap(), meta_data);
|
||||
|
||||
_tid.meta_data = 0;
|
||||
_native_thread = nullptr;
|
||||
|
||||
/* inform core about the killed thread */
|
||||
cpu_session(_cpu_session)->kill_thread(_thread_cap);
|
||||
|
@ -15,27 +15,16 @@
|
||||
#ifndef _INCLUDE__BASE__NATIVE_TYPES_H_
|
||||
#define _INCLUDE__BASE__NATIVE_TYPES_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/native_capability.h>
|
||||
#include <base/stdint.h>
|
||||
|
||||
#include <nova/syscalls.h>
|
||||
|
||||
#include <base/cap_map.h>
|
||||
|
||||
/* NOVA includes */
|
||||
#include <nova/syscalls.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
struct Native_thread
|
||||
{
|
||||
enum { INVALID_INDEX = ~0UL };
|
||||
|
||||
addr_t ec_sel; /* NOVA cap selector for execution context */
|
||||
addr_t exc_pt_sel; /* base of event portal window */
|
||||
bool is_vcpu;
|
||||
|
||||
Native_thread() : ec_sel(INVALID_INDEX),
|
||||
exc_pt_sel (INVALID_INDEX), is_vcpu(false) {}
|
||||
};
|
||||
|
||||
class Native_capability
|
||||
{
|
||||
public:
|
||||
|
38
repos/base-nova/include/nova/native_thread.h
Normal file
38
repos/base-nova/include/nova/native_thread.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* \brief Kernel-specific thread meta data
|
||||
* \author Norman Feske
|
||||
* \date 2016-03-11
|
||||
*
|
||||
* On most platforms, the 'Genode::Native_thread' type is private to the
|
||||
* base framework. However, on NOVA, we make the type publicly available to
|
||||
* expose the low-level thread-specific capability selectors to user-level
|
||||
* virtual-machine monitors (Seoul or VirtualBox).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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__NOVA__NATIVE_THREAD_H_
|
||||
#define _INCLUDE__NOVA__NATIVE_THREAD_H_
|
||||
|
||||
#include <base/stdint.h>
|
||||
|
||||
namespace Genode { struct Native_thread; }
|
||||
|
||||
struct Genode::Native_thread
|
||||
{
|
||||
enum { INVALID_INDEX = ~0UL };
|
||||
|
||||
addr_t ec_sel; /* selector for execution context */
|
||||
addr_t exc_pt_sel; /* base of event portal window */
|
||||
bool is_vcpu;
|
||||
|
||||
Native_thread() : ec_sel(INVALID_INDEX),
|
||||
exc_pt_sel(INVALID_INDEX), is_vcpu(false) { }
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__NOVA__NATIVE_THREAD_H_ */
|
@ -21,9 +21,13 @@
|
||||
#ifndef _INCLUDE__SIGNAL_SOURCE__CLIENT_H_
|
||||
#define _INCLUDE__SIGNAL_SOURCE__CLIENT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/rpc_client.h>
|
||||
#include <signal_source/nova_signal_source.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/native_thread.h>
|
||||
|
||||
/* NOVA includes */
|
||||
#include <nova/syscalls.h>
|
||||
#include <nova/util.h>
|
||||
@ -49,9 +53,9 @@ namespace Genode {
|
||||
|
||||
/* request mapping of semaphore capability selector */
|
||||
Thread_base * myself = Thread_base::myself();
|
||||
request_signal_sm_cap(Native_capability(myself->tid().ec_sel + 1),
|
||||
myself->tid().exc_pt_sel + Nova::PT_SEL_STARTUP);
|
||||
_sem = Native_capability(myself->tid().exc_pt_sel + Nova::PT_SEL_STARTUP);
|
||||
request_signal_sm_cap(Native_capability(myself->native_thread().ec_sel + 1),
|
||||
myself->native_thread().exc_pt_sel + Nova::PT_SEL_STARTUP);
|
||||
_sem = Native_capability(myself->native_thread().exc_pt_sel + Nova::PT_SEL_STARTUP);
|
||||
call<Rpc_register_semaphore>(_sem);
|
||||
}
|
||||
|
||||
|
@ -39,8 +39,8 @@ Untyped_capability Rpc_entrypoint::_manage(Rpc_object_base *obj)
|
||||
Untyped_capability ec_cap;
|
||||
|
||||
/* _ec_sel is invalid until thread gets started */
|
||||
if (tid().ec_sel != Native_thread::INVALID_INDEX)
|
||||
ec_cap = Native_capability(tid().ec_sel);
|
||||
if (native_thread().ec_sel != Native_thread::INVALID_INDEX)
|
||||
ec_cap = Native_capability(native_thread().ec_sel);
|
||||
else
|
||||
ec_cap = _thread_cap;
|
||||
|
||||
@ -193,14 +193,14 @@ Rpc_entrypoint::Rpc_entrypoint(Pd_session *pd_session, size_t stack_size,
|
||||
_pd_session(*pd_session)
|
||||
{
|
||||
/* when not running in core set the affinity via cpu session */
|
||||
if (_tid.ec_sel == Native_thread::INVALID_INDEX) {
|
||||
if (native_thread().ec_sel == Native_thread::INVALID_INDEX) {
|
||||
|
||||
/* place new thread on the specified CPU */
|
||||
if (location.valid())
|
||||
_cpu_session->affinity(_thread_cap, location);
|
||||
|
||||
/* magic value evaluated by thread_nova.cc to start a local thread */
|
||||
_tid.ec_sel = Native_thread::INVALID_INDEX - 1;
|
||||
native_thread().ec_sel = Native_thread::INVALID_INDEX - 1;
|
||||
} else {
|
||||
/* tell affinity CPU in 'core' via stack */
|
||||
reinterpret_cast<Affinity::Location *>(stack_base())[0] = location;
|
||||
@ -210,7 +210,7 @@ Rpc_entrypoint::Rpc_entrypoint(Pd_session *pd_session, size_t stack_size,
|
||||
Thread_base::start();
|
||||
|
||||
/* create cleanup portal */
|
||||
_cap = _alloc_rpc_cap(_pd_session, Native_capability(_tid.ec_sel),
|
||||
_cap = _alloc_rpc_cap(_pd_session, Native_capability(native_thread().ec_sel),
|
||||
(addr_t)_activation_entry);
|
||||
if (!_cap.valid())
|
||||
throw Cpu_session::Thread_creation_failed();
|
||||
|
@ -16,6 +16,9 @@
|
||||
#include <base/sleep.h>
|
||||
#include <base/lock.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/native_thread.h>
|
||||
|
||||
/* NOVA includes */
|
||||
#include <nova/syscalls.h>
|
||||
#include <nova/util.h>
|
||||
@ -25,7 +28,7 @@ void Genode::sleep_forever()
|
||||
using namespace Nova;
|
||||
|
||||
Thread_base *myself = Thread_base::myself();
|
||||
addr_t sem = myself ? myself->tid().exc_pt_sel + SM_SEL_EC : SM_SEL_EC;
|
||||
addr_t sem = myself ? myself->native_thread().exc_pt_sel + SM_SEL_EC : SM_SEL_EC;
|
||||
|
||||
while (1) {
|
||||
if (Nova::sm_ctrl(sem, SEMAPHORE_DOWNZERO))
|
||||
|
@ -75,7 +75,7 @@ void Thread_base::_init_platform_thread(size_t weight, Type type)
|
||||
* Allocate capability selectors for the thread's execution context,
|
||||
* running semaphore and exception handler portals.
|
||||
*/
|
||||
_tid.ec_sel = Native_thread::INVALID_INDEX;
|
||||
native_thread().ec_sel = Native_thread::INVALID_INDEX;
|
||||
|
||||
/* for main threads the member initialization differs */
|
||||
if (type == MAIN || type == REINITIALIZED_MAIN) {
|
||||
@ -84,10 +84,10 @@ void Thread_base::_init_platform_thread(size_t weight, Type type)
|
||||
Genode::Native_capability pager_cap(Nova::PT_SEL_MAIN_PAGER);
|
||||
_pager_cap = reinterpret_cap_cast<Pager_object>(pager_cap);
|
||||
|
||||
_tid.exc_pt_sel = 0;
|
||||
_tid.ec_sel = Nova::PT_SEL_MAIN_EC;
|
||||
native_thread().exc_pt_sel = 0;
|
||||
native_thread().ec_sel = Nova::PT_SEL_MAIN_EC;
|
||||
|
||||
request_native_ec_cap(_pager_cap, _tid.ec_sel);
|
||||
request_native_ec_cap(_pager_cap, native_thread().ec_sel);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -104,8 +104,8 @@ void Thread_base::_init_platform_thread(size_t weight, Type type)
|
||||
addr_t utcb = reinterpret_cast<addr_t>(&_stack->utcb());
|
||||
revoke(Mem_crd(utcb >> 12, 0, rwx));
|
||||
|
||||
_tid.exc_pt_sel = cap_map()->insert(NUM_INITIAL_PT_LOG2);
|
||||
if (_tid.exc_pt_sel == Native_thread::INVALID_INDEX)
|
||||
native_thread().exc_pt_sel = cap_map()->insert(NUM_INITIAL_PT_LOG2);
|
||||
if (native_thread().exc_pt_sel == Native_thread::INVALID_INDEX)
|
||||
throw Cpu_session::Thread_creation_failed();
|
||||
|
||||
/* if no cpu session is given, use it from the environment */
|
||||
@ -131,16 +131,16 @@ void Thread_base::_deinit_platform_thread()
|
||||
{
|
||||
using namespace Nova;
|
||||
|
||||
if (_tid.ec_sel != Native_thread::INVALID_INDEX) {
|
||||
revoke(Obj_crd(_tid.ec_sel, 1));
|
||||
cap_map()->remove(_tid.ec_sel, 1, false);
|
||||
if (native_thread().ec_sel != Native_thread::INVALID_INDEX) {
|
||||
revoke(Obj_crd(native_thread().ec_sel, 1));
|
||||
cap_map()->remove(native_thread().ec_sel, 1, false);
|
||||
}
|
||||
|
||||
/* de-announce thread */
|
||||
if (_thread_cap.valid())
|
||||
_cpu_session->kill_thread(_thread_cap);
|
||||
|
||||
cap_map()->remove(_tid.exc_pt_sel, NUM_INITIAL_PT_LOG2);
|
||||
cap_map()->remove(native_thread().exc_pt_sel, NUM_INITIAL_PT_LOG2);
|
||||
|
||||
if (_pager_cap.valid())
|
||||
env()->rm_session()->remove_client(_pager_cap);
|
||||
@ -149,14 +149,14 @@ void Thread_base::_deinit_platform_thread()
|
||||
|
||||
void Thread_base::start()
|
||||
{
|
||||
if (_tid.ec_sel < Native_thread::INVALID_INDEX - 1)
|
||||
if (native_thread().ec_sel < Native_thread::INVALID_INDEX - 1)
|
||||
throw Cpu_session::Thread_creation_failed();
|
||||
|
||||
/*
|
||||
* Default: create global thread - ec.sel == INVALID_INDEX
|
||||
* create local thread - ec.sel == INVALID_INDEX - 1
|
||||
*/
|
||||
bool global = _tid.ec_sel == Native_thread::INVALID_INDEX;
|
||||
bool global = native_thread().ec_sel == Native_thread::INVALID_INDEX;
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
@ -170,8 +170,8 @@ void Thread_base::start()
|
||||
|
||||
/* create EC at core */
|
||||
Thread_state state;
|
||||
state.sel_exc_base = _tid.exc_pt_sel;
|
||||
state.is_vcpu = _tid.is_vcpu;
|
||||
state.sel_exc_base = native_thread().exc_pt_sel;
|
||||
state.is_vcpu = native_thread().is_vcpu;
|
||||
|
||||
/* local thread have no start instruction pointer - set via portal entry */
|
||||
addr_t thread_ip = global ? reinterpret_cast<addr_t>(_thread_start) : 0;
|
||||
@ -183,19 +183,19 @@ void Thread_base::start()
|
||||
throw Cpu_session::Thread_creation_failed();
|
||||
|
||||
/* request native EC thread cap */
|
||||
_tid.ec_sel = cap_map()->insert(1);
|
||||
if (_tid.ec_sel == Native_thread::INVALID_INDEX)
|
||||
native_thread().ec_sel = cap_map()->insert(1);
|
||||
if (native_thread().ec_sel == Native_thread::INVALID_INDEX)
|
||||
throw Cpu_session::Thread_creation_failed();
|
||||
|
||||
/* requested pager cap used by request_native_ec_cap in Signal_source_client */
|
||||
enum { MAP_PAGER_CAP = 1 };
|
||||
request_native_ec_cap(_pager_cap, _tid.ec_sel, MAP_PAGER_CAP);
|
||||
request_native_ec_cap(_pager_cap, native_thread().ec_sel, MAP_PAGER_CAP);
|
||||
|
||||
using namespace Nova;
|
||||
|
||||
/* request exception portals for normal threads */
|
||||
if (!_tid.is_vcpu) {
|
||||
request_event_portal(_pager_cap, _tid.exc_pt_sel, 0, NUM_INITIAL_PT_LOG2);
|
||||
if (!native_thread().is_vcpu) {
|
||||
request_event_portal(_pager_cap, native_thread().exc_pt_sel, 0, NUM_INITIAL_PT_LOG2);
|
||||
|
||||
/* default: we don't accept any mappings or translations */
|
||||
Utcb * utcb_obj = reinterpret_cast<Utcb *>(utcb());
|
||||
@ -213,6 +213,6 @@ void Thread_base::cancel_blocking()
|
||||
{
|
||||
using namespace Nova;
|
||||
|
||||
if (sm_ctrl(_tid.exc_pt_sel + SM_SEL_EC, SEMAPHORE_UP))
|
||||
if (sm_ctrl(native_thread().exc_pt_sel + SM_SEL_EC, SEMAPHORE_UP))
|
||||
nova_die();
|
||||
}
|
||||
|
@ -18,6 +18,9 @@
|
||||
#include <util/construct_at.h>
|
||||
#include <rm_session/rm_session.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/native_thread.h>
|
||||
|
||||
/* core-local includes */
|
||||
#include <pager.h>
|
||||
#include <imprint_badge.h>
|
||||
@ -444,7 +447,7 @@ void Exception_handlers::register_handler(Pager_object *obj, Mtd mtd,
|
||||
throw Rm_session::Invalid_thread();
|
||||
}
|
||||
|
||||
addr_t const ec_sel = pager_threads[use_cpu]->tid().ec_sel;
|
||||
addr_t const ec_sel = pager_threads[use_cpu]->native_thread().ec_sel;
|
||||
|
||||
/* compiler generates instance of exception entry if not specified */
|
||||
addr_t entry = func ? (addr_t)func : (addr_t)(&_handler<EV>);
|
||||
@ -531,7 +534,7 @@ Pager_object::Pager_object(unsigned long badge, Affinity::Location location)
|
||||
throw Rm_session::Invalid_thread();
|
||||
}
|
||||
|
||||
addr_t ec_sel = pager_threads[use_cpu]->tid().ec_sel;
|
||||
addr_t ec_sel = pager_threads[use_cpu]->native_thread().ec_sel;
|
||||
|
||||
/* create portal for page-fault handler - 14 */
|
||||
_exceptions.register_handler<14>(this, Mtd::QUAL | Mtd::EIP,
|
||||
@ -720,7 +723,7 @@ void Pager_object::_oom_handler(addr_t pager_dst, addr_t pager_src,
|
||||
if (assert) {
|
||||
PERR("unknown OOM case - stop core pager thread");
|
||||
utcb->set_msg_word(0);
|
||||
reply(myself->stack_top(), myself->tid().exc_pt_sel + Nova::SM_SEL_EC);
|
||||
reply(myself->stack_top(), myself->native_thread().exc_pt_sel + Nova::SM_SEL_EC);
|
||||
}
|
||||
|
||||
/* be strict in case of the -strict- STOP policy - stop causing thread */
|
||||
@ -740,7 +743,7 @@ void Pager_object::_oom_handler(addr_t pager_dst, addr_t pager_src,
|
||||
/* should not happen on Genode - we create and know every PD in core */
|
||||
PERR("Unknown PD has insufficient kernel memory left - stop thread");
|
||||
utcb->set_msg_word(0);
|
||||
reply(myself->stack_top(), myself->tid().exc_pt_sel + Nova::SM_SEL_EC);
|
||||
reply(myself->stack_top(), myself->native_thread().exc_pt_sel + Nova::SM_SEL_EC);
|
||||
|
||||
case SRC_CORE_PD:
|
||||
/* core PD -> other PD, which has insufficient kernel resources */
|
||||
@ -792,7 +795,7 @@ addr_t Pager_object::get_oom_portal()
|
||||
unsigned const use_cpu = location.xpos();
|
||||
|
||||
if (kernel_hip()->is_cpu_enabled(use_cpu) && pager_threads[use_cpu]) {
|
||||
addr_t const ec_sel = pager_threads[use_cpu]->tid().ec_sel;
|
||||
addr_t const ec_sel = pager_threads[use_cpu]->native_thread().ec_sel;
|
||||
|
||||
uint8_t res = create_portal(pt_oom, __core_pd_sel, ec_sel, Mtd(0),
|
||||
reinterpret_cast<addr_t>(_oom_handler),
|
||||
@ -866,7 +869,7 @@ Pager_capability Pager_entrypoint::manage(Pager_object *obj)
|
||||
PWRN("invalid CPU parameter used in pager object");
|
||||
return Pager_capability();
|
||||
}
|
||||
Native_capability pager_thread_cap(pager_threads[use_cpu]->tid().ec_sel);
|
||||
Native_capability pager_thread_cap(pager_threads[use_cpu]->native_thread().ec_sel);
|
||||
|
||||
/* request creation of portal bind to pager thread */
|
||||
Native_capability cap_session =
|
||||
|
@ -42,23 +42,23 @@ void Thread_base::_init_platform_thread(size_t, Type type)
|
||||
if (type == MAIN)
|
||||
{
|
||||
/* set EC selector according to NOVA spec */
|
||||
_tid.ec_sel = Platform_pd::pd_core_sel() + 1;
|
||||
native_thread().ec_sel = Platform_pd::pd_core_sel() + 1;
|
||||
|
||||
/*
|
||||
* Exception base of first thread in core is 0. We have to set
|
||||
* it here so that Thread_base code finds the semaphore of the
|
||||
* main thread.
|
||||
*/
|
||||
_tid.exc_pt_sel = 0;
|
||||
native_thread().exc_pt_sel = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
_tid.ec_sel = cap_map()->insert(1);
|
||||
_tid.exc_pt_sel = cap_map()->insert(NUM_INITIAL_PT_LOG2);
|
||||
native_thread().ec_sel = cap_map()->insert(1);
|
||||
native_thread().exc_pt_sel = cap_map()->insert(NUM_INITIAL_PT_LOG2);
|
||||
addr_t pd_sel = Platform_pd::pd_core_sel();
|
||||
|
||||
/* create running semaphore required for locking */
|
||||
addr_t rs_sel =_tid.exc_pt_sel + SM_SEL_EC;
|
||||
addr_t rs_sel =native_thread().exc_pt_sel + SM_SEL_EC;
|
||||
uint8_t res = create_sm(rs_sel, pd_sel, 0);
|
||||
if (res != NOVA_OK) {
|
||||
PERR("create_sm returned %u", res);
|
||||
@ -69,11 +69,11 @@ void Thread_base::_init_platform_thread(size_t, Type type)
|
||||
|
||||
void Thread_base::_deinit_platform_thread()
|
||||
{
|
||||
unmap_local(Nova::Obj_crd(_tid.ec_sel, 1));
|
||||
unmap_local(Nova::Obj_crd(_tid.exc_pt_sel, Nova::NUM_INITIAL_PT_LOG2));
|
||||
unmap_local(Nova::Obj_crd(native_thread().ec_sel, 1));
|
||||
unmap_local(Nova::Obj_crd(native_thread().exc_pt_sel, Nova::NUM_INITIAL_PT_LOG2));
|
||||
|
||||
cap_map()->remove(_tid.ec_sel, 1, false);
|
||||
cap_map()->remove(_tid.exc_pt_sel, Nova::NUM_INITIAL_PT_LOG2, false);
|
||||
cap_map()->remove(native_thread().ec_sel, 1, false);
|
||||
cap_map()->remove(native_thread().exc_pt_sel, Nova::NUM_INITIAL_PT_LOG2, false);
|
||||
|
||||
/* revoke utcb */
|
||||
Nova::Rights rwx(true, true, true);
|
||||
@ -106,8 +106,8 @@ void Thread_base::start()
|
||||
|
||||
/* create local EC */
|
||||
enum { LOCAL_THREAD = false };
|
||||
uint8_t res = create_ec(_tid.ec_sel, pd_sel, location.xpos(),
|
||||
utcb, sp, _tid.exc_pt_sel, LOCAL_THREAD);
|
||||
uint8_t res = create_ec(native_thread().ec_sel, pd_sel, location.xpos(),
|
||||
utcb, sp, native_thread().exc_pt_sel, LOCAL_THREAD);
|
||||
if (res != NOVA_OK) {
|
||||
PERR("create_ec returned %d cpu=%u", res, location.xpos());
|
||||
throw Cpu_session::Thread_creation_failed();
|
||||
@ -119,7 +119,7 @@ void Thread_base::start()
|
||||
|
||||
if (map_local(reinterpret_cast<Nova::Utcb *>(Thread_base::myself()->utcb()),
|
||||
Obj_crd(PT_SEL_PAGE_FAULT, 0),
|
||||
Obj_crd(_tid.exc_pt_sel + PT_SEL_PAGE_FAULT, 0))) {
|
||||
Obj_crd(native_thread().exc_pt_sel + PT_SEL_PAGE_FAULT, 0))) {
|
||||
PERR("could not create page fault portal");
|
||||
throw Cpu_session::Thread_creation_failed();
|
||||
}
|
||||
@ -130,6 +130,6 @@ void Thread_base::cancel_blocking()
|
||||
{
|
||||
using namespace Nova;
|
||||
|
||||
if (sm_ctrl(_tid.exc_pt_sel + SM_SEL_EC, SEMAPHORE_UP))
|
||||
if (sm_ctrl(native_thread().exc_pt_sel + SM_SEL_EC, SEMAPHORE_UP))
|
||||
nova_die();
|
||||
}
|
||||
|
@ -23,6 +23,9 @@
|
||||
#include <base/thread.h>
|
||||
#include <base/stdint.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/native_thread.h>
|
||||
|
||||
/* NOVA includes */
|
||||
#include <nova/syscalls.h>
|
||||
#include <nova/util.h>
|
||||
@ -34,7 +37,7 @@ extern int main_thread_running_semaphore();
|
||||
static inline bool thread_check_stopped_and_restart(Genode::Thread_base *thread_base)
|
||||
{
|
||||
Genode::addr_t sem = thread_base ?
|
||||
thread_base->tid().exc_pt_sel + Nova::SM_SEL_EC :
|
||||
thread_base->native_thread().exc_pt_sel + Nova::SM_SEL_EC :
|
||||
main_thread_running_semaphore();
|
||||
|
||||
Nova::sm_ctrl(sem, Nova::SEMAPHORE_UP);
|
||||
@ -53,7 +56,7 @@ static inline void thread_stop_myself()
|
||||
addr_t sem;
|
||||
Thread_base *myself = Thread_base::myself();
|
||||
if (myself)
|
||||
sem = myself->tid().exc_pt_sel + SM_SEL_EC;
|
||||
sem = myself->native_thread().exc_pt_sel + SM_SEL_EC;
|
||||
else
|
||||
sem = main_thread_running_semaphore();
|
||||
|
||||
|
14
repos/base-nova/src/include/base/internal/native_thread.h
Normal file
14
repos/base-nova/src/include/base/internal/native_thread.h
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* \brief Kernel-specific thread meta data
|
||||
* \author Norman Feske
|
||||
* \date 2016-03-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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 <nova/native_thread.h>
|
@ -35,7 +35,7 @@ static inline void spinlock_lock(volatile T *lock_variable)
|
||||
using Genode::cmpxchg;
|
||||
|
||||
Genode::Thread_base * myself = Genode::Thread_base::myself();
|
||||
T const tid = myself ? myself->tid().ec_sel : Nova::PT_SEL_MAIN_EC;
|
||||
T const tid = myself ? myself->native_thread().ec_sel : Nova::PT_SEL_MAIN_EC;
|
||||
|
||||
unsigned help_counter = 0;
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <os/config.h>
|
||||
|
||||
#include <trace/timestamp.h>
|
||||
#include <nova/native_thread.h>
|
||||
|
||||
#include "server.h"
|
||||
|
||||
@ -199,7 +200,7 @@ class Greedy : public Thread<4096> {
|
||||
Nova::Utcb * nova_utcb = reinterpret_cast<Nova::Utcb *>(utcb());
|
||||
Nova::Rights const mapping_rwx(true, true, true);
|
||||
|
||||
addr_t const page_fault_portal = tid().exc_pt_sel + 14;
|
||||
addr_t const page_fault_portal = native_thread().exc_pt_sel + 14;
|
||||
|
||||
PERR("cause mappings in range [0x%lx, 0x%lx) %p", mem,
|
||||
mem + SUB_RM_SIZE - 1, &mem);
|
||||
@ -268,7 +269,7 @@ int main(int argc, char **argv)
|
||||
return -__LINE__;
|
||||
|
||||
addr_t sel_pd = cap_map()->insert();
|
||||
addr_t sel_ec = myself->tid().ec_sel;
|
||||
addr_t sel_ec = myself->native_thread().ec_sel;
|
||||
addr_t sel_cap = cap_map()->insert();
|
||||
addr_t handler = 0UL;
|
||||
uint8_t res = 0;
|
||||
@ -287,7 +288,7 @@ int main(int argc, char **argv)
|
||||
|
||||
/* changing the badge of one of the portal must fail */
|
||||
for (unsigned i = 0; i < (1U << Nova::NUM_INITIAL_PT_LOG2); i++) {
|
||||
addr_t sel_exc = myself->tid().exc_pt_sel + i;
|
||||
addr_t sel_exc = myself->native_thread().exc_pt_sel + i;
|
||||
res = Nova::pt_ctrl(sel_exc, 0xbadbad);
|
||||
check(res, "pt_ctrl %2u", i);
|
||||
}
|
||||
|
@ -23,27 +23,12 @@ namespace Okl4 { extern "C" {
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Platform_thread;
|
||||
|
||||
/**
|
||||
* Index of the UTCB's thread word used for storing the own global
|
||||
* thread ID
|
||||
*/
|
||||
enum { UTCB_TCR_THREAD_WORD_MYSELF = 0 };
|
||||
|
||||
struct Native_thread
|
||||
{
|
||||
Okl4::L4_ThreadId_t l4id;
|
||||
|
||||
/**
|
||||
* Only used in core
|
||||
*
|
||||
* For 'Thread' objects created within core, 'pt' points to
|
||||
* the physical thread object, which is going to be destroyed
|
||||
* on destruction of the 'Thread'.
|
||||
*/
|
||||
Platform_thread *pt;
|
||||
};
|
||||
|
||||
struct Cap_dst_policy
|
||||
{
|
||||
|
@ -16,14 +16,14 @@
|
||||
#include <base/thread.h>
|
||||
#include <base/env.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/native_thread.h>
|
||||
|
||||
/* OKL4 includes */
|
||||
namespace Okl4
|
||||
{
|
||||
extern "C" {
|
||||
#include <l4/utcb.h>
|
||||
#include <l4/thread.h>
|
||||
}
|
||||
}
|
||||
namespace Okl4 { extern "C" {
|
||||
#include <l4/utcb.h>
|
||||
#include <l4/thread.h>
|
||||
} }
|
||||
|
||||
Okl4::L4_ThreadId_t main_thread_tid;
|
||||
|
||||
@ -75,13 +75,13 @@ void prepare_reinit_main_thread() { prepare_init_main_thread(); }
|
||||
|
||||
void Genode::Thread_base::_thread_bootstrap()
|
||||
{
|
||||
_tid.l4id.raw = Okl4::copy_uregister_to_utcb();
|
||||
native_thread().l4id.raw = Okl4::copy_uregister_to_utcb();
|
||||
}
|
||||
|
||||
|
||||
void Genode::Thread_base::_init_platform_thread(size_t, Type type)
|
||||
{
|
||||
if (type == NORMAL) { return; }
|
||||
_tid.l4id.raw = main_thread_tid.raw;
|
||||
native_thread().l4id.raw = main_thread_tid.raw;
|
||||
_thread_cap = env()->parent()->main_thread_cap();
|
||||
}
|
||||
|
@ -19,6 +19,9 @@
|
||||
#include <pager.h>
|
||||
#include <platform_thread.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/native_thread.h>
|
||||
|
||||
namespace Okl4 { extern "C" {
|
||||
#include <l4/message.h>
|
||||
#include <l4/ipc.h>
|
||||
@ -152,5 +155,5 @@ void Ipc_pager::acknowledge_wakeup()
|
||||
|
||||
Untyped_capability Pager_entrypoint::_pager_object_cap(unsigned long badge)
|
||||
{
|
||||
return Untyped_capability(_tid.l4id, badge);
|
||||
return Untyped_capability(native_thread().l4id, badge);
|
||||
}
|
||||
|
@ -37,13 +37,13 @@ void Thread_base::_thread_start()
|
||||
void Thread_base::start()
|
||||
{
|
||||
/* create and start platform thread */
|
||||
_tid.pt = new(platform_specific()->thread_slab())
|
||||
native_thread().pt = new(platform_specific()->thread_slab())
|
||||
Platform_thread(0, _stack->name().string());
|
||||
|
||||
if (platform_specific()->core_pd()->bind_thread(_tid.pt))
|
||||
if (platform_specific()->core_pd()->bind_thread(native_thread().pt))
|
||||
throw Cpu_session::Thread_creation_failed();
|
||||
|
||||
_tid.pt->start((void *)_thread_start, stack_top());
|
||||
native_thread().pt->start((void *)_thread_start, stack_top());
|
||||
}
|
||||
|
||||
|
||||
@ -58,5 +58,5 @@ void Thread_base::cancel_blocking()
|
||||
void Thread_base::_deinit_platform_thread()
|
||||
{
|
||||
/* destruct platform thread */
|
||||
destroy(platform_specific()->thread_slab(), _tid.pt);
|
||||
destroy(platform_specific()->thread_slab(), native_thread().pt);
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ static inline bool thread_check_stopped_and_restart(Genode::Thread_base *thread_
|
||||
L4_ThreadState_t state;
|
||||
|
||||
Okl4::L4_ThreadId_t tid = thread_base ?
|
||||
thread_base->tid().l4id :
|
||||
thread_base->native_thread().l4id :
|
||||
main_thread_tid;
|
||||
|
||||
L4_ExchangeRegisters(tid, L4_ExReg_Resume + L4_ExReg_AbortIPC, 0, 0, 0,
|
||||
@ -72,7 +72,7 @@ static inline bool thread_check_stopped_and_restart(Genode::Thread_base *thread_
|
||||
static inline void thread_switch_to(Genode::Thread_base *thread_base)
|
||||
{
|
||||
Okl4::L4_ThreadId_t tid = thread_base ?
|
||||
thread_base->tid().l4id :
|
||||
thread_base->native_thread().l4id :
|
||||
main_thread_tid;
|
||||
Okl4::L4_ThreadSwitch(tid);
|
||||
}
|
||||
@ -85,7 +85,7 @@ static inline void thread_stop_myself()
|
||||
{
|
||||
Genode::Thread_base *myself = Genode::Thread_base::myself();
|
||||
Okl4::L4_ThreadId_t tid = myself ?
|
||||
myself->tid().l4id :
|
||||
myself->native_thread().l4id :
|
||||
main_thread_tid;
|
||||
Okl4::L4_Stop(tid);
|
||||
}
|
||||
|
46
repos/base-okl4/src/include/base/internal/native_thread.h
Normal file
46
repos/base-okl4/src/include/base/internal/native_thread.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* \brief Kernel-specific thread meta data
|
||||
* \author Norman Feske
|
||||
* \date 2016-03-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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__INTERNAL__NATIVE_THREAD_H_
|
||||
#define _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/stdint.h>
|
||||
|
||||
/* OKL4 includes */
|
||||
namespace Okl4 { extern "C" {
|
||||
#include <l4/types.h>
|
||||
} }
|
||||
|
||||
namespace Genode {
|
||||
|
||||
struct Native_thread;
|
||||
class Platform_thread;
|
||||
}
|
||||
|
||||
|
||||
struct Genode::Native_thread
|
||||
{
|
||||
Okl4::L4_ThreadId_t l4id;
|
||||
|
||||
/**
|
||||
* Only used in core
|
||||
*
|
||||
* For 'Thread' objects created within core, 'pt' points to
|
||||
* the physical thread object, which is going to be destroyed
|
||||
* on destruction of the 'Thread'.
|
||||
*/
|
||||
Platform_thread *pt;
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_ */
|
@ -23,8 +23,6 @@ namespace Pistachio {
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Platform_thread;
|
||||
|
||||
struct Cap_dst_policy
|
||||
{
|
||||
typedef Pistachio::L4_ThreadId_t Dst;
|
||||
@ -37,20 +35,6 @@ namespace Genode {
|
||||
static void copy(void* dst, Native_capability_tpl<Cap_dst_policy>* src);
|
||||
};
|
||||
|
||||
struct Native_thread
|
||||
{
|
||||
Pistachio::L4_ThreadId_t l4id;
|
||||
|
||||
/**
|
||||
* Only used in core
|
||||
*
|
||||
* For 'Thread' objects created within core, 'pt' points to
|
||||
* the physical thread object, which is going to be destroyed
|
||||
* on destruction of the 'Thread'.
|
||||
*/
|
||||
Platform_thread *pt;
|
||||
};
|
||||
|
||||
typedef Native_capability_tpl<Cap_dst_policy> Native_capability;
|
||||
|
||||
typedef Pistachio::L4_ThreadId_t Native_connection_state;
|
||||
|
@ -15,6 +15,9 @@
|
||||
#include <base/thread.h>
|
||||
#include <base/env.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/native_thread.h>
|
||||
|
||||
/* Pistachio includes */
|
||||
namespace Pistachio {
|
||||
#include <l4/thread.h>
|
||||
@ -41,13 +44,13 @@ void prepare_reinit_main_thread() { prepare_init_main_thread(); }
|
||||
|
||||
void Genode::Thread_base::_thread_bootstrap()
|
||||
{
|
||||
_tid.l4id = Pistachio::L4_Myself();
|
||||
native_thread().l4id = Pistachio::L4_Myself();
|
||||
}
|
||||
|
||||
|
||||
void Genode::Thread_base::_init_platform_thread(size_t, Type type)
|
||||
{
|
||||
if (type == NORMAL) { return; }
|
||||
_tid.l4id = main_thread_tid;
|
||||
native_thread().l4id = main_thread_tid;
|
||||
_thread_cap = env()->parent()->main_thread_cap();
|
||||
}
|
||||
|
@ -15,6 +15,9 @@
|
||||
#include <base/printf.h>
|
||||
#include <base/sleep.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/native_thread.h>
|
||||
|
||||
/* Core includes */
|
||||
#include <ipc_pager.h>
|
||||
#include <pager.h>
|
||||
@ -142,5 +145,5 @@ void Ipc_pager::acknowledge_wakeup()
|
||||
|
||||
Untyped_capability Pager_entrypoint::_pager_object_cap(unsigned long badge)
|
||||
{
|
||||
return Untyped_capability(_tid.l4id, badge);
|
||||
return Untyped_capability(native_thread().l4id, badge);
|
||||
}
|
||||
|
@ -37,15 +37,15 @@ void Thread_base::_thread_start()
|
||||
void Thread_base::start()
|
||||
{
|
||||
/* create and start platform thread */
|
||||
_tid.pt = new(platform()->core_mem_alloc())
|
||||
native_thread().pt = new(platform()->core_mem_alloc())
|
||||
Platform_thread(0, _stack->name().string());
|
||||
|
||||
platform_specific()->core_pd()->bind_thread(_tid.pt);
|
||||
platform_specific()->core_pd()->bind_thread(native_thread().pt);
|
||||
|
||||
_tid.pt->pager(platform_specific()->core_pager());
|
||||
_tid.l4id = _tid.pt->native_thread_id();
|
||||
native_thread().pt->pager(platform_specific()->core_pager());
|
||||
native_thread().l4id = native_thread().pt->native_thread_id();
|
||||
|
||||
_tid.pt->start((void *)_thread_start, stack_top());
|
||||
native_thread().pt->start((void *)_thread_start, stack_top());
|
||||
}
|
||||
|
||||
|
||||
@ -60,5 +60,5 @@ void Thread_base::cancel_blocking()
|
||||
void Thread_base::_deinit_platform_thread()
|
||||
{
|
||||
/* destruct platform thread */
|
||||
destroy(platform()->core_mem_alloc(), _tid.pt);
|
||||
destroy(platform()->core_mem_alloc(), native_thread().pt);
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ static inline bool thread_check_stopped_and_restart(Genode::Thread_base *thread_
|
||||
L4_ThreadState_t state;
|
||||
|
||||
Pistachio::L4_ThreadId_t tid = thread_base ?
|
||||
thread_base->tid().l4id :
|
||||
thread_base->native_thread().l4id :
|
||||
main_thread_tid;
|
||||
|
||||
enum { RESUME = 1 << 8, CANCEL_IPC = 3 << 1 };
|
||||
@ -73,7 +73,7 @@ static inline bool thread_check_stopped_and_restart(Genode::Thread_base *thread_
|
||||
static inline void thread_switch_to(Genode::Thread_base *thread_base)
|
||||
{
|
||||
Pistachio::L4_ThreadId_t tid = thread_base ?
|
||||
thread_base->tid().l4id :
|
||||
thread_base->native_thread().l4id :
|
||||
main_thread_tid;
|
||||
Pistachio::L4_ThreadSwitch(tid);
|
||||
}
|
||||
@ -86,7 +86,7 @@ static inline void thread_stop_myself()
|
||||
{
|
||||
Genode::Thread_base *myself = Genode::Thread_base::myself();
|
||||
Pistachio::L4_ThreadId_t tid = myself ?
|
||||
myself->tid().l4id :
|
||||
myself->native_thread().l4id :
|
||||
main_thread_tid;
|
||||
Pistachio::L4_Stop(tid);
|
||||
}
|
||||
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* \brief Kernel-specific thread meta data
|
||||
* \author Norman Feske
|
||||
* \date 2016-03-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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__INTERNAL__NATIVE_THREAD_H_
|
||||
#define _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/stdint.h>
|
||||
|
||||
/* Pistachio includes */
|
||||
namespace Pistachio {
|
||||
#include <l4/types.h>
|
||||
}
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Platform_thread;
|
||||
struct Native_thread;
|
||||
}
|
||||
|
||||
|
||||
struct Genode::Native_thread
|
||||
{
|
||||
Pistachio::L4_ThreadId_t l4id;
|
||||
|
||||
/**
|
||||
* Only used in core
|
||||
*
|
||||
* For 'Thread' objects created within core, 'pt' points to
|
||||
* the physical thread object, which is going to be destroyed
|
||||
* on destruction of the 'Thread'.
|
||||
*/
|
||||
Platform_thread *pt;
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_ */
|
@ -19,13 +19,6 @@
|
||||
|
||||
namespace Genode {
|
||||
|
||||
struct Native_thread
|
||||
{
|
||||
unsigned tcb_sel = 0;
|
||||
unsigned ep_sel = 0;
|
||||
unsigned rcv_sel = 0;
|
||||
};
|
||||
|
||||
class Native_capability
|
||||
{
|
||||
public:
|
||||
|
@ -14,6 +14,7 @@
|
||||
/* base includes */
|
||||
#include <base/native_types.h>
|
||||
#include <base/printf.h>
|
||||
#include <util/bit_allocator.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/capability_data.h>
|
||||
@ -94,7 +95,7 @@ namespace {
|
||||
|
||||
Native_capability Capability_space::create_ep_cap(Thread_base &ep_thread)
|
||||
{
|
||||
Cap_sel const ep_sel = Cap_sel(ep_thread.tid().ep_sel);
|
||||
Cap_sel const ep_sel = Cap_sel(ep_thread.native_thread().ep_sel);
|
||||
|
||||
Native_capability::Data &data =
|
||||
local_capability_space().create_capability(ep_sel, Rpc_obj_key());
|
||||
|
@ -44,13 +44,13 @@ enum {
|
||||
static unsigned &rcv_sel()
|
||||
{
|
||||
/*
|
||||
* When the function is called at the very early initialization phase,
|
||||
* we cannot access Thread_base::myself()->tid() because the Thread_base
|
||||
* object of the main thread does not exist yet. During this phase, we
|
||||
* return a reference to the 'main_rcv_sel' variable.
|
||||
* When the function is called at the very early initialization phase, we
|
||||
* cannot access Thread_base::myself()->native_thread() because the
|
||||
* Thread_base object of the main thread does not exist yet. During this
|
||||
* phase, we return a reference to the 'main_rcv_sel' variable.
|
||||
*/
|
||||
if (Thread_base::myself()) {
|
||||
return Thread_base::myself()->tid().rcv_sel;
|
||||
return Thread_base::myself()->native_thread().rcv_sel;
|
||||
}
|
||||
|
||||
static unsigned main_rcv_sel = Capability_space::alloc_rcv_sel();
|
||||
@ -374,7 +374,7 @@ void Ipc_server::_wait()
|
||||
{
|
||||
seL4_Word badge = Rpc_obj_key::INVALID;
|
||||
seL4_MessageInfo_t const msg_info =
|
||||
seL4_Recv(Thread_base::myself()->tid().ep_sel, &badge);
|
||||
seL4_Recv(Thread_base::myself()->native_thread().ep_sel, &badge);
|
||||
|
||||
decode_seL4_message(badge, msg_info, *_rcv_msg);
|
||||
|
||||
@ -401,7 +401,7 @@ void Ipc_server::_reply_wait()
|
||||
new_seL4_message(*_snd_msg, _write_offset);
|
||||
|
||||
seL4_MessageInfo_t const request_msg_info =
|
||||
seL4_ReplyRecv(Thread_base::myself()->tid().ep_sel,
|
||||
seL4_ReplyRecv(Thread_base::myself()->native_thread().ep_sel,
|
||||
reply_msg_info, &badge);
|
||||
|
||||
decode_seL4_message(badge, request_msg_info, *_rcv_msg);
|
||||
|
@ -34,7 +34,7 @@ void prepare_reinit_main_thread() { prepare_init_main_thread(); }
|
||||
|
||||
void Genode::Thread_base::_thread_bootstrap()
|
||||
{
|
||||
if (tid().ep_sel == 0) {
|
||||
tid().ep_sel = _stack->utcb().ep_sel;
|
||||
if (native_thread().ep_sel == 0) {
|
||||
native_thread().ep_sel = _stack->utcb().ep_sel;
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ Capability_space::create_rpc_obj_cap(Native_capability ep_cap,
|
||||
|
||||
Native_capability Capability_space::create_ep_cap(Thread_base &ep_thread)
|
||||
{
|
||||
Cap_sel const ep_sel(ep_thread.tid().ep_sel);
|
||||
Cap_sel const ep_sel(ep_thread.native_thread().ep_sel);
|
||||
|
||||
/* entrypoint capabilities are not allocated from a PD session */
|
||||
Pd_session const *pd_session = nullptr;
|
||||
|
@ -74,11 +74,11 @@ void Ipc_pager::reply_and_wait_for_fault()
|
||||
seL4_MessageInfo_t const reply_msg = seL4_MessageInfo_new(0, 0, 0, 0);
|
||||
|
||||
page_fault_msg_info =
|
||||
seL4_ReplyRecv(Thread_base::myself()->tid().ep_sel, reply_msg, &badge);
|
||||
seL4_ReplyRecv(Thread_base::myself()->native_thread().ep_sel, reply_msg, &badge);
|
||||
|
||||
} else {
|
||||
page_fault_msg_info =
|
||||
seL4_Recv(Thread_base::myself()->tid().ep_sel, &badge);
|
||||
seL4_Recv(Thread_base::myself()->native_thread().ep_sel, &badge);
|
||||
}
|
||||
|
||||
Fault_info const fault_info(page_fault_msg_info);
|
||||
|
@ -32,7 +32,7 @@ void Thread_base::_init_platform_thread(size_t, Type type)
|
||||
addr_t const utcb_virt_addr = (addr_t)&_stack->utcb();
|
||||
|
||||
if (type == MAIN) {
|
||||
_tid.tcb_sel = seL4_CapInitThreadTCB;
|
||||
native_thread().tcb_sel = seL4_CapInitThreadTCB;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -44,13 +44,13 @@ void Thread_base::_init_platform_thread(size_t, Type type)
|
||||
thread_info.ipc_buffer_phys, utcb_virt_addr);
|
||||
}
|
||||
|
||||
_tid.tcb_sel = thread_info.tcb_sel.value();
|
||||
_tid.ep_sel = thread_info.ep_sel.value();
|
||||
native_thread().tcb_sel = thread_info.tcb_sel.value();
|
||||
native_thread().ep_sel = thread_info.ep_sel.value();
|
||||
|
||||
Platform &platform = *platform_specific();
|
||||
|
||||
seL4_CapData_t no_cap_data = { { 0 } };
|
||||
int const ret = seL4_TCB_SetSpace(_tid.tcb_sel, 0,
|
||||
int const ret = seL4_TCB_SetSpace(native_thread().tcb_sel, 0,
|
||||
platform.top_cnode().sel().value(), no_cap_data,
|
||||
seL4_CapInitThreadPD, no_cap_data);
|
||||
ASSERT(ret == 0);
|
||||
@ -74,7 +74,7 @@ void Thread_base::_thread_start()
|
||||
|
||||
void Thread_base::start()
|
||||
{
|
||||
start_sel4_thread(Cap_sel(_tid.tcb_sel), (addr_t)&_thread_start,
|
||||
start_sel4_thread(Cap_sel(native_thread().tcb_sel), (addr_t)&_thread_start,
|
||||
(addr_t)stack_top());
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,9 @@
|
||||
/* base includes */
|
||||
#include <base/thread.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/native_thread.h>
|
||||
|
||||
/* seL4 includes */
|
||||
#include <sel4/sel4.h>
|
||||
|
||||
@ -31,7 +34,7 @@ static inline void kernel_debugger_panic(char const *msg)
|
||||
{
|
||||
kernel_debugger_outstring(msg);
|
||||
kernel_debugger_outstring("\n");
|
||||
seL4_TCB_Suspend(Genode::Thread_base::myself()->tid().tcb_sel);
|
||||
seL4_TCB_Suspend(Genode::Thread_base::myself()->native_thread().tcb_sel);
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__BASE__INTERNAL__KERNEL_DEBUGGER_H_ */
|
||||
|
28
repos/base-sel4/src/include/base/internal/native_thread.h
Normal file
28
repos/base-sel4/src/include/base/internal/native_thread.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* \brief Kernel-specific thread meta data
|
||||
* \author Norman Feske
|
||||
* \date 2016-03-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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__INTERNAL__NATIVE_THREAD_H_
|
||||
#define _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_
|
||||
|
||||
#include <base/stdint.h>
|
||||
|
||||
namespace Genode { struct Native_thread; }
|
||||
|
||||
struct Genode::Native_thread
|
||||
{
|
||||
unsigned tcb_sel = 0;
|
||||
unsigned ep_sel = 0;
|
||||
unsigned rcv_sel = 0;
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__BASE__INTERNAL__NATIVE_THREAD_H_ */
|
@ -17,19 +17,15 @@
|
||||
/* Genode includes */
|
||||
#include <base/exception.h>
|
||||
#include <base/lock.h>
|
||||
#include <base/native_types.h>
|
||||
#include <base/trace/logger.h>
|
||||
#include <cpu/consts.h>
|
||||
#include <util/string.h>
|
||||
#include <util/bit_allocator.h>
|
||||
#include <ram_session/ram_session.h> /* for 'Ram_dataspace_capability' type */
|
||||
#include <cpu_session/cpu_session.h> /* for 'Thread_capability' type */
|
||||
#include <cpu_session/capability.h> /* for 'Cpu_session_capability' type */
|
||||
|
||||
namespace Genode {
|
||||
|
||||
struct Native_utcb;
|
||||
class Rm_session;
|
||||
struct Native_thread;
|
||||
class Thread_base;
|
||||
class Stack;
|
||||
template <unsigned> class Thread;
|
||||
@ -37,7 +33,7 @@ namespace Genode {
|
||||
|
||||
|
||||
/**
|
||||
* Concurrent control flow
|
||||
* Concurrent flow of control
|
||||
*
|
||||
* A 'Thread_base' object corresponds to a physical thread. The execution
|
||||
* starts at the 'entry()' method as soon as 'start()' is called.
|
||||
@ -91,37 +87,37 @@ class Genode::Thread_base
|
||||
*
|
||||
* Used if thread creation involves core's CPU service.
|
||||
*/
|
||||
Genode::Thread_capability _thread_cap;
|
||||
Thread_capability _thread_cap;
|
||||
|
||||
/**
|
||||
* Capability to pager paging this thread (created by _start())
|
||||
*/
|
||||
Genode::Pager_capability _pager_cap;
|
||||
Pager_capability _pager_cap;
|
||||
|
||||
/**
|
||||
* Pointer to cpu session used for this thread
|
||||
*/
|
||||
Genode::Cpu_session *_cpu_session;
|
||||
Cpu_session *_cpu_session = nullptr;
|
||||
|
||||
/**
|
||||
* Base pointer to Trace::Control area used by this thread
|
||||
*/
|
||||
Trace::Control *_trace_control;
|
||||
Trace::Control *_trace_control = nullptr;
|
||||
|
||||
/**
|
||||
* Pointer to primary stack
|
||||
*/
|
||||
Stack *_stack;
|
||||
Stack *_stack = nullptr;
|
||||
|
||||
/**
|
||||
* Physical thread ID
|
||||
* Pointer to kernel-specific meta data
|
||||
*/
|
||||
Native_thread _tid;
|
||||
Native_thread *_native_thread = nullptr;
|
||||
|
||||
/**
|
||||
* Lock used for synchronizing the finalization of the thread
|
||||
*/
|
||||
Genode::Lock _join_lock;
|
||||
Lock _join_lock;
|
||||
|
||||
/**
|
||||
* Thread type
|
||||
@ -253,7 +249,7 @@ class Genode::Thread_base
|
||||
/**
|
||||
* Request capability of thread
|
||||
*/
|
||||
Genode::Thread_capability cap() const { return _thread_cap; }
|
||||
Thread_capability cap() const { return _thread_cap; }
|
||||
|
||||
/**
|
||||
* Cancel currently blocking operation
|
||||
@ -261,11 +257,9 @@ class Genode::Thread_base
|
||||
void cancel_blocking();
|
||||
|
||||
/**
|
||||
* Return thread ID
|
||||
*
|
||||
* \noapi Only to be called from platform-specific code
|
||||
* Return kernel-specific thread meta data
|
||||
*/
|
||||
Native_thread & tid() { return _tid; }
|
||||
Native_thread &native_thread();
|
||||
|
||||
/**
|
||||
* Return top of stack
|
||||
|
@ -174,6 +174,9 @@ void Thread_base::free_secondary_stack(void* stack_addr)
|
||||
}
|
||||
|
||||
|
||||
Native_thread &Thread_base::native_thread() { return _stack->native_thread(); }
|
||||
|
||||
|
||||
void *Thread_base::stack_top() const { return (void *)_stack->top(); }
|
||||
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <cpu/memory_barrier.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/native_thread.h>
|
||||
#include <base/internal/lock_helper.h>
|
||||
|
||||
/*
|
||||
|
@ -61,6 +61,7 @@
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/native_utcb.h>
|
||||
#include <base/internal/native_thread.h>
|
||||
|
||||
namespace Genode { class Stack; }
|
||||
|
||||
@ -112,6 +113,11 @@ class Genode::Stack
|
||||
*/
|
||||
Ram_dataspace_capability _ds_cap;
|
||||
|
||||
/**
|
||||
* Kernel-specific thread meta data
|
||||
*/
|
||||
Native_thread _native_thread;
|
||||
|
||||
/*
|
||||
* <- end of regular memory area
|
||||
*
|
||||
@ -157,6 +163,11 @@ class Genode::Stack
|
||||
*/
|
||||
void size(size_t const size);
|
||||
|
||||
/**
|
||||
* Return kernel-specific thread meta data
|
||||
*/
|
||||
Native_thread &native_thread() { return _native_thread; }
|
||||
|
||||
/**
|
||||
* Return UTCB of the stack's thread
|
||||
*/
|
||||
|
@ -14,6 +14,9 @@
|
||||
#ifndef _INCLUDE__BASE__INTERNAL__STACK_ALLOCATOR_H_
|
||||
#define _INCLUDE__BASE__INTERNAL__STACK_ALLOCATOR_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/bit_allocator.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/stack.h>
|
||||
#include <base/internal/stack_area.h>
|
||||
|
@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/bit_allocator.h>
|
||||
#include <base/printf.h>
|
||||
#include <os/attached_io_mem_dataspace.h>
|
||||
#include <os/config.h>
|
||||
|
@ -23,6 +23,8 @@
|
||||
#include <util/flex_iterator.h>
|
||||
#include <util/retry.h>
|
||||
|
||||
#include <nova/native_thread.h>
|
||||
|
||||
#include "../pci_device_pd_ipc.h"
|
||||
|
||||
/**
|
||||
@ -77,7 +79,7 @@ static bool map_eager(Genode::addr_t const page, unsigned log2_order)
|
||||
Nova::Utcb * utcb = reinterpret_cast<Nova::Utcb *>(myself->utcb());
|
||||
Nova::Rights const mapping_rw(true, true, false);
|
||||
|
||||
addr_t const page_fault_portal = myself->tid().exc_pt_sel + 14;
|
||||
addr_t const page_fault_portal = myself->native_thread().exc_pt_sel + 14;
|
||||
|
||||
/* setup faked page fault information */
|
||||
utcb->set_msg_word(((addr_t)&utcb->qual[2] - (addr_t)utcb->msg) / sizeof(addr_t));
|
||||
|
@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/bit_allocator.h>
|
||||
#include <base/printf.h>
|
||||
#include <irq_session/connection.h>
|
||||
|
||||
|
@ -11,8 +11,10 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef _X86_PCI_CONFIG_ACCESS_H_
|
||||
#define _X86_PCI_CONFIG_ACCESS_H_
|
||||
|
||||
#include <util/bit_array.h>
|
||||
#include <io_port_session/connection.h>
|
||||
#include <platform_device/platform_device.h>
|
||||
|
||||
@ -177,3 +179,5 @@ namespace Platform {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _X86_PCI_CONFIG_ACCESS_H_ */
|
||||
|
@ -19,6 +19,9 @@
|
||||
#include <os/server.h>
|
||||
#include <trace/timestamp.h>
|
||||
|
||||
/* NOVA includes */
|
||||
#include <nova/native_thread.h>
|
||||
|
||||
class Platform_timer
|
||||
{
|
||||
private:
|
||||
@ -102,7 +105,7 @@ class Platform_timer
|
||||
using namespace Nova;
|
||||
|
||||
if (_sem == ~0UL)
|
||||
_sem = blocking_thread->tid().exc_pt_sel + SM_SEL_EC;
|
||||
_sem = blocking_thread->native_thread().exc_pt_sel + SM_SEL_EC;
|
||||
|
||||
addr_t sem = _sem;
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <base/cap_map.h>
|
||||
#include <foc_cpu_session/connection.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <foc/native_thread.h>
|
||||
|
||||
namespace Fiasco {
|
||||
#include <l4/sys/utcb.h>
|
||||
@ -64,7 +65,7 @@ namespace L4lx {
|
||||
start();
|
||||
|
||||
/* set l4linux specific utcb entry: L4X_UTCB_TCR_ID */
|
||||
l4_utcb_tcr_u(_utcb)->user[0] = tid().kcap;
|
||||
l4_utcb_tcr_u(_utcb)->user[0] = native_thread().kcap;
|
||||
|
||||
/* enable vcpu functionality respectively */
|
||||
if (_vcpu_state)
|
||||
|
@ -212,7 +212,7 @@ l4_cap_idx_t l4lx_thread_get_cap(l4lx_thread_t t)
|
||||
PWRN("Invalid utcb %lx", (unsigned long) t);
|
||||
return L4_INVALID_CAP;
|
||||
}
|
||||
return vcpus[thread_id(t)]->tid().kcap;
|
||||
return vcpus[thread_id(t)]->native_thread().kcap;
|
||||
}
|
||||
|
||||
|
||||
|
@ -80,7 +80,7 @@ class Vmm::Vcpu_dispatcher : public T
|
||||
cpu_session->affinity(T::cap(), location);
|
||||
|
||||
/* request creation of a 'local' EC */
|
||||
T::_tid.ec_sel = Native_thread::INVALID_INDEX - 1;
|
||||
T::native_thread().ec_sel = Native_thread::INVALID_INDEX - 1;
|
||||
T::start();
|
||||
|
||||
}
|
||||
@ -99,7 +99,7 @@ class Vmm::Vcpu_dispatcher : public T
|
||||
cpu_session->affinity(T::cap(), location);
|
||||
|
||||
/* request creation of a 'local' EC */
|
||||
T::_tid.ec_sel = Native_thread::INVALID_INDEX - 1;
|
||||
T::native_thread().ec_sel = Native_thread::INVALID_INDEX - 1;
|
||||
T::start();
|
||||
}
|
||||
|
||||
@ -117,7 +117,7 @@ class Vmm::Vcpu_dispatcher : public T
|
||||
/* Create the portal at the desired selector index */
|
||||
_native_pd.rcv_window(exc_base + EV);
|
||||
|
||||
Native_capability thread_cap(T::tid().ec_sel);
|
||||
Native_capability thread_cap(T::native_thread().ec_sel);
|
||||
|
||||
Untyped_capability handler =
|
||||
retry<Genode::Pd_session::Out_of_metadata>(
|
||||
@ -158,7 +158,7 @@ class Vmm::Vcpu_dispatcher : public T
|
||||
*/
|
||||
Nova::mword_t sel_sm_ec()
|
||||
{
|
||||
return T::tid().exc_pt_sel + Nova::SM_SEL_EC;
|
||||
return T::native_thread().exc_pt_sel + Nova::SM_SEL_EC;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -23,6 +23,9 @@
|
||||
#include <pd_session/connection.h>
|
||||
#include <rm_session/connection.h>
|
||||
|
||||
/* NOVA includes */
|
||||
#include <nova/native_thread.h>
|
||||
|
||||
namespace Vmm {
|
||||
|
||||
using namespace Genode;
|
||||
@ -118,13 +121,13 @@ class Vmm::Vcpu_same_pd : public Vmm::Vcpu_thread, Genode::Thread_base
|
||||
Thread_base(WEIGHT, "vCPU", stack_size, Type::NORMAL, cpu_session)
|
||||
{
|
||||
/* release pre-allocated selectors of Thread */
|
||||
Genode::cap_map()->remove(tid().exc_pt_sel, Nova::NUM_INITIAL_PT_LOG2);
|
||||
Genode::cap_map()->remove(native_thread().exc_pt_sel, Nova::NUM_INITIAL_PT_LOG2);
|
||||
|
||||
/* allocate correct number of selectors */
|
||||
this->tid().exc_pt_sel = cap_map()->insert(Nova::NUM_INITIAL_VCPU_PT_LOG2);
|
||||
this->native_thread().exc_pt_sel = cap_map()->insert(Nova::NUM_INITIAL_VCPU_PT_LOG2);
|
||||
|
||||
/* tell generic thread code that this becomes a vCPU */
|
||||
this->tid().is_vcpu = true;
|
||||
this->native_thread().is_vcpu = true;
|
||||
|
||||
/* place the thread on CPU described by location object */
|
||||
cpu_session->affinity(Thread_base::cap(), location);
|
||||
@ -134,14 +137,14 @@ class Vmm::Vcpu_same_pd : public Vmm::Vcpu_thread, Genode::Thread_base
|
||||
{
|
||||
using namespace Nova;
|
||||
|
||||
revoke(Nova::Obj_crd(this->tid().exc_pt_sel, NUM_INITIAL_VCPU_PT_LOG2));
|
||||
cap_map()->remove(this->tid().exc_pt_sel, NUM_INITIAL_VCPU_PT_LOG2, false);
|
||||
revoke(Nova::Obj_crd(this->native_thread().exc_pt_sel, NUM_INITIAL_VCPU_PT_LOG2));
|
||||
cap_map()->remove(this->native_thread().exc_pt_sel, NUM_INITIAL_VCPU_PT_LOG2, false);
|
||||
|
||||
/* allocate selectors for ~Thread */
|
||||
this->tid().exc_pt_sel = cap_map()->insert(Nova::NUM_INITIAL_PT_LOG2);
|
||||
this->native_thread().exc_pt_sel = cap_map()->insert(Nova::NUM_INITIAL_PT_LOG2);
|
||||
}
|
||||
|
||||
addr_t exc_base() { return this->tid().exc_pt_sel; }
|
||||
addr_t exc_base() { return this->native_thread().exc_pt_sel; }
|
||||
|
||||
void start(Genode::addr_t sel_ec)
|
||||
{
|
||||
|
@ -197,7 +197,7 @@ void genode_update_tsc(void (*update_func)(void), unsigned long update_us)
|
||||
|
||||
enum { TSC_FACTOR = 1000ULL };
|
||||
|
||||
Genode::addr_t sem = Thread_base::myself()->tid().exc_pt_sel + Nova::SM_SEL_EC;
|
||||
Genode::addr_t sem = Thread_base::myself()->native_thread().exc_pt_sel + Nova::SM_SEL_EC;
|
||||
unsigned long tsc_khz = (genode_cpu_hz() / 1000) / TSC_FACTOR;
|
||||
|
||||
Trace::Timestamp us_64 = update_us;
|
||||
|
Loading…
x
Reference in New Issue
Block a user