diff --git a/headers/interrupts.h b/headers/interrupts.h new file mode 100644 index 0000000..e469d48 --- /dev/null +++ b/headers/interrupts.h @@ -0,0 +1,3 @@ +#pragma once + +void exception_handler(void); diff --git a/src/interrupt/handler.c b/src/interrupt/handler.c new file mode 100644 index 0000000..aeb95d7 --- /dev/null +++ b/src/interrupt/handler.c @@ -0,0 +1,77 @@ +#include "interrupts.h" +#include "kprintf.h" + +#include + +void exception_handler(void) +{ + int8_t index = -1; + __asm__ volatile("movb %%al, %0" ::"m"(index)); + + kprintf(KERN_CRIT "interrupt: "); + switch (index) { + case 0: + kprintf(KERN_CRIT "division by zero"); + break; + case 1: + kprintf(KERN_CRIT "debugger"); + break; + case 2: + kprintf(KERN_CRIT "NMI"); + break; + case 3: + kprintf(KERN_CRIT "breakpoint"); + break; + case 4: + kprintf(KERN_CRIT "overflow"); + break; + case 5: + kprintf(KERN_CRIT "bounds"); + break; + case 6: + kprintf(KERN_CRIT "invalid opcode"); + break; + case 7: + kprintf(KERN_CRIT "coprocessor not available"); + break; + case 8: + kprintf(KERN_CRIT "double fault"); + break; + case 9: + kprintf(KERN_CRIT "coprocessor segement overrun"); + break; + case 10: + kprintf(KERN_CRIT "invalid task state segment"); + break; + case 11: + kprintf(KERN_CRIT "segment not present"); + break; + case 12: + kprintf(KERN_CRIT "stack fault"); + break; + case 13: + kprintf(KERN_CRIT "general protection fault"); + break; + case 14: + kprintf(KERN_CRIT "page fault"); + break; + case 15: + kprintf(KERN_CRIT "reserved"); + break; + case 16: + kprintf(KERN_CRIT "math fault"); + break; + case 17: + kprintf(KERN_CRIT "alignment check"); + break; + case 18: + kprintf(KERN_CRIT "machine check"); + break; + case 19: + kprintf(KERN_CRIT "SIMD floating point exception"); + break; + default: + break; + } + kprintf(KERN_CRIT "\n"); +} diff --git a/src/interrupt/idt.c b/src/interrupt/idt.c index 06382f7..781a9da 100644 --- a/src/interrupt/idt.c +++ b/src/interrupt/idt.c @@ -33,4 +33,4 @@ void init_idt(void) { idtr.size = 8 * IDT_SIZE - 1; idtr.offset = (uint32_t)&idt_entries; -} \ No newline at end of file +} diff --git a/src/interrupt/isr.s b/src/interrupt/isr.s new file mode 100644 index 0000000..6d82c1a --- /dev/null +++ b/src/interrupt/isr.s @@ -0,0 +1,82 @@ +.intel_syntax noprefix +.extern exception_handler + +.macro isr_err_stub nb +isr_stub_\nb: + call exception_handler + iret +.endm + +.macro isr_no_err_stub nb +isr_stub_\nb: + call exception_handler + iret +.endm + +isr_no_err_stub 0 +isr_no_err_stub 1 +isr_no_err_stub 2 +isr_no_err_stub 3 +isr_no_err_stub 4 +isr_no_err_stub 5 +isr_no_err_stub 6 +isr_no_err_stub 7 +isr_err_stub 8 +isr_no_err_stub 9 +isr_err_stub 10 +isr_err_stub 11 +isr_err_stub 12 +isr_err_stub 13 +isr_err_stub 14 +isr_no_err_stub 15 +isr_no_err_stub 16 +isr_err_stub 17 +isr_no_err_stub 18 +isr_no_err_stub 19 +isr_no_err_stub 20 +isr_no_err_stub 21 +isr_no_err_stub 22 +isr_no_err_stub 23 +isr_no_err_stub 24 +isr_no_err_stub 25 +isr_no_err_stub 26 +isr_no_err_stub 27 +isr_no_err_stub 28 +isr_no_err_stub 29 +isr_err_stub 30 +isr_no_err_stub 31 + +.global isr_stub_table +isr_stub_table: + .long isr_stub_0 + .long isr_stub_1 + .long isr_stub_2 + .long isr_stub_3 + .long isr_stub_4 + .long isr_stub_5 + .long isr_stub_6 + .long isr_stub_7 + .long isr_stub_8 + .long isr_stub_9 + .long isr_stub_10 + .long isr_stub_11 + .long isr_stub_12 + .long isr_stub_13 + .long isr_stub_14 + .long isr_stub_15 + .long isr_stub_16 + .long isr_stub_17 + .long isr_stub_18 + .long isr_stub_19 + .long isr_stub_20 + .long isr_stub_21 + .long isr_stub_22 + .long isr_stub_23 + .long isr_stub_24 + .long isr_stub_25 + .long isr_stub_26 + .long isr_stub_27 + .long isr_stub_28 + .long isr_stub_29 + .long isr_stub_30 + .long isr_stub_31 diff --git a/src/power/halt.c b/src/power/halt.c index 2a3e656..8733485 100644 --- a/src/power/halt.c +++ b/src/power/halt.c @@ -1,4 +1,4 @@ void halt(void) { - asm volatile("hlt"); + __asm__ volatile("hlt"); } diff --git a/src/power/reboot.c b/src/power/reboot.c index 9aa5da7..49c08a1 100644 --- a/src/power/reboot.c +++ b/src/power/reboot.c @@ -19,7 +19,7 @@ void reboot(void) { uint8_t tmp; - asm volatile("cli"); /* disable all interrupts */ + __asm__ volatile("cli"); /* disable all interrupts */ do { tmp = inb(KBD_INTERFACE); /* empty user data */ if (check_flag(tmp, KBD_BIT_KDATA)) @@ -27,6 +27,6 @@ void reboot(void) } while (check_flag(tmp, KBD_BIT_UDATA)); outb(KBD_INTERFACE, KBD_RESET); /* pulse CPU reset line */ loop: - asm volatile("hlt"); + __asm__ volatile("hlt"); goto loop; -} \ No newline at end of file +}