From 6f0a745adc1ee021d2f366edc758443ee56cf948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Lov=C3=A9n?= Date: Tue, 13 Feb 2018 14:27:26 +0100 Subject: [PATCH] Ability to bind handler functions to interrupts --- src/kernel/boot/kmain.c | 12 +++++++++++- src/kernel/cpu/interrupts.c | 15 +++++++++++++-- src/kernel/include/interrupts.h | 4 ++++ 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/kernel/boot/kmain.c b/src/kernel/boot/kmain.c index 13f9d1a..025dc2c 100644 --- a/src/kernel/boot/kmain.c +++ b/src/kernel/boot/kmain.c @@ -4,6 +4,14 @@ #include #include #include +#include + +registers *divbyzero(registers *r) +{ + debug_error("Divide by zero error!\n"); + debug_print_registers(r); + for(;;); +} void kmain(uint64_t multiboot_magic, void *multiboot_data) { @@ -17,8 +25,10 @@ void kmain(uint64_t multiboot_magic, void *multiboot_data) cpu_init(); - // Force a divide by zero exception + + // Force and catch a divide by zero exception // ISR 0 + bind_interrupt(0, divbyzero); int a = 5, b = 0; int c = a/b; diff --git a/src/kernel/cpu/interrupts.c b/src/kernel/cpu/interrupts.c index c82814d..d159a70 100644 --- a/src/kernel/cpu/interrupts.c +++ b/src/kernel/cpu/interrupts.c @@ -5,9 +5,10 @@ struct int_gate_descriptor idt[NUM_INTERRUPTS]; struct idtr idtr; - extern uintptr_t isr_table[]; +int_handler_t int_handlers[NUM_INTERRUPTS]; + void idt_set_gate(uint32_t num, uintptr_t vector, uint16_t cs, uint8_t ist, uint8_t flags) { idt[num].base_l = vector & 0xFFFF; @@ -21,6 +22,7 @@ void idt_set_gate(uint32_t num, uintptr_t vector, uint16_t cs, uint8_t ist, uint void interrupt_init() { memset(idt, 0, sizeof(idt)); + memset(int_handlers, 0, sizeof(int_handlers)); for(int i=0; i < NUM_INTERRUPTS; i++) { @@ -32,9 +34,18 @@ void interrupt_init() load_idt(&idtr); } +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) { - (void)r; + if(int_handlers[r->int_no]) + return int_handlers[r->int_no](r); + debug("Unhandled interrupt occurred\n"); debug("Interrupt number: %d Error code: %d\n", r->int_no, r->err_code); debug_print_registers(r); diff --git a/src/kernel/include/interrupts.h b/src/kernel/include/interrupts.h index 3bbbdab..01ab576 100644 --- a/src/kernel/include/interrupts.h +++ b/src/kernel/include/interrupts.h @@ -63,4 +63,8 @@ debug("CS=%016x SS=%016x\n", r->cs, r->ss); \ debug("CR0=%08x CR2=%016x CR3=%016x CR4=%08x\n", read_cr0(), read_cr2(), read_cr3(), read_cr4()); +typedef registers *(*int_handler_t)(registers *); + void interrupt_init(); +int_handler_t bind_interrupt(uint32_t num, int_handler_t fn); +void isr_return(registers *);