mittos65/src/kernel/cpu/interrupts.c

65 lines
1.5 KiB
C

#include <interrupts.h>
#include <stdint.h>
#include <memory.h>
#include <cpu.h>
#include <debug.h>
#include <string.h>
#define IDT_INTERRUPT 0xE
#define IDT_DPL0 0x0
#define IDT_PRESENT 0x80
#define NUM_INTERRUPTS 256
struct idt {
uint16_t base_l;
uint16_t cs;
uint8_t ist;
uint8_t flags;
uint16_t base_m;
uint32_t base_h;
uint32_t _;
}__attribute__((packed)) idt[NUM_INTERRUPTS];
struct {
uint16_t len;
struct idt *addr;
}__attribute__((packed)) idtr;
extern uintptr_t isr_table[];
int_handler_t int_handlers[NUM_INTERRUPTS];
void interrupt_init()
{
memset(idt, 0, sizeof(idt));
for(int i=0; i < NUM_INTERRUPTS; i++)
{
idt[i].base_l = isr_table[i] & 0xFFFF;
idt[i].base_m = (isr_table[i] >> 16) & 0xFFFF;
idt[i].base_h = (isr_table[i] >> 32) & 0xFFFFFFFF;
idt[i].cs = 0x8;
idt[i].ist = 0;
idt[i].flags = IDT_PRESENT | IDT_DPL0 | IDT_INTERRUPT;
}
idtr.addr = idt;
idtr.len = sizeof(idt)-1;
load_idt(&idtr); // cpu/registers.S
}
int_handler_t bind_interrupt(uint32_t num, int_handler_t fn) {
int_handler_t old = int_handlers[num];
int_handlers[num] = fn;
return old;
}
registers *int_handler(registers *r)
{
if(int_handlers[r->int_no])
return int_handlers[r->int_no](r);
debug_error("Unhandled interrupt occurred\n");
debug_error("Interrupt number: %d, Error code: %d\n", r->int_no, r->err_code);
PANIC("Unhandled interrupt");
//for(;;);
return r;
}