[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:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user