mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +00:00
cpu_session: Access thread state by value
This commit is contained in:
parent
4dadd6a437
commit
05f5999e71
@ -87,14 +87,18 @@ namespace Genode {
|
||||
void cancel_blocking();
|
||||
|
||||
/**
|
||||
* Request thread state
|
||||
* Override thread state with 's'
|
||||
*
|
||||
* \param state_dst destination state buffer
|
||||
*
|
||||
* \retval 0 successful
|
||||
* \retval -1 thread state not accessible
|
||||
* \throw Cpu_session::State_access_failed
|
||||
*/
|
||||
int state(Genode::Thread_state *state_dst);
|
||||
void state(Thread_state s);
|
||||
|
||||
/**
|
||||
* Read thread state
|
||||
*
|
||||
* \throw Cpu_session::State_access_failed
|
||||
*/
|
||||
Thread_state state();
|
||||
|
||||
|
||||
/************************
|
||||
|
@ -78,10 +78,17 @@ void Platform_thread::resume()
|
||||
}
|
||||
|
||||
|
||||
int Platform_thread::state(Thread_state *state_dst)
|
||||
void Platform_thread::state(Thread_state s)
|
||||
{
|
||||
PDBG("not implemented");
|
||||
return -1;
|
||||
PDBG("Not implemented");
|
||||
throw Cpu_session::State_access_failed();
|
||||
}
|
||||
|
||||
|
||||
Thread_state Platform_thread::state()
|
||||
{
|
||||
PDBG("Not implemented");
|
||||
throw Cpu_session::State_access_failed();
|
||||
}
|
||||
|
||||
|
||||
|
@ -102,14 +102,18 @@ namespace Genode {
|
||||
void unbind();
|
||||
|
||||
/**
|
||||
* Request thread state
|
||||
* Override thread state with 's'
|
||||
*
|
||||
* \param state_dst destination state buffer
|
||||
*
|
||||
* \retval 0 successful
|
||||
* \retval -1 thread state not accessible
|
||||
* \throw Cpu_session::State_access_failed
|
||||
*/
|
||||
int state(Genode::Thread_state *state_dst);
|
||||
void state(Thread_state s);
|
||||
|
||||
/**
|
||||
* Read thread state
|
||||
*
|
||||
* \throw Cpu_session::State_access_failed
|
||||
*/
|
||||
Thread_state state();
|
||||
|
||||
/**
|
||||
* Set the executing CPU for this thread
|
||||
|
@ -17,6 +17,7 @@
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
#include <util/string.h>
|
||||
#include <cpu_session/cpu_session.h>
|
||||
|
||||
/* core includes */
|
||||
#include <platform_thread.h>
|
||||
@ -101,8 +102,17 @@ void Platform_thread::unbind()
|
||||
}
|
||||
|
||||
|
||||
int Platform_thread::state(Thread_state *state_dst)
|
||||
void Platform_thread::state(Thread_state s)
|
||||
{
|
||||
PDBG("Not implemented");
|
||||
throw Cpu_session::State_access_failed();
|
||||
}
|
||||
|
||||
|
||||
Thread_state Platform_thread::state()
|
||||
{
|
||||
Thread_state s;
|
||||
|
||||
l4_umword_t old_eflags, ip, sp;
|
||||
l4_threadid_t thread = _l4_thread_id;
|
||||
l4_threadid_t pager = L4_INVALID_ID;
|
||||
@ -117,10 +127,10 @@ int Platform_thread::state(Thread_state *state_dst)
|
||||
PWRN("old eflags == ~0 on ex_regs %x.%x", (int)thread.id.task, (int)thread.id.lthread);
|
||||
|
||||
/* fill thread state structure */
|
||||
state_dst->ip = ip;
|
||||
state_dst->sp = sp;
|
||||
s.ip = ip;
|
||||
s.sp = sp;
|
||||
|
||||
return 0;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
@ -55,8 +55,11 @@ namespace Genode {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int state(Thread_capability thread, Thread_state *dst_state) {
|
||||
return call<Rpc_state>(thread, dst_state); }
|
||||
Thread_state state(Thread_capability thread) {
|
||||
return call<Rpc_get_state>(thread); }
|
||||
|
||||
void state(Thread_capability thread, Thread_state const &state) {
|
||||
call<Rpc_set_state>(thread, state); }
|
||||
|
||||
void exception_handler(Thread_capability thread, Signal_context_capability handler) {
|
||||
call<Rpc_exception_handler>(thread, handler); }
|
||||
|
@ -53,7 +53,8 @@ void Thread_base::start()
|
||||
|
||||
/* get gate-capability and badge of new thread */
|
||||
Thread_state state;
|
||||
env()->cpu_session()->state(_thread_cap, &state);
|
||||
try { state = env()->cpu_session()->state(_thread_cap); }
|
||||
catch (...) { throw Cpu_session::Thread_creation_failed(); }
|
||||
_tid = state.kcap;
|
||||
_context->utcb = state.utcb;
|
||||
|
||||
|
@ -139,7 +139,8 @@ namespace Genode {
|
||||
void single_step(Thread_capability thread_cap, bool enable);
|
||||
void cancel_blocking(Thread_capability);
|
||||
int name(Thread_capability, char *, size_t);
|
||||
int state(Thread_capability, Thread_state *);
|
||||
Thread_state state(Thread_capability);
|
||||
void state(Thread_capability, Thread_state const &);
|
||||
void exception_handler(Thread_capability, Signal_context_capability);
|
||||
unsigned num_cpus() const;
|
||||
void affinity(Thread_capability, unsigned);
|
||||
|
@ -116,14 +116,18 @@ namespace Genode {
|
||||
void unbind();
|
||||
|
||||
/**
|
||||
* Request thread state
|
||||
* Override thread state with 's'
|
||||
*
|
||||
* \param state_dst destination state buffer
|
||||
*
|
||||
* \retval 0 successful
|
||||
* \retval -1 thread state not accessible
|
||||
* \throw Cpu_session::State_access_failed
|
||||
*/
|
||||
int state(Genode::Thread_state *state_dst);
|
||||
void state(Thread_state s);
|
||||
|
||||
/**
|
||||
* Read thread state
|
||||
*
|
||||
* \throw Cpu_session::State_access_failed
|
||||
*/
|
||||
Thread_state state();
|
||||
|
||||
/**
|
||||
* Set the executing CPU for this thread
|
||||
|
@ -161,16 +161,23 @@ void Platform_thread::pager(Pager_object *pager_obj)
|
||||
}
|
||||
|
||||
|
||||
int Platform_thread::state(Thread_state *state_dst)
|
||||
void Platform_thread::state(Thread_state s)
|
||||
{
|
||||
if (_pager_obj)
|
||||
*state_dst = _pager_obj->state;
|
||||
PDBG("Not implemented");
|
||||
throw Cpu_session::State_access_failed();
|
||||
}
|
||||
|
||||
state_dst->kcap = _gate.remote;
|
||||
state_dst->id = _gate.local.local_name();
|
||||
state_dst->utcb = _utcb;
|
||||
|
||||
return 0;
|
||||
Thread_state Platform_thread::state()
|
||||
{
|
||||
Thread_state s;
|
||||
if (_pager_obj) s = _pager_obj->state;
|
||||
|
||||
s.kcap = _gate.remote;
|
||||
s.id = _gate.local.local_name();
|
||||
s.utcb = _utcb;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
@ -67,14 +67,18 @@ namespace Genode {
|
||||
void cancel_blocking();
|
||||
|
||||
/**
|
||||
* Request thread state
|
||||
* Override thread state with 's'
|
||||
*
|
||||
* \param state_dst destination state buffer
|
||||
*
|
||||
* \retval 0 successful
|
||||
* \retval -1 thread state not accessible
|
||||
* \throw Cpu_session::State_access_failed
|
||||
*/
|
||||
int state(Genode::Thread_state *state_dst);
|
||||
void state(Thread_state s);
|
||||
|
||||
/**
|
||||
* Read thread state
|
||||
*
|
||||
* \throw Cpu_session::State_access_failed
|
||||
*/
|
||||
Thread_state state();
|
||||
|
||||
|
||||
/************************
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
#include <cpu_session/cpu_session.h>
|
||||
|
||||
/* core includes */
|
||||
#include <platform_thread.h>
|
||||
@ -45,10 +46,17 @@ void Platform_thread::resume()
|
||||
}
|
||||
|
||||
|
||||
int Platform_thread::state(Thread_state *state_dst)
|
||||
void Platform_thread::state(Thread_state s)
|
||||
{
|
||||
PWRN("not implemented");
|
||||
return -1;
|
||||
PDBG("Not implemented");
|
||||
throw Cpu_session::State_access_failed();
|
||||
}
|
||||
|
||||
|
||||
Thread_state Platform_thread::state()
|
||||
{
|
||||
PDBG("Not implemented");
|
||||
throw Cpu_session::State_access_failed();
|
||||
}
|
||||
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <base/native_types.h>
|
||||
#include <kernel/syscalls.h>
|
||||
#include <kernel/log.h>
|
||||
#include <base/thread.h>
|
||||
|
||||
/* core includes */
|
||||
#include <assert.h>
|
||||
@ -119,18 +120,21 @@ namespace Genode {
|
||||
};
|
||||
|
||||
/**
|
||||
* Request our raw thread state
|
||||
*
|
||||
* \param state_dst destination state buffer
|
||||
*
|
||||
* \retval 0 successful
|
||||
* \retval -1 thread state not accessible
|
||||
* Get raw thread state
|
||||
*/
|
||||
int state(Genode::Thread_state * state_dst)
|
||||
Thread_state state()
|
||||
{
|
||||
kernel_log() << __PRETTY_FUNCTION__ << ": Not implemented\n";
|
||||
while (1) ;
|
||||
return -1;
|
||||
Kernel::read_thread_state(id());
|
||||
return *(Thread_state *)Thread_base::myself()->utcb()->base();
|
||||
};
|
||||
|
||||
/**
|
||||
* Override raw thread state
|
||||
*/
|
||||
void state(Thread_state s)
|
||||
{
|
||||
*(Thread_state *)Thread_base::myself()->utcb()->base() = s;
|
||||
Kernel::write_thread_state(id());
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -48,8 +48,11 @@ namespace Genode {
|
||||
void cancel_blocking(Thread_capability thread) {
|
||||
call<Rpc_cancel_blocking>(thread); }
|
||||
|
||||
int state(Thread_capability thread, Thread_state *dst_state) {
|
||||
return call<Rpc_state>(thread, dst_state); }
|
||||
Thread_state state(Thread_capability thread) {
|
||||
return call<Rpc_get_state>(thread); }
|
||||
|
||||
void state(Thread_capability thread, Thread_state const &state) {
|
||||
call<Rpc_set_state>(thread, state); }
|
||||
|
||||
void exception_handler(Thread_capability thread, Signal_context_capability handler) {
|
||||
call<Rpc_exception_handler>(thread, handler); }
|
||||
|
@ -133,7 +133,8 @@ namespace Genode {
|
||||
void resume(Thread_capability thread_cap);
|
||||
void cancel_blocking(Thread_capability);
|
||||
int name(Thread_capability, char *, size_t);
|
||||
int state(Thread_capability, Thread_state *);
|
||||
Thread_state state(Thread_capability);
|
||||
void state(Thread_capability, Thread_state const &);
|
||||
void exception_handler(Thread_capability, Signal_context_capability);
|
||||
unsigned num_cpus() const;
|
||||
void affinity(Thread_capability, unsigned);
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include <base/pager.h>
|
||||
#include <base/thread_state.h>
|
||||
#include <cpu_session/cpu_session.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
@ -64,7 +65,19 @@ namespace Genode {
|
||||
Pager_object *pager() { return 0; }
|
||||
void pager(Pager_object *) { }
|
||||
int start(void *ip, void *sp) { return 0; }
|
||||
int state(Thread_state *state_dst) { return 0; }
|
||||
|
||||
Thread_state state()
|
||||
{
|
||||
PDBG("Not implemented");
|
||||
throw Cpu_session::State_access_failed();
|
||||
}
|
||||
|
||||
void state(Thread_state)
|
||||
{
|
||||
PDBG("Not implemented");
|
||||
throw Cpu_session::State_access_failed();
|
||||
}
|
||||
|
||||
const char *name() { return _name; }
|
||||
void affinity(unsigned) { }
|
||||
|
||||
|
@ -115,14 +115,18 @@ namespace Genode {
|
||||
void cancel_blocking();
|
||||
|
||||
/**
|
||||
* Request thread state
|
||||
* Override thread state with 's'
|
||||
*
|
||||
* \param state_dst destination state buffer
|
||||
*
|
||||
* \retval 0 successful
|
||||
* \retval -1 thread state not accessible
|
||||
* \throw Cpu_session::State_access_failed
|
||||
*/
|
||||
int state(Genode::Thread_state *state_dst);
|
||||
void state(Thread_state s);
|
||||
|
||||
/**
|
||||
* Read thread state
|
||||
*
|
||||
* \throw Cpu_session::State_access_failed
|
||||
*/
|
||||
Thread_state state();
|
||||
|
||||
|
||||
/************************
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <platform_pd.h>
|
||||
#include <kernel/syscalls.h>
|
||||
#include "include/platform.h"
|
||||
#include <cpu_session/cpu_session.h>
|
||||
|
||||
static bool const verbose = 0;
|
||||
|
||||
@ -87,10 +88,17 @@ void Platform_thread::affinity(unsigned int cpu_no) { PERR("not implemented"); }
|
||||
void Platform_thread::cancel_blocking() { PERR("not implemented"); }
|
||||
|
||||
|
||||
int Platform_thread::state(Thread_state *state_dst)
|
||||
void Platform_thread::state(Thread_state s)
|
||||
{
|
||||
PERR("not implemented");
|
||||
return -1;
|
||||
PDBG("Not implemented");
|
||||
throw Cpu_session::State_access_failed();
|
||||
}
|
||||
|
||||
|
||||
Thread_state Platform_thread::state()
|
||||
{
|
||||
PDBG("Not implemented");
|
||||
throw Cpu_session::State_access_failed();
|
||||
}
|
||||
|
||||
|
||||
|
@ -22,12 +22,13 @@ namespace Genode {
|
||||
|
||||
struct Thread_state : public Cpu_state
|
||||
{
|
||||
bool transfer;
|
||||
bool is_vcpu;
|
||||
addr_t sel_exc_base;
|
||||
|
||||
Thread_state(bool trans = false) : Cpu_state(), transfer(trans),
|
||||
is_vcpu(false), sel_exc_base(~0UL) {}
|
||||
Thread_state() : Cpu_state(), is_vcpu(false), sel_exc_base(~0UL) { }
|
||||
|
||||
Thread_state(bool is_vcpu, addr_t sel_exc_base)
|
||||
: is_vcpu(is_vcpu), sel_exc_base(sel_exc_base) { }
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -34,11 +34,9 @@ namespace Genode {
|
||||
Ram_dataspace_capability utcb(Thread_capability thread) {
|
||||
return call<Rpc_utcb>(thread); }
|
||||
|
||||
|
||||
void kill_thread(Thread_capability thread) {
|
||||
call<Rpc_kill_thread>(thread); }
|
||||
|
||||
|
||||
int set_pager(Thread_capability thread, Pager_capability pager) {
|
||||
return call<Rpc_set_pager>(thread, pager); }
|
||||
|
||||
@ -63,8 +61,11 @@ namespace Genode {
|
||||
void cancel_blocking(Thread_capability thread) {
|
||||
call<Rpc_cancel_blocking>(thread); }
|
||||
|
||||
int state(Thread_capability thread, Thread_state *dst_state) {
|
||||
return call<Rpc_state>(thread, dst_state); }
|
||||
Thread_state state(Thread_capability thread) {
|
||||
return call<Rpc_get_state>(thread); }
|
||||
|
||||
void state(Thread_capability thread, Thread_state const &state) {
|
||||
call<Rpc_set_state>(thread, state); }
|
||||
|
||||
void exception_handler(Thread_capability thread, Signal_context_capability handler) {
|
||||
call<Rpc_exception_handler>(thread, handler); }
|
||||
|
@ -215,11 +215,12 @@ Rpc_entrypoint::Rpc_entrypoint(Cap_session *cap_session, size_t stack_size,
|
||||
|
||||
addr_t thread_sp = (addr_t)&_context->stack[-4];
|
||||
|
||||
Thread_state state(true);
|
||||
Thread_state state;
|
||||
state.sel_exc_base = _tid.exc_pt_sel;
|
||||
|
||||
if (env()->cpu_session()->state(_thread_cap, &state) ||
|
||||
env()->cpu_session()->start(_thread_cap, 0, thread_sp))
|
||||
try { env()->cpu_session()->state(_thread_cap, state); }
|
||||
catch(...) { throw Cpu_session::Thread_creation_failed(); }
|
||||
if (env()->cpu_session()->start(_thread_cap, 0, thread_sp))
|
||||
throw Cpu_session::Thread_creation_failed();
|
||||
|
||||
for (unsigned i = 0; i < Nova::PT_SEL_PARENT; i++)
|
||||
|
@ -117,12 +117,13 @@ void Thread_base::start()
|
||||
/* create EC at core */
|
||||
addr_t thread_sp = reinterpret_cast<addr_t>(&_context->stack[-4]);
|
||||
|
||||
Thread_state state(true);
|
||||
Thread_state state;
|
||||
state.sel_exc_base = _tid.exc_pt_sel;
|
||||
state.is_vcpu = _tid.is_vcpu;
|
||||
|
||||
if (env()->cpu_session()->state(_thread_cap, &state) ||
|
||||
env()->cpu_session()->start(_thread_cap, (addr_t)_thread_start,
|
||||
try { env()->cpu_session()->state(_thread_cap, state); }
|
||||
catch (...) { throw Cpu_session::Thread_creation_failed(); }
|
||||
if (env()->cpu_session()->start(_thread_cap, (addr_t)_thread_start,
|
||||
thread_sp))
|
||||
throw Cpu_session::Thread_creation_failed();
|
||||
|
||||
|
@ -138,7 +138,8 @@ namespace Genode {
|
||||
void single_step(Thread_capability thread_cap, bool enable);
|
||||
void cancel_blocking(Thread_capability);
|
||||
int name(Thread_capability, char *, size_t);
|
||||
int state(Thread_capability, Thread_state *);
|
||||
Thread_state state(Thread_capability);
|
||||
void state(Thread_capability, Thread_state const &);
|
||||
void exception_handler(Thread_capability, Signal_context_capability);
|
||||
unsigned num_cpus() const;
|
||||
void affinity(Thread_capability, unsigned);
|
||||
|
@ -84,14 +84,18 @@ namespace Genode {
|
||||
void cancel_blocking();
|
||||
|
||||
/**
|
||||
* Request thread state
|
||||
* Override thread state with 's'
|
||||
*
|
||||
* \param state_dst destination state buffer
|
||||
*
|
||||
* \retval 0 successful
|
||||
* \retval -1 thread state not accessible
|
||||
* \throw Cpu_session::State_access_failed
|
||||
*/
|
||||
int state(Genode::Thread_state *state_dst);
|
||||
void state(Thread_state s);
|
||||
|
||||
/**
|
||||
* Read thread state
|
||||
*
|
||||
* \throw Cpu_session::State_access_failed
|
||||
*/
|
||||
Thread_state state();
|
||||
|
||||
|
||||
/************************
|
||||
|
@ -265,33 +265,32 @@ void Platform_thread::resume()
|
||||
_pager->wake_up();
|
||||
}
|
||||
|
||||
|
||||
int Platform_thread::state(Thread_state *state_dst)
|
||||
Thread_state Platform_thread::state()
|
||||
{
|
||||
if (!state_dst || !_pager) return -1;
|
||||
Thread_state s;
|
||||
if (!_pager) throw Cpu_session::State_access_failed();
|
||||
_pager->copy_thread_state(&s);
|
||||
return s;
|
||||
};
|
||||
|
||||
if (state_dst->transfer) {
|
||||
/* Not permitted for main thread */
|
||||
if (_is_main_thread) return -2;
|
||||
void Platform_thread::state(Thread_state s)
|
||||
{
|
||||
/* not permitted for main thread */
|
||||
if (_is_main_thread) throw Cpu_session::State_access_failed();
|
||||
|
||||
/* You can do it only once */
|
||||
if (_sel_exc_base != Native_thread::INVALID_INDEX) return -3;
|
||||
|
||||
/**
|
||||
* _sel_exc_base exception base of thread in caller
|
||||
* protection domain - not in Core !
|
||||
* _is_vcpu If true it will run as vCPU,
|
||||
* otherwise it will be a thread.
|
||||
*/
|
||||
_sel_exc_base = state_dst->sel_exc_base;
|
||||
_is_vcpu = state_dst->is_vcpu;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return _pager->copy_thread_state(state_dst);
|
||||
}
|
||||
/* you can do it only once */
|
||||
if (_sel_exc_base != Native_thread::INVALID_INDEX)
|
||||
throw Cpu_session::State_access_failed();
|
||||
|
||||
/**
|
||||
* _sel_exc_base exception base of thread in caller
|
||||
* protection domain - not in Core !
|
||||
* _is_vcpu If true it will run as vCPU,
|
||||
* otherwise it will be a thread.
|
||||
*/
|
||||
_sel_exc_base = s.sel_exc_base;
|
||||
_is_vcpu = s.is_vcpu;
|
||||
};
|
||||
|
||||
void Platform_thread::cancel_blocking()
|
||||
{
|
||||
|
@ -99,14 +99,16 @@ namespace Genode {
|
||||
void unbind();
|
||||
|
||||
/**
|
||||
* Request thread state
|
||||
* Override thread state with 's'
|
||||
*
|
||||
* \param state_dst destination state buffer
|
||||
*
|
||||
* \retval 0 successful
|
||||
* \retval -1 thread state not accessible
|
||||
* \throw Cpu_session::State_access_failed
|
||||
*/
|
||||
int state(Genode::Thread_state *state_dst);
|
||||
void state(Thread_state s);
|
||||
|
||||
/**
|
||||
* Read thread state
|
||||
*/
|
||||
Thread_state state();
|
||||
|
||||
|
||||
/************************
|
||||
|
@ -23,9 +23,10 @@ using namespace Genode;
|
||||
using namespace Okl4;
|
||||
|
||||
|
||||
int Platform_thread::state(Thread_state *state_dst)
|
||||
Thread_state Platform_thread::state()
|
||||
{
|
||||
state_dst->tid = _l4_thread_id;
|
||||
Thread_state s;
|
||||
s.tid = _l4_thread_id;
|
||||
|
||||
L4_Copy_regs_to_mrs(_l4_thread_id);
|
||||
|
||||
@ -42,16 +43,23 @@ int Platform_thread::state(Thread_state *state_dst)
|
||||
MR_EAX = 9,
|
||||
};
|
||||
|
||||
L4_StoreMR(MR_EIP, &state_dst->ip);
|
||||
L4_StoreMR(MR_EFLAGS, &state_dst->eflags);
|
||||
L4_StoreMR(MR_EDI, &state_dst->edi);
|
||||
L4_StoreMR(MR_ESI, &state_dst->esi);
|
||||
L4_StoreMR(MR_EBP, &state_dst->ebp);
|
||||
L4_StoreMR(MR_ESP, &state_dst->sp);
|
||||
L4_StoreMR(MR_EBX, &state_dst->ebx);
|
||||
L4_StoreMR(MR_EDX, &state_dst->edx);
|
||||
L4_StoreMR(MR_ECX, &state_dst->ecx);
|
||||
L4_StoreMR(MR_EAX, &state_dst->eax);
|
||||
L4_StoreMR(MR_EIP, &s.ip);
|
||||
L4_StoreMR(MR_EFLAGS, &s.eflags);
|
||||
L4_StoreMR(MR_EDI, &s.edi);
|
||||
L4_StoreMR(MR_ESI, &s.esi);
|
||||
L4_StoreMR(MR_EBP, &s.ebp);
|
||||
L4_StoreMR(MR_ESP, &s.sp);
|
||||
L4_StoreMR(MR_EBX, &s.ebx);
|
||||
L4_StoreMR(MR_EDX, &s.edx);
|
||||
L4_StoreMR(MR_ECX, &s.ecx);
|
||||
L4_StoreMR(MR_EAX, &s.eax);
|
||||
|
||||
return 0;
|
||||
return s;
|
||||
}
|
||||
|
||||
void Platform_thread::state(Thread_state)
|
||||
{
|
||||
PDBG("Not implemented");
|
||||
throw Cpu_session::State_access_failed();
|
||||
}
|
||||
|
||||
|
@ -103,14 +103,16 @@ namespace Genode {
|
||||
void unbind();
|
||||
|
||||
/**
|
||||
* Request thread state
|
||||
* Override thread state with 's'
|
||||
*
|
||||
* \param state_dst destination state buffer
|
||||
*
|
||||
* \retval 0 successful
|
||||
* \retval -1 thread state not accessible
|
||||
* \throw Cpu_session::State_access_failed
|
||||
*/
|
||||
int state(Genode::Thread_state *state_dst);
|
||||
void state(Thread_state s);
|
||||
|
||||
/**
|
||||
* Read thread state
|
||||
*/
|
||||
Thread_state state();
|
||||
|
||||
|
||||
/************************
|
||||
|
@ -162,8 +162,17 @@ void Platform_thread::unbind()
|
||||
}
|
||||
|
||||
|
||||
int Platform_thread::state(Thread_state *state_dst)
|
||||
void Platform_thread::state(Thread_state)
|
||||
{
|
||||
PDBG("Not implemented");
|
||||
throw Cpu_session::State_access_failed();
|
||||
}
|
||||
|
||||
|
||||
Thread_state Platform_thread::state()
|
||||
{
|
||||
Thread_state s;
|
||||
|
||||
L4_Word_t dummy;
|
||||
L4_ThreadId_t dummy_tid;
|
||||
L4_Word_t ip, sp;
|
||||
@ -177,9 +186,9 @@ int Platform_thread::state(Thread_state *state_dst)
|
||||
0, 0, 0, 0, L4_nilthread,
|
||||
&dummy, &sp, &ip, &dummy, &dummy,
|
||||
&dummy_tid);
|
||||
state_dst->ip = ip;
|
||||
state_dst->sp = sp;
|
||||
return 0;
|
||||
s.ip = ip;
|
||||
s.sp = sp;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
@ -48,8 +48,11 @@ namespace Genode {
|
||||
void cancel_blocking(Thread_capability thread) {
|
||||
call<Rpc_cancel_blocking>(thread); }
|
||||
|
||||
int state(Thread_capability thread, Thread_state *dst_state) {
|
||||
return call<Rpc_state>(thread, dst_state); }
|
||||
Thread_state state(Thread_capability thread) {
|
||||
return call<Rpc_get_state>(thread); }
|
||||
|
||||
void state(Thread_capability thread, Thread_state const &state) {
|
||||
call<Rpc_set_state>(thread, state); }
|
||||
|
||||
void exception_handler(Thread_capability thread, Signal_context_capability handler) {
|
||||
call<Rpc_exception_handler>(thread, handler); }
|
||||
|
@ -48,6 +48,7 @@ namespace Genode {
|
||||
*********************/
|
||||
|
||||
class Thread_creation_failed : public Exception { };
|
||||
class State_access_failed : public Exception { };
|
||||
|
||||
static const char *service_name() { return "CPU"; }
|
||||
|
||||
@ -124,15 +125,23 @@ namespace Genode {
|
||||
virtual void cancel_blocking(Thread_capability thread) = 0;
|
||||
|
||||
/**
|
||||
* Return thread state
|
||||
* Get the current state of a specific thread
|
||||
*
|
||||
* \param thread thread to spy on
|
||||
* \param state_dst result
|
||||
*
|
||||
* \return 0 on success
|
||||
* \param thread targeted thread
|
||||
* \return state of the targeted thread
|
||||
* \throw State_access_failed
|
||||
*/
|
||||
virtual int state(Thread_capability thread,
|
||||
Thread_state *state_dst) = 0;
|
||||
virtual Thread_state state(Thread_capability thread) = 0;
|
||||
|
||||
/**
|
||||
* Override the current state of a specific thread
|
||||
*
|
||||
* \param thread targeted thread
|
||||
* \param state state that shall be applied
|
||||
* \throw State_access_failed
|
||||
*/
|
||||
virtual void state(Thread_capability thread,
|
||||
Thread_state const &state) = 0;
|
||||
|
||||
/**
|
||||
* Register signal handler for exceptions of the specified thread
|
||||
@ -208,7 +217,12 @@ namespace Genode {
|
||||
GENODE_RPC(Rpc_pause, void, pause, Thread_capability);
|
||||
GENODE_RPC(Rpc_resume, void, resume, Thread_capability);
|
||||
GENODE_RPC(Rpc_cancel_blocking, void, cancel_blocking, Thread_capability);
|
||||
GENODE_RPC(Rpc_state, int, state, Thread_capability, Thread_state *);
|
||||
GENODE_RPC_THROW(Rpc_get_state, Thread_state, state,
|
||||
GENODE_TYPE_LIST(State_access_failed),
|
||||
Thread_capability);
|
||||
GENODE_RPC_THROW(Rpc_set_state, void, state,
|
||||
GENODE_TYPE_LIST(State_access_failed),
|
||||
Thread_capability, Thread_state const &);
|
||||
GENODE_RPC(Rpc_exception_handler, void, exception_handler,
|
||||
Thread_capability, Signal_context_capability);
|
||||
GENODE_RPC(Rpc_single_step, void, single_step, Thread_capability, bool);
|
||||
@ -231,13 +245,14 @@ namespace Genode {
|
||||
Meta::Type_tuple<Rpc_pause,
|
||||
Meta::Type_tuple<Rpc_resume,
|
||||
Meta::Type_tuple<Rpc_cancel_blocking,
|
||||
Meta::Type_tuple<Rpc_state,
|
||||
Meta::Type_tuple<Rpc_set_state,
|
||||
Meta::Type_tuple<Rpc_get_state,
|
||||
Meta::Type_tuple<Rpc_exception_handler,
|
||||
Meta::Type_tuple<Rpc_single_step,
|
||||
Meta::Type_tuple<Rpc_num_cpus,
|
||||
Meta::Type_tuple<Rpc_affinity,
|
||||
Meta::Empty>
|
||||
> > > > > > > > > > > > Rpc_functions;
|
||||
> > > > > > > > > > > > > Rpc_functions;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -122,15 +122,24 @@ void Cpu_session_component::cancel_blocking(Thread_capability thread_cap)
|
||||
}
|
||||
|
||||
|
||||
int Cpu_session_component::state(Thread_capability thread_cap,
|
||||
Thread_state *state_dst)
|
||||
Thread_state Cpu_session_component::state(Thread_capability thread_cap)
|
||||
{
|
||||
Cpu_thread_component * thread = _lookup_thread(thread_cap);
|
||||
if (!thread) throw State_access_failed();
|
||||
Thread_state state = thread->platform_thread()->state();
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
void Cpu_session_component::state(Thread_capability thread_cap,
|
||||
Thread_state const &state)
|
||||
{
|
||||
Cpu_thread_component *thread = _lookup_thread(thread_cap);
|
||||
if (!thread) return -1;
|
||||
|
||||
return thread->platform_thread()->state(state_dst);
|
||||
if (!thread) throw State_access_failed();
|
||||
thread->platform_thread()->state(state);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Cpu_session_component::exception_handler(Thread_capability thread_cap,
|
||||
Signal_context_capability sigh_cap)
|
||||
|
@ -130,7 +130,8 @@ namespace Genode {
|
||||
void resume(Thread_capability thread_cap);
|
||||
void cancel_blocking(Thread_capability);
|
||||
int name(Thread_capability, char *, size_t);
|
||||
int state(Thread_capability, Thread_state *);
|
||||
Thread_state state(Thread_capability);
|
||||
void state(Thread_capability, Thread_state const &);
|
||||
void exception_handler(Thread_capability, Signal_context_capability);
|
||||
unsigned num_cpus() const;
|
||||
void affinity(Thread_capability, unsigned);
|
||||
|
@ -86,8 +86,7 @@ namespace L4lx {
|
||||
vcpu_connection()->set_pager(_thread_cap, pager_cap);
|
||||
|
||||
/* get gate-capability and badge of new thread */
|
||||
Thread_state state;
|
||||
vcpu_connection()->state(_thread_cap, &state);
|
||||
Thread_state state = vcpu_connection()->state(_thread_cap);
|
||||
_tid = state.kcap;
|
||||
_context->utcb = state.utcb;
|
||||
|
||||
|
@ -77,8 +77,7 @@ L4_ThreadId_t Oklx_thread_list::add()
|
||||
(addr_t)thd->stack_addr());
|
||||
|
||||
/* Get the OKL4 thread id of the new thread */
|
||||
Thread_state state;
|
||||
_cpu.state(cap,&state);
|
||||
Thread_state state = _cpu.state(cap);
|
||||
thd->set_tid(state.tid);
|
||||
|
||||
/* Acknowledge startup and return */
|
||||
@ -127,7 +126,7 @@ Oklx_process::add_thread()
|
||||
* but will create the OKL4 thread inactive
|
||||
*/
|
||||
_cpu.start(th->cap(), 0xffffffff, 0xffffffff);
|
||||
_cpu.state(th->cap(), &dst_state);
|
||||
dst_state = _cpu.state(th->cap());
|
||||
th->_tid = dst_state.tid;
|
||||
_threads.insert(th);
|
||||
return th->_tid;
|
||||
|
@ -165,10 +165,16 @@ void Cpu_session_component::cancel_blocking(Thread_capability thread_cap)
|
||||
}
|
||||
|
||||
|
||||
int Cpu_session_component::state(Thread_capability thread_cap,
|
||||
Thread_state *state_dst)
|
||||
void Cpu_session_component::state(Thread_capability thread_cap,
|
||||
Thread_state const &state)
|
||||
{
|
||||
return _parent_cpu_session.state(thread_cap, state_dst);
|
||||
_parent_cpu_session.state(thread_cap, state);
|
||||
}
|
||||
|
||||
|
||||
Thread_state Cpu_session_component::state(Thread_capability thread_cap)
|
||||
{
|
||||
return _parent_cpu_session.state(thread_cap);
|
||||
}
|
||||
|
||||
|
||||
|
@ -65,7 +65,8 @@ class Cpu_session_component : public Rpc_object<Cpu_session>
|
||||
void resume(Thread_capability thread_cap);
|
||||
void cancel_blocking(Thread_capability);
|
||||
int name(Thread_capability, char *, Genode::size_t);
|
||||
int state(Thread_capability, Thread_state *);
|
||||
Thread_state state(Thread_capability);
|
||||
void state(Thread_capability, Thread_state const &);
|
||||
void exception_handler(Thread_capability thread,
|
||||
Signal_context_capability handler);
|
||||
void single_step(Thread_capability thread, bool enable);
|
||||
|
@ -29,8 +29,8 @@ extern "C" int genode_fetch_register(int regno, unsigned long *reg_content)
|
||||
{
|
||||
Thread_state thread_state;
|
||||
|
||||
if (!get_current_thread_state(thread_state))
|
||||
return 0;
|
||||
try { thread_state = get_current_thread_state(); }
|
||||
catch (...) { return 0; }
|
||||
|
||||
switch((enum reg_index)regno)
|
||||
{
|
||||
|
@ -49,8 +49,8 @@ extern "C" int genode_fetch_register(int regno, unsigned long *reg_content)
|
||||
{
|
||||
Thread_state thread_state;
|
||||
|
||||
if (!get_current_thread_state(thread_state))
|
||||
return 0;
|
||||
try { thread_state = get_current_thread_state(); }
|
||||
catch (...) { return 0; }
|
||||
|
||||
if (in_syscall(thread_state)) {
|
||||
switch((enum reg_index)regno)
|
||||
|
@ -48,8 +48,8 @@ extern "C" int genode_fetch_register(int regno, unsigned long *reg_content)
|
||||
{
|
||||
Thread_state thread_state;
|
||||
|
||||
if (!get_current_thread_state(thread_state))
|
||||
return 0;
|
||||
try { thread_state = get_current_thread_state(); }
|
||||
catch (...) { return 0; }
|
||||
|
||||
if (in_syscall(thread_state)) {
|
||||
switch((enum reg_index)regno)
|
||||
|
@ -27,12 +27,12 @@ using namespace Gdb_monitor;
|
||||
|
||||
extern Gdb_stub_thread *gdb_stub_thread();
|
||||
|
||||
bool get_current_thread_state(Thread_state &thread_state)
|
||||
Thread_state get_current_thread_state()
|
||||
{
|
||||
Cpu_session_component *csc = gdb_stub_thread()->cpu_session_component();
|
||||
|
||||
ptid_t ptid = ((struct inferior_list_entry*)current_inferior)->id;
|
||||
|
||||
return !csc->state(csc->thread_cap(ptid.lwp), &thread_state);
|
||||
return csc->state(csc->thread_cap(ptid.lwp));
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,9 @@
|
||||
#ifndef GDBSERVER_PLATFORM_HELPER_H
|
||||
#define GDBSERVER_PLATFORM_HELPER_H
|
||||
|
||||
bool get_current_thread_state(Genode::Thread_state &thread_state);
|
||||
/**
|
||||
* \throw Cpu_session::State_access_failed
|
||||
*/
|
||||
Genode::Thread_state get_current_thread_state();
|
||||
|
||||
#endif /* GDBSERVER_PLATFORM_HELPER_H */
|
||||
|
@ -29,8 +29,8 @@ extern "C" int genode_fetch_register(int regno, unsigned long *reg_content)
|
||||
{
|
||||
Thread_state thread_state;
|
||||
|
||||
if (!get_current_thread_state(thread_state))
|
||||
return 0;
|
||||
try { thread_state = get_current_thread_state(); }
|
||||
catch (...) { return 0; }
|
||||
|
||||
switch((enum reg_index)regno)
|
||||
{
|
||||
|
@ -22,8 +22,8 @@ extern "C" int genode_fetch_register(int regno, unsigned long *reg_content)
|
||||
{
|
||||
Thread_state thread_state;
|
||||
|
||||
if (!get_current_thread_state(thread_state))
|
||||
return -1;
|
||||
try { thread_state = get_current_thread_state(); }
|
||||
catch (...) { return -1; }
|
||||
|
||||
switch((enum reg_index)regno)
|
||||
{
|
||||
|
@ -29,8 +29,8 @@ extern "C" int genode_fetch_register(int regno, unsigned long *reg_content)
|
||||
{
|
||||
Thread_state thread_state;
|
||||
|
||||
if (!get_current_thread_state(thread_state))
|
||||
return 0;
|
||||
try { thread_state = get_current_thread_state(); }
|
||||
catch (...) { return 0; }
|
||||
|
||||
switch((enum reg_index)regno)
|
||||
{
|
||||
|
@ -29,8 +29,8 @@ extern "C" int genode_fetch_register(int regno, unsigned long *reg_content)
|
||||
{
|
||||
Thread_state thread_state;
|
||||
|
||||
if (!get_current_thread_state(thread_state))
|
||||
return 0;
|
||||
try { thread_state = get_current_thread_state(); }
|
||||
catch (...) { return 0; }
|
||||
|
||||
switch((enum reg_index)regno)
|
||||
{
|
||||
|
@ -95,7 +95,7 @@ namespace Noux {
|
||||
|
||||
int set_pager(Thread_capability thread,
|
||||
Pager_capability pager) {
|
||||
return _cpu.set_pager(thread, pager); }
|
||||
return _cpu.set_pager(thread, pager); }
|
||||
|
||||
int start(Thread_capability thread, addr_t ip, addr_t sp)
|
||||
{
|
||||
@ -115,12 +115,15 @@ namespace Noux {
|
||||
void cancel_blocking(Thread_capability thread) {
|
||||
_cpu.cancel_blocking(thread); }
|
||||
|
||||
int state(Thread_capability thread, Thread_state *dst) {
|
||||
return _cpu.state(thread, dst); }
|
||||
Thread_state state(Thread_capability thread) {
|
||||
return _cpu.state(thread); }
|
||||
|
||||
void state(Thread_capability thread, Thread_state const &state) {
|
||||
_cpu.state(thread, state); }
|
||||
|
||||
void exception_handler(Thread_capability thread,
|
||||
Signal_context_capability handler) {
|
||||
_cpu.exception_handler(thread, handler); }
|
||||
_cpu.exception_handler(thread, handler); }
|
||||
|
||||
void single_step(Thread_capability thread, bool enable) {
|
||||
_cpu.single_step(thread, enable); }
|
||||
|
@ -378,7 +378,7 @@ class Vcpu_dispatcher : public Genode::Thread<STACK_SIZE>,
|
||||
/* calculate maximal aligned order of page to be mapped */
|
||||
do {
|
||||
crd = Nova::Mem_crd(map_page, map_order,
|
||||
Nova::Rights(true, true, true));
|
||||
Nova::Rights(true, true, true));
|
||||
|
||||
map_order += 1;
|
||||
map_page &= ~((1UL << map_order) - 1);
|
||||
@ -586,24 +586,24 @@ class Vcpu_dispatcher : public Genode::Thread<STACK_SIZE>,
|
||||
_guest_memory(guest_memory),
|
||||
_motherboard(motherboard)
|
||||
{
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
/* create new pager object and assign it to the new thread */
|
||||
Pager_capability pager_cap =
|
||||
Pager_capability const pager_cap =
|
||||
env()->rm_session()->add_client(_thread_cap);
|
||||
|
||||
if (!pager_cap.valid())
|
||||
throw Cpu_session::Thread_creation_failed();
|
||||
|
||||
if (env()->cpu_session()->set_pager(_thread_cap, pager_cap))
|
||||
throw Cpu_session::Thread_creation_failed();
|
||||
|
||||
addr_t thread_sp = (addr_t)&_context->stack[-4];
|
||||
Thread_state state(true);
|
||||
state.sel_exc_base = _tid.exc_pt_sel;
|
||||
env()->cpu_session()->state(_thread_cap,
|
||||
Thread_state(false, _tid.exc_pt_sel));
|
||||
|
||||
if (env()->cpu_session()->state(_thread_cap, &state) ||
|
||||
env()->cpu_session()->start(_thread_cap, 0, thread_sp))
|
||||
addr_t const thread_sp = (addr_t)&_context->stack[-4];
|
||||
|
||||
if (env()->cpu_session()->start(_thread_cap, 0, thread_sp))
|
||||
throw Cpu_session::Thread_creation_failed();
|
||||
|
||||
/* Request exception portals for vCPU dispatcher */
|
||||
@ -611,7 +611,7 @@ class Vcpu_dispatcher : public Genode::Thread<STACK_SIZE>,
|
||||
request_event_portal(pager_cap, _tid.exc_pt_sel, i);
|
||||
|
||||
request_event_portal(pager_cap, _tid.exc_pt_sel,
|
||||
Nova::SM_SEL_EC);
|
||||
Nova::SM_SEL_EC);
|
||||
request_event_portal(pager_cap, _tid.exc_pt_sel,
|
||||
Nova::PT_SEL_RECALL);
|
||||
|
||||
@ -1149,8 +1149,8 @@ int main(int argc, char **argv)
|
||||
if (guest_memory.backing_store_local_base())
|
||||
Genode::printf("[0x%08p, 0x%08lx) - VMM local base of guest-physical"
|
||||
" memory\n", guest_memory.backing_store_local_base(),
|
||||
(Genode::addr_t)guest_memory.backing_store_local_base() +
|
||||
vm_size);
|
||||
(Genode::addr_t)guest_memory.backing_store_local_base() +
|
||||
vm_size);
|
||||
|
||||
Genode::printf("[0x%08lx, 0x%08lx) - Genode thread context area\n",
|
||||
Genode::Native_config::context_area_virtual_base(),
|
||||
|
Loading…
Reference in New Issue
Block a user