#include #include "pic.h" #include "irq.h" #include "idt.h" /* These are own ISRs that point to our special IRQ handler * instead of the regular 'fault_handler' function */ extern void Irq_0(); extern void Irq_1(); extern void Irq_2(); extern void Irq_3(); extern void Irq_4(); extern void Irq_5(); extern void Irq_6(); extern void Irq_7(); extern void Irq_8(); extern void Irq_9(); extern void Irq_10(); extern void Irq_11(); extern void Irq_12(); extern void Irq_13(); extern void Irq_14(); extern void Irq_15(); /* This array is actually an array of function pointers. We use * this to handle custom IRQ handlers for a given IRQ */ void *IrqRoutines[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* This installs a custom IRQ handler for the given IRQ */ void IrqInstallHandler (int irq, void (*handler)(_RegsStack32 *r)) { IrqRoutines[irq] = handler; } void IrqUninstallHandler (int irq) { IrqRoutines[irq] = 0; } /* We first remap the interrupt controllers, and then we install * the appropriate ISRs to the correct entries in the IDT. This * is just like installing the exception handlers */ void IrqInstall() { PicRemap(32,40); IdtSetGate(32, (unsigned)Irq_0, 0x08, 0x8E); IdtSetGate(33, (unsigned)Irq_1, 0x08, 0x8E); IdtSetGate(34, (unsigned)Irq_2, 0x08, 0x8E); IdtSetGate(35, (unsigned)Irq_3, 0x08, 0x8E); IdtSetGate(36, (unsigned)Irq_4, 0x08, 0x8E); IdtSetGate(37, (unsigned)Irq_5, 0x08, 0x8E); IdtSetGate(38, (unsigned)Irq_6, 0x08, 0x8E); IdtSetGate(39, (unsigned)Irq_7, 0x08, 0x8E); IdtSetGate(40, (unsigned)Irq_8, 0x08, 0x8E); IdtSetGate(41, (unsigned)Irq_9, 0x08, 0x8E); IdtSetGate(42, (unsigned)Irq_10, 0x08, 0x8E); IdtSetGate(43, (unsigned)Irq_11, 0x08, 0x8E); IdtSetGate(44, (unsigned)Irq_12, 0x08, 0x8E); IdtSetGate(45, (unsigned)Irq_13, 0x08, 0x8E); IdtSetGate(46, (unsigned)Irq_14, 0x08, 0x8E); IdtSetGate(47, (unsigned)Irq_15, 0x08, 0x8E); } // Default IRQ handler, launches other handler if installed. // Also sends end-of-interrupt messages to PIC void IrqHandler (_RegsStack32 *r) { /* This is a blank function pointer */ void (*handler)(_RegsStack32 *r); /* Find out if we have a custom handler to run for this * IRQ, and then finally, run it */ handler = IrqRoutines[r->int_no - 32]; if (handler) handler(r); /* If the IDT entry that was invoked was greater than 40 * (meaning IRQ8 - 15), then we need to send an EOI to * the slave controller */ if (r->int_no >=40) outportb(0xA0, 0x20); /* In either case, we need to send an EOI to the master * interrupt controller too */ outportb(0x20, 0x20); }