#include #include #include #include #include #if defined(__x86_64__) #include #endif /* TODO: figure out a generic way to work with IRQs */ static struct irq* irqs = NULL; static spin_lock_t irqs_lock; bool irq_attach (void (*func) (void*), void* arg, uint32_t irq_num) { struct irq* irq = malloc (sizeof (*irq)); if (irq == NULL) { return false; } irq->func = func; irq->arg = arg; irq->irq_num = irq_num; spin_lock (&irqs_lock); linklist_append (struct irq*, irqs, irq); spin_unlock (&irqs_lock); #if defined(__x86_64__) amd64_ioapic_route_irq (irq_num, irq_num - 0x20, 0, amd64_lapic_id ()); #endif return true; } void irq_detach (void (*func) (void*)) { spin_lock (&irqs_lock); struct irq *irq, *irq_tmp; linklist_foreach (irqs, irq, irq_tmp) { if ((uintptr_t)irq->func == (uintptr_t)func) linklist_remove (struct irq*, irqs, irq); } spin_unlock (&irqs_lock); } void irq_invoke_each (uint32_t irq_num) { spin_lock (&irqs_lock); struct irq *irq, *irq_tmp; linklist_foreach (irqs, irq, irq_tmp) { if (irq->irq_num == irq_num) irq->func (irq->arg); } spin_unlock (&irqs_lock); }