Implement interrupts

This commit is contained in:
2025-08-19 22:51:33 +02:00
parent 92ccd189e7
commit 3f6df79885
14 changed files with 455 additions and 101 deletions

176
kernel/hal/x86_64/isr.c Normal file
View File

@ -0,0 +1,176 @@
#include <stddef.h>
#include <stdint.h>
#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();
}