Files
nub-os/src/interrupts.c
nub31 1ed52d1e9e ...
2025-09-01 20:06:58 +02:00

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);
}
}