mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-21 14:37:50 +00:00
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
This commit is contained in:
parent
9de43a48b6
commit
82cf31ac27
@ -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
|
||||
|
@ -14,13 +14,7 @@
|
||||
|
||||
/* core includes */
|
||||
#include <kernel/pd.h>
|
||||
#include <kernel/cpu.h>
|
||||
#include <kernel/kernel.h>
|
||||
#include <kernel/lock.h>
|
||||
#include <platform_pd.h>
|
||||
#include <board.h>
|
||||
#include <platform_thread.h>
|
||||
#include <hw/boot_info.h>
|
||||
|
||||
/* base includes */
|
||||
#include <base/internal/unmanaged_singleton.h>
|
||||
@ -34,62 +28,3 @@ static_assert(sizeof(Genode::sizet_arithm_t) >= 2 * sizeof(size_t),
|
||||
|
||||
Pd &Kernel::core_pd() {
|
||||
return unmanaged_singleton<Genode::Core_platform_pd>()->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<Board::Boot_info>;
|
||||
Boot_info &boot_info {
|
||||
*reinterpret_cast<Boot_info*>(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();
|
||||
}
|
||||
|
@ -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 <kernel/cpu.h>
|
||||
#include <kernel/lock.h>
|
||||
#include <kernel/kernel.h>
|
||||
|
||||
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);
|
||||
}
|
@ -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;
|
||||
|
133
repos/base-hw/src/core/kernel/main.cc
Normal file
133
repos/base-hw/src/core/kernel/main.cc
Normal file
@ -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 <kernel/cpu.h>
|
||||
#include <kernel/lock.h>
|
||||
#include <kernel/main.h>
|
||||
|
||||
/* base-hw-internal includes */
|
||||
#include <hw/boot_info.h>
|
||||
|
||||
|
||||
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<Board::Boot_info>;
|
||||
Boot_info &boot_info {
|
||||
*reinterpret_cast<Boot_info*>(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();
|
||||
}
|
29
repos/base-hw/src/core/kernel/main.h
Normal file
29
repos/base-hw/src/core/kernel/main.h
Normal file
@ -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 <kernel/types.h>
|
||||
|
||||
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_ */
|
@ -23,6 +23,7 @@
|
||||
#include <hw/page_flags.h>
|
||||
#include <hw/util.h>
|
||||
#include <translation_table.h>
|
||||
#include <kernel/main.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/crt0.h>
|
||||
@ -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",
|
||||
|
@ -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
|
||||
|
@ -134,7 +134,7 @@
|
||||
bx lr
|
||||
|
||||
_kernel_entry:
|
||||
.long kernel
|
||||
.long _ZN6Kernel24main_handle_kernel_entryEv
|
||||
|
||||
_fpu_save:
|
||||
.long vfp_save_fpu_context
|
||||
|
@ -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 */
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <platform_pd.h>
|
||||
#include <kernel/cpu.h>
|
||||
#include <kernel/vm.h>
|
||||
#include <kernel/main.h>
|
||||
|
||||
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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -21,12 +21,12 @@
|
||||
#include <platform_pd.h>
|
||||
#include <kernel/cpu.h>
|
||||
#include <kernel/vm.h>
|
||||
#include <kernel/main.h>
|
||||
|
||||
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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -38,7 +38,7 @@
|
||||
movq %rax, %rsp
|
||||
|
||||
/* jump to C entry code */
|
||||
jmp kernel_init
|
||||
jmp _ZN6Kernel39main_initialize_and_handle_kernel_entryEv
|
||||
|
||||
|
||||
/*********************************
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user