1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-06-01 08:28:11 +00:00

Kernel/aarch64: Add {panic,dbgln}_without_mmu

And use it the code that will be part of the early boot process.

The PANIC macro and dbgln functions cannot be used as it accesses global
variables, which in the early boot process do not work, since the MMU is
not yet enabled.
This commit is contained in:
Timon Kruiper 2023-01-07 11:59:37 +01:00 committed by Linus Groh
parent 69c49b3d00
commit 150c52e420
4 changed files with 41 additions and 14 deletions

View file

@ -6,11 +6,14 @@
#pragma once
#include <AK/Forward.h>
#include <AK/Types.h>
namespace Kernel {
void initialize_exceptions(u32 cpu);
void initialize_exceptions();
void init_page_tables();
void panic_without_mmu(StringView);
void dbgln_without_mmu(StringView);
}

View file

@ -6,6 +6,7 @@
#include <Kernel/Arch/aarch64/ASM_wrapper.h>
#include <Kernel/Arch/aarch64/CPU.h>
#include <Kernel/Arch/aarch64/Processor.h>
#include <Kernel/Arch/aarch64/Registers.h>
#include <Kernel/Panic.h>
@ -84,30 +85,50 @@ static void setup_el1()
Aarch64::Asm::load_el1_vector_table(&vector_table_el1);
}
void initialize_exceptions(u32 cpu)
void initialize_exceptions()
{
auto base_exception_level = Aarch64::Asm::get_current_exception_level();
if (base_exception_level > Aarch64::Asm::ExceptionLevel::EL3) {
PANIC("CPU[{}]: Started in unknown EL{}", cpu, static_cast<u8>(base_exception_level));
panic_without_mmu("Started in unknown EL (Greater than EL3)"sv);
} else if (base_exception_level < Aarch64::Asm::ExceptionLevel::EL1) {
PANIC("CPU[{}]: Started in unsupported EL{}", cpu, static_cast<u8>(base_exception_level));
panic_without_mmu("Started in unsupported EL (Less than EL1)"sv);
} else {
dbgln("CPU[{}]: Started in EL{}", cpu, static_cast<u8>(base_exception_level));
if (base_exception_level == Aarch64::Asm::ExceptionLevel::EL1)
dbgln_without_mmu("Started in EL1"sv);
else if (base_exception_level == Aarch64::Asm::ExceptionLevel::EL2)
dbgln_without_mmu("Started in EL2"sv);
else if (base_exception_level == Aarch64::Asm::ExceptionLevel::EL3)
dbgln_without_mmu("Started in EL3"sv);
}
if (base_exception_level > Aarch64::Asm::ExceptionLevel::EL2) {
drop_el3_to_el2();
dbgln("CPU[{}]: Dropped to EL2", cpu);
dbgln_without_mmu("Dropped to EL2"sv);
}
if (base_exception_level > Aarch64::Asm::ExceptionLevel::EL1) {
drop_el2_to_el1();
dbgln("CPU[{}]: Dropped to EL1", cpu);
dbgln_without_mmu("Dropped to EL1"sv);
}
setup_el1();
dbgln("CPU[{}]: Set up EL1", cpu);
dbgln_without_mmu("Set up EL1"sv);
}
// NOTE: The normal PANIC macro cannot be used early in the boot process when the MMU is disabled,
// as it will access global variables, which will cause a crash since they aren't mapped yet.
void panic_without_mmu(StringView message)
{
(void)message;
// FIXME: Print out message to early boot console.
Processor::halt();
}
void dbgln_without_mmu(StringView message)
{
(void)message;
// FIXME: Print out message to early boot console.
}
}

View file

@ -46,17 +46,17 @@ public:
, m_current(start)
{
if (m_start >= m_end) {
PANIC("Invalid memory range passed to PageBumpAllocator");
panic_without_mmu("Invalid memory range passed to PageBumpAllocator"sv);
}
if ((FlatPtr)m_start % PAGE_TABLE_SIZE != 0 || (FlatPtr)m_end % PAGE_TABLE_SIZE != 0) {
PANIC("Memory range passed into PageBumpAllocator not aligned to PAGE_TABLE_SIZE");
panic_without_mmu("Memory range passed into PageBumpAllocator not aligned to PAGE_TABLE_SIZE"sv);
}
}
u64* take_page()
{
if (m_current == m_end) {
PANIC("Prekernel pagetable memory exhausted");
panic_without_mmu("Prekernel pagetable memory exhausted"sv);
}
u64* page = m_current;
@ -221,8 +221,11 @@ static u64* get_page_directory(u64* root_table, VirtualAddress virtual_addr)
static void setup_kernel_page_directory(u64* root_table)
{
boot_pd_kernel = PhysicalAddress((PhysicalPtr)get_page_directory(root_table, VirtualAddress { kernel_mapping_base }));
VERIFY(!boot_pd_kernel.is_null());
auto kernel_page_directory = (PhysicalPtr)get_page_directory(root_table, VirtualAddress { kernel_mapping_base });
if (!kernel_page_directory)
panic_without_mmu("Could not find kernel page directory!"sv);
boot_pd_kernel = PhysicalAddress(kernel_page_directory);
}
void init_page_tables()

View file

@ -36,7 +36,7 @@ void Processor::install(u32 cpu)
m_physical_address_bit_width = detect_physical_address_bit_width();
m_virtual_address_bit_width = detect_virtual_address_bit_width();
initialize_exceptions(cpu);
initialize_exceptions();
g_current_processor = this;
}