feat(cpu): install IDT with exception and syscall gate handling
This commit is contained in:
1 parent
4843406bf3
commit
e5c4139e49
4 files changed
+145
No files matched your search
@@ -0,0 +1,48 @@
|
||||
#include "idt.h"
|
||||
#include "types.h"
|
||||
|
||||
typedef struct IdtEntry {
|
||||
uint16 offsetLow;
|
||||
uint16 selector;
|
||||
uint8 ist;
|
||||
uint8 typeAttr;
|
||||
uint16 offsetMid;
|
||||
uint32 offsetHigh;
|
||||
uint32 reserved;
|
||||
} __attribute__((packed)) IdtEntry;
|
||||
|
||||
typedef struct IdtPointer {
|
||||
uint16 limit;
|
||||
uint64 base;
|
||||
} __attribute__((packed)) IdtPointer;
|
||||
|
||||
static IdtEntry idtEntries[256];
|
||||
static IdtPointer idtPointer;
|
||||
|
||||
extern void* isrStubTable[];
|
||||
extern void isrStub128(void);
|
||||
|
||||
static void setGate(int vector, void* handler, uint8 typeAttr)
|
||||
{
|
||||
uint64 address = (uint64)handler;
|
||||
idtEntries[vector].offsetLow = (uint16)(address & 0xFFFF);
|
||||
idtEntries[vector].selector = 0x08;
|
||||
idtEntries[vector].ist = 0;
|
||||
idtEntries[vector].typeAttr = typeAttr;
|
||||
idtEntries[vector].offsetMid = (uint16)((address >> 16) & 0xFFFF);
|
||||
idtEntries[vector].offsetHigh = (uint32)((address >> 32) & 0xFFFFFFFF);
|
||||
idtEntries[vector].reserved = 0;
|
||||
}
|
||||
|
||||
void idtInit(void)
|
||||
{
|
||||
for (int vector = 0; vector < 48; vector++)
|
||||
setGate(vector, isrStubTable[vector], 0x8E);
|
||||
|
||||
setGate(0x80, (void*)isrStub128, 0xEE);
|
||||
|
||||
idtPointer.limit = (uint16)(sizeof(idtEntries) - 1);
|
||||
idtPointer.base = (uint64)&idtEntries;
|
||||
|
||||
__asm__ volatile("lidt %0" : : "m"(idtPointer));
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
#include "isr.h"
|
||||
#include "console.h"
|
||||
#include "pic.h"
|
||||
#include "pit.h"
|
||||
#include "keyboard.h"
|
||||
#include "sched.h"
|
||||
#include "ports.h"
|
||||
|
||||
static const char* exceptionNames[32] = {
|
||||
"divide by zero",
|
||||
"debug",
|
||||
"non maskable interrupt",
|
||||
"breakpoint",
|
||||
"overflow",
|
||||
"bound range exceeded",
|
||||
"invalid opcode",
|
||||
"device not available",
|
||||
"double fault",
|
||||
"coprocessor segment overrun",
|
||||
"invalid tss",
|
||||
"segment not present",
|
||||
"stack segment fault",
|
||||
"general protection fault",
|
||||
"page fault",
|
||||
"reserved",
|
||||
"x87 floating point",
|
||||
"alignment check",
|
||||
"machine check",
|
||||
"simd floating point",
|
||||
"virtualization",
|
||||
"control protection",
|
||||
"reserved", "reserved", "reserved", "reserved",
|
||||
"reserved", "reserved", "reserved", "reserved",
|
||||
"hypervisor injection", "vmm communication"
|
||||
};
|
||||
|
||||
static void panicOnException(Registers* regs)
|
||||
{
|
||||
uint64 faultAddress = 0;
|
||||
if (regs->intNo == 14)
|
||||
__asm__ volatile("mov %%cr2, %0" : "=r"(faultAddress));
|
||||
|
||||
kprintf("\n[PANIC] exception %lu (%s)\n", regs->intNo, exceptionNames[regs->intNo]);
|
||||
kprintf(" errCode=%lx rip=%lx cs=%lx rflags=%lx\n",
|
||||
regs->errCode, regs->rip, regs->cs, regs->rflags);
|
||||
if (regs->intNo == 14)
|
||||
kprintf(" cr2=%lx (faulting address)\n", faultAddress);
|
||||
kprintf(" rax=%lx rbx=%lx rcx=%lx rdx=%lx\n", regs->rax, regs->rbx, regs->rcx, regs->rdx);
|
||||
kprintf(" system halted\n");
|
||||
|
||||
for (;;)
|
||||
__asm__ volatile("cli; hlt");
|
||||
}
|
||||
|
||||
uint64 isrDispatch(Registers* regs)
|
||||
{
|
||||
if (regs->intNo < 32)
|
||||
panicOnException(regs);
|
||||
|
||||
if (regs->intNo == 128)
|
||||
return syscallDispatch(regs);
|
||||
|
||||
uint8 irq = (uint8)(regs->intNo - 32);
|
||||
uint64 nextRsp = (uint64)regs;
|
||||
|
||||
if (irq == 0) {
|
||||
pitTick();
|
||||
nextRsp = schedule((uint64)regs);
|
||||
} else if (irq == 1) {
|
||||
keyboardHandler();
|
||||
}
|
||||
|
||||
picSendEoi(irq);
|
||||
return nextRsp;
|
||||
}
|
||||
Reference in new issue
Block a user