diff --git a/zion/common/gdt.cpp b/zion/common/gdt.cpp index cc7654a..e793c6b 100644 --- a/zion/common/gdt.cpp +++ b/zion/common/gdt.cpp @@ -93,4 +93,8 @@ void InitGdt() { : "rax"); } +void SetIst1(uint64_t* ist1) { + gTaskStateSegment.ist1 = reinterpret_cast(ist1); +} + void SetRsp0(uint64_t rsp0) { gTaskStateSegment.rsp0 = rsp0; } diff --git a/zion/common/gdt.h b/zion/common/gdt.h index 5cee0fd..0d55869 100644 --- a/zion/common/gdt.h +++ b/zion/common/gdt.h @@ -4,4 +4,6 @@ void InitGdt(); +void SetIst1(uint64_t* ist1); + void SetRsp0(uint64_t rsp0); diff --git a/zion/interrupt/interrupt.cpp b/zion/interrupt/interrupt.cpp index 9271788..6226330 100644 --- a/zion/interrupt/interrupt.cpp +++ b/zion/interrupt/interrupt.cpp @@ -30,12 +30,12 @@ struct InterruptDescriptor { static InterruptDescriptor gIdt[256]; -InterruptDescriptor CreateDescriptor(void isr(void)) { +InterruptDescriptor CreateDescriptor(void isr(void), uint8_t ist = 0) { uint64_t offset = reinterpret_cast(isr); return InterruptDescriptor{ .offset_low = static_cast(offset), .selector = KERNEL_CS, - .ist = 0, + .ist = ist, .flags = IDT_INTERRUPT_GATE, .offset_medium = static_cast(offset >> 16), .offset_high = static_cast(offset >> 32), @@ -192,4 +192,15 @@ void InitIdt() { asm volatile("lidt %0" ::"m"(idtp)); } +void UpdateFaultHandlersToIst1() { + gIdt[13] = CreateDescriptor(isr_protection_fault, 1); + gIdt[14] = CreateDescriptor(isr_page_fault, 1); + + InterruptDescriptorTablePointer idtp{ + .size = sizeof(gIdt), + .base = reinterpret_cast(gIdt), + }; + asm volatile("lidt %0" ::"m"(idtp)); +} + void RegisterPciPort(const glcr::RefPtr& port) { pci1_port = port; } diff --git a/zion/interrupt/interrupt.h b/zion/interrupt/interrupt.h index 30219b5..e1b5114 100644 --- a/zion/interrupt/interrupt.h +++ b/zion/interrupt/interrupt.h @@ -6,4 +6,6 @@ void InitIdt(); +void UpdateFaultHandlersToIst1(); + void RegisterPciPort(const glcr::RefPtr& port); diff --git a/zion/memory/kernel_stack_manager.cpp b/zion/memory/kernel_stack_manager.cpp index 4379444..abb0967 100644 --- a/zion/memory/kernel_stack_manager.cpp +++ b/zion/memory/kernel_stack_manager.cpp @@ -1,5 +1,6 @@ #include "memory/kernel_stack_manager.h" +#include "common/gdt.h" #include "debug/debug.h" #include "memory/paging_util.h" @@ -11,6 +12,8 @@ KernelStackManager* gKernelStackManager; void KernelStackManager::Init() { gKernelStackManager = new KernelStackManager(); + + SetIst1(gKernelStackManager->AllocateKernelStack()); } KernelStackManager::KernelStackManager() diff --git a/zion/zion.cpp b/zion/zion.cpp index ff72cbb..75ca733 100644 --- a/zion/zion.cpp +++ b/zion/zion.cpp @@ -38,6 +38,10 @@ extern "C" void zion() { dbgln("[boot] Init Kernel Stack Manager."); KernelStackManager::Init(); + // The KernelStackManager sets Ist1 as a part of initialization so we can use + // it now. + UpdateFaultHandlersToIst1(); + dbgln("[boot] Init syscalls."); InitSyscall();