117 lines
2.2 KiB
C
117 lines
2.2 KiB
C
#include "interrupts.h"
|
|
#include "vga.h"
|
|
#include "kernel.h"
|
|
#include "util.h"
|
|
|
|
#define PIC1_COMMAND 0x20
|
|
#define PIC1_DATA 0x21
|
|
#define PIC2_COMMAND 0xA0
|
|
#define PIC2_DATA 0xA1
|
|
|
|
void pic_remap()
|
|
{
|
|
outb(PIC1_COMMAND, 0x11);
|
|
outb(PIC2_COMMAND, 0x11);
|
|
|
|
outb(PIC1_DATA, 32);
|
|
outb(PIC2_DATA, 40);
|
|
|
|
outb(PIC1_DATA, 4);
|
|
outb(PIC2_DATA, 2);
|
|
|
|
outb(PIC1_DATA, 1);
|
|
outb(PIC2_DATA, 1);
|
|
|
|
outb(PIC1_DATA, 0);
|
|
outb(PIC2_DATA, 0);
|
|
}
|
|
|
|
static const char* exception_messages[32] = {
|
|
"divide by zero",
|
|
"debug",
|
|
"non maskable interrupt",
|
|
"breakpoint",
|
|
"overflow",
|
|
"bound range exceeded",
|
|
"invalid opcode",
|
|
"device not available",
|
|
"double fault",
|
|
"coprocessor segment overrun",
|
|
"invalid tss",
|
|
"segment not present",
|
|
"stack-segment fault",
|
|
"general protection fault",
|
|
"page fault",
|
|
"reserved",
|
|
"x87 floating point exception",
|
|
"alignment check",
|
|
"machine check",
|
|
"simd floating point exception",
|
|
"virtualization exception",
|
|
"control protection exception",
|
|
"reserved",
|
|
"reserved",
|
|
"reserved",
|
|
"reserved",
|
|
"reserved",
|
|
"reserved",
|
|
"hypervisor injection exception",
|
|
"vmm communication exception",
|
|
"security exception",
|
|
"reserved",
|
|
};
|
|
|
|
void handle_exception(const isr_frame_t* frame)
|
|
{
|
|
kprintf("exception[%d]: %s, error code: %d\n", frame->int_no, exception_messages[frame->int_no], frame->err_code);
|
|
kpanic();
|
|
}
|
|
|
|
static irq_handler_t irq_handlers[16] = {0};
|
|
|
|
void register_irq_handler(uint8_t irq, irq_handler_t handler)
|
|
{
|
|
if (irq >= 16)
|
|
{
|
|
kprintf("Cannot register irq %d is out of bounds\n", irq);
|
|
}
|
|
else
|
|
{
|
|
irq_handlers[irq] = handler;
|
|
}
|
|
}
|
|
|
|
void handle_irq(const isr_frame_t* frame)
|
|
{
|
|
uint8_t irq = frame->int_no - 32;
|
|
|
|
if (irq_handlers[irq])
|
|
{
|
|
irq_handlers[irq](frame);
|
|
}
|
|
|
|
if (irq >= 8)
|
|
{
|
|
outb(PIC2_COMMAND, 0x20);
|
|
}
|
|
|
|
outb(PIC1_COMMAND, 0x20);
|
|
}
|
|
|
|
void handle_isr(const isr_frame_t* frame)
|
|
{
|
|
kprintf("isr");
|
|
|
|
if (frame->int_no < 32)
|
|
{
|
|
handle_exception(frame);
|
|
}
|
|
else if (frame->int_no < 48)
|
|
{
|
|
handle_irq(frame);
|
|
}
|
|
else
|
|
{
|
|
kprintf("interrupt[%d]: not implemented\n", frame->int_no);
|
|
}
|
|
} |