summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/i386/boot/idt.c43
-rw-r--r--arch/i386/include/kernel/pic.h2
-rw-r--r--arch/i386/kernel/pic.c12
3 files changed, 39 insertions, 18 deletions
diff --git a/arch/i386/boot/idt.c b/arch/i386/boot/idt.c
index 0e641be..7b9401d 100644
--- a/arch/i386/boot/idt.c
+++ b/arch/i386/boot/idt.c
@@ -1,4 +1,6 @@
#include <kernel/syscall.h>
+#include <kernel/panic.h>
+#include <kernel/gdt.h>
#include <kernel/isr.h>
#include <kernel/io.h>
#include <kernel/pic.h>
@@ -10,7 +12,7 @@ __attribute__((aligned(0x10)))
struct idt_entry idt[256];
struct idt_ptr idtr;
-char *exceptions[] = {
+const char* exceptions[] = {
"Division by zero",
"Debug",
"Non-maskable interrupt",
@@ -45,39 +47,47 @@ char *exceptions[] = {
__attribute__((noreturn))
void halt_catch_fire(struct isr_frame *frame) {
dump_reg(frame);
+ kprintf("ERRNO=%x\n", frame->errno);
__asm__ volatile("cli;hlt");
while (1);
}
void exception_handler(struct isr_frame *frame) {
switch (frame->vector) {
+ case 0x00:
+ panic("Division by zero in kernel address space");
+ halt_catch_fire(frame);
+ case 0x06:
+ panic("Invalid opcode in kernel address space");
+ halt_catch_fire(frame);
+ case 0x08:
+ panic("Double fault in interrupt handler");
+ halt_catch_fire(frame);
+ case 0x0D:
+ panic("Protection fault in kernel address space");
+ halt_catch_fire(frame);
case 0x0E:
page_fault_handler(frame);
break;
default:
- kprintf("Unhandled exception: %s\n", exceptions[frame->vector]);
+ panic("Unhandled exception");
halt_catch_fire(frame);
}
}
-void irq_dispatch(struct isr_frame *frame) {
- pic_eoi(frame->vector-32);
- return;
-}
-
-void interrupt_handler(struct isr_frame *frame) {
- if (frame->vector < 32) {
- exception_handler(frame);
- } else if (frame->vector >= 32 && frame->vector < 48) {
- irq_dispatch(frame);
+void interrupt_handler(struct isr_frame frame) {
+ if (frame.vector < 32) {
+ exception_handler(&frame);
+ } else if (frame.vector < 48) {
+ irq_dispatch(&frame);
} else {
- switch (frame->vector) {
+ switch (frame.vector) {
case 0x80:
- handle_syscall(frame);
+ handle_syscall(&frame);
break;
default:
- kprintf("Error: Unmapped interrupt: %d\n", frame->vector);
- halt_catch_fire(frame);
+ panic("Unmapped interrupt");
+ halt_catch_fire(&frame);
__asm__ volatile("cli;hlt");
}
}
@@ -149,5 +159,4 @@ void idt_install(void) {
idt_set_gate(0x80, syscall_stub, 0x08, IDT_INTERRUPT);
__asm__ volatile("lidt %0" : : "memory"(idtr));
- __asm__ volatile("sti");
}
diff --git a/arch/i386/include/kernel/pic.h b/arch/i386/include/kernel/pic.h
index af7b5ba..ca3cc99 100644
--- a/arch/i386/include/kernel/pic.h
+++ b/arch/i386/include/kernel/pic.h
@@ -1,6 +1,7 @@
#ifndef I386_PIC_H
#define I386_PIC_H
+#include <kernel/isr.h>
#include <kernel/idt.h>
#include <stdint.h>
@@ -46,6 +47,7 @@ uint16_t pic_get_irr(void);
uint16_t pic_get_isr(void);
void register_irq_handler(uint8_t irq, void (*handler)(struct isr_frame *frame));
+void irq_dispatch(struct isr_frame *frame);
void irq_set_mask(uint8_t irq);
void irq_clear_mask(uint8_t irq);
diff --git a/arch/i386/kernel/pic.c b/arch/i386/kernel/pic.c
index 9494b92..7a51763 100644
--- a/arch/i386/kernel/pic.c
+++ b/arch/i386/kernel/pic.c
@@ -1,6 +1,6 @@
#include <kernel/pic.h>
-void (*irq_handlers[16])(struct isr_frame *frame);
+static void (*irq_handlers[16])(struct isr_frame *frame);
void pic_eoi(uint8_t irq) {
if (irq >= 8)
@@ -38,6 +38,16 @@ uint16_t pic_get_isr(void) {
return __pic_get_irq_reg(PIC_READ_ISR);
}
+void register_irq_handler(uint8_t irq, void (*handler)(struct isr_frame *frame)) {
+ irq_handlers[irq] = handler;
+}
+
+void irq_dispatch(struct isr_frame *frame) {
+ (*irq_handlers[frame->vector-32])(frame);
+ pic_eoi(frame->vector-32);
+ return;
+}
+
void irq_set_mask(uint8_t irq) {
uint16_t port;
uint8_t data;