#include "idt.h" #include "io.h" #include "pic/keyboard.h" #include "pic/pic.h" #include "pic/pit.h" #include "stdio.h" static struct idt idt = { 0 }; static struct idt_entry_info infos[] = { // Intel-defined (0-20) {int_de, INTERRUPT_TYPE}, {int_db, INTERRUPT_TYPE}, {int_nmi, INTERRUPT_TYPE}, {int_bp, TRAP_TYPE}, {int_of, TRAP_TYPE}, {int_br, INTERRUPT_TYPE}, {int_ud, INTERRUPT_TYPE}, {int_nm, INTERRUPT_TYPE}, {int_df, INTERRUPT_TYPE}, {0, INTERRUPT_TYPE}, {int_ts, INTERRUPT_TYPE}, {int_np, INTERRUPT_TYPE}, {int_ss, INTERRUPT_TYPE}, {int_gp, INTERRUPT_TYPE}, {int_pf, INTERRUPT_TYPE}, {0, INTERRUPT_TYPE}, {int_mf, INTERRUPT_TYPE}, {int_ac, INTERRUPT_TYPE}, {int_mc, INTERRUPT_TYPE}, {int_xm, INTERRUPT_TYPE}, {int_ve, INTERRUPT_TYPE}, // Intel-reserved (21-31) {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, // user-defined (32-255) {pic_pit, INTERRUPT_TYPE}, {pic_keyboard, INTERRUPT_TYPE} }; void handle_interrupt(struct int_args *args) { switch (args->int_code) { case 32: // PIT pit_handler(); outb(MASTER_PORT_A, OCW2_EOI); return; case 33: // keyboard keyboard_handler(); outb(MASTER_PORT_A, OCW2_EOI); return; } printf("INTERRUPT: %d, error code: %d\r\n", args->int_code, args->err_code); asm volatile("cli; hlt"); } static struct idt_entry create_idt_entry(uint32_t offset, struct segment_selector selector, uint32_t type) { struct idt_entry res = { 0 }; res.selector = selector; res.offset_1 = offset & 0xffff; res.offset_2 = (offset >> 16) & 0xffff; res.type = type; res.size = 1; res.desc_priv = 0; res.present = 1; return res; } static void create_idt(void) { struct segment_selector selector; selector.rpl = 0; selector.table_indicator = 0; selector.index = KERNEL_CS_INDEX; for (int i = 0; i < IDT_NB_ENTRIES; ++i) { struct idt_entry entry = create_idt_entry((uint32_t)infos[i].isr, selector, infos[i].type); 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(); }