summaryrefslogtreecommitdiff
path: root/arch/i386/kernel/idt.c
diff options
context:
space:
mode:
authorDanny Holman <dholman@gymli.org>2024-06-25 12:49:40 -0500
committerDanny Holman <dholman@gymli.org>2024-06-25 12:49:40 -0500
commit0dc4d97e70c17df56a260d31a1cb44881cf64520 (patch)
tree8fc93c709d334be836e3b896e2ed5f5320292169 /arch/i386/kernel/idt.c
parent3851af792ca7b4bb7fc998337c4aec05627cfa8f (diff)
kernel: interrupt: create a generic interrupt API
Create a generic interface for drivers to make use of interrupt vectors. This API should be platform-agnostic enough to allow any driver to make use of virtually any interrupt vector on any CPU. On x86, the first 32 interrupts are set aside for CPU exceptions, and interrupt 128 is set aside for system calls. Signed-off-by: Danny Holman <dholman@gymli.org>
Diffstat (limited to 'arch/i386/kernel/idt.c')
-rw-r--r--arch/i386/kernel/idt.c27
1 files changed, 12 insertions, 15 deletions
diff --git a/arch/i386/kernel/idt.c b/arch/i386/kernel/idt.c
index 1a06631..a178801 100644
--- a/arch/i386/kernel/idt.c
+++ b/arch/i386/kernel/idt.c
@@ -1,4 +1,5 @@
#include <kernel/idt.h>
+#include <kernel/interrupt.h>
#include <kernel/syscall.h>
#include <kernel/panic.h>
#include <kernel/gdt.h>
@@ -67,20 +68,10 @@ void exception_handler(struct isr_frame *frame) {
}
}
-void interrupt_handler(struct isr_frame frame) {
- if (frame.isr_vector < 32) {
- exception_handler(&frame);
- } else if (frame.isr_vector < 48) {
- irq_dispatch(&frame);
- } else {
- switch (frame.isr_vector) {
- case 0x80:
- handle_syscall(&frame);
- break;
- default:
- panic("Unmapped interrupt");
- }
- }
+void generic_handler(struct isr_frame *frame) {
+ kprintf("No handler registered for IRQ %d\n", frame->isr_vector);
+ if (frame->isr_vector > 32 && frame->isr_vector < 48)
+ pic_eoi(frame->isr_vector-32);
}
void idt_set_gate(uint8_t num, void (*handler)(void), uint16_t cs, uint8_t flags) {
@@ -96,6 +87,12 @@ void idt_install(void) {
idtr.limit = (uint16_t)sizeof(struct idt_entry) * 256 - 1;
idtr.base = (uint32_t)idt;
+ for (int i = 0; i < 32; i++)
+ register_isr_handler(i, exception_handler);
+ for (int i = 32; i < 224; i++)
+ register_isr_handler(i, generic_handler);
+ register_isr_handler(0x80, handle_syscall);
+
idt_set_gate(0x0, isr_stub_0, 0x08, IDT_EXCEPTION);
idt_set_gate(0x1, isr_stub_1, 0x08, IDT_EXCEPTION);
idt_set_gate(0x2, isr_stub_2, 0x08, IDT_EXCEPTION);
@@ -146,7 +143,7 @@ void idt_install(void) {
idt_set_gate(0x2E, irq_stub_14, 0x08, IDT_INTERRUPT);
idt_set_gate(0x2F, irq_stub_15, 0x08, IDT_INTERRUPT);
- idt_set_gate(0x80, syscall_stub, 0x08, IDT_INTERRUPT);
+ idt_set_gate(0x80, isr_stub_128, 0x08, IDT_INTERRUPT);
__asm__ volatile("lidt %0" : : "memory"(idtr));
}