67 lines
1.4 KiB
C
67 lines
1.4 KiB
C
#include <irq/irq.h>
|
|
#include <libk/list.h>
|
|
#include <libk/std.h>
|
|
#include <mm/liballoc.h>
|
|
#include <sync/spin_lock.h>
|
|
|
|
#if defined(__x86_64__)
|
|
#include <amd64/apic.h>
|
|
#include <amd64/intr.h>
|
|
#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*), 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);
|
|
linklist_append (struct irq*, irqs, irq);
|
|
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*)) {
|
|
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);
|
|
}
|
|
|
|
struct irq* irq_find (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) {
|
|
spin_unlock (&irqs_lock);
|
|
return irq;
|
|
}
|
|
}
|
|
|
|
spin_unlock (&irqs_lock);
|
|
|
|
return NULL;
|
|
}
|