From af7b9bde29a1e203f751d8ec1f1c28be2931bed0 Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Thu, 30 Dec 2021 20:27:16 -0800 Subject: [PATCH] [panic.serial] Add location to panic data Updated kassert to be an actual function, and used the __builtin_* functions for location data. Updated the panic handler protocol to include sending location data as three more parameters. Updated the serial panic handler to display that data along with the (optional) message. --- src/kernel/main.cpp | 30 +++++++++--------- src/kernel/panic.serial/display.cpp | 21 ++++++++++-- src/kernel/panic.serial/display.h | 8 ++++- src/kernel/panic.serial/entry.s | 2 +- src/kernel/panic.serial/main.cpp | 7 ++-- src/libraries/kutil/include/kutil/assert.h | 37 +++++++++++++++------- 6 files changed, 73 insertions(+), 32 deletions(-) diff --git a/src/kernel/main.cpp b/src/kernel/main.cpp index 03b6b62..3961110 100644 --- a/src/kernel/main.cpp +++ b/src/kernel/main.cpp @@ -89,21 +89,6 @@ kernel_main(init::args *args) cpu_validate(); - kassert(args->magic == init::args_magic, - "Bad kernel args magic number"); - - log::debug(logs::boot, "jsix init args are at: %016lx", args); - log::debug(logs::boot, " Memory map is at: %016lx", args->mem_map); - log::debug(logs::boot, "ACPI root table is at: %016lx", args->acpi_table); - log::debug(logs::boot, "Runtime service is at: %016lx", args->runtime_services); - log::debug(logs::boot, " Kernel PML4 is at: %016lx", args->pml4); - - uint64_t cr0, cr4; - asm ("mov %%cr0, %0" : "=r"(cr0)); - asm ("mov %%cr4, %0" : "=r"(cr4)); - uint64_t efer = rdmsr(msr::ia32_efer); - log::debug(logs::boot, "Control regs: cr0:%lx cr4:%lx efer:%lx", cr0, cr4, efer); - extern IDT &g_bsp_idt; extern TSS &g_bsp_tss; extern GDT &g_bsp_gdt; @@ -120,6 +105,21 @@ kernel_main(init::args *args) cpu->rsp0 = idle_stack_end; cpu_early_init(cpu); + kassert(args->magic == init::args_magic, + "Bad kernel args magic number"); + + log::debug(logs::boot, "jsix init args are at: %016lx", args); + log::debug(logs::boot, " Memory map is at: %016lx", args->mem_map); + log::debug(logs::boot, "ACPI root table is at: %016lx", args->acpi_table); + log::debug(logs::boot, "Runtime service is at: %016lx", args->runtime_services); + log::debug(logs::boot, " Kernel PML4 is at: %016lx", args->pml4); + + uint64_t cr0, cr4; + asm ("mov %%cr0, %0" : "=r"(cr0)); + asm ("mov %%cr4, %0" : "=r"(cr4)); + uint64_t efer = rdmsr(msr::ia32_efer); + log::debug(logs::boot, "Control regs: cr0:%lx cr4:%lx efer:%lx", cr0, cr4, efer); + disable_legacy_pic(); memory_initialize_pre_ctors(*args); diff --git a/src/kernel/panic.serial/display.cpp b/src/kernel/panic.serial/display.cpp index 0873cb0..9aeaabc 100644 --- a/src/kernel/panic.serial/display.cpp +++ b/src/kernel/panic.serial/display.cpp @@ -7,10 +7,27 @@ namespace panic { void -print_header(serial_port &out, const char *message) +print_header( + serial_port &out, + const char *message, + const char *function, + const char *file, + uint64_t line) { out.write("\n\n\e[5;31m PANIC:\e[0;1;31m "); - out.write(message); + if (message) { + out.write(message); + out.write("\n "); + } + out.write(function); + out.write(" "); + out.write(file); + out.write(":"); + + char linestr[6]; + snprintf(linestr, sizeof(linestr), "%d", line); + out.write(linestr); + out.write("\n \e[0;31m===================================================================================\n"); } diff --git a/src/kernel/panic.serial/display.h b/src/kernel/panic.serial/display.h index c5c646a..3ac06f1 100644 --- a/src/kernel/panic.serial/display.h +++ b/src/kernel/panic.serial/display.h @@ -17,7 +17,13 @@ struct frame uintptr_t return_addr; }; -void print_header(serial_port &out, const char *message); +void print_header( + serial_port &out, + const char *message, + const char *function, + const char *file, + uint64_t line); + void print_callstack(serial_port &out, symbol_table &syms, frame const *fp); void print_cpu_state(serial_port &out, const cpu_state ®s); diff --git a/src/kernel/panic.serial/entry.s b/src/kernel/panic.serial/entry.s index c4bdb6d..3bd157f 100644 --- a/src/kernel/panic.serial/entry.s +++ b/src/kernel/panic.serial/entry.s @@ -10,7 +10,7 @@ _panic_entry: push 0 ; NMI doesn't push an error code push 2 ; NMI is int 2 push_all - mov rdx, rsp + mov r9, rsp mov rax, [rsp + REGS.rip] push rax diff --git a/src/kernel/panic.serial/main.cpp b/src/kernel/panic.serial/main.cpp index df4cefd..a4693b2 100644 --- a/src/kernel/panic.serial/main.cpp +++ b/src/kernel/panic.serial/main.cpp @@ -6,8 +6,11 @@ struct cpu_state; extern "C" void panic_handler( - const char *message, const void *symbol_data, + const char *message, + const char *function, + const char *file, + uint64_t line, const cpu_state *regs) { panic::serial_port com1(panic::COM1); @@ -16,7 +19,7 @@ void panic_handler( panic::frame const *fp = nullptr; asm ( "mov %%rbp, %0" : "=r" (fp) ); - print_header(com1, message); + print_header(com1, message, function, file, line); print_callstack(com1, syms, fp); print_cpu_state(com1, *regs); diff --git a/src/libraries/kutil/include/kutil/assert.h b/src/libraries/kutil/include/kutil/assert.h index b1cd5be..c9c31c6 100644 --- a/src/libraries/kutil/include/kutil/assert.h +++ b/src/libraries/kutil/include/kutil/assert.h @@ -16,14 +16,29 @@ extern uintptr_t symbol_table; } // namespace assert } // namespace kutil -#define kassert(stmt, message) \ - do { \ - if(!(stmt)) { \ - register const char *m asm("rdi"); \ - register uintptr_t i asm("rsi"); \ - asm volatile ("mov %1, %0" : "=r"(m) : "r"(message)); \ - asm volatile ("mov %1, %0" : "=r"(i) : "r"(kutil::assert::symbol_table)); \ - *kutil::assert::apic_icr = kutil::assert::send_nmi_command; \ - while (1) __asm__ __volatile__ ("hlt"); \ - } \ - } while(0); +__attribute__ ((always_inline)) +inline void kassert( + bool check, + const char *message = nullptr, + const char *function = __builtin_FUNCTION(), + const char *file = __builtin_FILE(), + uint64_t line = __builtin_LINE()) +{ + if (!check) { + register uintptr_t syms asm("rdi"); + register const char *m asm("rsi"); + register const char *fn asm("rdx"); + register const char *fi asm("rcx"); + register uint64_t l asm("r8"); + + asm volatile ("mov %1, %0" : "=r"(syms) : "r"(kutil::assert::symbol_table)); + asm volatile ("mov %1, %0" : "=r"(m) : "r"(message)); + asm volatile ("mov %1, %0" : "=r"(fn) : "r"(function)); + asm volatile ("mov %1, %0" : "=r"(fi) : "r"(file)); + asm volatile ("mov %1, %0" : "=r"(l) : "r"(line)); + + *kutil::assert::apic_icr = kutil::assert::send_nmi_command; + + while (1) asm ("hlt"); + } +}