diff --git a/src/boot/osloader/include/amd64/page.h b/src/boot/osloader/include/amd64/page.h index 3cb8a71..8a0bec7 100644 --- a/src/boot/osloader/include/amd64/page.h +++ b/src/boot/osloader/include/amd64/page.h @@ -6,22 +6,25 @@ #include -typedef struct __attribute__((packed)) { - uint64_t Present : 1; - uint64_t Writable : 1; - uint64_t User : 1; - uint64_t WriteThrough : 1; - uint64_t CacheDisable : 1; - uint64_t Accessed : 1; - uint64_t Dirty : 1; - uint64_t PageSize : 1; - uint64_t Global : 1; - uint64_t Available0 : 2; - uint64_t Pat : 1; - uint64_t Address : 40; - uint64_t Available1 : 7; - uint64_t ProtectionKey : 4; - uint64_t NoExecute : 1; +typedef union { + struct __attribute__((packed)) { + uint64_t Present : 1; + uint64_t Writable : 1; + uint64_t User : 1; + uint64_t WriteThrough : 1; + uint64_t CacheDisable : 1; + uint64_t Accessed : 1; + uint64_t Dirty : 1; + uint64_t PageSize : 1; + uint64_t Global : 1; + uint64_t Available0 : 2; + uint64_t Pat : 1; + uint64_t Address : 40; + uint64_t Available1 : 7; + uint64_t ProtectionKey : 4; + uint64_t NoExecute : 1; + }; + uint64_t RawData; } PageFrame; #endif /* _AMD64_PAGE_H_ */ diff --git a/src/kernel/hal/amd64/gdt.c b/src/kernel/hal/amd64/gdt.c index 2319e44..27c8dcf 100644 --- a/src/kernel/hal/amd64/gdt.c +++ b/src/kernel/hal/amd64/gdt.c @@ -5,6 +5,40 @@ extern void HalpFlushGdt(void); +/*------------------------------------------------------------------------------------------------- + * PURPOSE: + * This function initializes an entry inside the GDT. + * + * PARAMETERS: + * Processor - Pointer to the processor-specific structure. + * EntryOffset - Which entry to initialize. + * + * RETURN VALUE: + * None. + *-----------------------------------------------------------------------------------------------*/ +static void InitializeEntry( + KeProcessor *Processor, + uint8_t EntryOffset, + uint64_t Base, + uint32_t Limit, + uint8_t Type, + uint8_t Dpl) { + HalpGdtEntry *Entry = (HalpGdtEntry *)(Processor->GdtEntries + EntryOffset); + Entry->LimitLow = Limit & 0xFFFF; + Entry->BaseLow = Base & 0xFFFFFF; + Entry->Type = Type; + Entry->Dpl = Dpl; + Entry->Present = 1; + Entry->LimitHigh = (Limit >> 16) & 0x0F; + Entry->System = 0; + Entry->LongMode = 1; + Entry->DefaultBig = 0; + Entry->Granularity = 1; + Entry->BaseHigh = (Base >> 24) & 0xFF; + Entry->BaseUpper = (Base >> 32) & 0xFFFFFFFF; + Entry->MustBeZero = 0; +} + /*------------------------------------------------------------------------------------------------- * PURPOSE: * This function initializes the Global Descriptor Table. This, in combination with @@ -17,15 +51,23 @@ extern void HalpFlushGdt(void); * None. *-----------------------------------------------------------------------------------------------*/ void HalpInitializeGdt(KeProcessor *Processor) { - Processor->GdtEntries[0] = 0x0000000000000000; - Processor->GdtEntries[1] = 0x00AF9A000000FFFF; - Processor->GdtEntries[2] = 0x00AF92000000FFFF; - Processor->GdtEntries[3] = 0x00AFFA000000FFFF; - Processor->GdtEntries[4] = 0x00AFF2000000FFFF; + /* The NULL descriptor should have already been zeroed out during the processor block + * allocation. */ + InitializeEntry(Processor, GDT_ENTRY_KCODE, 0, 0xFFFFF, GDT_TYPE_CODE, GDT_DPL_KERNEL); + InitializeEntry(Processor, GDT_ENTRY_KDATA, 0, 0xFFFFF, GDT_TYPE_DATA, GDT_DPL_KERNEL); + InitializeEntry(Processor, GDT_ENTRY_UCODE, 0, 0xFFFFF, GDT_TYPE_CODE, GDT_DPL_USER); + InitializeEntry(Processor, GDT_ENTRY_UDATA, 0, 0xFFFFF, GDT_TYPE_DATA, GDT_DPL_USER); - Processor->GdtDescriptor.Limit = sizeof(Processor->GdtEntries) - 1; - Processor->GdtDescriptor.Base = (uint64_t)Processor->GdtEntries; + uint64_t TssBase = (uint64_t)&Processor->TssEntry; + uint16_t TssSize = sizeof(HalpTssEntry); + InitializeEntry(Processor, GDT_ENTRY_TSS, TssBase, TssSize, GDT_TYPE_TSS, GDT_DPL_KERNEL); + Processor->TssEntry.Rsp0 = (uint64_t)&Processor->SystemStack; + Processor->TssEntry.IoMapBase = TssSize; - __asm__ volatile("lgdt %0" : : "m"(Processor->GdtDescriptor)); + HalpGdtDescriptor Descriptor; + Descriptor.Limit = sizeof(Processor->GdtEntries) - 1; + Descriptor.Base = (uint64_t)Processor->GdtEntries; + __asm__ volatile("lgdt %0" : : "m"(Descriptor)); HalpFlushGdt(); + __asm__ volatile("mov $0x28, %%ax; ltr %%ax" : : : "%rax"); } diff --git a/src/kernel/include/public/amd64/gdt.h b/src/kernel/include/public/amd64/gdt.h new file mode 100644 index 0000000..4db01be --- /dev/null +++ b/src/kernel/include/public/amd64/gdt.h @@ -0,0 +1,63 @@ +/* SPDX-FileCopyrightText: (C) 2025 ilmmatias + * SPDX-License-Identifier: GPL-3.0-or-later */ + +#ifndef _AMD64_GDT_H_ +#define _AMD64_GDT_H_ + +#include + +#define GDT_ENTRY_NULL 0x00 +#define GDT_ENTRY_KCODE 0x08 +#define GDT_ENTRY_KDATA 0x10 +#define GDT_ENTRY_UCODE 0x18 +#define GDT_ENTRY_UDATA 0x20 +#define GDT_ENTRY_TSS 0x28 + +#define GDT_TYPE_TSS 0x09 +#define GDT_TYPE_CODE 0x1A +#define GDT_TYPE_DATA 0x12 + +#define GDT_DPL_KERNEL 0x00 +#define GDT_DPL_USER 0x03 + +typedef struct __attribute__((packed)) { + uint32_t Reserved0; + uint64_t Rsp0; + uint64_t Rsp1; + uint64_t Rsp2; + uint64_t Ist[8]; + uint64_t Reserved1; + uint16_t Reserved2; + uint16_t IoMapBase; +} HalpTssEntry; + +typedef union { + struct __attribute__((packed)) { + struct __attribute__((packed)) { + uint64_t LimitLow : 16; + uint64_t BaseLow : 24; + uint64_t Type : 5; + uint64_t Dpl : 2; + uint64_t Present : 1; + uint64_t LimitHigh : 4; + uint64_t System : 1; + uint64_t LongMode : 1; + uint64_t DefaultBig : 1; + uint64_t Granularity : 1; + uint64_t BaseHigh : 8; + }; + uint32_t BaseUpper; + uint32_t MustBeZero; + }; + struct __attribute__((packed)) { + uint64_t DataLow; + uint64_t DataHigh; + }; +} HalpGdtEntry; + +typedef struct __attribute__((packed)) { + uint16_t Limit; + uint64_t Base; +} HalpGdtDescriptor; + +#endif /* _AMD64_GDT_H_ */ diff --git a/src/kernel/include/public/amd64/processor.h b/src/kernel/include/public/amd64/processor.h index 293380d..6ed9af8 100644 --- a/src/kernel/include/public/amd64/processor.h +++ b/src/kernel/include/public/amd64/processor.h @@ -4,6 +4,7 @@ #ifndef _AMD64_PROCESSOR_H_ #define _AMD64_PROCESSOR_H_ +#include #include #include @@ -20,11 +21,8 @@ typedef struct { RtDList DpcQueue; RtDList EventQueue; char SystemStack[8192] __attribute__((aligned(4096))); - uint64_t GdtEntries[5]; - struct __attribute__((packed)) __attribute__((aligned(4))) { - uint16_t Limit; - uint64_t Base; - } GdtDescriptor; + char GdtEntries[56]; + HalpTssEntry TssEntry; struct __attribute__((packed)) { uint16_t BaseLow; uint16_t Cs;