diff options
Diffstat (limited to 'Private/HALKit/AMD64/HalPlatformAMD64.cpp')
| -rw-r--r-- | Private/HALKit/AMD64/HalPlatformAMD64.cpp | 66 |
1 files changed, 54 insertions, 12 deletions
diff --git a/Private/HALKit/AMD64/HalPlatformAMD64.cpp b/Private/HALKit/AMD64/HalPlatformAMD64.cpp index b2e343b6..e9e7fb82 100644 --- a/Private/HALKit/AMD64/HalPlatformAMD64.cpp +++ b/Private/HALKit/AMD64/HalPlatformAMD64.cpp @@ -11,31 +11,73 @@ namespace HCore::HAL { namespace Detail { -struct RegisterAMD64 final { +struct PACKED RegisterAMD64 final { UIntPtr base; UShort limit; }; } // namespace Detail void GDTLoader::Load(Register64 &gdt) { - Detail::RegisterAMD64 *reg = new Detail::RegisterAMD64(); - MUST_PASS(reg); + Detail::RegisterAMD64 *gdtReg = new Detail::RegisterAMD64(); + MUST_PASS(gdtReg); - reg->base = gdt.Base; - reg->limit = gdt.Limit; + gdtReg->base = gdt.Base; + gdtReg->limit = gdt.Limit; - rt_cli(); - rt_load_gdt(reg); - rt_sti(); + rt_load_gdt((VoidPtr)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 0xE +#define kTrapGate 0xF +#define kRing0 (0 << 5) +#define kRing3 (3 << 5) +#define kIdtPresent (1 << 7) +#define kGdtSelector 0x08 + +extern "C" HCore::UIntPtr rt_handle_interrupts(HCore::UIntPtr &rsp); + +static ALIGN( + 0x10) Detail::AMD64::InterruptDescriptorAMD64 kIdtRegs[kMaxSyscalls]; +static HAL::Register64 kRegIdt; + void IDTLoader::Load(Register64 &idt) { - Detail::RegisterAMD64 *reg = new Detail::RegisterAMD64(); + for (auto i = 0; i < 32; i++) { + kIdtRegs[i].Selector = kGdtSelector; + kIdtRegs[i].Ist = 0x00; + kIdtRegs[i].TypeAttributes = kInterruptGate | kRing0 | kIdtPresent; + kIdtRegs[i].OffsetLow = (((UIntPtr *)idt.Base)[i]) & 0xFFFF; + kIdtRegs[i].OffsetMid = (((UIntPtr *)idt.Base)[i] >> 16) & 0xFFFF; + kIdtRegs[i].OffsetHigh = (((UIntPtr *)idt.Base)[i] >> 32) & 0xFFFF; + kIdtRegs[i].Zero = 0; + } + + kIdtRegs[0x21].Selector = kGdtSelector; + kIdtRegs[0x21].Ist = 0x00; + kIdtRegs[0x21].TypeAttributes = kInterruptGate | kRing3 | kIdtPresent; + kIdtRegs[0x21].OffsetLow = (((UIntPtr *)idt.Base)[0x21]) & 0xFFFF; + kIdtRegs[0x21].OffsetMid = (((UIntPtr *)idt.Base)[0x21] >> 16) & 0xFFFF; + kIdtRegs[0x21].OffsetHigh = (((UIntPtr *)idt.Base)[0x21] >> 32) & 0xFFFF; + kIdtRegs[0x21].Zero = 0; + + kRegIdt.Base = (UIntPtr)kIdtRegs; + kRegIdt.Limit = sizeof(Detail::AMD64::InterruptDescriptorAMD64) * idt.Limit; - reg->base = idt.Base; - reg->limit = idt.Limit; + rt_load_idt((VoidPtr)&kRegIdt); - rt_load_idt(reg); + kcout << "Krnl: IDT loaded\n"; } void GDTLoader::Load(Ref<Register64> &gdt) { GDTLoader::Load(gdt.Leak()); } |
