kernel/CPU: Allow passing arbitrary data to interrupt handlers

This commit is contained in:
apio 2023-05-13 14:14:12 +02:00
parent e616af3b89
commit 2505d914c2
Signed by: apio
GPG Key ID: B8A7D06E42258954
2 changed files with 19 additions and 13 deletions

View File

@ -29,7 +29,7 @@ namespace CPU
u16 get_processor_id(); 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(); void pause();
} }

View File

@ -28,9 +28,15 @@ extern void setup_idt();
static Thread* g_io_thread; 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() 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(); Timer::tick();
if (should_invoke_scheduler()) Scheduler::invoke(regs); if (should_invoke_scheduler()) Scheduler::invoke(regs);
} }
static void keyboard_interrupt(Registers*) static void keyboard_interrupt(Registers*, void*)
{ {
u8 scancode = IO::inb(0x60); u8 scancode = IO::inb(0x60);
scancode_queue.try_push(scancode); 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 else if (regs->isr >= 32 && regs->isr < 48) // IRQ from the PIC
{ {
u64 irq = regs->error; u64 irq = regs->error;
interrupt_handler_t handler = irq_handlers[irq]; auto handler = irq_handlers[irq];
if (!handler) if (!handler.function)
{ {
kwarnln("Unhandled IRQ catched! Halting."); kwarnln("Unhandled IRQ catched! Halting.");
CPU::efficient_halt(); CPU::efficient_halt();
} }
handler(regs); handler.function(regs, handler.context);
pic_eoi(regs); pic_eoi(regs);
} }
else if (regs->isr == 66) // System call else if (regs->isr == 66) // System call
@ -237,8 +243,8 @@ namespace CPU
setup_idt(); setup_idt();
memset(irq_handlers, 0, sizeof(irq_handlers)); memset(irq_handlers, 0, sizeof(irq_handlers));
register_interrupt(0, timer_interrupt); register_interrupt(0, timer_interrupt, nullptr);
register_interrupt(1, keyboard_interrupt); register_interrupt(1, keyboard_interrupt, nullptr);
} }
void platform_finish_init() void platform_finish_init()
@ -360,11 +366,11 @@ namespace CPU
return (u16)(ebx >> 24); 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; return true;
} }