68 lines
1.9 KiB
C++
68 lines
1.9 KiB
C++
#include <idt.h>
|
||
#include <common.h>
|
||
#include <string_utils.h>
|
||
#include <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=0,64 位中断门
|
||
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");
|
||
}
|