#include "idt.h" #include "smp.h" #include "gdt.h" #include "jove.h" #include "lib/printf.h" #include "lib/string.h" #include "panic/panic.h" ALIGN(8) static struct idt_entry s_idt[IDT_ENTRIES]; typedef void (*isr_t)(void); extern isr_t __isrs[IDT_ENTRIES]; typedef struct int_stackframe *(*int_handler_t)(struct int_stackframe*); int_handler_t __int_kernel_handles[IDT_ENTRIES]; struct int_user_handle __int_user_handles[IDT_ENTRIES]; static struct int_stackframe* s_int_handle_stub(struct int_stackframe* frame) { kprintf("Unhandled interrupt %i at %p\n", frame->int_num, frame->int_rip); hcf(); } struct int_stackframe* __int_handle_body(struct int_stackframe *frame) { frame = __int_kernel_handles[frame->int_num](frame); struct int_user_handle *usr_handle = &__int_user_handles[frame->int_num]; if(usr_handle->pid == 0) return frame; kprintf("TODO: Handle user interrupt switching\n"); return frame; } void idt_init(void) { memset(__int_user_handles, 0, sizeof(struct int_user_handle) * IDT_ENTRIES); for(size_t i = 0; i < IDT_ENTRIES; i++) { uintptr_t isr = (uintptr_t)(__isrs[i]); s_idt[i] = (struct idt_entry) { .offset_0_15 = (uint16_t)(isr & 0xFFFF), .segment_selector = GDT_KERNEL_CODE * 8, .ist = 0, .type = IDT_INTERRUPT_GATE, .dpl = 0, .p = 1, .offset_16_31 = (uint16_t)((isr >> 16) & 0xFFFF), .offset_32_63 = (uint32_t)(isr >> 32) }; __int_kernel_handles[i] = s_int_handle_stub; } } void idt_setup(processor_t *processor) { struct idt_descriptor idtr = (struct idt_descriptor) { .limit = sizeof(struct idt_entry) * IDT_ENTRIES - 1, .base = (uint64_t)&s_idt }; __asm__ volatile("lidt %0":: "m"(idtr)); }