mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 02:01:38 +00:00
base-hw: Read and write whole thread states.
By now there is no use case for read/write a single register of a thread state. Thus the new syscalls 'read_thread_state' and 'write_thread_state' replace the old ones 'read_register' and 'write_register'.
This commit is contained in:
parent
6cb89f79e3
commit
4dadd6a437
@ -43,8 +43,8 @@ namespace Kernel
|
||||
GET_THREAD = 5,
|
||||
CURRENT_THREAD_ID = 6,
|
||||
YIELD_THREAD = 7,
|
||||
READ_REGISTER = 18,
|
||||
WRITE_REGISTER = 19,
|
||||
READ_THREAD_STATE = 18,
|
||||
WRITE_THREAD_STATE = 19,
|
||||
|
||||
/* interprocess communication */
|
||||
REQUEST_AND_WAIT = 8,
|
||||
@ -380,41 +380,31 @@ namespace Kernel
|
||||
|
||||
|
||||
/**
|
||||
* Get the current value of a register of a specific CPU context
|
||||
* Copy the current state of a thread to the callers UTCB
|
||||
*
|
||||
* \param thread_id ID of the thread that owns the targeted context
|
||||
* \param reg_id platform-specific ID of the targeted register
|
||||
* \param thread_id ID of the targeted thread
|
||||
*
|
||||
* Restricted to core threads. One can also read from its own context,
|
||||
* or any thread that is active in the meantime. In these cases
|
||||
* be aware of the fact, that the result reflects the context
|
||||
* be aware of the fact, that the result reflects the thread
|
||||
* state that were backed at the last kernel entry of the thread.
|
||||
* The copy might be incoherent when this function returns because
|
||||
* the caller might get scheduled away before then.
|
||||
*/
|
||||
inline unsigned long read_register(unsigned long const thread_id,
|
||||
unsigned long const reg_id)
|
||||
{
|
||||
return syscall(READ_REGISTER, (Syscall_arg)thread_id,
|
||||
(Syscall_arg)reg_id);
|
||||
}
|
||||
inline void read_thread_state(unsigned const thread_id) {
|
||||
syscall(READ_THREAD_STATE, (Syscall_arg)thread_id); }
|
||||
|
||||
|
||||
/**
|
||||
* Write a value to a register of a specific CPU context
|
||||
* Override the state of a thread with the callers UTCB content
|
||||
*
|
||||
* \param thread_id ID of the thread that owns the targeted context
|
||||
* \param reg_id platform-specific ID of the targeted register
|
||||
* \param value value that shall be written to the register
|
||||
* \param thread_id ID of the targeted thread
|
||||
*
|
||||
* Restricted to core threads. One can also write to its own context, or
|
||||
* to that of a thread that is active in the meantime.
|
||||
*/
|
||||
inline void write_register(unsigned long const thread_id,
|
||||
unsigned long const reg_id,
|
||||
unsigned long const value)
|
||||
{
|
||||
syscall(WRITE_REGISTER, (Syscall_arg)thread_id, (Syscall_arg)reg_id,
|
||||
(Syscall_arg)value);
|
||||
}
|
||||
inline void write_thread_state(unsigned const thread_id) {
|
||||
syscall(WRITE_THREAD_STATE, (Syscall_arg)thread_id); }
|
||||
|
||||
|
||||
/**
|
||||
|
@ -480,6 +480,52 @@ namespace Arm
|
||||
addr_t tlb() const { return section_table; }
|
||||
|
||||
void protection_domain(unsigned const id) { cidr = id; }
|
||||
|
||||
/**
|
||||
* Copy CPU state data to 'c'
|
||||
*/
|
||||
void read_cpu_state(Cpu_state * const s)
|
||||
{
|
||||
s->r0 = r0;
|
||||
s->r1 = r1;
|
||||
s->r2 = r2;
|
||||
s->r3 = r3;
|
||||
s->r4 = r4;
|
||||
s->r5 = r5;
|
||||
s->r6 = r6;
|
||||
s->r7 = r7;
|
||||
s->r8 = r8;
|
||||
s->r9 = r9;
|
||||
s->r10 = r10;
|
||||
s->r11 = r11;
|
||||
s->r12 = r12;
|
||||
s->sp = sp;
|
||||
s->lr = lr;
|
||||
s->ip = ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override CPU state with data from 'c'
|
||||
*/
|
||||
void write_cpu_state(Cpu_state * const s)
|
||||
{
|
||||
r0 = s->r0;
|
||||
r1 = s->r1;
|
||||
r2 = s->r2;
|
||||
r3 = s->r3;
|
||||
r4 = s->r4;
|
||||
r5 = s->r5;
|
||||
r6 = s->r6;
|
||||
r7 = s->r7;
|
||||
r8 = s->r8;
|
||||
r9 = s->r9;
|
||||
r10 = s->r10;
|
||||
r11 = s->r11;
|
||||
r12 = s->r12;
|
||||
sp = s->sp;
|
||||
lr = s->lr;
|
||||
ip = s->ip;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@ -513,66 +559,6 @@ namespace Arm
|
||||
unsigned user_arg_6() const { return r6; }
|
||||
unsigned user_arg_7() const { return r7; }
|
||||
|
||||
/**
|
||||
* Read a general purpose register
|
||||
*
|
||||
* \param id ID of the targeted register
|
||||
* \param v Holds register value if this returns 1
|
||||
*/
|
||||
bool get_gpr(unsigned id, unsigned & v) const
|
||||
{
|
||||
switch(id)
|
||||
{
|
||||
case 0: v = r0; return 1;
|
||||
case 1: v = r1; return 1;
|
||||
case 2: v = r2; return 1;
|
||||
case 3: v = r3; return 1;
|
||||
case 4: v = r4; return 1;
|
||||
case 5: v = r5; return 1;
|
||||
case 6: v = r6; return 1;
|
||||
case 7: v = r7; return 1;
|
||||
case 8: v = r8; return 1;
|
||||
case 9: v = r9; return 1;
|
||||
case 10: v = r10; return 1;
|
||||
case 11: v = r11; return 1;
|
||||
case 12: v = r12; return 1;
|
||||
case 13: v = sp; return 1;
|
||||
case 14: v = lr; return 1;
|
||||
case 15: v = ip; return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override a general purpose register
|
||||
*
|
||||
* \param id ID of the targeted register
|
||||
* \param v Has been written to register if this returns 1
|
||||
*/
|
||||
bool set_gpr(unsigned id, unsigned const v)
|
||||
{
|
||||
switch(id)
|
||||
{
|
||||
case 0: r0 = v; return 1;
|
||||
case 1: r1 = v; return 1;
|
||||
case 2: r2 = v; return 1;
|
||||
case 3: r3 = v; return 1;
|
||||
case 4: r4 = v; return 1;
|
||||
case 5: r5 = v; return 1;
|
||||
case 6: r6 = v; return 1;
|
||||
case 7: r7 = v; return 1;
|
||||
case 8: r8 = v; return 1;
|
||||
case 9: r9 = v; return 1;
|
||||
case 10: r10 = v; return 1;
|
||||
case 11: r11 = v; return 1;
|
||||
case 12: r12 = v; return 1;
|
||||
case 13: sp = v; return 1;
|
||||
case 14: lr = v; return 1;
|
||||
case 15: ip = v; return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a pagefault has occured due to a translation miss
|
||||
*
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <cpu/cpu_state.h>
|
||||
#include <util/fifo.h>
|
||||
#include <util/avl_tree.h>
|
||||
#include <base/thread_state.h>
|
||||
|
||||
/* core includes */
|
||||
#include <kernel_support.h>
|
||||
@ -54,6 +55,7 @@ extern Genode::addr_t _mt_master_context_end;
|
||||
namespace Kernel
|
||||
{
|
||||
/* import Genode types */
|
||||
typedef Genode::Thread_state Thread_state;
|
||||
typedef Genode::size_t size_t;
|
||||
typedef Genode::addr_t addr_t;
|
||||
typedef Genode::umword_t umword_t;
|
||||
@ -1899,37 +1901,26 @@ namespace Kernel
|
||||
/**
|
||||
* Do specific syscall for 'user', for details see 'syscall.h'
|
||||
*/
|
||||
void do_read_register(Thread * const user)
|
||||
void do_read_thread_state(Thread * const user)
|
||||
{
|
||||
/* check permissions */
|
||||
assert(user->pd_id() == core_id());
|
||||
|
||||
/* get targeted thread */
|
||||
Thread * const t = Thread::pool()->object(user->user_arg_1());
|
||||
assert(t);
|
||||
|
||||
/* return requested register */
|
||||
unsigned gpr;
|
||||
assert(t->get_gpr(user->user_arg_2(), gpr));
|
||||
user->user_arg_0(gpr);
|
||||
if (!t) PDBG("Targeted thread unknown");
|
||||
Thread_state * const ts = (Thread_state *)user->phys_utcb()->base();
|
||||
t->Cpu::Context::read_cpu_state(ts);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Do specific syscall for 'user', for details see 'syscall.h'
|
||||
*/
|
||||
void do_write_register(Thread * const user)
|
||||
void do_write_thread_state(Thread * const user)
|
||||
{
|
||||
/* check permissions */
|
||||
assert(user->pd_id() == core_id());
|
||||
|
||||
/* get targeted thread */
|
||||
Thread * const t = Thread::pool()->object(user->user_arg_1());
|
||||
assert(t);
|
||||
|
||||
/* write to requested register */
|
||||
unsigned const gpr = user->user_arg_3();
|
||||
assert(t->set_gpr(user->user_arg_2(), gpr));
|
||||
if (!t) PDBG("Targeted thread unknown");
|
||||
Thread_state * const ts = (Thread_state *)user->phys_utcb()->base();
|
||||
t->Cpu::Context::write_cpu_state(ts);
|
||||
}
|
||||
|
||||
|
||||
@ -2090,8 +2081,8 @@ namespace Kernel
|
||||
/* 15 */ do_await_irq,
|
||||
/* 16 */ do_free_irq,
|
||||
/* 17 */ do_print_char,
|
||||
/* 18 */ do_read_register,
|
||||
/* 19 */ do_write_register,
|
||||
/* 18 */ do_read_thread_state,
|
||||
/* 19 */ do_write_thread_state,
|
||||
/* 20 */ do_new_signal_receiver,
|
||||
/* 21 */ do_new_signal_context,
|
||||
/* 22 */ do_await_signal,
|
||||
|
Loading…
x
Reference in New Issue
Block a user