/** * idt.c * Инициализация обработчика прерываний * * Настройка обработчика прерываний и системных исключений * */ #include "idt.h" #include #include #include #include #include static struct idt_desc IDT[IDT_SIZE] __attribute__((aligned(16))); struct idt_ptr IDT_POINT = { .limit = sizeof(IDT) - 1, .base = (uint64_t)IDT }; const char *exception_names[] = { "Деление на ноль", "Отладка", "NMI", "Точка останова", "Переполнение", "Выход за границы", "Недопустимая операция", "Устройство недоступно", "Двойное исключение", NO_NAME, "Недопустимый TSS", "Сегмент не присутствует", "Ошибка сегмента стека", "Общая защитная ошибка", "Ошибка страницы", NO_NAME, "x87 исключение", "Проверка выравнивания", "Ошибка машины", "SIMD исключение", "Виртуализация", NO_NAME, NO_NAME, NO_NAME, NO_NAME, NO_NAME, NO_NAME, NO_NAME, NO_NAME, "Безопасность" }; void exception_handler(struct frame state) { LOG("\nПОЛУЧЕНО ИСКЛЮЧЕНИЕ: %s\n", exception_names[state.int_number]); uintptr_t rsp = state.rsp; const uintptr_t stack_bottom = rsp & ~((uintptr_t)4096 - 1); const uintptr_t stack_top = stack_bottom + 4096; LOG(" RAX=%x RBX=%x\n" " RCX=%x RDX=%x\n" " RSI=%x RDI=%x\n" " RBP=%x RSP=%x\n" " R08=%x R09=%x\n" " R10=%x R11=%x\n" " R12=%x R13=%x\n" " R14=%x R15=%x\n" " RIP=%x RFLAGS=%x\n" " CS=%x SS=%x\n" " ERR=%x INT=%u", state.rax, state.rbx, state.rcx, state.rdx, state.rsi, state.rdi, state.rbp, state.rsp, state.r8, state.r9, state.r10, state.r11, state.r12, state.r13, state.r14, state.r15, state.rip, state.rflags, state.cs, state.ss, state.err, state.int_number); LOG("stack_top = %x\n", stack_top); asm volatile("cli; hlt"); } static void idt_desc_setup(struct idt_desc *desc, unsigned sel, uintptr_t offs, unsigned flags) { desc->offs0 = offs & 0xfffful; desc->offs1 = (offs >> 16) & 0xfffful; desc->offs2 = (offs >> 32) & 0xfffffffful; desc->sel = sel; desc->flags = flags; desc->_reserved = 0; } static void idt_load( ) { struct idt_ptr *ptr = &IDT_POINT; asm volatile("lidt %0" : : "m"(*ptr)); } void idt_set_int(uint8_t vector, void *int_handler) { idt_desc_setup(&IDT[vector], KERNEL_CS, (uintptr_t)int_handler, IDT_INTERRUPT_FLAGS); idt_load( ); } void idt_init( ) { asm volatile("sti"); for (int i = 0; i != IDT_EXCEPTIONS; ++i) { const uintptr_t handler = (uintptr_t)isr_stubs[i]; idt_desc_setup(&IDT[i], KERNEL_CS, handler, IDT_EXCEPTION_FLAGS); } for (int i = IDT_EXCEPTIONS; i != IDT_SIZE; ++i) { const uintptr_t handler = (uintptr_t)isr_stubs[i]; idt_desc_setup(&IDT[i], KERNEL_CS, handler, IDT_INTERRUPT_FLAGS); } idt_desc_setup(&IDT[255], KERNEL_CS, (uintptr_t)isr_stubs[255], IDT_SPURIOUS_FLAGS); idt_load( ); LOG("IDT инициализирован\n"); }