#include #include #include #include #include "amd64.h" #include "lapic.h" #include "trap.h" extern uint64_t trap_table[T_MAX]; extern void trap_pop(TrapFrame *tf); static InteruptGate64 idt[256]; static PseudoDescriptor idtdesc; void Trap_Init() { int i; kprintf("Initializing IDT... "); for (i = 0; i < T_MAX; i++) { idt[i].pc_low = trap_table[i] & 0x0000ffff; idt[i].pc_mid = (trap_table[i] >> 16) & 0x0000ffff; idt[i].pc_high = trap_table[i] >> 32; idt[i].cs = 0x0008; idt[i].type = 0x8E; idt[i].ist = 0x00; idt[i]._unused1 = 0x00000000; } for (; i < 256; i++) { idt[i].pc_low = 0; idt[i].pc_mid = 0; idt[i].pc_high = 0; idt[i].cs = 0; idt[i].type = 0; idt[i].ist = 0; idt[i]._unused1 = 0; } // Double fault handler idt[T_DF].ist = 0x01; idtdesc.off = (uint64_t)&idt; idtdesc.lim = sizeof(idt) - 1; lidt(&idtdesc); kprintf("Done!\n"); } void Trap_Dump(TrapFrame *tf) { kprintf("Interrupt %d Error Code: %016llx\n", tf->vector, tf->errcode); kprintf("cr0: %016llx cr2: %016llx\n", read_cr0(), read_cr2()); kprintf("cr3: %016llx cr4: %016llx\n", read_cr3(), read_cr4()); kprintf("dr0: %016llx dr1: %016llx dr2: %016llx\n", read_dr0(), read_dr1(), read_dr2()); kprintf("dr3: %016llx dr6: %016llx dr7: %016llx\n", read_dr3(), read_dr6(), read_dr7()); kprintf("rip: %04x:%016x rsp: %04x:%016x\n", tf->cs, tf->rip, tf->ss, tf->rsp); kprintf("rflags: %016x ds: %04x es: %04x fs: %04x gs: %04x\n", tf->rflags, read_ds(), read_es(), read_fs(), read_gs()); kprintf("rax: %016llx rbx: %016llx rcx: %016llx\n", tf->rax, tf->rbx, tf->rcx); kprintf("rdx: %016llx rsi: %016llx rdi: %016llx\n", tf->rdx, tf->rsi, tf->rdi); kprintf("rbp: %016llx r8: %016llx r9: %016llx\n", tf->rbp, tf->r8, tf->r9); kprintf("r10: %016llx r11: %016llx r12: %016llx\n", tf->r10, tf->r11, tf->r12); kprintf("r13: %016llx r14: %016llx r15: %016llx\n", tf->r13, tf->r14, tf->r15); } void trap_entry(TrapFrame *tf) { // Kernel Debugger if (tf->vector == T_BP && tf->cs == SEL_KCS) { Debug_Breakpoint(tf); return; } // Halt on kernel errors if (tf->vector <= T_CPU_LAST && tf->cs == SEL_KCS) { kprintf("Kernel Fault!\n"); Trap_Dump(tf); Debug_Breakpoint(tf); while (1) hlt(); } switch (tf->vector) { case T_DE: break; case T_DB: case T_BP: break; case T_UD: case T_DF: break; default: break; } if (tf->vector >= T_IRQ_BASE && tf->vector <= T_IRQ_MAX) { kprintf("IRQ: %d\n", tf->vector); IRQ_Handler(tf->vector - T_IRQ_BASE); LAPIC_SendEOI(); return; } // LAPIC Special Vectors if (tf->vector == T_IRQ_SPURIOUS) return; if (tf->vector == T_IRQ_ERROR) { kprintf("LAPIC Error!\n"); while (1) hlt(); } if (tf->vector == T_IRQ_THERMAL) { kprintf("Thermal Error!\n"); while (1) hlt(); } kprintf("Unhandled Interrupt!\n"); Trap_Dump(tf); while (1) hlt(); }