#define MODULE "isr" #include "assert.h" #include "interrupts/Context.h" #include "interrupts/IRQ.h" #include "interrupts/Interrupts.h" #include "log/Log.h" #include "misc/hang.h" #include "std/stdio.h" #include "thread/Scheduler.h" #include "trace/StackTracer.h" extern "C" void common_handler(Context* context) { ASSERT(Interrupts::is_in_handler()); if (context->number >= 0x20 && context->number < 0x30) { Interrupts::ensure_handler(); // restore the "in interrupt flag" if an interrupt happened in the middle of this // one IRQ::interrupt_handler(context); return; } if (context->number == 13) { kerrorln("General protection fault at RIP %lx, cs %ld, ss %ld, RSP %lx, error code %ld", context->rip, context->cs, context->ss, context->rsp, context->error_code); kinfoln("Stack trace:"); StackTracer tracer(context->rbp); tracer.trace_with_ip(context->rip); if (context->cs == 0x8) { PANIC("Fatal: GPF in kernel task"); } else { Interrupts::ensure_handler(); Scheduler::task_misbehave(context); } } if (context->number == 14) { Interrupts::disable(); kerrorln("Page fault in %s (RIP %lx), while trying to access %lx, error code %ld", context->cs == 8 ? "ring 0" : "ring 3", context->rip, context->cr2, context->error_code); kinfoln("Stack trace:"); StackTracer tracer(context->rbp); tracer.trace_with_ip(context->rip); if (context->cs == 0x8) { PANIC("Fatal: Page fault in kernel task"); } else { Interrupts::ensure_handler(); Scheduler::task_misbehave(context); } } if (context->number == 8) { kerrorln("Double fault, halting"); kinfoln("Stack trace:"); StackTracer tracer(context->rbp); tracer.trace_with_ip(context->rip); hang(); } if (context->number == 48) { Interrupts::ensure_handler(); Scheduler::task_yield(context); } if (context->number == 49) { Interrupts::ensure_handler(); Scheduler::task_exit(context); } if (context->number == 256) { kwarnln("Unused interrupt"); } return; }