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,6 @@
|
|||||||
|
#ifndef FROSTBYTE_IDT_H
|
||||||
|
#define FROSTBYTE_IDT_H
|
||||||
|
|
||||||
|
void idtInit(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
#ifndef FROSTBYTE_ISR_H
|
||||||
|
#define FROSTBYTE_ISR_H
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
typedef struct Registers {
|
||||||
|
uint64 r15, r14, r13, r12, r11, r10, r9, r8;
|
||||||
|
uint64 rbp, rdi, rsi, rdx, rcx, rbx, rax;
|
||||||
|
uint64 intNo, errCode;
|
||||||
|
uint64 rip, cs, rflags, rsp, ss;
|
||||||
|
} __attribute__((packed)) Registers;
|
||||||
|
|
||||||
|
uint64 isrDispatch(Registers* regs);
|
||||||
|
uint64 syscallDispatch(Registers* regs);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -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