Ability to bind handler functions to interrupts
This commit is contained in:
parent
c1c3842ace
commit
6f0a745adc
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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 *);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user