diff --git a/repos/base-hw/include/arm/kernel/interface_support.h b/repos/base-hw/include/arm/kernel/interface_support.h index 2eee68c5e6..50fa16d69a 100644 --- a/repos/base-hw/include/arm/kernel/interface_support.h +++ b/repos/base-hw/include/arm/kernel/interface_support.h @@ -22,37 +22,6 @@ namespace Kernel typedef Genode::uint32_t Call_arg; typedef Genode::uint32_t Call_ret; - /** - * Registers that are provided by a kernel thread-object for user access - */ - struct Thread_reg_id - { - enum { - R0 = 0, - R1 = 1, - R2 = 2, - R3 = 3, - R4 = 4, - R5 = 5, - R6 = 6, - R7 = 7, - R8 = 8, - R9 = 9, - R10 = 10, - R11 = 11, - R12 = 12, - SP = 13, - LR = 14, - IP = 15, - CPSR = 16, - CPU_EXCEPTION = 17, - FAULT_TLB = 18, - FAULT_ADDR = 19, - FAULT_WRITES = 20, - FAULT_SIGNAL = 21, - }; - }; - /** * Events that are provided by a kernel thread-object for user handling */ diff --git a/repos/base-hw/include/x86_64/kernel/interface_support.h b/repos/base-hw/include/x86_64/kernel/interface_support.h index d4dd8c6b88..cbaa6f5705 100644 --- a/repos/base-hw/include/x86_64/kernel/interface_support.h +++ b/repos/base-hw/include/x86_64/kernel/interface_support.h @@ -22,21 +22,6 @@ namespace Kernel typedef Genode::uint64_t Call_arg; typedef Genode::uint64_t Call_ret; - /** - * Registers that are provided by a kernel thread-object for user access - */ - struct Thread_reg_id - { - enum { - IP = 0, - SP = 1, - FAULT_TLB = 2, - FAULT_ADDR = 3, - FAULT_WRITES = 4, - FAULT_SIGNAL = 5, - }; - }; - /** * Events that are provided by a kernel thread-object for user handling */ diff --git a/repos/base-hw/src/core/include/kernel/core_interface.h b/repos/base-hw/src/core/include/kernel/core_interface.h index 558f424b57..a0a9476afe 100644 --- a/repos/base-hw/src/core/include/kernel/core_interface.h +++ b/repos/base-hw/src/core/include/kernel/core_interface.h @@ -37,25 +37,24 @@ namespace Kernel constexpr Call_arg call_id_start_thread() { return 17; } constexpr Call_arg call_id_pause_thread() { return 18; } constexpr Call_arg call_id_resume_thread() { return 19; } - constexpr Call_arg call_id_access_thread_regs() { return 20; } - constexpr Call_arg call_id_route_thread_event() { return 21; } - constexpr Call_arg call_id_thread_quota() { return 22; } - constexpr Call_arg call_id_update_pd() { return 23; } - constexpr Call_arg call_id_new_pd() { return 24; } - constexpr Call_arg call_id_delete_pd() { return 25; } - constexpr Call_arg call_id_new_signal_receiver() { return 26; } - constexpr Call_arg call_id_new_signal_context() { return 27; } - constexpr Call_arg call_id_delete_signal_context() { return 28; } - constexpr Call_arg call_id_delete_signal_receiver() { return 29; } - constexpr Call_arg call_id_new_vm() { return 30; } - constexpr Call_arg call_id_run_vm() { return 31; } - constexpr Call_arg call_id_pause_vm() { return 32; } - constexpr Call_arg call_id_delete_vm() { return 33; } - constexpr Call_arg call_id_new_irq() { return 34; } - constexpr Call_arg call_id_delete_irq() { return 35; } - constexpr Call_arg call_id_ack_irq() { return 36; } - constexpr Call_arg call_id_new_obj() { return 37; } - constexpr Call_arg call_id_delete_obj() { return 38; } + constexpr Call_arg call_id_route_thread_event() { return 20; } + constexpr Call_arg call_id_thread_quota() { return 21; } + constexpr Call_arg call_id_update_pd() { return 22; } + constexpr Call_arg call_id_new_pd() { return 23; } + constexpr Call_arg call_id_delete_pd() { return 24; } + constexpr Call_arg call_id_new_signal_receiver() { return 25; } + constexpr Call_arg call_id_new_signal_context() { return 26; } + constexpr Call_arg call_id_delete_signal_context() { return 27; } + constexpr Call_arg call_id_delete_signal_receiver() { return 28; } + constexpr Call_arg call_id_new_vm() { return 29; } + constexpr Call_arg call_id_run_vm() { return 30; } + constexpr Call_arg call_id_pause_vm() { return 31; } + constexpr Call_arg call_id_delete_vm() { return 32; } + constexpr Call_arg call_id_new_irq() { return 33; } + constexpr Call_arg call_id_delete_irq() { return 34; } + constexpr Call_arg call_id_ack_irq() { return 35; } + constexpr Call_arg call_id_new_obj() { return 36; } + constexpr Call_arg call_id_delete_obj() { return 37; } /** * Update locally effective domain configuration to in-memory state @@ -146,48 +145,6 @@ namespace Kernel } - /** - * Access plain member variables of a kernel thread-object - * - * \param thread pointer to thread kernel object - * \param reads amount of read operations - * \param writes amount of write operations - * \param values base of the value buffer for all operations - * - * \return amount of undone operations according to the execution order - * - * Operations are executed in order of the appearance of the register names - * in the callers UTCB. If reads = 0, read_values is of no relevance. If - * writes = 0, write_values is of no relevance. - * - * Expected structure at the callers UTCB base: - * - * 0 * sizeof(addr_t): read register name #1 - * ... ... - * (reads - 1) * sizeof(addr_t): read register name #reads - * (reads - 0) * sizeof(addr_t): write register name #1 - * ... ... - * (reads + writes - 1) * sizeof(addr_t): write register name #writes - * - * Expected structure at values: - * - * 0 * sizeof(addr_t): read destination #1 - * ... ... - * (reads - 1) * sizeof(addr_t): read destination #reads - * (reads - 0) * sizeof(addr_t): write value #1 - * ... ... - * (reads + writes - 1) * sizeof(addr_t): write value #writes - */ - inline unsigned access_thread_regs(Thread * const thread, - unsigned const reads, - unsigned const writes, - addr_t * const values) - { - return call(call_id_access_thread_regs(), (Call_arg)thread, - reads, writes, (Call_arg)values); - } - - /** * Execute a virtual-machine (again) * diff --git a/repos/base-hw/src/core/include/kernel/thread.h b/repos/base-hw/src/core/include/kernel/thread.h index 209cc7b9aa..6bfd1c4223 100644 --- a/repos/base-hw/src/core/include/kernel/thread.h +++ b/repos/base-hw/src/core/include/kernel/thread.h @@ -141,43 +141,11 @@ class Kernel::Thread */ void _call(); - /** - * Read a thread register - * - * \param id kernel name of targeted thread register - * \param value read-value buffer - * - * \retval 0 succeeded - * \retval -1 failed - */ - int _read_reg(addr_t const id, addr_t & value) const; - /** * Return amount of timer tics that 'quota' is worth */ size_t _core_to_kernel_quota(size_t const quota) const; - /** - * Override a thread register - * - * \param id kernel name of targeted thread register - * \param value write-value buffer - * - * \retval 0 succeeded - * \retval -1 failed - */ - int _write_reg(addr_t const id, addr_t const value); - - /** - * Map kernel names of thread registers to the corresponding data - * - * \param id kernel name of thread register - * - * \retval 0 failed - * \retval >0 pointer to register content - */ - addr_t Thread::* _reg(addr_t const id) const; - /** * Print the activity of the thread * @@ -224,7 +192,6 @@ class Kernel::Thread void _call_delete_vm(); void _call_run_vm(); void _call_pause_vm(); - void _call_access_thread_regs(); void _call_route_thread_event(); void _call_new_irq(); void _call_ack_irq(); diff --git a/repos/base-hw/src/core/include/spec/arm/kernel/thread_base.h b/repos/base-hw/src/core/include/kernel/thread_base.h similarity index 77% rename from repos/base-hw/src/core/include/spec/arm/kernel/thread_base.h rename to repos/base-hw/src/core/include/kernel/thread_base.h index 55ccb4954e..0a218ef00e 100644 --- a/repos/base-hw/src/core/include/spec/arm/kernel/thread_base.h +++ b/repos/base-hw/src/core/include/kernel/thread_base.h @@ -41,6 +41,14 @@ class Kernel::Thread_base * \param t generic part of kernel thread-object */ Thread_base(Thread * const t); + + public: + + /* Accessors */ + addr_t fault_pd() const { return _fault_pd; } + addr_t fault_addr() const { return _fault_addr; } + addr_t fault_writes() const { return _fault_writes; } + addr_t fault_signal() const { return _fault_signal; } }; #endif /* _KERNEL__THREAD_BASE_H_ */ diff --git a/repos/base-hw/src/core/include/spec/x86/kernel/thread_base.h b/repos/base-hw/src/core/include/spec/x86/kernel/thread_base.h deleted file mode 100644 index 55ccb4954e..0000000000 --- a/repos/base-hw/src/core/include/spec/x86/kernel/thread_base.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * \brief Hardware specific base of kernel thread-objects - * \author Martin Stein - * \date 2013-11-13 - */ - -/* - * Copyright (C) 2013 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 _KERNEL__THREAD_BASE_H_ -#define _KERNEL__THREAD_BASE_H_ - -/* core includes */ -#include - -namespace Kernel -{ - /** - * Hardware specific base of kernel thread-objects - */ - class Thread_base; -} - -class Kernel::Thread_base -{ - protected: - - Thread_event _fault; - addr_t _fault_pd; - addr_t _fault_addr; - addr_t _fault_writes; - addr_t _fault_signal; - - /** - * Constructor - * - * \param t generic part of kernel thread-object - */ - Thread_base(Thread * const t); -}; - -#endif /* _KERNEL__THREAD_BASE_H_ */ diff --git a/repos/base-hw/src/core/kernel/thread.cc b/repos/base-hw/src/core/kernel/thread.cc index 6c831369d8..7bcf3f78bd 100644 --- a/repos/base-hw/src/core/kernel/thread.cc +++ b/repos/base-hw/src/core/kernel/thread.cc @@ -362,42 +362,6 @@ Signal_context * const Thread_event::signal_context() const { return _signal_context; } -void Thread::_call_access_thread_regs() -{ - /* get targeted thread */ - unsigned const reads = user_arg_2(); - unsigned const writes = user_arg_3(); - Thread * const t = (Thread*) user_arg_1(); - if (!t) { - PWRN("unknown thread"); - user_arg_0(reads + writes); - return; - } - /* execute read operations */ - addr_t * const utcb = (addr_t *) this->utcb()->base(); - addr_t * const read_ids = &utcb[0]; - addr_t * values = (addr_t *)user_arg_4(); - for (unsigned i = 0; i < reads; i++) { - if (t->_read_reg(read_ids[i], *values)) { - user_arg_0(reads + writes - i); - return; - } - values++; - } - /* execute write operations */ - addr_t * const write_ids = &utcb[reads]; - for (unsigned i = 0; i < writes; i++) { - if (t->_write_reg(write_ids[i], *values)) { - user_arg_0(writes - i); - return; - } - values++; - } - user_arg_0(0); - return; -} - - void Thread::_call_update_data_region() { /* @@ -648,32 +612,6 @@ void Thread::_call_delete_cap() } -int Thread::_read_reg(addr_t const id, addr_t & value) const -{ - addr_t Thread::* const reg = _reg(id); - if (reg) { - value = this->*reg; - return 0; - } - PWRN("%s -> %s: cannot read unknown thread register %p", - pd_label(), label(), (void*)id); - return -1; -} - - -int Thread::_write_reg(addr_t const id, addr_t const value) -{ - addr_t Thread::* const reg = _reg(id); - if (reg) { - this->*reg = value; - return 0; - } - PWRN("%s -> %s: cannot write unknown thread register %p", - pd_label(), label(), (void*)id); - return -1; -} - - void Thread::_call() { try { @@ -712,7 +650,6 @@ void Thread::_call() case call_id_delete_thread(): _call_delete(); return; case call_id_start_thread(): _call_start_thread(); return; case call_id_resume_thread(): _call_resume_thread(); return; - case call_id_access_thread_regs(): _call_access_thread_regs(); return; case call_id_route_thread_event(): _call_route_thread_event(); return; case call_id_update_pd(): _call_update_pd(); return; case call_id_new_pd(): diff --git a/repos/base-hw/src/core/platform_thread.cc b/repos/base-hw/src/core/platform_thread.cc index 0238a63491..29adee6879 100644 --- a/repos/base-hw/src/core/platform_thread.cc +++ b/repos/base-hw/src/core/platform_thread.cc @@ -150,16 +150,8 @@ int Platform_thread::start(void * const ip, void * const sp) } /* initialize thread registers */ - typedef Kernel::Thread_reg_id Reg_id; - enum { WRITES = 2 }; - addr_t * write_regs = (addr_t*) Thread_base::myself()->utcb()->base(); - write_regs[0] = Reg_id::IP; - write_regs[1] = Reg_id::SP; - addr_t values[] = { (addr_t)ip, (addr_t)sp }; - if (Kernel::access_thread_regs(kernel_object(), 0, WRITES, values)) { - PERR("failed to initialize thread registers"); - return -1; - } + kernel_object()->ip = reinterpret_cast(ip); + kernel_object()->sp = reinterpret_cast(sp); /* start executing new thread */ if (!_pd) { @@ -200,38 +192,15 @@ void Platform_thread::pager(Pager_object * const pager) Genode::Pager_object * Platform_thread::pager() { return _pager; } -addr_t const * cpu_state_regs(); - -size_t cpu_state_regs_length(); - - Thread_state Platform_thread::state() { - static addr_t const * const src = cpu_state_regs(); - static size_t const length = cpu_state_regs_length(); - static size_t const size = length * sizeof(src[0]); - void * dst = (void*)Thread_base::myself()->utcb()->base(); - Genode::memcpy(dst, src, size); - Thread_state thread_state; - Cpu_state * const cpu_state = static_cast(&thread_state); - if (Kernel::access_thread_regs(kernel_object(), length, 0, - (addr_t *)cpu_state)) { - throw Cpu_session::State_access_failed(); - } - return thread_state; -}; + Thread_state_base bstate(*kernel_object()); + return Thread_state(bstate); +} void Platform_thread::state(Thread_state thread_state) { - static addr_t const * const src = cpu_state_regs(); - static size_t const length = cpu_state_regs_length(); - static size_t const size = length * sizeof(src[0]); - void * dst = (void*)Thread_base::myself()->utcb()->base(); - Genode::memcpy(dst, src, size); - Cpu_state * const cpu_state = static_cast(&thread_state); - if (Kernel::access_thread_regs(kernel_object(), 0, length, - (addr_t *)cpu_state)) { - throw Cpu_session::State_access_failed(); - } -}; + Cpu_state * cstate = static_cast(kernel_object()); + *cstate = static_cast(thread_state); +} diff --git a/repos/base-hw/src/core/rm_session_support.cc b/repos/base-hw/src/core/rm_session_support.cc index 2f73037bb8..8e47b40759 100644 --- a/repos/base-hw/src/core/rm_session_support.cc +++ b/repos/base-hw/src/core/rm_session_support.cc @@ -78,18 +78,13 @@ void Pager_entrypoint::entry() PWRN("failed to get platform thread of faulter"); continue; } - typedef Kernel::Thread_reg_id Reg_id; - static addr_t const read_regs[] = { - Reg_id::FAULT_TLB, Reg_id::IP, Reg_id::FAULT_ADDR, - Reg_id::FAULT_WRITES, Reg_id::FAULT_SIGNAL }; - enum { READS = sizeof(read_regs)/sizeof(read_regs[0]) }; - memcpy((void*)Thread_base::myself()->utcb()->base(), - read_regs, sizeof(read_regs)); - addr_t * const values = (addr_t *)&_fault; - if (Kernel::access_thread_regs(pt->kernel_object(), READS, 0, values)) { - PWRN("failed to read fault data"); - continue; - } + + _fault.pd = pt->kernel_object()->fault_pd(); + _fault.ip = pt->kernel_object()->ip; + _fault.addr = pt->kernel_object()->fault_addr(); + _fault.writes = pt->kernel_object()->fault_writes(); + _fault.signal = pt->kernel_object()->fault_signal(); + /* try to resolve fault directly via local region managers */ if (pog->pager(*this)) { continue; } diff --git a/repos/base-hw/src/core/spec/arm/kernel/thread.cc b/repos/base-hw/src/core/spec/arm/kernel/thread.cc index 38ab6dc11c..9ba3402441 100644 --- a/repos/base-hw/src/core/spec/arm/kernel/thread.cc +++ b/repos/base-hw/src/core/spec/arm/kernel/thread.cc @@ -63,36 +63,6 @@ void Thread::exception(unsigned const cpu) } -addr_t Thread::* Thread::_reg(addr_t const id) const -{ - static addr_t Thread::* const _regs[] = { - /* [0] */ (addr_t Thread::*)&Thread::r0, - /* [1] */ (addr_t Thread::*)&Thread::r1, - /* [2] */ (addr_t Thread::*)&Thread::r2, - /* [3] */ (addr_t Thread::*)&Thread::r3, - /* [4] */ (addr_t Thread::*)&Thread::r4, - /* [5] */ (addr_t Thread::*)&Thread::r5, - /* [6] */ (addr_t Thread::*)&Thread::r6, - /* [7] */ (addr_t Thread::*)&Thread::r7, - /* [8] */ (addr_t Thread::*)&Thread::r8, - /* [9] */ (addr_t Thread::*)&Thread::r9, - /* [10] */ (addr_t Thread::*)&Thread::r10, - /* [11] */ (addr_t Thread::*)&Thread::r11, - /* [12] */ (addr_t Thread::*)&Thread::r12, - /* [13] */ (addr_t Thread::*)&Thread::sp, - /* [14] */ (addr_t Thread::*)&Thread::lr, - /* [15] */ (addr_t Thread::*)&Thread::ip, - /* [16] */ (addr_t Thread::*)&Thread::cpsr, - /* [17] */ (addr_t Thread::*)&Thread::cpu_exception, - /* [18] */ (addr_t Thread::*)&Thread::_fault_pd, - /* [19] */ (addr_t Thread::*)&Thread::_fault_addr, - /* [20] */ (addr_t Thread::*)&Thread::_fault_writes, - /* [21] */ (addr_t Thread::*)&Thread::_fault_signal - }; - return id < sizeof(_regs)/sizeof(_regs[0]) ? _regs[id] : 0; -} - - Thread_event Thread::* Thread::_event(unsigned const id) const { static Thread_event Thread::* _events[] = { diff --git a/repos/base-hw/src/core/spec/arm/kernel/thread_base.cc b/repos/base-hw/src/core/spec/arm/kernel/thread_base.cc index 3dca6539da..f89bcc04b5 100644 --- a/repos/base-hw/src/core/spec/arm/kernel/thread_base.cc +++ b/repos/base-hw/src/core/spec/arm/kernel/thread_base.cc @@ -30,24 +30,3 @@ Thread_base::Thread_base(Thread * const t) _fault_writes(0), _fault_signal(0) { } - - -/************************* - ** CPU-state utilities ** - *************************/ - -typedef Thread_reg_id Reg_id; - -static addr_t const _cpu_state_regs[] = { - Reg_id::R0, Reg_id::R1, Reg_id::R2, Reg_id::R3, Reg_id::R4, - Reg_id::R5, Reg_id::R6, Reg_id::R7, Reg_id::R8, Reg_id::R9, - Reg_id::R10, Reg_id::R11, Reg_id::R12, Reg_id::SP, Reg_id::LR, - Reg_id::IP, Reg_id::CPSR, Reg_id::CPU_EXCEPTION }; - -addr_t const * cpu_state_regs() { return _cpu_state_regs; } - - -size_t cpu_state_regs_length() -{ - return sizeof(_cpu_state_regs)/sizeof(_cpu_state_regs[0]); -} diff --git a/repos/base-hw/src/core/spec/x86_64/kernel/thread_base.cc b/repos/base-hw/src/core/spec/x86_64/kernel/thread_base.cc index fde201e3f8..d2cc8b9f25 100644 --- a/repos/base-hw/src/core/spec/x86_64/kernel/thread_base.cc +++ b/repos/base-hw/src/core/spec/x86_64/kernel/thread_base.cc @@ -39,20 +39,6 @@ Thread_base::Thread_base(Thread * const t) ** Kernel::Thread ** ********************/ -addr_t Thread::* Thread::_reg(addr_t const id) const -{ - static addr_t Thread::* const _regs[] = { - /* [0] */ (addr_t Thread::*)&Thread::ip, - /* [1] */ (addr_t Thread::*)&Thread::sp, - /* [2] */ (addr_t Thread::*)&Thread::_fault_pd, - /* [3] */ (addr_t Thread::*)&Thread::_fault_addr, - /* [4] */ (addr_t Thread::*)&Thread::_fault_writes, - /* [5] */ (addr_t Thread::*)&Thread::_fault_signal - }; - return id < sizeof(_regs)/sizeof(_regs[0]) ? _regs[id] : 0; -} - - Thread_event Thread::* Thread::_event(unsigned const id) const { static Thread_event Thread::* _events[] = { @@ -95,20 +81,3 @@ void Kernel::Cpu_context::_init(size_t const stack_size, addr_t const table) */ sp = sp + stack_size; } - - -/************************* - ** CPU-state utilities ** - *************************/ - -typedef Thread_reg_id Reg_id; - -static addr_t const _cpu_state_regs[] = { }; - -addr_t const * cpu_state_regs() { return _cpu_state_regs; } - - -size_t cpu_state_regs_length() -{ - return sizeof(_cpu_state_regs)/sizeof(_cpu_state_regs[0]); -} diff --git a/repos/base/include/base/thread_state.h b/repos/base/include/base/thread_state.h index 05322381e1..34d0033f5c 100644 --- a/repos/base/include/base/thread_state.h +++ b/repos/base/include/base/thread_state.h @@ -21,6 +21,10 @@ namespace Genode { struct Thread_state; } -struct Genode::Thread_state : Thread_state_base { }; +struct Genode::Thread_state : Thread_state_base +{ + Thread_state() {} + Thread_state(Thread_state_base &base) : Thread_state_base(base) {} +}; #endif /* _INCLUDE__BASE__THREAD_STATE_H_ */ diff --git a/repos/base/include/base/thread_state_base.h b/repos/base/include/base/thread_state_base.h index 49d2223499..f863119b39 100644 --- a/repos/base/include/base/thread_state_base.h +++ b/repos/base/include/base/thread_state_base.h @@ -25,6 +25,7 @@ struct Genode::Thread_state_base : Cpu_state bool unresolved_page_fault; Thread_state_base() : unresolved_page_fault(false) { }; + Thread_state_base(Cpu_state &c) : Cpu_state(c), unresolved_page_fault(false) { }; }; #endif /* _INCLUDE__BASE__THREAD_STATE_BASE_H_ */