From 05659debd17cd69188996204ce4e5bae95d83d5f Mon Sep 17 00:00:00 2001 From: Timon Kruiper Date: Sun, 8 Jan 2023 13:23:55 +0100 Subject: [PATCH] Kernel/aarch64: Move exception handler to Interrupts.cpp Also dump the registers in a nicer format. --- Kernel/Arch/aarch64/Interrupts.cpp | 55 ++++++++++++++++++++++++++++++ Kernel/Arch/aarch64/init.cpp | 35 ------------------- 2 files changed, 55 insertions(+), 35 deletions(-) diff --git a/Kernel/Arch/aarch64/Interrupts.cpp b/Kernel/Arch/aarch64/Interrupts.cpp index 450053daad..c23943e34f 100644 --- a/Kernel/Arch/aarch64/Interrupts.cpp +++ b/Kernel/Arch/aarch64/Interrupts.cpp @@ -10,9 +10,64 @@ #include #include #include +#include +#include namespace Kernel { +static void dump_registers(RegisterState const& regs) +{ + dbgln(" x0={:p} x1={:p} x2={:p} x3={:p} x4={:p}", regs.x[0], regs.x[1], regs.x[2], regs.x[3], regs.x[4]); + dbgln(" x5={:p} x6={:p} x7={:p} x8={:p} x9={:p}", regs.x[5], regs.x[6], regs.x[7], regs.x[8], regs.x[9]); + dbgln("x10={:p} x11={:p} x12={:p} x13={:p} x14={:p}", regs.x[10], regs.x[11], regs.x[12], regs.x[13], regs.x[14]); + dbgln("x15={:p} x16={:p} x17={:p} x18={:p} x19={:p}", regs.x[15], regs.x[16], regs.x[17], regs.x[18], regs.x[19]); + dbgln("x20={:p} x21={:p} x22={:p} x23={:p} x24={:p}", regs.x[20], regs.x[21], regs.x[22], regs.x[23], regs.x[24]); + dbgln("x25={:p} x26={:p} x27={:p} x28={:p} x29={:p}", regs.x[25], regs.x[26], regs.x[27], regs.x[28], regs.x[29]); + dbgln("x30={:p}", regs.x[30]); + + // Special registers + Aarch64::SPSR_EL1 spsr_el1 = {}; + memcpy(&spsr_el1, (u8 const*)®s.spsr_el1, sizeof(u64)); + + dbgln("spsr_el1: 0x{:x} (NZCV({:#b}) DAIF({:#b}) M({:#b}))", regs.spsr_el1, ((regs.spsr_el1 >> 28) & 0b1111), ((regs.spsr_el1 >> 6) & 0b1111), regs.spsr_el1 & 0b1111); + dbgln("elr_el1: 0x{:x}", regs.elr_el1); + dbgln("tpidr_el0: 0x{:x}", regs.tpidr_el0); + dbgln("sp_el0: 0x{:x}", regs.sp_el0); + + constexpr bool print_backtrace = true; + if constexpr (print_backtrace) { + auto const* symbol = symbolicate_kernel_address(regs.elr_el1); + dbgln("{:p} {} +{}", regs.elr_el1, (symbol ? symbol->name : "(k?)"), (symbol ? regs.elr_el1 - symbol->address : 0)); + dump_backtrace_from_base_pointer(regs.x[29]); + } +} + +static void dump_exception_syndrome_register(Aarch64::ESR_EL1 const& esr_el1) +{ + dbgln("esr_el1: EC({:#b}) IL({:#b}) ISS({:#b}) ISS2({:#b})", esr_el1.EC, esr_el1.IL, esr_el1.ISS, esr_el1.ISS2); + dbgln("Exception Class: {}", Aarch64::exception_class_to_string(esr_el1.EC)); + if (Aarch64::exception_class_has_set_far(esr_el1.EC)) + dbgln("Faulting Virtual Address: 0x{:x}", Aarch64::FAR_EL1::read().virtual_address); + + if (Aarch64::exception_class_is_data_abort(esr_el1.EC)) + dbgln("Data Fault Status Code: {}", Aarch64::data_fault_status_code_to_string(esr_el1.ISS)); +} + +extern "C" void exception_common(Kernel::TrapFrame const* const trap_frame); +extern "C" void exception_common(Kernel::TrapFrame const* const trap_frame) +{ + auto esr_el1 = Kernel::Aarch64::ESR_EL1::read(); + + constexpr bool print_state = true; + if constexpr (print_state) { + dbgln("Exception Generated by processor!"); + dump_registers(*trap_frame->regs); + dump_exception_syndrome_register(esr_el1); + } + + Kernel::Processor::halt(); +} + static Array s_interrupt_handlers; extern "C" void handle_interrupt(TrapFrame&); diff --git a/Kernel/Arch/aarch64/init.cpp b/Kernel/Arch/aarch64/init.cpp index 8a50e15cc2..da1bb588d1 100644 --- a/Kernel/Arch/aarch64/init.cpp +++ b/Kernel/Arch/aarch64/init.cpp @@ -31,41 +31,6 @@ #include #include -extern "C" void exception_common(Kernel::TrapFrame const* const trap_frame); -extern "C" void exception_common(Kernel::TrapFrame const* const trap_frame) -{ - constexpr bool print_stack_frame = true; - - if constexpr (print_stack_frame) { - dbgln("Exception Generated by processor!"); - - auto* regs = trap_frame->regs; - - for (auto reg = 0; reg < 31; reg++) { - dbgln("x{}: {:x}", reg, regs->x[reg]); - } - - // Special registers - dbgln("spsr_el1: {:x}", regs->spsr_el1); - dbgln("elr_el1: {:x}", regs->elr_el1); - dbgln("tpidr_el0: {:x}", regs->tpidr_el0); - dbgln("sp_el0: {:x}", regs->sp_el0); - - auto esr_el1 = Kernel::Aarch64::ESR_EL1::read(); - dbgln("esr_el1: EC({:#b}) IL({:#b}) ISS({:#b}) ISS2({:#b})", esr_el1.EC, esr_el1.IL, esr_el1.ISS, esr_el1.ISS2); - dbgln("Exception Class: {}", Aarch64::exception_class_to_string(esr_el1.EC)); - if (Aarch64::exception_class_has_set_far(esr_el1.EC)) - dbgln("Faulting Virtual Address: 0x{:x}", Aarch64::FAR_EL1::read().virtual_address); - - if (Aarch64::exception_class_is_data_abort(esr_el1.EC)) - dbgln("Data Fault Status Code: {}", Aarch64::data_fault_status_code_to_string(esr_el1.ISS)); - - dump_backtrace_from_base_pointer(regs->x[29]); - } - - Kernel::Processor::halt(); -} - typedef void (*ctor_func_t)(); extern ctor_func_t start_heap_ctors[]; extern ctor_func_t end_heap_ctors[];