From 82cf31ac278fcb5a4a4a5298d95c31114fbedcd0 Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Mon, 5 Jul 2021 15:47:24 +0200 Subject: [PATCH] base-hw: introduce Kernel::Main class This commit introduces the Kernel::Main class that replaces the former way of initializing the kernel (former 'kernel_init' function) and calling the C++ kernel entry handler (former 'kernel' function). These two are now 'Main::initialize_and_handle_kernel_entry' and 'Main::handle_kernel_entry'. Also reading the execution time of the idle threads was already moved to 'Main'. The one static Main instance is meant to successivly replace all the global static objects of the base-hw kernel with data members of the Main instance making the data model of the kernel much more comprehensible. The instance and most of its interface are hidden in kernel/main.cc. There are only rare cases where parts of the Main interface must be accessible from the outside. This should be done in the most specific way possible (see main.h) and, if possible, without handing out references to Main data members or the Main instance itself. Ref #4217 --- repos/base-hw/lib/mk/core-hw.inc | 2 +- repos/base-hw/src/core/kernel/init.cc | 65 --------- repos/base-hw/src/core/kernel/kernel.cc | 46 ------ repos/base-hw/src/core/kernel/kernel.h | 6 - repos/base-hw/src/core/kernel/main.cc | 133 ++++++++++++++++++ repos/base-hw/src/core/kernel/main.h | 29 ++++ repos/base-hw/src/core/platform.cc | 8 +- repos/base-hw/src/core/spec/arm/crt0.s | 2 +- .../src/core/spec/arm/exception_vector.S | 2 +- .../spec/arm_v7/trustzone/exception_vector.s | 2 +- .../spec/arm_v7/virtualization/kernel/vm.cc | 6 +- repos/base-hw/src/core/spec/arm_v8/crt0.s | 2 +- .../src/core/spec/arm_v8/exception_vector.s | 2 +- .../spec/arm_v8/virtualization/kernel/vm.cc | 4 +- repos/base-hw/src/core/spec/riscv/crt0.s | 2 +- .../src/core/spec/riscv/exception_vector.s | 2 +- repos/base-hw/src/core/spec/x86_64/crt0.s | 2 +- .../src/core/spec/x86_64/exception_vector.s | 2 +- 18 files changed, 179 insertions(+), 138 deletions(-) delete mode 100644 repos/base-hw/src/core/kernel/kernel.cc create mode 100644 repos/base-hw/src/core/kernel/main.cc create mode 100644 repos/base-hw/src/core/kernel/main.h diff --git a/repos/base-hw/lib/mk/core-hw.inc b/repos/base-hw/lib/mk/core-hw.inc index 3ccafb95e2..9991c2c9be 100644 --- a/repos/base-hw/lib/mk/core-hw.inc +++ b/repos/base-hw/lib/mk/core-hw.inc @@ -54,7 +54,7 @@ SRC_CC += kernel/cpu_scheduler.cc SRC_CC += kernel/init.cc SRC_CC += kernel/ipc_node.cc SRC_CC += kernel/irq.cc -SRC_CC += kernel/kernel.cc +SRC_CC += kernel/main.cc SRC_CC += kernel/object.cc SRC_CC += kernel/signal_receiver.cc SRC_CC += kernel/thread.cc diff --git a/repos/base-hw/src/core/kernel/init.cc b/repos/base-hw/src/core/kernel/init.cc index c7cdc72755..0ffea4e574 100644 --- a/repos/base-hw/src/core/kernel/init.cc +++ b/repos/base-hw/src/core/kernel/init.cc @@ -14,13 +14,7 @@ /* core includes */ #include -#include -#include -#include #include -#include -#include -#include /* base includes */ #include @@ -34,62 +28,3 @@ static_assert(sizeof(Genode::sizet_arithm_t) >= 2 * sizeof(size_t), Pd &Kernel::core_pd() { return unmanaged_singleton()->kernel_pd(); } - - -extern "C" void kernel_init(); - -/** - * Setup kernel environment - */ -extern "C" void kernel_init() -{ - static volatile bool lock_ready = false; - static volatile bool pool_ready = false; - static volatile bool kernel_ready = false; - - /** - * It is essential to guard the initialization of the data_lock object - * in the SMP case, because otherwise the __cxa_guard_aquire of the cxx - * library contention path might get called, which ends up in - * calling a Semaphore, which will call Kernel::stop_thread() or - * Kernel::yield() system-calls in this code - */ - while (Cpu::executing_id() != Cpu::primary_id() && !lock_ready) { ; } - - { - Lock::Guard guard(data_lock()); - - lock_ready = true; - - /* initialize current cpu */ - pool_ready = cpu_pool().initialize(); - }; - - /* wait until all cpus have initialized their corresponding cpu object */ - while (!pool_ready) { ; } - - /* the boot-cpu initializes the rest of the kernel */ - if (Cpu::executing_id() == Cpu::primary_id()) { - Lock::Guard guard(data_lock()); - - using Boot_info = Hw::Boot_info; - Boot_info &boot_info { - *reinterpret_cast(Hw::Mm::boot_info().base) }; - - cpu_pool().for_each_cpu([&] (Kernel::Cpu &cpu) { - boot_info.kernel_irqs.add(cpu.timer().interrupt_id()); - }); - boot_info.kernel_irqs.add((unsigned)Board::Pic::IPI); - - Genode::log(""); - Genode::log("kernel initialized"); - - Core_main_thread::singleton(); - kernel_ready = true; - } else { - /* secondary cpus spin until the kernel is initialized */ - while (!kernel_ready) {;} - } - - kernel(); -} diff --git a/repos/base-hw/src/core/kernel/kernel.cc b/repos/base-hw/src/core/kernel/kernel.cc deleted file mode 100644 index 608fd9dddd..0000000000 --- a/repos/base-hw/src/core/kernel/kernel.cc +++ /dev/null @@ -1,46 +0,0 @@ -/* - * \brief Kernel entrypoint - * \author Martin Stein - * \author Stefan Kalkowski - * \date 2011-10-20 - */ - -/* - * Copyright (C) 2011-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 - -namespace Kernel { - - time_t read_idle_thread_execution_time(unsigned cpu_idx); -} - - -Kernel::time_t Kernel::read_idle_thread_execution_time(unsigned cpu_idx) -{ - return cpu_pool().cpu(cpu_idx).idle_thread().execution_time(); -} - - -extern "C" void kernel() -{ - using namespace Kernel; - - Cpu &cpu = cpu_pool().cpu(Cpu::executing_id()); - Cpu_job * new_job; - - { - Lock::Guard guard(data_lock()); - - new_job = &cpu.schedule(); - } - - new_job->proceed(cpu); -} diff --git a/repos/base-hw/src/core/kernel/kernel.h b/repos/base-hw/src/core/kernel/kernel.h index 9768aed162..92d6f79f15 100644 --- a/repos/base-hw/src/core/kernel/kernel.h +++ b/repos/base-hw/src/core/kernel/kernel.h @@ -15,12 +15,6 @@ #ifndef _CORE__KERNEL__KERNEL_H_ #define _CORE__KERNEL__KERNEL_H_ -/** - * Main routine of every kernel pass - */ -extern "C" void kernel(); - - namespace Kernel { class Pd; diff --git a/repos/base-hw/src/core/kernel/main.cc b/repos/base-hw/src/core/kernel/main.cc new file mode 100644 index 0000000000..253e066e9f --- /dev/null +++ b/repos/base-hw/src/core/kernel/main.cc @@ -0,0 +1,133 @@ +/* + * \brief Main object of the kernel + * \author Martin Stein + * \author Stefan Kalkowski + * \date 2021-07-09 + */ + +/* + * Copyright (C) 2021 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. + */ + +/* base-hw Core includes */ +#include +#include +#include + +/* base-hw-internal includes */ +#include + + +namespace Kernel { + + class Main; +} + + +class Kernel::Main +{ + private: + + friend void main_handle_kernel_entry(); + friend void main_initialize_and_handle_kernel_entry(); + + static Main *_instance; + + void _handle_kernel_entry(); +}; + + +Kernel::Main *Kernel::Main::_instance; + + +void Kernel::Main::_handle_kernel_entry() +{ + Cpu &cpu = cpu_pool().cpu(Cpu::executing_id()); + Cpu_job * new_job; + + { + Lock::Guard guard(data_lock()); + + new_job = &cpu.schedule(); + } + + new_job->proceed(cpu); +} + + +void Kernel::main_handle_kernel_entry() +{ + Main::_instance->_handle_kernel_entry(); +} + + +void Kernel::main_initialize_and_handle_kernel_entry() +{ + static volatile bool lock_ready = false; + static volatile bool pool_ready = false; + static volatile bool kernel_ready = false; + + /** + * It is essential to guard the initialization of the data_lock object + * in the SMP case, because otherwise the __cxa_guard_aquire of the cxx + * library contention path might get called, which ends up in + * calling a Semaphore, which will call Kernel::stop_thread() or + * Kernel::yield() system-calls in this code + */ + while (Cpu::executing_id() != Cpu::primary_id() && !lock_ready) { } + + /** + * Create a main object and initialize static reference to it + */ + if (Cpu::executing_id() == Cpu::primary_id()) { + + static Main instance { }; + Main::_instance = &instance; + } + + { + Lock::Guard guard(data_lock()); + + lock_ready = true; + + /* initialize current cpu */ + pool_ready = cpu_pool().initialize(); + }; + + /* wait until all cpus have initialized their corresponding cpu object */ + while (!pool_ready) { ; } + + /* the boot-cpu initializes the rest of the kernel */ + if (Cpu::executing_id() == Cpu::primary_id()) { + Lock::Guard guard(data_lock()); + + using Boot_info = Hw::Boot_info; + Boot_info &boot_info { + *reinterpret_cast(Hw::Mm::boot_info().base) }; + + cpu_pool().for_each_cpu([&] (Kernel::Cpu &cpu) { + boot_info.kernel_irqs.add(cpu.timer().interrupt_id()); + }); + boot_info.kernel_irqs.add((unsigned)Board::Pic::IPI); + + Genode::log(""); + Genode::log("kernel initialized"); + + Core_main_thread::singleton(); + kernel_ready = true; + } else { + /* secondary cpus spin until the kernel is initialized */ + while (!kernel_ready) {;} + } + + Main::_instance->_handle_kernel_entry(); +} + + +Kernel::time_t Kernel::main_read_idle_thread_execution_time(unsigned cpu_idx) +{ + return cpu_pool().cpu(cpu_idx).idle_thread().execution_time(); +} diff --git a/repos/base-hw/src/core/kernel/main.h b/repos/base-hw/src/core/kernel/main.h new file mode 100644 index 0000000000..b7046174d6 --- /dev/null +++ b/repos/base-hw/src/core/kernel/main.h @@ -0,0 +1,29 @@ +/* + * \brief Main object of the kernel + * \author Martin Stein + * \date 2021-07-09 + */ + +/* + * Copyright (C) 2021 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. + */ + +#ifndef _KERNEL__MAIN_H_ +#define _KERNEL__MAIN_H_ + +/* base-hw Core includes */ +#include + +namespace Kernel { + + void main_handle_kernel_entry(); + + void main_initialize_and_handle_kernel_entry(); + + time_t main_read_idle_thread_execution_time(unsigned cpu_idx); +} + +#endif /* _KERNEL__MAIN_H_ */ diff --git a/repos/base-hw/src/core/platform.cc b/repos/base-hw/src/core/platform.cc index 4f42d9c8a4..42d3dcd883 100644 --- a/repos/base-hw/src/core/platform.cc +++ b/repos/base-hw/src/core/platform.cc @@ -23,6 +23,7 @@ #include #include #include +#include /* base-internal includes */ #include @@ -35,11 +36,6 @@ using namespace Genode; -namespace Kernel { - - time_t read_idle_thread_execution_time(unsigned cpu_idx); -} - /************** ** Platform ** @@ -236,7 +232,7 @@ Platform::Platform() Info trace_source_info() const override { Trace::Execution_time execution_time { - Kernel::read_idle_thread_execution_time( + Kernel::main_read_idle_thread_execution_time( _affinity.xpos()), 0 }; return { Session_label("kernel"), "idle", diff --git a/repos/base-hw/src/core/spec/arm/crt0.s b/repos/base-hw/src/core/spec/arm/crt0.s index fd59a3a8f8..b11c3ae502 100644 --- a/repos/base-hw/src/core/spec/arm/crt0.s +++ b/repos/base-hw/src/core/spec/arm/crt0.s @@ -31,7 +31,7 @@ add sp, r1, r0 /* jump into init C code */ - b kernel_init + b _ZN6Kernel39main_initialize_and_handle_kernel_entryEv _kernel_stack: .long kernel_stack _kernel_stack_size: .long kernel_stack_size diff --git a/repos/base-hw/src/core/spec/arm/exception_vector.S b/repos/base-hw/src/core/spec/arm/exception_vector.S index 3a7d9b6e4f..a4f14339d6 100644 --- a/repos/base-hw/src/core/spec/arm/exception_vector.S +++ b/repos/base-hw/src/core/spec/arm/exception_vector.S @@ -134,7 +134,7 @@ bx lr _kernel_entry: - .long kernel + .long _ZN6Kernel24main_handle_kernel_entryEv _fpu_save: .long vfp_save_fpu_context diff --git a/repos/base-hw/src/core/spec/arm_v7/trustzone/exception_vector.s b/repos/base-hw/src/core/spec/arm_v7/trustzone/exception_vector.s index b159aec6b5..05cccd3f56 100644 --- a/repos/base-hw/src/core/spec/arm_v7/trustzone/exception_vector.s +++ b/repos/base-hw/src/core/spec/arm_v7/trustzone/exception_vector.s @@ -99,7 +99,7 @@ monitor_mode_exception_vector: ldr lr, [lr] subs pc, lr, #0 /* jump back into kernel */ - _kernel_entry: .long kernel + _kernel_entry: .long _ZN6Kernel24main_handle_kernel_entryEv /* jump to this point to switch to TrustZone's normal world */ 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 5691068d17..811733ee5a 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 @@ -18,6 +18,7 @@ #include #include #include +#include namespace Kernel { @@ -60,8 +61,7 @@ struct Host_context } vt_host_context; -extern "C" void kernel(); -extern "C" void hypervisor_enter_vm(Genode::Vm_state&, Host_context&); +extern "C" void hypervisor_enter_vm(Genode::Vm_state&, Host_context&); static Host_context & host_context(Cpu & cpu) @@ -78,7 +78,7 @@ static Host_context & host_context(Cpu & cpu) c.mair0 = Cpu::Mair0::read(); c.dacr = Cpu::Dacr::read(); c.vmpidr = Cpu::Mpidr::read(); - c.ip = (addr_t) &kernel; + c.ip = (addr_t)&Kernel::main_handle_kernel_entry; c.vttbr = 0; c.hcr = 0; c.hstr = 0; diff --git a/repos/base-hw/src/core/spec/arm_v8/crt0.s b/repos/base-hw/src/core/spec/arm_v8/crt0.s index 9adb479fbd..58cbdc240c 100644 --- a/repos/base-hw/src/core/spec/arm_v8/crt0.s +++ b/repos/base-hw/src/core/spec/arm_v8/crt0.s @@ -31,7 +31,7 @@ add sp, r1, r0*/ /* jump into init C code */ - b kernel_init + b _ZN6Kernel39main_initialize_and_handle_kernel_entryEv _kernel_stack: .quad kernel_stack _kernel_stack_size: .quad kernel_stack_size diff --git a/repos/base-hw/src/core/spec/arm_v8/exception_vector.s b/repos/base-hw/src/core/spec/arm_v8/exception_vector.s index ebd9b26eb1..8236b7feb3 100644 --- a/repos/base-hw/src/core/spec/arm_v8/exception_vector.s +++ b/repos/base-hw/src/core/spec/arm_v8/exception_vector.s @@ -67,7 +67,7 @@ _kernel_entry: ldr x0, [sp, #-16] ldr x1, [sp, #-32] str x1, [x0] - bl kernel + bl _ZN6Kernel24main_handle_kernel_entryEv .section .text diff --git a/repos/base-hw/src/core/spec/arm_v8/virtualization/kernel/vm.cc b/repos/base-hw/src/core/spec/arm_v8/virtualization/kernel/vm.cc index 08f8154d5a..cd93e368f2 100644 --- a/repos/base-hw/src/core/spec/arm_v8/virtualization/kernel/vm.cc +++ b/repos/base-hw/src/core/spec/arm_v8/virtualization/kernel/vm.cc @@ -21,12 +21,12 @@ #include #include #include +#include using Genode::addr_t; using Kernel::Cpu; using Kernel::Vm; -extern "C" void kernel(); extern void * kernel_stack; extern "C" void hypervisor_enter_vm(addr_t vm, addr_t host, addr_t pic, addr_t guest_table); @@ -40,7 +40,7 @@ static Genode::Vm_state & host_context(Cpu & cpu) host_context[cpu.id()].construct(); Genode::Vm_state & c = *host_context[cpu.id()]; c.sp_el1 = cpu.stack_start(); - c.ip = (addr_t) &kernel; + c.ip = (addr_t)&Kernel::main_handle_kernel_entry; c.pstate = 0; Cpu::Spsr::Sp::set(c.pstate, 1); /* select non-el0 stack pointer */ Cpu::Spsr::El::set(c.pstate, Cpu::Current_el::EL1); diff --git a/repos/base-hw/src/core/spec/riscv/crt0.s b/repos/base-hw/src/core/spec/riscv/crt0.s index b1808fa107..b106768555 100644 --- a/repos/base-hw/src/core/spec/riscv/crt0.s +++ b/repos/base-hw/src/core/spec/riscv/crt0.s @@ -24,7 +24,7 @@ la x30, kernel_stack_size ld x30, (x30) add sp, x29, x30 - la x30, kernel_init + la x30, _ZN6Kernel39main_initialize_and_handle_kernel_entryEv jalr x30 diff --git a/repos/base-hw/src/core/spec/riscv/exception_vector.s b/repos/base-hw/src/core/spec/riscv/exception_vector.s index 59fd76b903..d70e238a9e 100644 --- a/repos/base-hw/src/core/spec/riscv/exception_vector.s +++ b/repos/base-hw/src/core/spec/riscv/exception_vector.s @@ -49,7 +49,7 @@ _kernel_entry: la x30, kernel_stack_size ld x30, (x30) add sp, x29, x30 - la x30, kernel + la x30, _ZN6Kernel24main_handle_kernel_entryEv jalr x30 diff --git a/repos/base-hw/src/core/spec/x86_64/crt0.s b/repos/base-hw/src/core/spec/x86_64/crt0.s index e7842bb7dc..0ca72835b8 100644 --- a/repos/base-hw/src/core/spec/x86_64/crt0.s +++ b/repos/base-hw/src/core/spec/x86_64/crt0.s @@ -38,7 +38,7 @@ movq %rax, %rsp /* jump to C entry code */ - jmp kernel_init + jmp _ZN6Kernel39main_initialize_and_handle_kernel_entryEv /********************************* diff --git a/repos/base-hw/src/core/spec/x86_64/exception_vector.s b/repos/base-hw/src/core/spec/x86_64/exception_vector.s index 3d3e8ebcd0..e5e9deed8d 100644 --- a/repos/base-hw/src/core/spec/x86_64/exception_vector.s +++ b/repos/base-hw/src/core/spec/x86_64/exception_vector.s @@ -133,7 +133,7 @@ addq $KERNEL_STACK_OFFSET, %rax movq (%rax), %rsp - _load_address kernel rcx + _load_address _ZN6Kernel24main_handle_kernel_entryEv rcx jmp *%rcx