Files
my-os-project2/kernel/hal/x86_64/intr.c
2025-08-22 12:37:48 +02:00

202 lines
4.3 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"
#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);
}
}