Parcourir la source

Kernel/aarch64: Move exception handler to Interrupts.cpp

Also dump the registers in a nicer format.
Timon Kruiper il y a 2 ans
Parent
commit
05659debd1
2 fichiers modifiés avec 55 ajouts et 35 suppressions
  1. 55 0
      Kernel/Arch/aarch64/Interrupts.cpp
  2. 0 35
      Kernel/Arch/aarch64/init.cpp

+ 55 - 0
Kernel/Arch/aarch64/Interrupts.cpp

@@ -10,9 +10,64 @@
 #include <Kernel/Interrupts/GenericInterruptHandler.h>
 #include <Kernel/Interrupts/SharedIRQHandler.h>
 #include <Kernel/Interrupts/UnhandledInterruptHandler.h>
+#include <Kernel/KSyms.h>
+#include <Kernel/StdLib.h>
 
 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*)&regs.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<GenericInterruptHandler*, 64> s_interrupt_handlers;
 
 extern "C" void handle_interrupt(TrapFrame&);

+ 0 - 35
Kernel/Arch/aarch64/init.cpp

@@ -31,41 +31,6 @@
 #include <Kernel/Panic.h>
 #include <Kernel/Scheduler.h>
 
-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[];