[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:
Justin C. Miller
2021-12-30 20:27:16 -08:00
parent 1fb47318c0
commit af7b9bde29
6 changed files with 73 additions and 32 deletions

View File

@@ -89,21 +89,6 @@ kernel_main(init::args *args)
cpu_validate(); 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 IDT &g_bsp_idt;
extern TSS &g_bsp_tss; extern TSS &g_bsp_tss;
extern GDT &g_bsp_gdt; extern GDT &g_bsp_gdt;
@@ -120,6 +105,21 @@ kernel_main(init::args *args)
cpu->rsp0 = idle_stack_end; cpu->rsp0 = idle_stack_end;
cpu_early_init(cpu); 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(); disable_legacy_pic();
memory_initialize_pre_ctors(*args); memory_initialize_pre_ctors(*args);

View File

@@ -7,10 +7,27 @@
namespace panic { namespace panic {
void 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("\n\n\e[5;31m PANIC:\e[0;1;31m ");
if (message) {
out.write(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"); out.write("\n \e[0;31m===================================================================================\n");
} }

View File

@@ -17,7 +17,13 @@ struct frame
uintptr_t return_addr; 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_callstack(serial_port &out, symbol_table &syms, frame const *fp);
void print_cpu_state(serial_port &out, const cpu_state &regs); void print_cpu_state(serial_port &out, const cpu_state &regs);

View File

@@ -10,7 +10,7 @@ _panic_entry:
push 0 ; NMI doesn't push an error code push 0 ; NMI doesn't push an error code
push 2 ; NMI is int 2 push 2 ; NMI is int 2
push_all push_all
mov rdx, rsp mov r9, rsp
mov rax, [rsp + REGS.rip] mov rax, [rsp + REGS.rip]
push rax push rax

View File

@@ -6,8 +6,11 @@ struct cpu_state;
extern "C" extern "C"
void panic_handler( void panic_handler(
const char *message,
const void *symbol_data, const void *symbol_data,
const char *message,
const char *function,
const char *file,
uint64_t line,
const cpu_state *regs) const cpu_state *regs)
{ {
panic::serial_port com1(panic::COM1); panic::serial_port com1(panic::COM1);
@@ -16,7 +19,7 @@ void panic_handler(
panic::frame const *fp = nullptr; panic::frame const *fp = nullptr;
asm ( "mov %%rbp, %0" : "=r" (fp) ); asm ( "mov %%rbp, %0" : "=r" (fp) );
print_header(com1, message); print_header(com1, message, function, file, line);
print_callstack(com1, syms, fp); print_callstack(com1, syms, fp);
print_cpu_state(com1, *regs); print_cpu_state(com1, *regs);

View File

@@ -16,14 +16,29 @@ extern uintptr_t symbol_table;
} // namespace assert } // namespace assert
} // namespace kutil } // namespace kutil
#define kassert(stmt, message) \ __attribute__ ((always_inline))
do { \ inline void kassert(
if(!(stmt)) { \ bool check,
register const char *m asm("rdi"); \ const char *message = nullptr,
register uintptr_t i asm("rsi"); \ const char *function = __builtin_FUNCTION(),
asm volatile ("mov %1, %0" : "=r"(m) : "r"(message)); \ const char *file = __builtin_FILE(),
asm volatile ("mov %1, %0" : "=r"(i) : "r"(kutil::assert::symbol_table)); \ uint64_t line = __builtin_LINE())
*kutil::assert::apic_icr = kutil::assert::send_nmi_command; \ {
while (1) __asm__ __volatile__ ("hlt"); \ if (!check) {
} \ register uintptr_t syms asm("rdi");
} while(0); 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");
}
}