#include #include #include "isr.h" #include "io.h" #include "gdt.h" #include "hal/hal.h" #include "kprintf.h" #include "compiler/attr.h" typedef struct { uint16_t isrlow; uint16_t kernelcs; uint8_t ist; uint8_t attrs; uint16_t isrmid; uint32_t isrhigh; uint32_t resv; } PACKED IdtGate; typedef struct { uint16_t limit; uint64_t base; } PACKED Idt; #define ENTRIES 256 ALIGNED(0x10) static IdtGate idtgates[ENTRIES] = {0}; static Idt idt = {0}; void idt_setentry(int i, uint64_t handler, uint8_t ist, uint8_t flags) { idtgates[i].isrlow = handler & 0xffff; idtgates[i].kernelcs = KCODE; idtgates[i].ist = ist; idtgates[i].attrs = flags; idtgates[i].isrmid = (handler >> 16) & 0xFFFF; idtgates[i].isrhigh = (handler >> 32) & 0xFFFFFFFF; idtgates[i].resv = 0; } void idt_init(void) { idt.base = (uint64_t)&idtgates; idt.limit = ENTRIES * sizeof(IdtGate) - 1; asm volatile("lidt %0" :: "m"(idt) : "memory"); LOG("idt", "idt init\n"); } typedef struct { uint64_t r15; uint64_t r14; uint64_t r13; uint64_t r12; uint64_t r11; uint64_t r10; uint64_t r9; uint64_t r8; uint64_t rsi; uint64_t rdi; uint64_t rbp; uint64_t rdx; uint64_t rcx; uint64_t rbx; uint64_t rax; } PACKED CpuRegs; typedef struct { uint64_t cr8; uint64_t cr4; uint64_t cr3; uint64_t cr2; uint64_t cr0; } PACKED CpuCtrlRegs; typedef struct { CpuCtrlRegs ctrl; CpuRegs regs; uint64_t trapnum; uint64_t errnum; uint64_t rip; uint64_t cs; uint64_t rflags; uint64_t rsp; uint64_t ss; } PACKED IntrStackFrame; extern void *ISR_REDIRTABLE[]; static const char *exceptions[] = { "#DE", "#DB", "NMI", "#BP", "#OF", "#BR", "#UD", "#NM", "#DF", "CSO", "#TS", "#NP", "#SS", "#GP", "#PF", "RES", "#MF", "#AC", "#MC", "#XM", "#VE", "#CP", }; extern void isr_vec0(void); extern void isr_vec1(void); extern void isr_vec2(void); extern void isr_vec3(void); extern void isr_vec4(void); extern void isr_vec5(void); extern void isr_vec6(void); extern void isr_vec7(void); extern void isr_vec8(void); extern void isr_vec10(void); extern void isr_vec11(void); extern void isr_vec12(void); extern void isr_vec13(void); extern void isr_vec14(void); extern void isr_vec16(void); extern void isr_vec17(void); extern void isr_vec18(void); extern void isr_vec19(void); extern void isr_vec20(void); extern void isr_vec21(void); extern void isr_vec32(void); extern void isr_vec33(void); extern void isr_vec39(void); void isr_init(void) { idt_setentry(0, (uint64_t)&isr_vec0, 0, 0x8E); idt_setentry(1, (uint64_t)&isr_vec1, 0, 0x8E); idt_setentry(2, (uint64_t)&isr_vec2, 2, 0x8E); idt_setentry(3, (uint64_t)&isr_vec3, 0, 0x8E); idt_setentry(4, (uint64_t)&isr_vec4, 0, 0x8E); idt_setentry(5, (uint64_t)&isr_vec5, 0, 0x8E); idt_setentry(6, (uint64_t)&isr_vec6, 0, 0x8E); idt_setentry(7, (uint64_t)&isr_vec7, 0, 0x8E); idt_setentry(8, (uint64_t)&isr_vec8, 1, 0x8E); idt_setentry(10, (uint64_t)&isr_vec10, 0, 0x8E); idt_setentry(11, (uint64_t)&isr_vec11, 0, 0x8E); idt_setentry(12, (uint64_t)&isr_vec12, 0, 0x8E); idt_setentry(13, (uint64_t)&isr_vec13, 0, 0x8E); idt_setentry(14, (uint64_t)&isr_vec14, 0, 0x8E); idt_setentry(16, (uint64_t)&isr_vec16, 0, 0x8E); idt_setentry(17, (uint64_t)&isr_vec17, 0, 0x8E); idt_setentry(18, (uint64_t)&isr_vec18, 0, 0x8E); idt_setentry(19, (uint64_t)&isr_vec19, 0, 0x8E); idt_setentry(20, (uint64_t)&isr_vec20, 0, 0x8E); idt_setentry(21, (uint64_t)&isr_vec21, 0, 0x8E); idt_setentry(32, (uint64_t)&isr_vec32, 0, 0x8E); idt_setentry(33, (uint64_t)&isr_vec33, 0, 0x8E); idt_setentry(39, (uint64_t)&isr_vec39, 0, 0x8E); idt_init(); } void isr_dumpframe(IntrStackFrame *frame) { kprintf("r15=%016llx r14=%016llx r13=%016llx r12=%016llx\n" "r11=%016llx r10=%016llx r9 =%016llx r8 =%016llx\n" "rsi=%016llx rdi=%016llx rbp=%016llx rdx=%016llx\n" "rcx=%016llx rbx=%016llx rax=%016llx\n" "cr8=%016llx cr4=%016llx cr3=%016llx cr2=%016llx\n" "cr0=%016llx rip=%016llx cs =%016llx rfl=%016llx\n" "rsp=%016llx ss =%016llx trp=%016llx err=%016llx\n", frame->regs.r15, frame->regs.r14, frame->regs.r13, frame->regs.r12, frame->regs.r11, frame->regs.r10, frame->regs.r9, frame->regs.r8, frame->regs.rsi, frame->regs.rdi, frame->regs.rbp, frame->regs.rdx, frame->regs.rcx, frame->regs.rbx, frame->regs.rax, frame->ctrl.cr8, frame->ctrl.cr4, frame->ctrl.cr3, frame->ctrl.cr2, frame->ctrl.cr0, frame->rip, frame->cs, frame->rflags, frame->rsp, frame->ss, frame->trapnum, frame->errnum ); } void isr_handleintr(IntrStackFrame *frame) { hal_intr_disable(); ERR("ERROR", "%s, 0x%X\n", exceptions[frame->trapnum], frame->errnum); isr_dumpframe(frame); hal_hang(); }