#include #include #include #include #include #if defined(__x86_64__) #include #include #endif /* TODO: figure out a generic way to work with IRQs */ static struct list_node_link* irqs = NULL; static spin_lock_t irqs_lock; bool irq_attach (void (*func) (void*, void*), void* arg, uint32_t irq_num, uint32_t flags) { struct irq* irq = malloc (sizeof (*irq)); if (irq == NULL) { return false; } irq->func = func; irq->arg = arg; irq->irq_num = irq_num; irq->flags = flags; spin_lock (&irqs_lock); list_append (irqs, &irq->irqs_link); spin_unlock (&irqs_lock); #if defined(__x86_64__) uint8_t resolution = amd64_resolve_irq (irq_num); amd64_ioapic_route_irq (irq_num, resolution, 0, amd64_lapic_id ()); #endif return true; } void irq_detach (void (*func) (void*, void*)) { struct list_node_link *irq_link, *irq_link_tmp; spin_lock (&irqs_lock); list_foreach (irqs, irq_link, irq_link_tmp) { struct irq* irq = list_entry (irq_link, struct irq, irqs_link); if ((uintptr_t)irq->func == (uintptr_t)func) list_remove (irqs, irq_link); } spin_unlock (&irqs_lock); } struct irq* irq_find (uint32_t irq_num) { struct list_node_link *irq_link, *irq_link_tmp; spin_lock (&irqs_lock); list_foreach (irqs, irq_link, irq_link_tmp) { struct irq* irq = list_entry (irq_link, struct irq, irqs_link); if (irq->irq_num == irq_num) { spin_unlock (&irqs_lock); return irq; } } spin_unlock (&irqs_lock); return NULL; }