#include "irq.h" #include "idt.h" #include "io.h" #include "klibc.h" #include "pic.h" #include "stdarg.h" #include "types.h" int irqSetup() { initPic(); return 0; } // Assembly defined array. This is used to wrap C function than cannot: // * get some cpu state // * return using "iret" instead of "ret" without some compiler __attribute__ extern vaddr_t irq_handler_wrapper_array[IRQ_NUM]; irq_handler irq_handler_array[IRQ_NUM] = { NULL, }; void interrupt_handler_pic(int interrupt, struct interrupt_frame *frame) { if (0 > interrupt || IRQ_NUM <= interrupt) { pr_err("Trying to handle unknow interrupt %d\n", interrupt); return; } EOIIrq(interrupt); if (irq_handler_array[interrupt] != NULL) irq_handler_array[interrupt](frame); } int irqSetRoutine(int irq, irq_handler handler) { uint32_t flags; if ((irq < 0) || irq >= IRQ_NUM) return -1; disable_IRQs(flags); irq_handler_array[irq] = handler; if (handler != NULL) { int ret = idt_set_handler(IRQ_INTERRUPT_BASE_ADDRESS + irq, (unsigned int)irq_handler_array[irq], 0); if (!ret) enableIrq(irq); } restore_IRQs(flags); return 0; } int irqSetRoutineWrapped(int irq, irq_handler handler) { uint32_t flags; if ((irq < 0) || irq >= IRQ_NUM) return -1; disable_IRQs(flags); irq_handler_array[irq] = handler; if (handler != NULL) { int ret = idt_set_handler(IRQ_INTERRUPT_BASE_ADDRESS + irq, (unsigned int)irq_handler_wrapper_array[irq], 0); if (!ret) enableIrq(irq); } restore_IRQs(flags); return 0; }