[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.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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 ");
|
||||
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");
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user