[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();
|
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);
|
||||||
|
|||||||
@@ -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 ");
|
||||||
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");
|
out.write("\n \e[0;31m===================================================================================\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 ®s);
|
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 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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user