Ability to bind handler functions to interrupts

This commit is contained in:
Thomas Lovén 2018-02-13 14:27:26 +01:00
parent c1c3842ace
commit 6f0a745adc
3 changed files with 28 additions and 3 deletions

View File

@ -4,6 +4,14 @@
#include <debug.h> #include <debug.h>
#include <multiboot.h> #include <multiboot.h>
#include <cpu.h> #include <cpu.h>
#include <interrupts.h>
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) void kmain(uint64_t multiboot_magic, void *multiboot_data)
{ {
@ -17,8 +25,10 @@ void kmain(uint64_t multiboot_magic, void *multiboot_data)
cpu_init(); cpu_init();
// Force a divide by zero exception
// Force and catch a divide by zero exception
// ISR 0 // ISR 0
bind_interrupt(0, divbyzero);
int a = 5, b = 0; int a = 5, b = 0;
int c = a/b; int c = a/b;

View File

@ -5,9 +5,10 @@
struct int_gate_descriptor idt[NUM_INTERRUPTS]; struct int_gate_descriptor idt[NUM_INTERRUPTS];
struct idtr idtr; struct idtr idtr;
extern uintptr_t isr_table[]; 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) 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; 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() void interrupt_init()
{ {
memset(idt, 0, sizeof(idt)); memset(idt, 0, sizeof(idt));
memset(int_handlers, 0, sizeof(int_handlers));
for(int i=0; i < NUM_INTERRUPTS; i++) for(int i=0; i < NUM_INTERRUPTS; i++)
{ {
@ -32,9 +34,18 @@ void interrupt_init()
load_idt(&idtr); 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) 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("Unhandled interrupt occurred\n");
debug("Interrupt number: %d Error code: %d\n", r->int_no, r->err_code); debug("Interrupt number: %d Error code: %d\n", r->int_no, r->err_code);
debug_print_registers(r); debug_print_registers(r);

View File

@ -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()); 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(); void interrupt_init();
int_handler_t bind_interrupt(uint32_t num, int_handler_t fn);
void isr_return(registers *);