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

IDTR idtr;
IDTEntry* entries;
void* buffer;

void setInterrupt(uint8_t vector, void* callback) {
    IDTEntry* descriptor = &entries[vector];
    descriptor->isr_low        = (uint32_t)callback & 0xFFFF;
    descriptor->codeSegment    = 0x08;
    descriptor->attributes     = 0x8E;
    descriptor->isr_high       = (uint32_t)callback >> 16;
    descriptor->reserved       = 0;
    __asm__ volatile ("lidt %0" : : "memory"(idtr));
}

uint32_t count = 0x01;

void testInterrupt() {
    printf("interrupt 0x%x!\n", count++);
    yields();
}

#define PIC1		0x20
#define PIC2		0xA0
#define PIC1_COMMAND	PIC1
#define PIC1_DATA	(PIC1+1)
#define PIC2_COMMAND	PIC2
#define PIC2_DATA	(PIC2+1)

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 initInterrupts() {
    remapPIC(32, 40);
    buffer = malloc(sizeof(IDTEntry) * 256);
    entries = (IDTEntry*) (((int) buffer + sizeof(IDTEntry)) & -1 ^ 0x0F);
    idtr.limit = sizeof(IDTEntry) * 256 - 1;
    idtr.base = (uint32_t) entries;
    for (int i = 0; i < 256; i++) {
        setInterrupt(i, &testInterrupt);
    }
    setupExceptions();
    // setupTimer();
    __asm__ volatile ("sti");
}