Files
Sylva/kernel/interrupt/idt.cpp
T
2026-06-06 10:37:51 +08:00

68 lines
1.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <interrupt/idt.h>
#include <common.h>
#include <string_utils.h>
#include <interrupt/pic.h>
#include <serial.h>
// isr.S 中定义的 256 个 ISR 桩函数
extern "C" void* isr_stub_table[256];
static idt_entry g_idt[256];
static idt_ptr g_idt_ptr;
static isr_handler_t g_handlers[256] = {0};
void idt_set_handler(UINT8 vector, isr_handler_t handler) {
g_handlers[vector] = handler;
}
// 由 isr.S 通用处理函数调用
extern "C" void isr_dispatch(trap_frame* frame) {
UINT8 vector = (UINT8)frame->vector;
if (g_handlers[vector]) {
g_handlers[vector](frame);
} else if (vector < 32) {
serial_write("IDT: unhandled exception #");
serial_write_hex(vector);
serial_write(" error=");
serial_write_hex(frame->error_code);
serial_write("\n");
while (1) ASM("hlt");
}
}
// IDT 辅助函数(定义在 idt_helpers.S
extern "C" void idt_load(UINT64 base, UINT16 limit);
static void idt_set_entry(UINT8 vector, UINT64 handler_addr) {
g_idt[vector].offset_low = handler_addr & 0xFFFF;
g_idt[vector].selector = 0x08; // 内核代码段
g_idt[vector].ist = 0;
g_idt[vector].type_attr = 0x8E; // 存在,DPL=064 位中断门
g_idt[vector].offset_mid = (handler_addr >> 16) & 0xFFFF;
g_idt[vector].offset_high = (handler_addr >> 32) & 0xFFFFFFFF;
g_idt[vector].reserved = 0;
}
void idt_init(void) {
serial_write("IDT: initializing 256 entries\n");
// 清空 IDT
for (SSINT32 i = 0; i < 256; i++) {
g_idt[i] = {0};
g_handlers[i] = NULL;
}
// 安装所有 256 个 ISR 桩函数
for (SSINT32 i = 0; i < 256; i++) {
idt_set_entry(i, (UINT64)isr_stub_table[i]);
}
// 加载 IDT
g_idt_ptr.limit = sizeof(g_idt) - 1;
g_idt_ptr.base = (UINT64)&g_idt[0];
idt_load(g_idt_ptr.base, g_idt_ptr.limit);
serial_write("IDT: loaded\n");
}