summaryrefslogtreecommitdiffhomepage
path: root/Private/HALKit/AMD64/HalDescriptorLoader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Private/HALKit/AMD64/HalDescriptorLoader.cpp')
-rw-r--r--Private/HALKit/AMD64/HalDescriptorLoader.cpp70
1 files changed, 70 insertions, 0 deletions
diff --git a/Private/HALKit/AMD64/HalDescriptorLoader.cpp b/Private/HALKit/AMD64/HalDescriptorLoader.cpp
new file mode 100644
index 00000000..64f7ca65
--- /dev/null
+++ b/Private/HALKit/AMD64/HalDescriptorLoader.cpp
@@ -0,0 +1,70 @@
+/*
+ * ========================================================
+ *
+ * HCore
+ * Copyright Mahrouss Logic, all rights reserved.
+ *
+ * ========================================================
+ */
+
+#include <ArchKit/ArchKit.hpp>
+
+namespace HCore::HAL {
+void GDTLoader::Load(Register64 &gdt) {
+ Register64 gdtReg;
+
+ gdtReg.Base = gdt.Base;
+ gdtReg.Limit = gdt.Limit;
+
+ rt_load_gdt(gdtReg);
+}
+
+namespace Detail::AMD64 {
+struct InterruptDescriptorAMD64 final {
+ UInt16 OffsetLow; // offset bits 0..15
+ UInt16 Selector; // a code segment selector in GDT or LDT
+ UInt8
+ Ist; // bits 0..2 holds Interrupt Stack Table offset, rest of bits zero.
+ UInt8 TypeAttributes; // gate type, dpl, and p fields
+ UInt16 OffsetMid; // offset bits 16..31
+ UInt32 OffsetHigh; // offset bits 32..63
+ UInt32 Zero; // reserved
+};
+} // namespace Detail::AMD64
+
+#define kInterruptGate 0x8E
+#define kTrapGate 0x8F
+#define kTaskGate 0x85
+#define kGdtSelector 0xa0
+
+extern "C" HCore::UIntPtr rt_handle_interrupts(HCore::UIntPtr &rsp);
+
+static ALIGN(0x10)
+ Detail::AMD64::InterruptDescriptorAMD64 kIdtRegs[kKernelMaxSystemCalls];
+
+static HAL::Register64 kRegIdt;
+
+void IDTLoader::Load(Register64 &idt) {
+ VoidPtr *baseIdt = (VoidPtr *)idt.Base;
+
+ for (auto i = 0; i < 32; i++) {
+ kIdtRegs[i].Selector = kGdtSelector;
+ kIdtRegs[i].Ist = 001;
+ kIdtRegs[i].TypeAttributes = kTrapGate;
+ kIdtRegs[i].OffsetLow = (UIntPtr)baseIdt & 0xFFFF;
+ kIdtRegs[i].OffsetMid = (UIntPtr)baseIdt >> 16 & 0xFFFF;
+ kIdtRegs[i].OffsetHigh = (UIntPtr)baseIdt >> 32 & 0xFFFFFFFF;
+ kIdtRegs[i].Zero = 0;
+ }
+
+ kRegIdt.Base = (UIntPtr)&kIdtRegs[0];
+ kRegIdt.Limit =
+ sizeof(Detail::AMD64::InterruptDescriptorAMD64) * idt.Limit - 1;
+
+ rt_load_idt(kRegIdt);
+}
+
+void GDTLoader::Load(Ref<Register64> &gdt) { GDTLoader::Load(gdt.Leak()); }
+
+void IDTLoader::Load(Ref<Register64> &idt) { IDTLoader::Load(idt.Leak()); }
+} // namespace HCore::HAL