mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 00:07:36 +00:00
Kernel: Introduce stages in Aarch64 CPU initialization phase
Dropping to each exception level is now more explicit.
This commit is contained in:
parent
c08f059340
commit
0f81fb03f2
4 changed files with 33 additions and 28 deletions
|
@ -68,7 +68,7 @@ inline void wait_cycles(int n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void el1_vector_table_install(void* vector_table)
|
inline void load_el1_vector_table(void* vector_table)
|
||||||
{
|
{
|
||||||
asm("msr VBAR_EL1, %[value]" ::[value] "r"(vector_table));
|
asm("msr VBAR_EL1, %[value]" ::[value] "r"(vector_table));
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,11 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/Types.h>
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
void drop_to_exception_level_1();
|
void initialize_exceptions(u32 cpu);
|
||||||
void init_page_tables();
|
void init_page_tables();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,11 @@
|
||||||
#include <Kernel/Arch/aarch64/Registers.h>
|
#include <Kernel/Arch/aarch64/Registers.h>
|
||||||
#include <Kernel/Panic.h>
|
#include <Kernel/Panic.h>
|
||||||
|
|
||||||
|
extern "C" uintptr_t vector_table_el1;
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
static void drop_to_el2()
|
static void drop_el3_to_el2()
|
||||||
{
|
{
|
||||||
Aarch64::SCR_EL3 secure_configuration_register_el3 = {};
|
Aarch64::SCR_EL3 secure_configuration_register_el3 = {};
|
||||||
|
|
||||||
|
@ -40,7 +42,7 @@ static void drop_to_el2()
|
||||||
Aarch64::Asm::enter_el2_from_el3();
|
Aarch64::Asm::enter_el2_from_el3();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drop_to_el1()
|
static void drop_el2_to_el1()
|
||||||
{
|
{
|
||||||
Aarch64::HCR_EL2 hypervisor_configuration_register_el2 = {};
|
Aarch64::HCR_EL2 hypervisor_configuration_register_el2 = {};
|
||||||
hypervisor_configuration_register_el2.RW = 1; // EL1 to use 64-bit mode
|
hypervisor_configuration_register_el2.RW = 1; // EL1 to use 64-bit mode
|
||||||
|
@ -64,7 +66,7 @@ static void drop_to_el1()
|
||||||
Aarch64::Asm::enter_el1_from_el2();
|
Aarch64::Asm::enter_el1_from_el2();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_up_el1()
|
static void setup_el1()
|
||||||
{
|
{
|
||||||
Aarch64::SCTLR_EL1 system_control_register_el1 = Aarch64::SCTLR_EL1::reset_value();
|
Aarch64::SCTLR_EL1 system_control_register_el1 = Aarch64::SCTLR_EL1::reset_value();
|
||||||
|
|
||||||
|
@ -78,24 +80,34 @@ static void set_up_el1()
|
||||||
system_control_register_el1.A = 1; // Enable memory access alignment check
|
system_control_register_el1.A = 1; // Enable memory access alignment check
|
||||||
|
|
||||||
Aarch64::SCTLR_EL1::write(system_control_register_el1);
|
Aarch64::SCTLR_EL1::write(system_control_register_el1);
|
||||||
|
|
||||||
|
Aarch64::Asm::load_el1_vector_table(&vector_table_el1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void drop_to_exception_level_1()
|
void initialize_exceptions(u32 cpu)
|
||||||
{
|
{
|
||||||
switch (Aarch64::Asm::get_current_exception_level()) {
|
auto base_exception_level = Aarch64::Asm::get_current_exception_level();
|
||||||
case Aarch64::Asm::ExceptionLevel::EL3:
|
|
||||||
drop_to_el2();
|
if (base_exception_level > Aarch64::Asm::ExceptionLevel::EL3) {
|
||||||
[[fallthrough]];
|
PANIC("CPU[{}]: Started in unknown EL{}", cpu, static_cast<u8>(base_exception_level));
|
||||||
case Aarch64::Asm::ExceptionLevel::EL2:
|
} else if (base_exception_level < Aarch64::Asm::ExceptionLevel::EL1) {
|
||||||
drop_to_el1();
|
PANIC("CPU[{}]: Started in unsupported EL{}", cpu, static_cast<u8>(base_exception_level));
|
||||||
[[fallthrough]];
|
} else {
|
||||||
case Aarch64::Asm::ExceptionLevel::EL1:
|
dbgln("CPU[{}]: Started in EL{}", cpu, static_cast<u8>(base_exception_level));
|
||||||
set_up_el1();
|
|
||||||
break;
|
|
||||||
default: {
|
|
||||||
PANIC("CPU booted in unsupported exception mode!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (base_exception_level > Aarch64::Asm::ExceptionLevel::EL2) {
|
||||||
|
drop_el3_to_el2();
|
||||||
|
dbgln("CPU[{}]: Dropped to EL2", cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (base_exception_level > Aarch64::Asm::ExceptionLevel::EL1) {
|
||||||
|
drop_el2_to_el1();
|
||||||
|
dbgln("CPU[{}]: Dropped to EL1", cpu);
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_el1();
|
||||||
|
dbgln("CPU[{}]: Set up EL1", cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
#include <Kernel/Thread.h>
|
#include <Kernel/Thread.h>
|
||||||
#include <Kernel/Time/TimeManagement.h>
|
#include <Kernel/Time/TimeManagement.h>
|
||||||
|
|
||||||
extern "C" uintptr_t vector_table_el1;
|
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
extern "C" void thread_context_first_enter(void);
|
extern "C" void thread_context_first_enter(void);
|
||||||
|
@ -33,14 +31,7 @@ void Processor::initialize(u32 cpu)
|
||||||
{
|
{
|
||||||
VERIFY(g_current_processor == nullptr);
|
VERIFY(g_current_processor == nullptr);
|
||||||
|
|
||||||
auto current_exception_level = static_cast<u64>(Aarch64::Asm::get_current_exception_level());
|
initialize_exceptions(cpu);
|
||||||
dbgln("CPU{} started in: EL{}", cpu, current_exception_level);
|
|
||||||
|
|
||||||
dbgln("Drop CPU{} to EL1", cpu);
|
|
||||||
drop_to_exception_level_1();
|
|
||||||
|
|
||||||
// Load EL1 vector table
|
|
||||||
Aarch64::Asm::el1_vector_table_install(&vector_table_el1);
|
|
||||||
|
|
||||||
g_current_processor = this;
|
g_current_processor = this;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue