From 27860cfaa2dd36389c79eddf31e78c6668cc9070 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Holz?= Date: Wed, 3 Jan 2024 17:21:19 +0100 Subject: [PATCH] Kernel/riscv64: Add a basic trap handler to `pre_init` This trap handler uses the SBI to print an error message via a newly introduced panic function, which is necessary as `pre_init` is running identity mapped. Also add a header file for `pre_init.cpp` as we wan't to use the panic and `dbgln` function in the MMU init code as well. --- Kernel/Arch/riscv64/pre_init.cpp | 42 +++++++++++++++++++++++++++++--- Kernel/Arch/riscv64/pre_init.h | 22 +++++++++++++++++ 2 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 Kernel/Arch/riscv64/pre_init.h diff --git a/Kernel/Arch/riscv64/pre_init.cpp b/Kernel/Arch/riscv64/pre_init.cpp index 3bbbd7d99f..1f277ad051 100644 --- a/Kernel/Arch/riscv64/pre_init.cpp +++ b/Kernel/Arch/riscv64/pre_init.cpp @@ -4,19 +4,53 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include +#include #include -#include +#include +#include +#include namespace Kernel { -extern "C" [[noreturn]] void pre_init(FlatPtr mhartid, PhysicalPtr fdt_phys_addr); -extern "C" [[noreturn]] void pre_init(FlatPtr mhartid, PhysicalPtr fdt_phys_addr) +UNMAP_AFTER_INIT void dbgln_without_mmu(StringView message) +{ + auto probe_result = SBI::Base::probe_extension(SBI::EID::DebugConsole); + if (probe_result.is_error() || probe_result.value() == 0) { + for (auto const ch : message.bytes()) + (void)SBI::Legacy::console_putchar(ch); + (void)SBI::Legacy::console_putchar('\n'); + } else { + for (auto const ch : message.bytes()) + (void)SBI::DBCN::debug_console_write_byte(ch); + (void)SBI::DBCN::debug_console_write_byte('\n'); + } +} + +[[noreturn]] UNMAP_AFTER_INIT void panic_without_mmu(StringView message) +{ + dbgln_without_mmu("KERNEL PANIC in pre_init :^("sv); + dbgln_without_mmu(message); + + // We can't use Processor::halt() here, as that would result in an absolute jump. + RISCV64::CSR::write(RISCV64::CSR::Address::SIE, 0); + for (;;) + asm volatile("wfi"); +} + +[[gnu::aligned(4)]] [[noreturn]] UNMAP_AFTER_INIT static void early_trap_handler() +{ + panic_without_mmu("Unexpected trap"sv); +} + +extern "C" [[noreturn]] UNMAP_AFTER_INIT void pre_init(FlatPtr mhartid, PhysicalPtr fdt_phys_addr) { (void)mhartid; (void)fdt_phys_addr; + // Catch traps in pre_init + RISCV64::CSR::write(RISCV64::CSR::Address::STVEC, bit_cast(&early_trap_handler)); + // FIXME: Implement this Processor::halt(); diff --git a/Kernel/Arch/riscv64/pre_init.h b/Kernel/Arch/riscv64/pre_init.h new file mode 100644 index 0000000000..d304c85a3d --- /dev/null +++ b/Kernel/Arch/riscv64/pre_init.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023, Sönke Holz + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include + +#include +VALIDATE_IS_RISCV64() + +namespace Kernel { + +void dbgln_without_mmu(StringView); +[[noreturn]] void panic_without_mmu(StringView); + +extern "C" [[noreturn]] void pre_init(FlatPtr mhartid, PhysicalPtr fdt_phys_addr); + +}