/* * This file contains the abstraction for exceptions and interrupts. It * presents a system of registrable exception/interrupt handlers. It also * contains the generic handlers, which pass control to the appropriate * registered handler. This file does not deal with dispatching * messages/signals to processes on an interrupt. */ #include #include "proc.h" #include "../proc/proc.h" #include "../task/task.h" #include "../io.h" #include "../screen.h" void (**exceptions)(InterruptFrame *); void (**interrupts)(InterruptFrame *); /* Register an exception handler */ void register_exception(int num, void (*addr)(InterruptFrame *)) { if (num >= 0 && num < 32) exceptions[num] = addr; } /* Register an interrupt handler */ void register_interrupt(int num, void (*addr)(InterruptFrame *)) { if (num >= 0 && num < 224) interrupts[num] = addr; } /* Call the appropriate exception handler */ uintptr_t exc_handler(InterruptFrame frame) { uint8_t num = frame.intNo & 0xFF; /* System Call */ if (num == 0x80) syscall_handler(&frame); /* Other exception */ else if (exceptions[num]) exceptions[num](&frame); else panic("Unhandled exception %d (%#x) @ %#.8x [CPU#%d]\n" "EFLAGS: %#.8x", num, frame.errCode, frame.eip, CPUID, frame.eflags); /* Send EOI */ LAPIC(0xB0) = 0; if (current) if (current->tls) return current->tls->start + 4; return 0; } /* Call the appropriate interrupt handler */ uintptr_t irq_handler(InterruptFrame frame) { uint8_t num = (frame.intNo & 0xFF) - 32; if (interrupts[num]) interrupts[num](&frame); /* Send EOI */ outb(0x20, 0x20); if (num >= 8) outb(0xA0, 0x20); LAPIC(0xB0) = 0; if (current) if (current->tls) return current->tls->start + 4; return 0; }