[kernel] Move interrupt error handling to kassert

Remove all the console-printing code in the interrupt handling routine
and have it pass off to the panic handler.
This commit is contained in:
Justin C. Miller
2021-08-01 16:13:26 -07:00
parent 76beee62c3
commit 2b16b69afa
3 changed files with 56 additions and 118 deletions

View File

@@ -1,6 +1,7 @@
#include <stdint.h> #include <stdint.h>
#include "kernel_memory.h" #include "kernel_memory.h"
#include "kutil/printf.h"
#include "apic.h" #include "apic.h"
#include "console.h" #include "console.h"
@@ -92,87 +93,43 @@ isr_handler(cpu_state *regs)
if (old_ist) if (old_ist)
idt.set_ist(vector, 0); idt.set_ist(vector, 0);
char message[200];
switch (static_cast<isr>(vector)) { switch (static_cast<isr>(vector)) {
case isr::isrDebug: { case isr::isrDebug:
cons->set_color(11); asm volatile ("mov %%dr0, %%r8" ::: "r8");
cons->puts("\nDebug Exception:\n"); asm volatile ("mov %%dr1, %%r9" ::: "r9");
cons->set_color(); asm volatile ("mov %%dr2, %%r10" ::: "r10");
asm volatile ("mov %%dr3, %%r11" ::: "r11");
uint64_t dr = 0; asm volatile ("mov %%dr4, %%r12" ::: "r12");
asm volatile ("mov %%dr5, %%r13" ::: "r13");
__asm__ __volatile__ ("mov %%dr0, %0" : "=r"(dr)); asm volatile ("mov %%dr6, %%r14" ::: "r14");
print_regL("dr0", dr); asm volatile ("mov %%dr7, %%r15" ::: "r15");
kassert(false, "Debug exception");
__asm__ __volatile__ ("mov %%dr1, %0" : "=r"(dr));
print_regM("dr1", dr);
__asm__ __volatile__ ("mov %%dr2, %0" : "=r"(dr));
print_regM("dr2", dr);
__asm__ __volatile__ ("mov %%dr3, %0" : "=r"(dr));
print_regR("dr3", dr);
__asm__ __volatile__ ("mov %%dr6, %0" : "=r"(dr));
print_regL("dr6", dr);
__asm__ __volatile__ ("mov %%dr7, %0" : "=r"(dr));
print_regR("dr7", dr);
print_regL("rip", regs->rip);
print_regM("rsp", regs->rsp);
print_regM("fla", regs->rflags);
_halt();
}
break; break;
case isr::isrDoubleFault: case isr::isrDoubleFault:
cons->set_color(9); kassert(false, "Double fault");
cons->printf("\nDouble Fault:\n");
cons->set_color();
print_regs(*regs);
//print_stacktrace(2);
_halt();
break; break;
case isr::isrGPFault: { case isr::isrGPFault:
cons->set_color(9); if (regs->errorcode & 0xfff0) {
cons->puts("\nGeneral Protection Fault:\n");
cons->set_color();
cons->printf(" errorcode: %lx", regs->errorcode);
if (regs->errorcode & 0x01) cons->puts(" external");
int index = (regs->errorcode & 0xffff) >> 4; int index = (regs->errorcode & 0xffff) >> 4;
if (index) { int ti = (regs->errorcode & 0x07) >> 1;
switch ((regs->errorcode & 0x07) >> 1) { char const *table =
case 0: (ti & 1) ? "IDT" :
cons->printf(" GDT[%x]\n", index); (!ti) ? "GDT" :
GDT::current().dump(index); "LDT";
break;
case 1: snprintf(message, sizeof(message), "General Protection Fault, error:%lx%s %s[%d]",
case 3: regs->errorcode, regs->errorcode & 1 ? " external" : "", table, index);
cons->printf(" IDT[%x]\n", index); } else {
IDT::current().dump(index); snprintf(message, sizeof(message), "General Protection Fault, error:%lx%s",
break; regs->errorcode, regs->errorcode & 1 ? " external" : "");
}
default: kassert(false, message);
cons->printf(" LDT[%x]??\n", index); break;
break;
}
} else {
cons->putc('\n');
}
print_regs(*regs);
/*
print_stacktrace(2);
print_stack(*regs);
*/
}
_halt();
break;
case isr::isrPageFault: { case isr::isrPageFault: {
uintptr_t cr2 = 0; uintptr_t cr2 = 0;
@@ -189,20 +146,14 @@ isr_handler(cpu_state *regs)
if (cr2 && space.handle_fault(cr2, ft)) if (cr2 && space.handle_fault(cr2, ft))
break; break;
cons->set_color(11); snprintf(message, sizeof(message),
cons->puts("\nPage Fault:\n"); "Page fault: %016llx%s%s%s%s%s", cr2,
cons->set_color(); (regs->errorcode & 0x01) ? " present" : "",
(regs->errorcode & 0x02) ? " write" : "",
cons->puts(" flags:"); (regs->errorcode & 0x04) ? " user" : "",
if (regs->errorcode & 0x01) cons->puts(" present"); (regs->errorcode & 0x08) ? " reserved" : "",
if (regs->errorcode & 0x02) cons->puts(" write"); (regs->errorcode & 0x10) ? " ip" : "");
if (regs->errorcode & 0x04) cons->puts(" user"); kassert(false, message);
if (regs->errorcode & 0x08) cons->puts(" reserved");
if (regs->errorcode & 0x10) cons->puts(" ip");
cons->puts("\n");
print_regs(*regs);
//print_stacktrace(2);
_halt();
} }
break; break;
@@ -211,27 +162,9 @@ isr_handler(cpu_state *regs)
break; break;
case isr::isrLINT0: case isr::isrLINT0:
cons->puts("\nLINT0\n");
break;
case isr::isrLINT1: case isr::isrLINT1:
cons->puts("\nLINT1\n");
break; break;
case isr::isrAssert: {
cons->set_color();
print_regs(*regs);
//print_stacktrace(2);
}
_halt();
break;
/*
case isr::isrSyscall:
syscall_dispatch(regs);
break;
*/
case isr::isrSpurious: case isr::isrSpurious:
// No EOI for the spurious interrupt // No EOI for the spurious interrupt
return; return;
@@ -262,17 +195,8 @@ isr_handler(cpu_state *regs)
break; break;
default: default:
cons->set_color(9); snprintf(message, sizeof(message), "Unknown interrupt 0x%x", regs->interrupt);
cons->printf("\nReceived %02x interrupt:\n", kassert(false, message);
(static_cast<isr>(regs->interrupt)));
cons->set_color();
cons->printf(" ISR: %02lx ERR: %lx\n\n",
regs->interrupt, regs->errorcode);
print_regs(*regs);
//print_stacktrace(2);
_halt();
} }
// Return the IST for this vector to what it was // Return the IST for this vector to what it was

