diff --git a/kernel/src/arch/CPU.h b/kernel/src/arch/CPU.h index 3d9a2849..f446a0a0 100644 --- a/kernel/src/arch/CPU.h +++ b/kernel/src/arch/CPU.h @@ -29,7 +29,7 @@ namespace CPU u16 get_processor_id(); - bool register_interrupt(u8 interrupt, void (*handler)(Registers*)); + bool register_interrupt(u8 interrupt, void (*handler)(Registers*, void*), void* context); void pause(); } diff --git a/kernel/src/arch/x86_64/CPU.cpp b/kernel/src/arch/x86_64/CPU.cpp index ab4cf8e6..4225fda4 100644 --- a/kernel/src/arch/x86_64/CPU.cpp +++ b/kernel/src/arch/x86_64/CPU.cpp @@ -28,9 +28,15 @@ extern void setup_idt(); static Thread* g_io_thread; -typedef void (*interrupt_handler_t)(Registers*); +typedef void (*interrupt_handler_t)(Registers*, void*); -static interrupt_handler_t irq_handlers[16]; +struct InterruptHandler +{ + interrupt_handler_t function; + void* context; +}; + +static InterruptHandler irq_handlers[16]; void FPData::save() { @@ -139,13 +145,13 @@ void io_thread() } } -static void timer_interrupt(Registers* regs) +static void timer_interrupt(Registers* regs, void*) { Timer::tick(); if (should_invoke_scheduler()) Scheduler::invoke(regs); } -static void keyboard_interrupt(Registers*) +static void keyboard_interrupt(Registers*, void*) { u8 scancode = IO::inb(0x60); scancode_queue.try_push(scancode); @@ -159,14 +165,14 @@ extern "C" void arch_interrupt_entry(Registers* regs) else if (regs->isr >= 32 && regs->isr < 48) // IRQ from the PIC { u64 irq = regs->error; - interrupt_handler_t handler = irq_handlers[irq]; - if (!handler) + auto handler = irq_handlers[irq]; + if (!handler.function) { kwarnln("Unhandled IRQ catched! Halting."); CPU::efficient_halt(); } - handler(regs); + handler.function(regs, handler.context); pic_eoi(regs); } else if (regs->isr == 66) // System call @@ -237,8 +243,8 @@ namespace CPU setup_idt(); memset(irq_handlers, 0, sizeof(irq_handlers)); - register_interrupt(0, timer_interrupt); - register_interrupt(1, keyboard_interrupt); + register_interrupt(0, timer_interrupt, nullptr); + register_interrupt(1, keyboard_interrupt, nullptr); } void platform_finish_init() @@ -360,11 +366,11 @@ namespace CPU return (u16)(ebx >> 24); } - bool register_interrupt(u8 interrupt, interrupt_handler_t handler) + bool register_interrupt(u8 interrupt, interrupt_handler_t handler, void* context) { - if (irq_handlers[interrupt]) return false; + if (irq_handlers[interrupt].function) return false; - irq_handlers[interrupt] = handler; + irq_handlers[interrupt] = { handler, context }; return true; }