#include "idt.h" #include "stdio.h" #include "pic/pic.h" #include "pic/keyboard.h" #include "pic/pit.h" #include "io.h" static struct idt idt = { 0 }; static struct idt_entry_descriptor idt_entries_descriptors[IDT_NB_ENTRIES] = { {(uint32_t)&isr_divide, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 0 {(uint32_t)&isr_debug, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 1 {(uint32_t)&isr_nmi, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 2 {(uint32_t)&isr_breakpoint, KERNEL_CS_SEGMENT_SELECTOR, TRAP_TYPE}, // 3 {(uint32_t)&isr_overflow, KERNEL_CS_SEGMENT_SELECTOR, TRAP_TYPE}, // 4 {(uint32_t)&isr_bound_range_exceeded, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 5 {(uint32_t)&isr_invalid_opcode, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 6 {(uint32_t)&isr_device_not_available, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 7 {(uint32_t)&isr_double_fault, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 8 {(uint32_t)&isr_coprocessor_segment_overrun, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 9 {(uint32_t)&isr_invalid_tss, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 10 {(uint32_t)&isr_segment_not_present, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 11 {(uint32_t)&isr_stack_segment_fault, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 12 {(uint32_t)&isr_general_protection, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 13 {(uint32_t)&isr_page_fault, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 14 {0, {0, 0, 0}, 0}, // 15 {(uint32_t)&isr_fpu_floating_point_error, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 16 {(uint32_t)&isr_alignment_check, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 17 {(uint32_t)&isr_machine_check, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 18 {(uint32_t)&isr_simd_floating_point_exception, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 19 {(uint32_t)&isr_virtualization_exception, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 20 {(uint32_t)&isr_control_protection_exception, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 21 {0, {0, 0, 0}, 0}, // 22 {0, {0, 0, 0}, 0}, // 23 {0, {0, 0, 0}, 0}, // 24 {0, {0, 0, 0}, 0}, // 25 {0, {0, 0, 0}, 0}, // 26 {0, {0, 0, 0}, 0}, // 27 {0, {0, 0, 0}, 0}, // 28 {0, {0, 0, 0}, 0}, // 29 {0, {0, 0, 0}, 0}, // 30 {0, {0, 0, 0}, 0}, // 31 {(uint32_t)&isr_pit, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE}, // 32 {(uint32_t)&isr_keyboard, KERNEL_CS_SEGMENT_SELECTOR, INTERRUPT_TYPE} // 33 }; void interrupt_handler(struct isr_param *isr_param) { switch (isr_param->int_vector) { case PIT_INT_VECTOR: pit_handler(); break; case KEYBOARD_INT_VECTOR: keyboard_handler(); break; } if (isr_param->int_vector >= IDT_RESERVED_ENTRIES && isr_param->int_vector < IDT_RESERVED_ENTRIES + 16) acknowledge(isr_param->int_vector); } struct idt_entry create_idt_entry(struct idt_entry_descriptor descriptor) { struct idt_entry res = { 0 }; res.selector = descriptor.selector; res.offset_1 = descriptor.offset & 0xffff; res.offset_2 = (descriptor.offset >> 16) & 0xffff; res.type = descriptor.type; res.size = 1; res.desc_priv = 0; res.present = 1; return res; } static void create_idt(void) { for (int i = 0; i < IDT_NB_ENTRIES; ++i) { struct idt_entry entry = create_idt_entry(idt_entries_descriptors[i]); idt.entries[i] = entry; } } static void load_idt(void) { struct idt_r idtr; idtr.addr = (uint32_t)&idt; idtr.limit = IDT_SIZE - 1; asm volatile("lidt %0\n" : : "m" (idtr) : "memory"); } void init_idt(void) { create_idt(); load_idt(); }