65 lines
1.5 KiB
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;
|
|
} |