#include #include #include "intr.h" #include "io.h" #include "gdt.h" #include "hal/hal.h" #include "kprintf.h" #include "compiler/attr.h" #include "pic.h" #include "apic.h" #include "pit.h" void hal_intr_disable(void) { asm volatile("cli"); } void hal_intr_enable(void) { asm volatile("sti"); } typedef struct { uint16_t intrlow; uint16_t kernelcs; uint8_t ist; uint8_t attrs; uint16_t intrmid; uint32_t intrhigh; 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].intrlow = handler & 0xffff; idtgates[i].kernelcs = KCODE; idtgates[i].ist = ist; idtgates[i].attrs = flags; idtgates[i].intrmid = (handler >> 16) & 0xFFFF; idtgates[i].intrhigh = (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("hal", "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", }; void intr_init(void) { #define MKINTR(N, IST) \ extern void intr_vec##N(void); \ idt_setentry(N, (uint64_t)&intr_vec##N, IST, 0x8E); MKINTR(0, 0); MKINTR(1, 0); MKINTR(2, 2); MKINTR(4, 0); MKINTR(5, 0); MKINTR(6, 0); MKINTR(7, 0); MKINTR(8, 1); MKINTR(9, 0); MKINTR(10, 0); MKINTR(11, 0); MKINTR(12, 0); MKINTR(13, 0); MKINTR(14, 0); MKINTR(15, 0); MKINTR(16, 0); MKINTR(17, 0); MKINTR(18, 0); MKINTR(19, 0); MKINTR(20, 0); MKINTR(21, 0); MKINTR(22, 0); MKINTR(23, 0); MKINTR(24, 0); MKINTR(25, 0); MKINTR(26, 0); MKINTR(27, 0); MKINTR(28, 0); MKINTR(29, 0); MKINTR(30, 0); MKINTR(31, 0); MKINTR(32, 0); MKINTR(33, 0); MKINTR(34, 0); MKINTR(35, 0); MKINTR(36, 0); MKINTR(37, 0); MKINTR(38, 0); MKINTR(39, 0); MKINTR(40, 3); MKINTR(41, 0); MKINTR(42, 0); MKINTR(43, 0); MKINTR(44, 0); MKINTR(45, 0); MKINTR(46, 0); MKINTR(47, 0); idt_init(); } void intr_dumpframe(IntrStackFrame *frame) { kprintf("r15=%016lx r14=%016lx r13=%016lx r12=%016lx\n" "r11=%016lx r10=%016lx r9 =%016lx r8 =%016lx\n" "rsi=%016lx rdi=%016lx rbp=%016lx rdx=%016lx\n" "rcx=%016lx rbx=%016lx rax=%016lx\n" "cr8=%016lx cr4=%016lx cr3=%016lx cr2=%016lx\n" "cr0=%016lx rip=%016lx cs =%016lx rfl=%016lx\n" "rsp=%016lx ss =%016lx trp=%016lx err=%016lx\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 intr_handleintr(IntrStackFrame *frame) { if (frame->trapnum >= 0 && frame->trapnum <= 31) { // EXCEPTION ERR("ERROR", "%s, 0x%lX\n", exceptions[frame->trapnum], frame->errnum); intr_dumpframe(frame); hal_hang(); } else if (frame->trapnum >= 32 && frame->trapnum <= 47) { if (frame->trapnum == INTR_TIMER) { kprintf("ACK %d\n", PIT_TICKS); PIT_TICKS++; io_out8(PIC2_CMD, 0x20); } io_out8(PIC1_CMD, 0x20); lapic_write(LAPIC_EOI, 0x00); } }