Newer
Older
tree-os / src / interrupts / irqs.c
#include <irqs.h>
#include <interrupts.h>
#include <ports.h>
#include <task.h>
#include <timer.h>
#include <_stdio.h>

#define OFFSET_1 32
#define OFFSET_2 40

void remapPIC(int offset1, int offset2) {
    printf("remapping pic\n");
    outb(0x20, 0x11);
    outb(0xA0, 0x11);
    outb(0x21, 0x20);
    outb(0xA1, offset1);
    outb(0x21, offset2);
    outb(0xA1, 0x02);
    outb(0x21, 0x01);
    outb(0xA1, 0x01);
    outb(0x21, 0x0);
    outb(0xA1, 0x0);
}

void setupIRQs() {
    printf("setting IRQs\n");
    setInterrupt(OFFSET_1 + 0, &irqHandler0);
    setInterrupt(OFFSET_1 + 1, &irqHandler1);
    setInterrupt(OFFSET_1 + 2, &irqHandler2);
    setInterrupt(OFFSET_1 + 3, &irqHandler3);
    setInterrupt(OFFSET_1 + 4, &irqHandler4);
    setInterrupt(OFFSET_1 + 5, &irqHandler5);
    setInterrupt(OFFSET_1 + 6, &irqHandler6);
    setInterrupt(OFFSET_1 + 7, &irqHandler7);
    setInterrupt(OFFSET_2 + 0, &irqHandler8);
    setInterrupt(OFFSET_2 + 1, &irqHandler9);
    setInterrupt(OFFSET_2 + 2, &irqHandler10);
    setInterrupt(OFFSET_2 + 3, &irqHandler11);
    setInterrupt(OFFSET_2 + 4, &irqHandler12);
    setInterrupt(OFFSET_2 + 5, &irqHandler13);
    setInterrupt(OFFSET_2 + 6, &irqHandler14);
    setInterrupt(OFFSET_2 + 7, &irqHandler15);
    remapPIC(OFFSET_1, OFFSET_2);
}

void* irqHandlers[16];

void setIRQHandler(uint8_t irqNumber, void* fun) {
    irqHandlers[irqNumber] = fun;
}

void handleIRQ(regs* registers) {
    if (registers->int_no >= OFFSET_2) {
        outb(0xA0, 0x20);
    }
    outb(0x20, 0x20);
    void (*handler)() = irqHandlers[registers->int_no - OFFSET_1];
    if (handler) {
        handler();
        return;
    }
    printf("unhandeled IRQ no. 0x%x was triggered!\n", registers->int_no);
    yields();
}