184 lines
4.9 KiB
C
184 lines
4.9 KiB
C
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include "intr.h"
|
|
#include "io.h"
|
|
#include "gdt.h"
|
|
#include "hal/hal.h"
|
|
#include "kprintf.h"
|
|
#include "compiler/attr.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",
|
|
};
|
|
|
|
extern void intr_vec0(void);
|
|
extern void intr_vec1(void);
|
|
extern void intr_vec2(void);
|
|
extern void intr_vec3(void);
|
|
extern void intr_vec4(void);
|
|
extern void intr_vec5(void);
|
|
extern void intr_vec6(void);
|
|
extern void intr_vec7(void);
|
|
extern void intr_vec8(void);
|
|
extern void intr_vec10(void);
|
|
extern void intr_vec11(void);
|
|
extern void intr_vec12(void);
|
|
extern void intr_vec13(void);
|
|
extern void intr_vec14(void);
|
|
extern void intr_vec16(void);
|
|
extern void intr_vec17(void);
|
|
extern void intr_vec18(void);
|
|
extern void intr_vec19(void);
|
|
extern void intr_vec20(void);
|
|
extern void intr_vec21(void);
|
|
extern void intr_vec32(void);
|
|
extern void intr_vec33(void);
|
|
extern void intr_vec39(void);
|
|
|
|
void intr_init(void) {
|
|
idt_setentry(0, (uint64_t)&intr_vec0, 0, 0x8E);
|
|
idt_setentry(1, (uint64_t)&intr_vec1, 0, 0x8E);
|
|
idt_setentry(2, (uint64_t)&intr_vec2, 2, 0x8E);
|
|
idt_setentry(3, (uint64_t)&intr_vec3, 0, 0x8E);
|
|
idt_setentry(4, (uint64_t)&intr_vec4, 0, 0x8E);
|
|
idt_setentry(5, (uint64_t)&intr_vec5, 0, 0x8E);
|
|
idt_setentry(6, (uint64_t)&intr_vec6, 0, 0x8E);
|
|
idt_setentry(7, (uint64_t)&intr_vec7, 0, 0x8E);
|
|
idt_setentry(8, (uint64_t)&intr_vec8, 1, 0x8E);
|
|
idt_setentry(10, (uint64_t)&intr_vec10, 0, 0x8E);
|
|
idt_setentry(11, (uint64_t)&intr_vec11, 0, 0x8E);
|
|
idt_setentry(12, (uint64_t)&intr_vec12, 0, 0x8E);
|
|
idt_setentry(13, (uint64_t)&intr_vec13, 0, 0x8E);
|
|
idt_setentry(14, (uint64_t)&intr_vec14, 0, 0x8E);
|
|
idt_setentry(16, (uint64_t)&intr_vec16, 0, 0x8E);
|
|
idt_setentry(17, (uint64_t)&intr_vec17, 0, 0x8E);
|
|
idt_setentry(18, (uint64_t)&intr_vec18, 0, 0x8E);
|
|
idt_setentry(19, (uint64_t)&intr_vec19, 0, 0x8E);
|
|
idt_setentry(20, (uint64_t)&intr_vec20, 0, 0x8E);
|
|
idt_setentry(21, (uint64_t)&intr_vec21, 0, 0x8E);
|
|
idt_setentry(32, (uint64_t)&intr_vec32, 0, 0x8E);
|
|
idt_setentry(33, (uint64_t)&intr_vec33, 0, 0x8E);
|
|
idt_setentry(39, (uint64_t)&intr_vec39, 0, 0x8E);
|
|
|
|
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) {
|
|
hal_intr_disable();
|
|
ERR("ERROR", "%s, 0x%lX\n", exceptions[frame->trapnum], frame->errnum);
|
|
intr_dumpframe(frame);
|
|
hal_hang();
|
|
}
|
|
|