kernel/CPU: Allow passing arbitrary data to interrupt handlers

This commit is contained in:
apio 2023-05-13 14:14:12 +02:00
parent 3a84127fd6
commit 739950e8f0
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();
bool register_interrupt(u8 interrupt, void (*handler)(Registers*));
bool register_interrupt(u8 interrupt, void (*handler)(Registers*, void*), void* context);
void pause();
}

View File

@ -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()
{
@ -154,13 +160,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);
@ -174,14 +180,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
@ -252,8 +258,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()
@ -375,11 +381,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;
}