View File

@@ -14,6 +14,13 @@ isr_handler_prelude:
mov rdi, rsp mov rdi, rsp
mov rsi, rsp mov rsi, rsp
mov rax, [rsp + REGS.rip]
push rax
push rbp
mov rbp, rsp
call isr_handler call isr_handler
jmp isr_handler_return jmp isr_handler_return
.end: .end:
@@ -30,12 +37,22 @@ irq_handler_prelude:
mov rdi, rsp mov rdi, rsp
mov rsi, rsp mov rsi, rsp
mov rax, [rsp + REGS.rip]
push rax
push rbp
mov rbp, rsp
call irq_handler call irq_handler
; fall through to isr_handler_return ; fall through to isr_handler_return
.end: .end:
global isr_handler_return:function (isr_handler_return.end - isr_handler_return) global isr_handler_return:function (isr_handler_return.end - isr_handler_return)
isr_handler_return: isr_handler_return:
pop rbp
pop rax ; get rid of the manufactured stack frame
check_swap_gs check_swap_gs
pop_all pop_all

View File

@@ -16,9 +16,6 @@ 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) );
// Skip the panic handler itself
if (fp) fp = fp->prev;
print_header(com1, message); print_header(com1, message);
print_callstack(com1, syms, fp); print_callstack(com1, syms, fp);
print_cpu_state(com1, *regs); print_cpu_state(com1, *regs);