From d6a05245f2bbb3283c445d9938a9da5e163d412d Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Fri, 6 Oct 2017 12:02:36 +0200 Subject: [PATCH] hw: remove User_context Fix #2540 --- repos/base-hw/lib/mk/spec/arm/core-hw.inc | 2 +- .../lib/mk/spec/cortex_a15/core-hw.inc | 1 + .../base-hw/lib/mk/spec/cortex_a9/core-hw.inc | 1 - .../base-hw/lib/mk/spec/imx53_qsb/core-hw.mk | 1 - repos/base-hw/lib/mk/spec/muen/core-hw.mk | 2 - repos/base-hw/lib/mk/spec/riscv/core-hw.mk | 2 +- repos/base-hw/lib/mk/spec/x86_pc/core-hw.mk | 1 - repos/base-hw/src/core/kernel/cpu.cc | 34 +--- repos/base-hw/src/core/kernel/cpu.h | 4 +- repos/base-hw/src/core/kernel/cpu_context.h | 7 +- repos/base-hw/src/core/kernel/kernel.cc | 2 +- repos/base-hw/src/core/kernel/pd.h | 26 ++- repos/base-hw/src/core/kernel/thread.cc | 7 +- repos/base-hw/src/core/kernel/thread.h | 42 ++-- repos/base-hw/src/core/kernel/vm.h | 4 +- repos/base-hw/src/core/spec/arm/cpu.cc | 31 ++- repos/base-hw/src/core/spec/arm/cpu_support.h | 189 ++++++------------ .../src/core/spec/arm/cpu_trustzone.cc | 26 --- repos/base-hw/src/core/spec/arm/kernel/pd.cc | 56 ------ .../src/core/spec/arm/kernel/thread.cc | 35 ++-- .../core/spec/arm/kernel/thread_update_pd.cc | 4 +- .../spec/arm/smp/kernel/thread_update_pd.cc | 2 +- repos/base-hw/src/core/spec/arm_gic/pic.h | 2 + .../core/spec/arm_v7/trustzone/kernel/vm.cc | 11 +- .../spec/arm_v7/virtualization/kernel/vm.cc | 15 +- repos/base-hw/src/core/spec/cortex_a15/cpu.cc | 35 ++++ repos/base-hw/src/core/spec/cortex_a15/cpu.h | 178 +++++------------ .../src/core/spec/cortex_a15/kernel/cpu.cc | 21 +- repos/base-hw/src/core/spec/cortex_a9/cpu.h | 35 +--- repos/base-hw/src/core/spec/imx53/pic.h | 2 + repos/base-hw/src/core/spec/riscv/cpu.cc | 69 +++++++ repos/base-hw/src/core/spec/riscv/cpu.h | 98 +-------- .../base-hw/src/core/spec/riscv/kernel/pd.cc | 52 ----- .../src/core/spec/riscv/kernel/thread.cc | 21 +- repos/base-hw/src/core/spec/rpi/pic.h | 2 + .../src/core/spec/smp/kernel/kernel.cc | 7 +- repos/base-hw/src/core/spec/x86_64/cpu.cc | 19 +- repos/base-hw/src/core/spec/x86_64/cpu.h | 62 ++---- .../base-hw/src/core/spec/x86_64/kernel/pd.cc | 36 ---- .../src/core/spec/x86_64/kernel/thread.cc | 23 ++- .../spec/x86_64/kernel/thread_exception.cc | 6 +- .../x86_64/muen/kernel/thread_exception.cc | 7 +- .../src/core/spec/x86_64/muen/kernel/vm.cc | 27 +-- .../src/include/base/internal/align_at.h | 6 +- repos/base-hw/src/lib/hw/spec/arm/cpu.h | 4 +- 45 files changed, 463 insertions(+), 754 deletions(-) delete mode 100644 repos/base-hw/src/core/spec/arm/cpu_trustzone.cc delete mode 100644 repos/base-hw/src/core/spec/arm/kernel/pd.cc create mode 100644 repos/base-hw/src/core/spec/cortex_a15/cpu.cc create mode 100644 repos/base-hw/src/core/spec/riscv/cpu.cc delete mode 100644 repos/base-hw/src/core/spec/riscv/kernel/pd.cc delete mode 100644 repos/base-hw/src/core/spec/x86_64/kernel/pd.cc diff --git a/repos/base-hw/lib/mk/spec/arm/core-hw.inc b/repos/base-hw/lib/mk/spec/arm/core-hw.inc index 83701473a..375925a20 100644 --- a/repos/base-hw/lib/mk/spec/arm/core-hw.inc +++ b/repos/base-hw/lib/mk/spec/arm/core-hw.inc @@ -9,8 +9,8 @@ INC_DIR += $(BASE_DIR)/../base-hw/src/core/spec/arm # add C++ sources SRC_CC += spec/32bit/memory_map.cc +SRC_CC += spec/arm/cpu.cc SRC_CC += spec/arm/kernel/thread.cc -SRC_CC += spec/arm/kernel/pd.cc SRC_CC += spec/arm/platform_support.cc # add assembly sources diff --git a/repos/base-hw/lib/mk/spec/cortex_a15/core-hw.inc b/repos/base-hw/lib/mk/spec/cortex_a15/core-hw.inc index 0fe9f92e4..29fffe701 100644 --- a/repos/base-hw/lib/mk/spec/cortex_a15/core-hw.inc +++ b/repos/base-hw/lib/mk/spec/cortex_a15/core-hw.inc @@ -9,6 +9,7 @@ INC_DIR += $(BASE_DIR)/../base-hw/src/core/spec/cortex_a15 INC_DIR += $(BASE_DIR)/../base-hw/src/core/spec/arm_gic # add C++ sources +SRC_CC += spec/cortex_a15/cpu.cc SRC_CC += spec/cortex_a15/kernel/cpu.cc SRC_CC += spec/arm/smp/kernel/thread_update_pd.cc SRC_CC += spec/arm/smp/kernel/cpu.cc diff --git a/repos/base-hw/lib/mk/spec/cortex_a9/core-hw.inc b/repos/base-hw/lib/mk/spec/cortex_a9/core-hw.inc index 87d5a1f76..b78001b04 100644 --- a/repos/base-hw/lib/mk/spec/cortex_a9/core-hw.inc +++ b/repos/base-hw/lib/mk/spec/cortex_a9/core-hw.inc @@ -13,7 +13,6 @@ SRC_CC += spec/cortex_a9/kernel/cpu.cc SRC_CC += spec/cortex_a9/fpu.cc SRC_CC += spec/cortex_a9/board.cc SRC_CC += spec/cortex_a9/timer.cc -SRC_CC += spec/arm/cpu.cc SRC_CC += spec/arm/smp/kernel/thread_update_pd.cc SRC_CC += spec/arm/smp/kernel/cpu.cc SRC_CC += spec/arm_gic/pic.cc diff --git a/repos/base-hw/lib/mk/spec/imx53_qsb/core-hw.mk b/repos/base-hw/lib/mk/spec/imx53_qsb/core-hw.mk index fc280493d..d3f18351b 100644 --- a/repos/base-hw/lib/mk/spec/imx53_qsb/core-hw.mk +++ b/repos/base-hw/lib/mk/spec/imx53_qsb/core-hw.mk @@ -11,7 +11,6 @@ INC_DIR += $(REP_DIR)/src/core/spec/imx53 SRC_CC += spec/imx53/pic.cc SRC_CC += spec/imx53/timer.cc -SRC_CC += spec/arm/cpu_trustzone.cc ifneq ($(filter-out $(SPECS),trustzone),) SRC_CC += kernel/vm_thread_off.cc diff --git a/repos/base-hw/lib/mk/spec/muen/core-hw.mk b/repos/base-hw/lib/mk/spec/muen/core-hw.mk index 25b9ddafe..f354fed3a 100644 --- a/repos/base-hw/lib/mk/spec/muen/core-hw.mk +++ b/repos/base-hw/lib/mk/spec/muen/core-hw.mk @@ -18,7 +18,6 @@ SRC_S += spec/x86_64/crt0.s SRC_S += spec/x86_64/exception_vector.s # add C++ sources -SRC_CC += spec/x86_64/muen/kernel/cpu_exception.cc SRC_CC += spec/x86_64/muen/kernel/thread_exception.cc SRC_CC += spec/x86_64/muen/platform_support.cc SRC_CC += spec/x86_64/muen/kernel/vm.cc @@ -34,7 +33,6 @@ SRC_CC += spec/x86_64/bios_data_area.cc SRC_CC += spec/x86_64/cpu.cc SRC_CC += spec/x86_64/fpu.cc SRC_CC += spec/x86_64/kernel/cpu.cc -SRC_CC += spec/x86_64/kernel/pd.cc SRC_CC += spec/x86_64/kernel/thread.cc SRC_CC += spec/x86_64/kernel/thread.cc SRC_CC += spec/x86_64/platform_support_common.cc diff --git a/repos/base-hw/lib/mk/spec/riscv/core-hw.mk b/repos/base-hw/lib/mk/spec/riscv/core-hw.mk index c34e512d0..0f489769c 100644 --- a/repos/base-hw/lib/mk/spec/riscv/core-hw.mk +++ b/repos/base-hw/lib/mk/spec/riscv/core-hw.mk @@ -5,8 +5,8 @@ CC_OPT += -fno-delete-null-pointer-checks # add C++ sources SRC_CC += platform_services.cc SRC_CC += kernel/vm_thread_off.cc kernel/kernel.cc +SRC_CC += spec/riscv/cpu.cc SRC_CC += spec/riscv/kernel/thread.cc -SRC_CC += spec/riscv/kernel/pd.cc SRC_CC += spec/riscv/kernel/cpu.cc SRC_CC += spec/riscv/platform_support.cc SRC_CC += spec/riscv/timer.cc diff --git a/repos/base-hw/lib/mk/spec/x86_pc/core-hw.mk b/repos/base-hw/lib/mk/spec/x86_pc/core-hw.mk index 53c564408..55035f922 100644 --- a/repos/base-hw/lib/mk/spec/x86_pc/core-hw.mk +++ b/repos/base-hw/lib/mk/spec/x86_pc/core-hw.mk @@ -27,7 +27,6 @@ SRC_CC += spec/x86_64/bios_data_area.cc SRC_CC += spec/x86_64/cpu.cc SRC_CC += spec/x86_64/fpu.cc SRC_CC += spec/x86_64/kernel/cpu.cc -SRC_CC += spec/x86_64/kernel/pd.cc SRC_CC += spec/x86_64/kernel/thread.cc SRC_CC += spec/x86_64/kernel/thread.cc SRC_CC += spec/x86_64/platform_support_common.cc diff --git a/repos/base-hw/src/core/kernel/cpu.cc b/repos/base-hw/src/core/kernel/cpu.cc index 5d7784620..5b87b1943 100644 --- a/repos/base-hw/src/core/kernel/cpu.cc +++ b/repos/base-hw/src/core/kernel/cpu.cc @@ -133,7 +133,6 @@ Cpu::Idle_thread::Idle_thread(Cpu * const cpu) affinity(cpu); Thread::_pd = core_pd(); - Thread::_pd->admit(*regs); } @@ -169,7 +168,7 @@ Cpu_job & Cpu::schedule() /* update scheduler */ time_t quota = _timer.update_time(); Job & old_job = scheduled_job(); - old_job.exception(id()); + old_job.exception(*this); _timer.process_timeouts(); _scheduler.update(quota); @@ -181,14 +180,20 @@ Cpu_job & Cpu::schedule() _timer.schedule_timeout(); - /* switch to new job */ - switch_to(new_job); - /* return new job */ return new_job; } +Genode::size_t kernel_stack_size = Cpu::KERNEL_STACK_SIZE; +Genode::uint8_t kernel_stack[NR_OF_CPUS][Cpu::KERNEL_STACK_SIZE] +__attribute__((aligned(Genode::get_page_size()))); + + +addr_t Cpu::stack_start() { + return (addr_t)&kernel_stack + KERNEL_STACK_SIZE * (_id+1); } + + Cpu::Cpu(unsigned const id) : _id(id), _timer(_id), @@ -222,22 +227,3 @@ Cpu_pool::Cpu_pool() Cpu_domain_update::Cpu_domain_update() { for (unsigned i = 0; i < NR_OF_CPUS; i++) { _pending[i] = false; } } - - -/** - * FIXME THIS IS ONLY USED BY IDLE THREAD - * Enable kernel-entry assembly to get an exclusive stack for every CPU - * - * The stack alignment is determined as follows: - * - * 1) There is an architectural minimum alignment for stacks that originates - * from the assumptions that some instructions make. - * 2) Shared cache lines between yet uncached and already cached - * CPUs during multiprocessor bring-up must be avoided. Thus, the alignment - * must be at least the maximum line size of global caches. - * 3) The alignment that originates from 1) and 2) is assumed to be always - * less or equal to the minimum page size. - */ -Genode::size_t kernel_stack_size = Cpu::KERNEL_STACK_SIZE; -Genode::uint8_t kernel_stack[NR_OF_CPUS][Cpu::KERNEL_STACK_SIZE] -__attribute__((aligned(Genode::get_page_size()))); diff --git a/repos/base-hw/src/core/kernel/cpu.h b/repos/base-hw/src/core/kernel/cpu.h index 48eb0b151..6f14308e2 100644 --- a/repos/base-hw/src/core/kernel/cpu.h +++ b/repos/base-hw/src/core/kernel/cpu.h @@ -142,9 +142,7 @@ class Kernel::Cpu : public Genode::Cpu, public Irq::Pool, private Timeout time_t time() const { return _timer.time(); } - /*************** - ** Accessors ** - ***************/ + addr_t stack_start(); /** * Returns the currently active job diff --git a/repos/base-hw/src/core/kernel/cpu_context.h b/repos/base-hw/src/core/kernel/cpu_context.h index 7c86d18d6..44942c96d 100644 --- a/repos/base-hw/src/core/kernel/cpu_context.h +++ b/repos/base-hw/src/core/kernel/cpu_context.h @@ -16,7 +16,6 @@ #define _CORE__KERNEL__CPU_CONTEXT_H_ /* core includes */ -#include #include #include @@ -69,7 +68,7 @@ class Kernel::Cpu_domain_update : public Double_list_item virtual void _cpu_domain_update_unblocks() = 0; }; -class Kernel::Cpu_job : public Genode::Cpu::User_context, public Cpu_share +class Kernel::Cpu_job : public Cpu_share { protected: @@ -105,12 +104,12 @@ class Kernel::Cpu_job : public Genode::Cpu::User_context, public Cpu_share /** * Handle exception that occured during execution on CPU 'id' */ - virtual void exception(unsigned const id) = 0; + virtual void exception(Cpu & cpu) = 0; /** * Continue execution on CPU 'id' */ - virtual void proceed(unsigned const id) = 0; + virtual void proceed(Cpu & cpu) = 0; /** * Return which job currently uses our CPU-share diff --git a/repos/base-hw/src/core/kernel/kernel.cc b/repos/base-hw/src/core/kernel/kernel.cc index 72fccc0b9..7eb7809db 100644 --- a/repos/base-hw/src/core/kernel/kernel.cc +++ b/repos/base-hw/src/core/kernel/kernel.cc @@ -21,7 +21,7 @@ extern "C" void kernel() using namespace Kernel; Cpu * const cpu = cpu_pool()->cpu(Cpu::executing_id()); - cpu->schedule().proceed(cpu->id()); + cpu->schedule().proceed(*cpu); } diff --git a/repos/base-hw/src/core/kernel/pd.h b/repos/base-hw/src/core/kernel/pd.h index f5e8a307f..42aec8ba9 100644 --- a/repos/base-hw/src/core/kernel/pd.h +++ b/repos/base-hw/src/core/kernel/pd.h @@ -16,6 +16,7 @@ #define _CORE__KERNEL__PD_H_ /* core includes */ +#include #include #include #include @@ -34,8 +35,7 @@ namespace Kernel } -class Kernel::Pd : public Genode::Cpu::Pd, - public Kernel::Object +class Kernel::Pd : public Kernel::Object { public: @@ -52,6 +52,8 @@ class Kernel::Pd : public Genode::Cpu::Pd, public: + Genode::Cpu::Mmu_context mmu_regs; + /** * Constructor * @@ -59,14 +61,19 @@ class Kernel::Pd : public Genode::Cpu::Pd, * \param platform_pd core object of the PD */ Pd(Hw::Page_table * const table, - Genode::Platform_pd * const platform_pd); + Genode::Platform_pd * const platform_pd) + : _table(table), _platform_pd(platform_pd), + mmu_regs((addr_t)table) + { + capid_t invalid = _capid_alloc.alloc(); + assert(invalid == cap_id_invalid()); + } - ~Pd(); - - /** - * Let the CPU context 'c' join the PD - */ - void admit(Genode::Cpu::Context & c); + ~Pd() + { + while (Object_identity_reference *oir = _cap_tree.first()) + oir->~Object_identity_reference(); + } static capid_t syscall_create(void * const dst, @@ -80,6 +87,7 @@ class Kernel::Pd : public Genode::Cpu::Pd, static void syscall_destroy(Pd * const pd) { call(call_id_delete_pd(), (Call_arg)pd); } + /*************** ** Accessors ** ***************/ diff --git a/repos/base-hw/src/core/kernel/thread.cc b/repos/base-hw/src/core/kernel/thread.cc index 6e845aa62..ea62c8340 100644 --- a/repos/base-hw/src/core/kernel/thread.cc +++ b/repos/base-hw/src/core/kernel/thread.cc @@ -201,7 +201,6 @@ void Thread::_call_start_thread() /* join protection domain */ thread->_pd = (Pd *) user_arg_3(); - thread->_pd->admit(*thread->regs); thread->Ipc_node::_init((Native_utcb *)user_arg_4(), this); thread->_become_active(); } @@ -625,10 +624,7 @@ Thread::Thread(unsigned const priority, unsigned const quota, : Cpu_job(priority, quota), _fault_pd(0), _fault_addr(0), _fault_writes(0), _state(AWAITS_START), - _signal_receiver(0), _label(label), _core(core) -{ - _init(); -} + _signal_receiver(0), _label(label), _core(core), regs(core) { } void Thread::print(Genode::Output &out) const @@ -670,7 +666,6 @@ Core_thread::Core_thread() affinity(cpu_pool()->primary_cpu()); _utcb = utcb; Thread::_pd = core_pd(); - Thread::_pd->admit(*regs); _become_active(); } diff --git a/repos/base-hw/src/core/kernel/thread.h b/repos/base-hw/src/core/kernel/thread.h index 4a9ad52ed..39d75e6b5 100644 --- a/repos/base-hw/src/core/kernel/thread.h +++ b/repos/base-hw/src/core/kernel/thread.h @@ -15,6 +15,7 @@ #define _CORE__KERNEL__THREAD_H_ /* core includes */ +#include #include #include #include @@ -36,7 +37,7 @@ class Kernel::Thread public Ipc_node, public Signal_context_killer, public Signal_handler, private Timeout { - private: + protected: enum { START_VERBOSE = 0 }; @@ -64,8 +65,6 @@ class Kernel::Thread bool const _core = false; bool _fault_exec = false; - void _init(); - /** * Notice that another thread yielded the CPU to this thread */ @@ -83,15 +82,11 @@ class Kernel::Thread int _route_event(unsigned const event_id, Signal_context * const signal_context_id); - protected: - /** * Switch from an inactive state to the active state */ void _become_active(); - private: - /** * Switch from the active state to the inactive state 's' */ @@ -226,6 +221,8 @@ class Kernel::Thread public: + Genode::Align_at regs; + /** * Constructor * @@ -245,6 +242,23 @@ class Kernel::Thread Thread(char const * const label) : Thread(Cpu_priority::MIN, 0, label, true) { } + + /************************** + ** Support for syscalls ** + **************************/ + + void user_arg_0(Kernel::Call_arg const arg); + void user_arg_1(Kernel::Call_arg const arg); + void user_arg_2(Kernel::Call_arg const arg); + void user_arg_3(Kernel::Call_arg const arg); + void user_arg_4(Kernel::Call_arg const arg); + + Kernel::Call_arg user_arg_0() const; + Kernel::Call_arg user_arg_1() const; + Kernel::Call_arg user_arg_2() const; + Kernel::Call_arg user_arg_3() const; + Kernel::Call_arg user_arg_4() const; + /** * Syscall to create a thread * @@ -292,8 +306,8 @@ class Kernel::Thread ** Cpu_job ** *************/ - void exception(unsigned const cpu); - void proceed(unsigned const cpu); + void exception(Cpu & cpu); + void proceed(Cpu & cpu); Cpu_job * helping_sink(); @@ -319,15 +333,11 @@ class Kernel::Thread /** * The first core thread in the system bootstrapped by the Kernel */ -class Kernel::Core_thread : public Core_object +struct Kernel::Core_thread : Core_object { - private: + Core_thread(); - Core_thread(); - - public: - - static Thread & singleton(); + static Thread & singleton(); }; #endif /* _CORE__KERNEL__THREAD_H_ */ diff --git a/repos/base-hw/src/core/kernel/vm.h b/repos/base-hw/src/core/kernel/vm.h index 0d8999cc3..dedb3bda1 100644 --- a/repos/base-hw/src/core/kernel/vm.h +++ b/repos/base-hw/src/core/kernel/vm.h @@ -118,8 +118,8 @@ class Kernel::Vm : public Cpu_job, ** Cpu_job ** *************/ - void exception(unsigned const cpu); - void proceed(unsigned const cpu); + void exception(Cpu & cpu); + void proceed(Cpu & cpu); Cpu_job * helping_sink() { return this; } }; diff --git a/repos/base-hw/src/core/spec/arm/cpu.cc b/repos/base-hw/src/core/spec/arm/cpu.cc index 3217086f4..5c5e854bb 100644 --- a/repos/base-hw/src/core/spec/arm/cpu.cc +++ b/repos/base-hw/src/core/spec/arm/cpu.cc @@ -11,16 +11,39 @@ * under the terms of the GNU Affero General Public License version 3. */ +#include +#include + +#include #include -void Genode::Arm_cpu::User_context::init(bool privileged) +Genode::Arm_cpu::Context::Context(bool privileged) { using Psr = Arm_cpu::Psr; Psr::access_t v = 0; Psr::M::set(v, privileged ? Psr::M::SYS : Psr::M::USR); - Psr::F::set(v, 1); + if (Genode::Pic::fast_interrupts()) Psr::I::set(v, 1); + else Psr::F::set(v, 1); Psr::A::set(v, 1); - regs->cpsr = v; - regs->cpu_exception = Genode::Arm_cpu::Context::RESET; + cpsr = v; + cpu_exception = RESET; +} + + +using Asid_allocator = Genode::Bit_allocator<256>; + +static Asid_allocator &alloc() { + return *unmanaged_singleton(); } + + +Genode::Arm_cpu::Mmu_context::Mmu_context(addr_t table) +: cidr((Genode::uint8_t)alloc().alloc()), ttbr0(Ttbr0::init(table)) { } + + +Genode::Arm_cpu::Mmu_context::~Mmu_context() +{ + /* flush TLB by ASID */ + Cpu::Tlbiasid::write(id()); + alloc().free(id()); } diff --git a/repos/base-hw/src/core/spec/arm/cpu_support.h b/repos/base-hw/src/core/spec/arm/cpu_support.h index 7fa39bc71..2fa009f27 100644 --- a/repos/base-hw/src/core/spec/arm/cpu_support.h +++ b/repos/base-hw/src/core/spec/arm/cpu_support.h @@ -58,130 +58,23 @@ struct Genode::Arm_cpu : public Hw::Arm_cpu } }; - struct Dfsr : Hw::Arm_cpu::Dfsr + struct alignas(4) Context : Cpu_state { - struct Wnr : Bitfield<11, 1> { }; /* write not read bit */ - }; - - /** - * Extend basic CPU state by members relevant for 'base-hw' only - */ - struct Context : Cpu_state - { - Cidr::access_t cidr; - Ttbr0::access_t ttbr0; - - /** - * Return base of assigned translation table - */ - addr_t translation_table() const { - return Ttbr::Ba::masked(ttbr0); } - - - /** - * Assign translation-table base 'table' - */ - void translation_table(addr_t const table) { - ttbr0 = Ttbr0::init(table); } - - /** - * Assign protection domain - */ - void protection_domain(Genode::uint8_t const id) { cidr = id; } + Context(bool privileged); }; /** * This class comprises ARM specific protection domain attributes */ - struct Pd + struct Mmu_context { - Genode::uint8_t asid; /* address space id */ + Cidr::access_t cidr; + Ttbr0::access_t ttbr0; - Pd(Genode::uint8_t id) : asid(id) {} - }; - - /** - * An usermode execution state - */ - struct User_context - { - Align_at regs; - - void init(bool privileged); - - /** - * Support for kernel calls - */ - void user_arg_0(Kernel::Call_arg const arg) { regs->r0 = arg; } - void user_arg_1(Kernel::Call_arg const arg) { regs->r1 = arg; } - void user_arg_2(Kernel::Call_arg const arg) { regs->r2 = arg; } - void user_arg_3(Kernel::Call_arg const arg) { regs->r3 = arg; } - void user_arg_4(Kernel::Call_arg const arg) { regs->r4 = arg; } - Kernel::Call_arg user_arg_0() const { return regs->r0; } - Kernel::Call_arg user_arg_1() const { return regs->r1; } - Kernel::Call_arg user_arg_2() const { return regs->r2; } - Kernel::Call_arg user_arg_3() const { return regs->r3; } - Kernel::Call_arg user_arg_4() const { return regs->r4; } - - /** - * Return if the context is in a page fault due to translation miss - * - * \param va holds the virtual fault-address if call returns 1 - * \param w holds whether it's a write fault if call returns 1 - * \param p holds whether it's a permission fault if call returns 1 - */ - bool in_fault(addr_t & va, addr_t & w, bool & p) const - { - /* translation fault on section */ - static constexpr Fsr::access_t section = 5; - /* translation fault on page */ - static constexpr Fsr::access_t page = 7; - /* permission fault on page */ - static constexpr Fsr::access_t permission = 0xf; - - switch (regs->cpu_exception) { - - case Context::PREFETCH_ABORT: - { - /* check if fault was caused by a translation miss */ - Ifsr::access_t const fs = Fsr::Fs::get(Ifsr::read()); - - if (fs == permission) { - w = 0; - va = regs->ip; - p = true; - return true; - } - - if (fs != section && fs != page) - return false; - - /* fetch fault data */ - w = 0; - va = regs->ip; - p = false; - return true; - } - case Context::DATA_ABORT: - { - /* check if fault is of known type */ - Dfsr::access_t const fs = Fsr::Fs::get(Dfsr::read()); - if (fs != permission && fs != section && fs != page) - return false; - - /* fetch fault data */ - Dfsr::access_t const dfsr = Dfsr::read(); - w = Dfsr::Wnr::get(dfsr); - va = Dfar::read(); - p = false; - return true; - } - - default: - return false; - }; - } + Mmu_context(addr_t page_table_base); + ~Mmu_context(); + uint8_t id() { return cidr; } }; /** @@ -233,23 +126,65 @@ struct Genode::Arm_cpu : public Hw::Arm_cpu for (; base < top; base += line_size) { Icimvau::write(base); } } + void switch_to(Context&, Mmu_context & o) + { + if (o.cidr == 0) return; + + Cidr::access_t cidr = Cidr::read(); + if (cidr != o.cidr) { + Cidr::write(o.cidr); + Ttbr0::write(o.ttbr0); + } + } + + static bool in_fault(Context & c, addr_t & va, addr_t & w, bool & p) + { + /* translation fault on section */ + static constexpr Fsr::access_t section = 5; + /* translation fault on page */ + static constexpr Fsr::access_t page = 7; + /* permission fault on page */ + static constexpr Fsr::access_t permission = 0xf; + + if (c.cpu_exception == Context::PREFETCH_ABORT) { + /* check if fault was caused by a translation miss */ + Ifsr::access_t const fs = Fsr::Fs::get(Ifsr::read()); + + if (fs == permission) { + w = 0; + va = Ifar::read(); + p = true; + return true; + } + + if (fs != section && fs != page) + return false; + + /* fetch fault data */ + w = 0; + va = Ifar::read(); + p = false; + return true; + } else { + /* check if fault is of known type */ + Dfsr::access_t const fs = Fsr::Fs::get(Dfsr::read()); + if (fs != permission && fs != section && fs != page) + return false; + + /* fetch fault data */ + Dfsr::access_t const dfsr = Dfsr::read(); + w = Dfsr::Wnr::get(dfsr); + va = Dfar::read(); + p = false; + return true; + } + } /************* ** Dummies ** *************/ - void switch_to(User_context & o) - { - if (o.regs->cidr == 0) return; - - Cidr::access_t cidr = Cidr::read(); - if (cidr != o.regs->cidr) { - Cidr::write(o.regs->cidr); - Ttbr0::write(o.regs->ttbr0); - } - } - - bool retry_undefined_instr(User_context&) { return false; } + bool retry_undefined_instr(Context&) { return false; } /** * Return kernel name of the executing CPU diff --git a/repos/base-hw/src/core/spec/arm/cpu_trustzone.cc b/repos/base-hw/src/core/spec/arm/cpu_trustzone.cc deleted file mode 100644 index a938b833c..000000000 --- a/repos/base-hw/src/core/spec/arm/cpu_trustzone.cc +++ /dev/null @@ -1,26 +0,0 @@ -/* - * \brief ARM cpu context initialization when TrustZone is used - * \author Stefan Kalkowski - * \date 2017-04-12 - */ - -/* - * Copyright (C) 2017 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -#include - -void Genode::Arm_cpu::User_context::init(bool privileged) -{ - using Psr = Genode::Arm_cpu::Psr; - - Psr::access_t v = 0; - Psr::M::set(v, privileged ? Psr::M::SYS : Psr::M::USR); - Psr::I::set(v, 1); - Psr::A::set(v, 1); - regs->cpsr = v; - regs->cpu_exception = Cpu::Context::RESET; -} diff --git a/repos/base-hw/src/core/spec/arm/kernel/pd.cc b/repos/base-hw/src/core/spec/arm/kernel/pd.cc deleted file mode 100644 index e40e1805d..000000000 --- a/repos/base-hw/src/core/spec/arm/kernel/pd.cc +++ /dev/null @@ -1,56 +0,0 @@ -/* - * \brief Kernel backend for protection domains - * \author Stefan Kalkowski - * \date 2015-03-20 - */ - -/* - * Copyright (C) 2015-2017 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -/* Genode includes */ -#include - -/* core includes */ -#include -#include -#include - -using Asid_allocator = Genode::Bit_allocator<256>; - -static Asid_allocator &alloc() { - return *unmanaged_singleton(); } - - -Kernel::Pd::Pd(Hw::Page_table * const table, - Genode::Platform_pd * const platform_pd) -: Kernel::Cpu::Pd((Genode::uint8_t)alloc().alloc()), - _table(table), _platform_pd(platform_pd) -{ - capid_t invalid = _capid_alloc.alloc(); - assert(invalid == cap_id_invalid()); -} - - -Kernel::Pd::~Pd() { - - while (Object_identity_reference *oir = _cap_tree.first()) - oir->~Object_identity_reference(); - - /* clean up buffers of memory management */ - Cpu * const cpu = cpu_pool()->cpu(Cpu::executing_id()); - cpu->clean_invalidate_data_cache(); - cpu->invalidate_instr_cache(); - Cpu::Tlbiasid::write(asid); /* flush TLB by ASID */ - alloc().free(asid); -} - - -void Kernel::Pd::admit(Kernel::Cpu::Context & c) -{ - c.protection_domain(asid); - c.translation_table((addr_t)translation_table()); -} 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 b3a6d6c60..0f7707bc1 100644 --- a/repos/base-hw/src/core/spec/arm/kernel/thread.cc +++ b/repos/base-hw/src/core/spec/arm/kernel/thread.cc @@ -19,13 +19,7 @@ using namespace Kernel; -void Kernel::Thread::_init() -{ - init(_core); -} - - -void Thread::exception(unsigned const cpu) +void Thread::exception(Cpu & cpu) { switch (regs->cpu_exception) { case Cpu::Context::SUPERVISOR_CALL: @@ -37,10 +31,10 @@ void Thread::exception(unsigned const cpu) return; case Cpu::Context::INTERRUPT_REQUEST: case Cpu::Context::FAST_INTERRUPT_REQUEST: - _interrupt(cpu); + _interrupt(cpu.id()); return; case Cpu::Context::UNDEFINED_INSTRUCTION: - if (_cpu->retry_undefined_instr(*this)) { return; } + if (_cpu->retry_undefined_instr(*regs)) { return; } Genode::warning(*this, ": undefined instruction at ip=", Genode::Hex(regs->ip)); _die(); @@ -59,14 +53,14 @@ void Thread::exception(unsigned const cpu) void Thread::_mmu_exception() { _become_inactive(AWAITS_RESTART); - if (in_fault(_fault_addr, _fault_writes, _fault_exec)) { + if (Cpu::in_fault(*regs, _fault_addr, _fault_writes, _fault_exec)) { _fault_pd = (addr_t)_pd->platform_pd(); /* * Core should never raise a page-fault. If this happens, print out an * error message with debug information. */ - if (_pd == Kernel::core_pd()) + if (_core) Genode::error("page fault in core thread (", label(), "): " "ip=", Genode::Hex(regs->ip), " fault=", Genode::Hex(_fault_addr)); @@ -142,9 +136,11 @@ void Kernel::Thread::_call_update_instr_region() extern void * kernel_stack; -void Thread::proceed(unsigned const cpu) +void Thread::proceed(Cpu & cpu) { - regs->cpu_exception = (addr_t)&kernel_stack + Cpu::KERNEL_STACK_SIZE * (cpu+1); + cpu.switch_to(*regs, pd()->mmu_regs); + + regs->cpu_exception = cpu.stack_start(); asm volatile("mov sp, %0 \n" "msr spsr_cxsf, %1 \n" @@ -154,3 +150,16 @@ void Thread::proceed(unsigned const cpu) :: "r" (static_cast(&*regs)), "r" (regs->cpsr), "r" (regs->ip)); } + + +void Thread::user_arg_0(Kernel::Call_arg const arg) { regs->r0 = arg; } +void Thread::user_arg_1(Kernel::Call_arg const arg) { regs->r1 = arg; } +void Thread::user_arg_2(Kernel::Call_arg const arg) { regs->r2 = arg; } +void Thread::user_arg_3(Kernel::Call_arg const arg) { regs->r3 = arg; } +void Thread::user_arg_4(Kernel::Call_arg const arg) { regs->r4 = arg; } + +Kernel::Call_arg Thread::user_arg_0() const { return regs->r0; } +Kernel::Call_arg Thread::user_arg_1() const { return regs->r1; } +Kernel::Call_arg Thread::user_arg_2() const { return regs->r2; } +Kernel::Call_arg Thread::user_arg_3() const { return regs->r3; } +Kernel::Call_arg Thread::user_arg_4() const { return regs->r4; } diff --git a/repos/base-hw/src/core/spec/arm/kernel/thread_update_pd.cc b/repos/base-hw/src/core/spec/arm/kernel/thread_update_pd.cc index 011d4deec..291974650 100644 --- a/repos/base-hw/src/core/spec/arm/kernel/thread_update_pd.cc +++ b/repos/base-hw/src/core/spec/arm/kernel/thread_update_pd.cc @@ -21,8 +21,8 @@ void Kernel::Thread::_call_update_pd() Cpu * const cpu = cpu_pool()->cpu(Cpu::executing_id()); cpu->invalidate_instr_cache(); cpu->clean_invalidate_data_cache(); - if (pd->asid) - Cpu::Tlbiasid::write(pd->asid); /* flush TLB by ASID */ + if (pd->mmu_regs.id()) + Cpu::Tlbiasid::write(pd->mmu_regs.id()); /* flush TLB by ASID */ else Cpu::Tlbiall::write(0); } diff --git a/repos/base-hw/src/core/spec/arm/smp/kernel/thread_update_pd.cc b/repos/base-hw/src/core/spec/arm/smp/kernel/thread_update_pd.cc index da42e4e7d..a4943d9ac 100644 --- a/repos/base-hw/src/core/spec/arm/smp/kernel/thread_update_pd.cc +++ b/repos/base-hw/src/core/spec/arm/smp/kernel/thread_update_pd.cc @@ -18,6 +18,6 @@ void Kernel::Thread::_call_update_pd() { Pd * const pd = (Pd *) user_arg_1(); - if (Cpu_domain_update::_do_global(pd->asid)) { + if (Cpu_domain_update::_do_global(pd->mmu_regs.id())) { _become_inactive(AWAITS_RESTART); } } diff --git a/repos/base-hw/src/core/spec/arm_gic/pic.h b/repos/base-hw/src/core/spec/arm_gic/pic.h index 95499c5ba..f4f23d259 100644 --- a/repos/base-hw/src/core/spec/arm_gic/pic.h +++ b/repos/base-hw/src/core/spec/arm_gic/pic.h @@ -50,6 +50,8 @@ class Genode::Pic : public Hw::Pic Sgir::Target_list_filter::ALL_OTHER); _distr.write(sgir); } + + static constexpr bool fast_interrupts() { return false; } }; #endif /* _CORE__SPEC__ARM_GIC__PIC_H_ */ diff --git a/repos/base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc b/repos/base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc index 7dfaa2085..f4792c07b 100644 --- a/repos/base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc +++ b/repos/base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc @@ -13,6 +13,7 @@ */ /* core includes */ +#include #include using namespace Kernel; @@ -30,12 +31,12 @@ Kernel::Vm::Vm(void * const state, Kernel::Vm::~Vm() {} -void Vm::exception(unsigned const cpu) +void Vm::exception(Cpu & cpu) { switch(_state->cpu_exception) { case Genode::Cpu_state::INTERRUPT_REQUEST: case Genode::Cpu_state::FAST_INTERRUPT_REQUEST: - _interrupt(cpu); + _interrupt(cpu.id()); return; case Genode::Cpu_state::DATA_ABORT: _state->dfar = Cpu::Dfar::read(); @@ -53,7 +54,7 @@ extern "C" void monitor_mode_enter_normal_world(Cpu::Context*, void*); extern void * kernel_stack; -void Vm::proceed(unsigned const cpu) +void Vm::proceed(Cpu & cpu) { unsigned const irq = _state->irq_injection; if (irq) { @@ -65,6 +66,6 @@ void Vm::proceed(unsigned const cpu) } } - void * stack = (void*)((addr_t)&kernel_stack + Cpu::KERNEL_STACK_SIZE * (cpu+1)); - monitor_mode_enter_normal_world(reinterpret_cast(_state), stack); + monitor_mode_enter_normal_world(reinterpret_cast(_state), + (void*) cpu.stack_start()); } diff --git a/repos/base-hw/src/core/spec/arm_v7/virtualization/kernel/vm.cc b/repos/base-hw/src/core/spec/arm_v7/virtualization/kernel/vm.cc index 2cd916fe4..f285d9dbd 100644 --- a/repos/base-hw/src/core/spec/arm_v7/virtualization/kernel/vm.cc +++ b/repos/base-hw/src/core/spec/arm_v7/virtualization/kernel/vm.cc @@ -172,7 +172,7 @@ struct Kernel::Virtual_timer /** * Load the virtual timer state from VM state */ - static void load(Genode::Vm_state *s, unsigned const cpu_id) + static void load(Genode::Vm_state *s) { if (s->timer_irq) timer().irq.enable(); @@ -213,7 +213,7 @@ Kernel::Vm::Vm(void * const state, affinity(cpu_pool()->primary_cpu()); Virtual_pic::pic().irq.enable(); - vt_host_context.sp = (addr_t)&kernel_stack + Cpu::KERNEL_STACK_SIZE; + vt_host_context.sp = _cpu->stack_start(); vt_host_context.ttbr0 = Cpu::Ttbr0_64bit::read(); vt_host_context.ttbr1 = Cpu::Ttbr1_64bit::read(); vt_host_context.sctlr = Cpu::Sctlr::read(); @@ -227,7 +227,7 @@ Kernel::Vm::Vm(void * const state, Kernel::Vm::~Vm() { alloc().free(_id); } -void Kernel::Vm::exception(unsigned const cpu_id) +void Kernel::Vm::exception(Cpu & cpu) { Virtual_timer::save(_state); @@ -235,7 +235,7 @@ void Kernel::Vm::exception(unsigned const cpu_id) case Genode::Cpu_state::INTERRUPT_REQUEST: case Genode::Cpu_state::FAST_INTERRUPT_REQUEST: _state->gic_irq = Board::VT_MAINTAINANCE_IRQ; - _interrupt(cpu_id); + _interrupt(cpu.id()); break; default: pause(); @@ -247,12 +247,13 @@ void Kernel::Vm::exception(unsigned const cpu_id) } -void Kernel::Vm::proceed(unsigned const cpu_id) +void Kernel::Vm::proceed(Cpu &) { /* * the following values have to be enforced by the hypervisor */ - _state->vttbr = Cpu::Ttbr0::init((Genode::addr_t)_table, _id); + _state->vttbr = Cpu::Ttbr_64bit::Ba::masked((Cpu::Ttbr_64bit::access_t)_table); + Cpu::Ttbr_64bit::Asid::set(_state->vttbr, _id); /* * use the following report fields not needed for loading the context @@ -263,7 +264,7 @@ void Kernel::Vm::proceed(unsigned const cpu_id) _state->hpfar = Cpu::Hcr::init(); Virtual_pic::load(_state); - Virtual_timer::load(_state, cpu_id); + Virtual_timer::load(_state); hypervisor_enter_vm(reinterpret_cast(_state)); } diff --git a/repos/base-hw/src/core/spec/cortex_a15/cpu.cc b/repos/base-hw/src/core/spec/cortex_a15/cpu.cc new file mode 100644 index 000000000..422f39429 --- /dev/null +++ b/repos/base-hw/src/core/spec/cortex_a15/cpu.cc @@ -0,0 +1,35 @@ +/* + * \brief Cortex A15 specific MMU context initialization + * \author Stefan Kalkowski + * \date 2017-10-17 + */ + +/* + * Copyright (C) 2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#include +#include + +#include + +using Asid_allocator = Genode::Bit_allocator<256>; + +static Asid_allocator &alloc() { + return *unmanaged_singleton(); } + + +Genode::Cpu::Mmu_context::Mmu_context(addr_t table) +: ttbr0(Ttbr_64bit::Ba::masked((Ttbr_64bit::access_t)table)) { + Ttbr_64bit::Asid::set(ttbr0, (Genode::uint8_t)alloc().alloc()); } + + +Genode::Cpu::Mmu_context::~Mmu_context() +{ + /* flush TLB by ASID */ + Cpu::Tlbiasid::write(id()); + alloc().free(id()); +} diff --git a/repos/base-hw/src/core/spec/cortex_a15/cpu.h b/repos/base-hw/src/core/spec/cortex_a15/cpu.h index 8f5eab89c..87605156e 100644 --- a/repos/base-hw/src/core/spec/cortex_a15/cpu.h +++ b/repos/base-hw/src/core/spec/cortex_a15/cpu.h @@ -25,30 +25,6 @@ class Genode::Cpu : public Arm_v7_cpu { public: - /** - * Translation table base register 0 (64-bit format) - */ - struct Ttbr0 : Ttbr0_64bit - { - enum Memory_region { NON_CACHEABLE = 0, CACHEABLE = 1 }; - - /** - * Return initialized value - * - * \param table base of targeted translation table - */ - static access_t init(addr_t const table, unsigned const id) - { - access_t v = Ttbr_64bit::Ba::masked((access_t)table); - Ttbr_64bit::Asid::set(v, id); - return v; - } - - static Genode::uint32_t init(addr_t const table) { - return table; } - }; - - /********************************* ** Virtualization extensions ** *********************************/ @@ -115,124 +91,73 @@ class Genode::Cpu : public Arm_v7_cpu }; }; + /** - * Extend basic CPU state by members relevant for 'base-hw' only - * - * Note: this class redefines Genode::Arm::Context + * An usermode execution state */ - struct Context : Genode::Cpu_state + struct Mmu_context { - Ttbr0::access_t ttbr0 = 0; - addr_t sctlr = 0; - addr_t ttbrc = 0; - addr_t mair0 = 0; + Ttbr_64bit::access_t ttbr0; - /** - * Return base of assigned translation table - */ - addr_t translation_table() const { - return Ttbr_64bit::Ba::masked(ttbr0); } + Mmu_context(addr_t const table); + ~Mmu_context(); - /** - * Assign translation-table base 'table' - */ - void translation_table(addr_t const table) { - Ttbr_64bit::Ba::set(ttbr0, Ttbr_64bit::Ba::get(table)); } - - /** - * Assign protection domain - */ - void protection_domain(Genode::uint8_t const id) { - Ttbr_64bit::Asid::set(ttbr0, id); } + Genode::uint8_t id() const { return Ttbr_64bit::Asid::get(ttbr0); } }; /** - * An usermode execution state + * Return if the context is in a page fault due to translation miss * - * FIXME: this class largely overlaps with Genode::Arm::User_context + * \param va holds the virtual fault-address if call returns 1 + * \param w holds wether it's a write fault if call returns 1 + * \param p holds whether it's a permission fault if call returns 1 */ - struct User_context + static bool in_fault(Context & c, addr_t & va, addr_t & w, bool & p) { - Align_at regs; + /* permission fault on page, 2nd level */ + static constexpr Fsr::access_t permission = 0b1111; - void init(bool privileged) - { - Psr::access_t v = 0; - Psr::M::set(v, privileged ? Psr::M::SYS : Psr::M::USR); - Psr::F::set(v, 1); - Psr::A::set(v, 1); - regs->cpsr = v; - regs->cpu_exception = Cpu::Context::RESET; - } + switch (c.cpu_exception) { - /** - * Support for kernel calls - */ - void user_arg_0(Kernel::Call_arg const arg) { regs->r0 = arg; } - void user_arg_1(Kernel::Call_arg const arg) { regs->r1 = arg; } - void user_arg_2(Kernel::Call_arg const arg) { regs->r2 = arg; } - void user_arg_3(Kernel::Call_arg const arg) { regs->r3 = arg; } - void user_arg_4(Kernel::Call_arg const arg) { regs->r4 = arg; } - Kernel::Call_arg user_arg_0() const { return regs->r0; } - Kernel::Call_arg user_arg_1() const { return regs->r1; } - Kernel::Call_arg user_arg_2() const { return regs->r2; } - Kernel::Call_arg user_arg_3() const { return regs->r3; } - Kernel::Call_arg user_arg_4() const { return regs->r4; } - - /** - * Return if the context is in a page fault due to translation miss - * - * \param va holds the virtual fault-address if call returns 1 - * \param w holds whether it's a write fault if call returns 1 - * \param p holds whether it's a permission fault if call returns 1 - */ - bool in_fault(addr_t & va, addr_t & w, bool &p) const - { - /* permission fault on page, 2nd level */ - static constexpr Fsr::access_t permission = 0b1111; - - switch (regs->cpu_exception) { - - case Context::PREFETCH_ABORT: - { - /* check if fault was caused by a translation miss */ - Fsr::access_t const fs = Fsr::Fs::get(Ifsr::read()); - if (fs == permission) { - w = 0; - va = regs->ip; - p = true; - return true; - } - - if ((fs & 0b11100) != 0b100) return false; - - /* fetch fault data */ + case Context::PREFETCH_ABORT: + { + /* check if fault was caused by a translation miss */ + Fsr::access_t const fs = Fsr::Fs::get(Ifsr::read()); + if (fs == permission) { w = 0; - va = regs->ip; - p = false; + va = Ifar::read(); + p = true; return true; } - case Context::DATA_ABORT: - { - /* check if fault was caused by translation miss */ - Fsr::access_t const fs = Fsr::Fs::get(Dfsr::read()); - if ((fs != permission) && (fs & 0b11100) != 0b100) - return false; + if ((fs & 0b11100) != 0b100) return false; - /* fetch fault data */ - Dfsr::access_t const dfsr = Dfsr::read(); - w = Dfsr::Wnr::get(dfsr); - va = Dfar::read(); - p = false; - return true; - } + /* fetch fault data */ + w = 0; + va = Ifar::read(); + p = false; + return true; + } - default: - return false; - }; - } + case Context::DATA_ABORT: + { + /* check if fault was caused by translation miss */ + Fsr::access_t const fs = Fsr::Fs::get(Dfsr::read()); + if ((fs != permission) && (fs & 0b11100) != 0b100) + return false; + + /* fetch fault data */ + Dfsr::access_t const dfsr = Dfsr::read(); + w = Dfsr::Wnr::get(dfsr); + va = Dfar::read(); + p = false; + return true; + } + + default: + return false; + }; }; @@ -258,11 +183,10 @@ class Genode::Cpu : public Arm_v7_cpu void invalidate_data_cache() { invalidate_inner_data_cache(); } - void switch_to(User_context& o) + void switch_to(Context &, Mmu_context & mmu_context) { - if (Ttbr_64bit::Asid::get(o.regs->ttbr0) && - (Ttbr0_64bit::read() != o.regs->ttbr0)) - Ttbr0_64bit::write(o.regs->ttbr0); + if (mmu_context.id() && (Ttbr0_64bit::read() != mmu_context.ttbr0)) + Ttbr0_64bit::write(mmu_context.ttbr0); } @@ -270,7 +194,7 @@ class Genode::Cpu : public Arm_v7_cpu ** Dummies ** *************/ - bool retry_undefined_instr(User_context&) { return false; } + bool retry_undefined_instr(Context&) { return false; } }; #endif /* _CORE__SPEC__CORTEX_A15__CPU_H_ */ diff --git a/repos/base-hw/src/core/spec/cortex_a15/kernel/cpu.cc b/repos/base-hw/src/core/spec/cortex_a15/kernel/cpu.cc index de4585de2..e25482be7 100644 --- a/repos/base-hw/src/core/spec/cortex_a15/kernel/cpu.cc +++ b/repos/base-hw/src/core/spec/cortex_a15/kernel/cpu.cc @@ -14,31 +14,20 @@ /* core includes */ #include #include -#include #include -#include /* base-hw includes */ #include using namespace Kernel; -/* entrypoint for non-boot CPUs */ -extern "C" void * _start_secondary_cpus; - -/* indicates boot cpu status */ -static volatile bool primary_cpu = true; - - void Kernel::Cpu::init(Kernel::Pic &pic) { - { - Lock::Guard guard(data_lock()); + Lock::Guard guard(data_lock()); - /* enable performance counter */ - perf_counter()->enable(); + /* enable performance counter */ + perf_counter()->enable(); - /* enable timer interrupt */ - pic.unmask(_timer.interrupt_id(), id()); - } + /* enable timer interrupt */ + pic.unmask(_timer.interrupt_id(), id()); } diff --git a/repos/base-hw/src/core/spec/cortex_a9/cpu.h b/repos/base-hw/src/core/spec/cortex_a9/cpu.h index 66f88a854..45292569e 100644 --- a/repos/base-hw/src/core/spec/cortex_a9/cpu.h +++ b/repos/base-hw/src/core/spec/cortex_a9/cpu.h @@ -30,43 +30,20 @@ class Genode::Cpu : public Arm_v7_cpu public: - /** - * Coprocessor Access Control Register - */ - struct Cpacr : Register<32> + struct Context : Arm_cpu::Context, Fpu::Context { - struct Cp10 : Bitfield<20, 2> { }; - struct Cp11 : Bitfield<22, 2> { }; - - /** - * Read register value - */ - static access_t read() - { - access_t v; - asm volatile ("mrc p15, 0, %[v], c1, c0, 2" : [v]"=r"(v) ::); - return v; - } - - /** - * Override register value - * - * \param v write value - */ - static void write(access_t const v) { - asm volatile ("mcr p15, 0, %[v], c1, c0, 2" :: [v]"r"(v) :); } + Context(bool privileged) + : Arm_cpu::Context(privileged) {} }; - struct User_context : Arm_cpu::User_context, Fpu::Context { }; - /** * Next cpu context to switch to * * \param context context to switch to */ - void switch_to(User_context & context) + void switch_to(Context & context, Mmu_context & mmu_context) { - Arm_cpu::switch_to(context); + Arm_cpu::switch_to(context, mmu_context); _fpu.switch_to(context); } @@ -75,7 +52,7 @@ class Genode::Cpu : public Arm_v7_cpu * * \param state CPU state of the user */ - bool retry_undefined_instr(User_context & context) { + bool retry_undefined_instr(Context & context) { return _fpu.fault(context); } /** diff --git a/repos/base-hw/src/core/spec/imx53/pic.h b/repos/base-hw/src/core/spec/imx53/pic.h index 3e22363af..647cd47c4 100644 --- a/repos/base-hw/src/core/spec/imx53/pic.h +++ b/repos/base-hw/src/core/spec/imx53/pic.h @@ -41,6 +41,8 @@ class Genode::Pic : public Hw::Pic bool secure(unsigned i) { return !read(i); } + + static constexpr bool fast_interrupts() { return true; } }; namespace Kernel { using Pic = Genode::Pic; } diff --git a/repos/base-hw/src/core/spec/riscv/cpu.cc b/repos/base-hw/src/core/spec/riscv/cpu.cc new file mode 100644 index 000000000..dcde9c77b --- /dev/null +++ b/repos/base-hw/src/core/spec/riscv/cpu.cc @@ -0,0 +1,69 @@ +/* + * \brief CPU driver + * \author Stefan Kalkowski + * \date 2017-10-06 + */ + +/* + * Copyright (C) 2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + +#include + +#include +#include +#include +#include + +using Mmu_context = Genode::Cpu::Mmu_context; +using Asid_allocator = Genode::Bit_allocator<256>; + + +Genode::Cpu::Context::Context(bool) +{ + /* + * initialize cpu_exception with something that gets ignored in + * Thread::exception + */ + cpu_exception = IRQ_FLAG; +} + + +static Asid_allocator & alloc() { + return *unmanaged_singleton(); } + + +Mmu_context::Mmu_context(addr_t page_table_base) +{ + Sptbr::Asid::set(sptbr, (Genode::uint8_t)alloc().alloc()); + Sptbr::Ppn::set(sptbr, page_table_base >> 12); +} + + +Mmu_context::~Mmu_context() +{ + unsigned asid = Sptbr::Asid::get(sptbr); + Cpu::invalidate_tlb_by_pid(asid); + alloc().free(asid); +} + + +void Genode::Cpu::switch_to(Mmu_context & context) +{ + /* + * The sstatus register defines to which privilege level + * the machin returns when doing an exception return + */ + bool user = Sptbr::Asid::get(context.sptbr); + Sstatus::access_t v = Sstatus::read(); + Sstatus::Spp::set(v, user ? 0 : 1); + Sstatus::write(v); + + /* change the translation table when necessary */ + //Sptbr::access_t sptbr = Sptbr::read(); + if (user /*&& sptbr != context.sptbr*/) + Sptbr::write(context.sptbr); +} diff --git a/repos/base-hw/src/core/spec/riscv/cpu.h b/repos/base-hw/src/core/spec/riscv/cpu.h index 5f6de0335..301bf570e 100644 --- a/repos/base-hw/src/core/spec/riscv/cpu.h +++ b/repos/base-hw/src/core/spec/riscv/cpu.h @@ -40,69 +40,19 @@ class Genode::Cpu : public Hw::Riscv_cpu { public: - /** - * Extend basic CPU state by members relevant for 'base-hw' only - */ - struct Context : Cpu_state + struct alignas(8) Context : Cpu_state + { + Context(bool); + }; + + struct Mmu_context { Sptbr::access_t sptbr; - /** - * Return base of assigned translation table - */ - addr_t translation_table() const { - return Sptbr::Ppn::get(sptbr) << 12; } - - /** - * Assign translation-table base 'table' - */ - void translation_table(addr_t const table) { - Sptbr::Ppn::set(sptbr, table >> 12); } - - /** - * Assign protection domain - */ - void protection_domain(Genode::uint8_t const id) { - Sptbr::Asid::set(sptbr, id); } + Mmu_context(addr_t page_table_base); + ~Mmu_context(); }; - struct Pd - { - Genode::uint8_t asid; /* address space id */ - - Pd(Genode::uint8_t id) : asid(id) {} - }; - - /** - * A usermode execution state - */ - struct User_context - { - Align_at regs; - - User_context() - { - /* - * initialize cpu_exception with something that gets ignored in - * Thread::exception - */ - regs->cpu_exception = IRQ_FLAG; - } - - /** - * Support for kernel calls - */ - void user_arg_0(Kernel::Call_arg const arg) { regs->a0 = arg; } - void user_arg_1(Kernel::Call_arg const arg) { regs->a1 = arg; } - void user_arg_2(Kernel::Call_arg const arg) { regs->a2 = arg; } - void user_arg_3(Kernel::Call_arg const arg) { regs->a3 = arg; } - void user_arg_4(Kernel::Call_arg const arg) { regs->a4 = arg; } - Kernel::Call_arg user_arg_0() const { return regs->a0; } - Kernel::Call_arg user_arg_1() const { return regs->a1; } - Kernel::Call_arg user_arg_2() const { return regs->a2; } - Kernel::Call_arg user_arg_3() const { return regs->a3; } - Kernel::Call_arg user_arg_4() const { return regs->a4; } - }; /** * From the manual @@ -123,38 +73,12 @@ class Genode::Cpu : public Hw::Riscv_cpu asm volatile ("sfence.vm\n"); } - /** - * Post processing after a translation was added to a translation table - * - * \param addr virtual address of the translation - * \param size size of the translation - */ - static void translation_added(addr_t const addr, size_t const size); - static void invalidate_tlb_by_pid(unsigned const pid) { sfence(); } - /** - * Return kernel name of the executing CPU - */ - static unsigned executing_id() { return primary_id(); } + void switch_to(Mmu_context & context); - /** - * Return kernel name of the primary CPU - */ - static unsigned primary_id() { return 0; } - - /************* - ** Dummies ** - *************/ - - void switch_to(User_context& context) - { - bool user = Sptbr::Asid::get(context.regs->sptbr); - Sstatus::access_t v = Sstatus::read(); - Sstatus::Spp::set(v, user ? 0 : 1); - Sstatus::write(v); - if (user) Sptbr::write(context.regs->sptbr); - } + static unsigned executing_id() { return 0; } + static unsigned primary_id() { return 0; } }; #endif /* _CORE__SPEC__RISCV__CPU_H_ */ diff --git a/repos/base-hw/src/core/spec/riscv/kernel/pd.cc b/repos/base-hw/src/core/spec/riscv/kernel/pd.cc deleted file mode 100644 index b96476505..000000000 --- a/repos/base-hw/src/core/spec/riscv/kernel/pd.cc +++ /dev/null @@ -1,52 +0,0 @@ -/* - * \brief Kernel backend for protection domains - * \author Seastian Sumpf - * \date 2015-06-02 - */ - -/* - * Copyright (C) 2015-2017 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -#include - -#include -#include -#include -#include - -using Asid_allocator = Genode::Bit_allocator<256>; - -static Asid_allocator & alloc() { - return *unmanaged_singleton(); } - - -Kernel::Pd::Pd(Hw::Page_table * const table, - Genode::Platform_pd * const platform_pd) -: Kernel::Cpu::Pd((Genode::uint8_t)alloc().alloc()), - _table(table), _platform_pd(platform_pd) -{ - capid_t invalid = _capid_alloc.alloc(); - assert(invalid == cap_id_invalid()); -} - - -Kernel::Pd::~Pd() -{ - while (Object_identity_reference *oir = _cap_tree.first()) - oir->~Object_identity_reference(); - - /* clean up buffers of memory management */ - Cpu::invalidate_tlb_by_pid(asid); - alloc().free(asid); -} - - -void Kernel::Pd::admit(Kernel::Cpu::Context & c) -{ - c.protection_domain(asid); - c.translation_table((addr_t)translation_table()); -} diff --git a/repos/base-hw/src/core/spec/riscv/kernel/thread.cc b/repos/base-hw/src/core/spec/riscv/kernel/thread.cc index 7bdd7523f..239166db2 100644 --- a/repos/base-hw/src/core/spec/riscv/kernel/thread.cc +++ b/repos/base-hw/src/core/spec/riscv/kernel/thread.cc @@ -12,14 +12,13 @@ */ /* core includes */ +#include #include #include using namespace Kernel; -void Kernel::Thread::_init() { } - -void Thread::exception(unsigned const cpu) +void Thread::exception(Cpu&) { using Context = Genode::Cpu::Context; @@ -71,8 +70,10 @@ void Thread::_call_update_data_region() void Thread::_call_update_instr_region() { } -void Kernel::Thread::proceed(unsigned const) +void Kernel::Thread::proceed(Cpu & cpu) { + cpu.switch_to(_pd->mmu_regs); + asm volatile("csrw sscratch, %1 \n" "mv x31, %0 \n" "ld x30, (x31) \n" @@ -85,3 +86,15 @@ void Kernel::Thread::proceed(unsigned const) "sret \n" :: "r" (&*regs), "r" (regs->t6) : "x30", "x31"); } + + +void Thread::user_arg_0(Kernel::Call_arg const arg) { regs->a0 = arg; } +void Thread::user_arg_1(Kernel::Call_arg const arg) { regs->a1 = arg; } +void Thread::user_arg_2(Kernel::Call_arg const arg) { regs->a2 = arg; } +void Thread::user_arg_3(Kernel::Call_arg const arg) { regs->a3 = arg; } +void Thread::user_arg_4(Kernel::Call_arg const arg) { regs->a4 = arg; } +Kernel::Call_arg Thread::user_arg_0() const { return regs->a0; } +Kernel::Call_arg Thread::user_arg_1() const { return regs->a1; } +Kernel::Call_arg Thread::user_arg_2() const { return regs->a2; } +Kernel::Call_arg Thread::user_arg_3() const { return regs->a3; } +Kernel::Call_arg Thread::user_arg_4() const { return regs->a4; } diff --git a/repos/base-hw/src/core/spec/rpi/pic.h b/repos/base-hw/src/core/spec/rpi/pic.h index 1da8f3ddc..1c9d9544e 100644 --- a/repos/base-hw/src/core/spec/rpi/pic.h +++ b/repos/base-hw/src/core/spec/rpi/pic.h @@ -127,6 +127,8 @@ class Genode::Pic : Mmio void mask(); void unmask(unsigned const i, unsigned); void mask(unsigned const i); + + static constexpr bool fast_interrupts() { return false; } }; namespace Kernel { using Genode::Pic; } diff --git a/repos/base-hw/src/core/spec/smp/kernel/kernel.cc b/repos/base-hw/src/core/spec/smp/kernel/kernel.cc index dd6e7be81..199ef1b01 100644 --- a/repos/base-hw/src/core/spec/smp/kernel/kernel.cc +++ b/repos/base-hw/src/core/spec/smp/kernel/kernel.cc @@ -22,15 +22,14 @@ extern "C" void kernel() using namespace Kernel; Cpu_job * new_job; - unsigned cpu_id; + Cpu * cpu; { Lock::Guard guard(data_lock()); - cpu_id = Cpu::executing_id(); - Cpu * const cpu = cpu_pool()->cpu(cpu_id); + cpu = cpu_pool()->cpu(Cpu::executing_id()); new_job = &cpu->schedule(); } - new_job->proceed(cpu_id); + new_job->proceed(*cpu); } diff --git a/repos/base-hw/src/core/spec/x86_64/cpu.cc b/repos/base-hw/src/core/spec/x86_64/cpu.cc index 98301bbd0..62b6acfee 100644 --- a/repos/base-hw/src/core/spec/x86_64/cpu.cc +++ b/repos/base-hw/src/core/spec/x86_64/cpu.cc @@ -21,23 +21,18 @@ extern int __gdt_start; extern int __gdt_end; -void Genode::Cpu::Context::init(addr_t const table, bool core) +Genode::Cpu::Context::Context(bool core) { - /* Constants to handle IF, IOPL values */ - enum { - EFLAGS_IF_SET = 1 << 9, - EFLAGS_IOPL_3 = 3 << 12, - }; - - cr3 = Cr3::init(table); - - /* enable interrupts for all threads */ eflags = EFLAGS_IF_SET; - cs = core ? 0x8 : 0x1b; - ss = core ? 0x10 : 0x23; + cs = core ? 0x8 : 0x1b; + ss = core ? 0x10 : 0x23; } +Genode::Cpu::Mmu_context::Mmu_context(addr_t const table) +: cr3(Cr3::Pdb::masked(table)) {} + + void Genode::Cpu::Tss::init() { enum { TSS_SELECTOR = 0x28, }; diff --git a/repos/base-hw/src/core/spec/x86_64/cpu.h b/repos/base-hw/src/core/spec/x86_64/cpu.h index 7740c42bc..b9bce5b92 100644 --- a/repos/base-hw/src/core/spec/x86_64/cpu.h +++ b/repos/base-hw/src/core/spec/x86_64/cpu.h @@ -75,51 +75,25 @@ class Genode::Cpu /** * Extend basic CPU state by members relevant for 'base-hw' only */ - struct alignas(16) Context : Cpu_state + struct alignas(16) Context : Cpu_state, Fpu::Context + { + enum Eflags { + EFLAGS_IF_SET = 1 << 9, + EFLAGS_IOPL_3 = 3 << 12, + }; + + Context(bool privileged); + }; + + + struct Mmu_context { - /** - * Address of top-level paging structure. - */ addr_t cr3; - /** - * Return base of assigned translation table - */ - addr_t translation_table() const { return cr3; } - - /** - * Initialize context - * - * \param table physical base of appropriate translation table - * \param core whether it is a core thread or not - */ - void init(addr_t const table, bool core); + Mmu_context(addr_t page_table_base); }; - /** - * An usermode execution state - */ - struct User_context - { - Align_at regs; - Fpu::Context fpu_regs; - - /** - * Support for kernel calls - */ - void user_arg_0(Kernel::Call_arg const arg) { regs->rdi = arg; } - void user_arg_1(Kernel::Call_arg const arg) { regs->rsi = arg; } - void user_arg_2(Kernel::Call_arg const arg) { regs->rdx = arg; } - void user_arg_3(Kernel::Call_arg const arg) { regs->rcx = arg; } - void user_arg_4(Kernel::Call_arg const arg) { regs->r8 = arg; } - Kernel::Call_arg user_arg_0() const { return regs->rdi; } - Kernel::Call_arg user_arg_1() const { return regs->rsi; } - Kernel::Call_arg user_arg_2() const { return regs->rdx; } - Kernel::Call_arg user_arg_3() const { return regs->rcx; } - Kernel::Call_arg user_arg_4() const { return regs->r8; } - }; - protected: Fpu _fpu; @@ -149,7 +123,7 @@ class Genode::Cpu * * \param context next CPU context */ - inline void switch_to(User_context &context); + inline void switch_to(Context & context, Mmu_context &); }; @@ -279,12 +253,12 @@ struct Genode::Cpu::Cr4 : Register<64> }; -void Genode::Cpu::switch_to(User_context &context) +void Genode::Cpu::switch_to(Context & context, Mmu_context & mmu_context) { - _fpu.switch_to(context.fpu_regs); + _fpu.switch_to(context); - if ((context.regs->cs != 0x8) && (context.regs->cr3 != Cr3::read())) - Cr3::write(context.regs->cr3); + if ((context.cs != 0x8) && (mmu_context.cr3 != Cr3::read())) + Cr3::write(mmu_context.cr3); }; #endif /* _CORE__SPEC__X86_64__CPU_H_ */ diff --git a/repos/base-hw/src/core/spec/x86_64/kernel/pd.cc b/repos/base-hw/src/core/spec/x86_64/kernel/pd.cc deleted file mode 100644 index 2c5392b0c..000000000 --- a/repos/base-hw/src/core/spec/x86_64/kernel/pd.cc +++ /dev/null @@ -1,36 +0,0 @@ -/* - * \brief Kernel backend for protection domains - * \author Stefan Kalkowski - * \date 2015-03-20 - */ - -/* - * Copyright (C) 2015-2017 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU Affero General Public License version 3. - */ - -/* core includes */ -#include -#include -#include - -Kernel::Pd::Pd(Hw::Page_table * const table, - Genode::Platform_pd * const platform_pd) -: _table(table), _platform_pd(platform_pd) -{ - capid_t invalid = _capid_alloc.alloc(); - assert(invalid == cap_id_invalid()); -} - - -Kernel::Pd::~Pd() -{ - while (Object_identity_reference *oir = _cap_tree.first()) - oir->~Object_identity_reference(); -} - - -void Kernel::Pd::admit(Genode::Cpu::Context & c) { - c.init((addr_t)translation_table(), this == Kernel::core_pd()); } diff --git a/repos/base-hw/src/core/spec/x86_64/kernel/thread.cc b/repos/base-hw/src/core/spec/x86_64/kernel/thread.cc index c167e45f1..01fbeb626 100644 --- a/repos/base-hw/src/core/spec/x86_64/kernel/thread.cc +++ b/repos/base-hw/src/core/spec/x86_64/kernel/thread.cc @@ -14,6 +14,7 @@ */ /* core includes */ +#include #include #include @@ -58,18 +59,17 @@ void Kernel::Thread::_mmu_exception() } -void Kernel::Thread::_init() { } - - void Kernel::Thread::_call_update_pd() { } extern void * __tss_client_context_ptr; -void Kernel::Thread::proceed(unsigned const) +void Kernel::Thread::proceed(Cpu & cpu) { void * * tss_stack_ptr = (&__tss_client_context_ptr); - *tss_stack_ptr = ®s->cr3; + *tss_stack_ptr = (void*)((addr_t)&*regs + sizeof(Genode::Cpu_state)); + + cpu.switch_to(*regs, pd()->mmu_regs); asm volatile("mov %0, %%rsp \n" "popq %%r8 \n" @@ -90,3 +90,16 @@ void Kernel::Thread::proceed(unsigned const) "add $16, %%rsp \n" "iretq \n" :: "r" (®s->r8)); } + + +void Kernel::Thread::user_arg_0(Kernel::Call_arg const arg) { regs->rdi = arg; } +void Kernel::Thread::user_arg_1(Kernel::Call_arg const arg) { regs->rsi = arg; } +void Kernel::Thread::user_arg_2(Kernel::Call_arg const arg) { regs->rdx = arg; } +void Kernel::Thread::user_arg_3(Kernel::Call_arg const arg) { regs->rcx = arg; } +void Kernel::Thread::user_arg_4(Kernel::Call_arg const arg) { regs->r8 = arg; } + +Kernel::Call_arg Kernel::Thread::user_arg_0() const { return regs->rdi; } +Kernel::Call_arg Kernel::Thread::user_arg_1() const { return regs->rsi; } +Kernel::Call_arg Kernel::Thread::user_arg_2() const { return regs->rdx; } +Kernel::Call_arg Kernel::Thread::user_arg_3() const { return regs->rcx; } +Kernel::Call_arg Kernel::Thread::user_arg_4() const { return regs->r8; } diff --git a/repos/base-hw/src/core/spec/x86_64/kernel/thread_exception.cc b/repos/base-hw/src/core/spec/x86_64/kernel/thread_exception.cc index 8e4f51b0c..87de886c5 100644 --- a/repos/base-hw/src/core/spec/x86_64/kernel/thread_exception.cc +++ b/repos/base-hw/src/core/spec/x86_64/kernel/thread_exception.cc @@ -19,7 +19,7 @@ using namespace Kernel; -void Thread::exception(unsigned const cpu) +void Thread::exception(Cpu & cpu) { using Genode::Cpu_state; @@ -28,7 +28,7 @@ void Thread::exception(unsigned const cpu) _mmu_exception(); return; case Cpu_state::NO_MATH_COPROC: - if (_cpu->fpu().fault(fpu_regs)) { return; } + if (_cpu->fpu().fault(*regs)) { return; } Genode::warning(*this, ": FPU error"); _die(); return; @@ -42,7 +42,7 @@ void Thread::exception(unsigned const cpu) } if (regs->trapno >= Cpu_state::INTERRUPTS_START && regs->trapno <= Cpu_state::INTERRUPTS_END) { - _interrupt(cpu); + _interrupt(cpu.id()); return; } Genode::warning(*this, ": triggered unknown exception ", regs->trapno, diff --git a/repos/base-hw/src/core/spec/x86_64/muen/kernel/thread_exception.cc b/repos/base-hw/src/core/spec/x86_64/muen/kernel/thread_exception.cc index 1d7338d4c..0843217c5 100644 --- a/repos/base-hw/src/core/spec/x86_64/muen/kernel/thread_exception.cc +++ b/repos/base-hw/src/core/spec/x86_64/muen/kernel/thread_exception.cc @@ -13,19 +13,20 @@ */ /* core includes */ +#include #include #include using namespace Kernel; -void Thread::exception(unsigned const cpu) +void Thread::exception(Cpu & cpu) { switch (regs->trapno) { case Cpu::Context::PAGE_FAULT: _mmu_exception(); return; case Cpu::Context::NO_MATH_COPROC: - if (_cpu->fpu().fault(fpu_regs)) { return; } + if (_cpu->fpu().fault(*regs)) { return; } Genode::warning(*this, ": FPU error"); _die(); return; @@ -40,7 +41,7 @@ void Thread::exception(unsigned const cpu) if (regs->trapno >= Cpu::Context::INTERRUPTS_START && regs->trapno <= Cpu::Context::INTERRUPTS_END) { pic()->irq_occurred(regs->trapno); - _interrupt(cpu); + _interrupt(cpu.id()); return; } Genode::warning(*this, ": triggered unknown exception ", regs->trapno, diff --git a/repos/base-hw/src/core/spec/x86_64/muen/kernel/vm.cc b/repos/base-hw/src/core/spec/x86_64/muen/kernel/vm.cc index a1271c4cb..c9adafea3 100644 --- a/repos/base-hw/src/core/spec/x86_64/muen/kernel/vm.cc +++ b/repos/base-hw/src/core/spec/x86_64/muen/kernel/vm.cc @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -27,35 +28,29 @@ Kernel::Vm::Vm(void * const state, Kernel::Signal_context * const context, _table(nullptr) { affinity(cpu_pool()->primary_cpu()); - - /* - * Initialize VM context as a core/kernel context to prevent - * page-table switching before doing the world switch - */ - regs->init((addr_t)core_pd()->translation_table(), true); } Kernel::Vm::~Vm() { } -void Kernel::Vm::exception(unsigned const cpu_id) +void Kernel::Vm::exception(Cpu & cpu) { pause(); - if (regs->trapno == 200) { + if (_state->trapno == 200) { _context->submit(1); return; } - if (regs->trapno >= Genode::Cpu_state::INTERRUPTS_START && - regs->trapno <= Genode::Cpu_state::INTERRUPTS_END) { - pic()->irq_occurred(regs->trapno); - _interrupt(cpu_id); + if (_state->trapno >= Genode::Cpu_state::INTERRUPTS_START && + _state->trapno <= Genode::Cpu_state::INTERRUPTS_END) { + pic()->irq_occurred(_state->trapno); + _interrupt(cpu.id()); _context->submit(1); return; } - Genode::warning("VM: triggered unknown exception ", regs->trapno, - " with error code ", regs->errcode); + Genode::warning("VM: triggered unknown exception ", _state->trapno, + " with error code ", _state->errcode); ASSERT_NEVER_CALLED; } @@ -63,10 +58,10 @@ void Kernel::Vm::exception(unsigned const cpu_id) extern void * __tss_client_context_ptr; -void Kernel::Vm::proceed(unsigned const cpu_id) +void Kernel::Vm::proceed(Cpu &) { void * * tss_stack_ptr = (&__tss_client_context_ptr); - *tss_stack_ptr = ®s->cr3; + *tss_stack_ptr = (void*)((addr_t)_state + sizeof(Genode::Cpu_state)); asm volatile("sti \n" "mov $1, %rax \n" diff --git a/repos/base-hw/src/include/base/internal/align_at.h b/repos/base-hw/src/include/base/internal/align_at.h index d06959de3..8a54af329 100644 --- a/repos/base-hw/src/include/base/internal/align_at.h +++ b/repos/base-hw/src/include/base/internal/align_at.h @@ -18,15 +18,17 @@ #include namespace Genode { - template class Align_at; + template class Align_at; } -template +template class Genode::Align_at { private: + static constexpr Genode::size_t ALIGN = alignof(T); + char _space[sizeof(T) + ALIGN - 1]; T & _obj; diff --git a/repos/base-hw/src/lib/hw/spec/arm/cpu.h b/repos/base-hw/src/lib/hw/spec/arm/cpu.h index 306370b51..36dcc16b7 100644 --- a/repos/base-hw/src/lib/hw/spec/arm/cpu.h +++ b/repos/base-hw/src/lib/hw/spec/arm/cpu.h @@ -167,7 +167,9 @@ struct Hw::Arm_cpu }; /* Data Fault Status Register */ - ARM_CP15_REGISTER_32BIT(Dfsr, c5, c0, 0, 0); + ARM_CP15_REGISTER_32BIT(Dfsr, c5, c0, 0, 0, + struct Wnr : Bitfield<11, 1> { }; /* write not read bit */ + ); /* Instruction Fault Status Register */ ARM_CP15_REGISTER_32BIT(Ifsr, c5, c0, 0, 1);