From 7bf4a9ab8d82c91d1d3433d9f15bcc8c0ebf7f2e Mon Sep 17 00:00:00 2001 From: belliash Date: Sun, 29 Jan 2023 00:45:17 +0100 Subject: [PATCH] Initialize boot CPU structures inside kernel on AMD64 --- sdk/xtdk/amd64/arfuncs.h | 4 + sdk/xtdk/amd64/artypes.h | 4 + xtoskrnl/CMakeLists.txt | 2 + xtoskrnl/ar/amd64/globals.c | 19 ++++ xtoskrnl/ar/amd64/procsup.c | 196 +++++++++++++++++++++++++++++++++++ xtoskrnl/includes/arpfuncs.h | 34 ++++++ xtoskrnl/includes/globals.h | 9 ++ xtoskrnl/includes/xtos.h | 1 + xtoskrnl/ke/krnlinit.c | 3 + 9 files changed, 272 insertions(+) create mode 100644 xtoskrnl/ar/amd64/globals.c create mode 100644 xtoskrnl/ar/amd64/procsup.c create mode 100644 xtoskrnl/includes/arpfuncs.h diff --git a/sdk/xtdk/amd64/arfuncs.h b/sdk/xtdk/amd64/arfuncs.h index 12b8f88..314d396 100644 --- a/sdk/xtdk/amd64/arfuncs.h +++ b/sdk/xtdk/amd64/arfuncs.h @@ -28,6 +28,10 @@ XTCDECL VOID ArHalt(); +XTAPI +VOID +ArInitializeProcessor(VOID); + XTCDECL VOID ArInvalidateTlbEntry(IN PVOID Address); diff --git a/sdk/xtdk/amd64/artypes.h b/sdk/xtdk/amd64/artypes.h index ebb81b0..b95c1fd 100644 --- a/sdk/xtdk/amd64/artypes.h +++ b/sdk/xtdk/amd64/artypes.h @@ -46,6 +46,10 @@ #define CR4_XSAVE 0x00020000 #define CR4_RESERVED3 0xFFFC0000 +/* Descriptors size */ +#define GDT_ENTRIES 128 +#define IDT_ENTRIES 256 + /* Initial MXCSR control */ #define INITIAL_MXCSR 0x1F80 diff --git a/xtoskrnl/CMakeLists.txt b/xtoskrnl/CMakeLists.txt index 1896a8d..90a0cfe 100644 --- a/xtoskrnl/CMakeLists.txt +++ b/xtoskrnl/CMakeLists.txt @@ -9,6 +9,8 @@ include_directories( # Specify list of source code files list(APPEND XTOSKRNL_SOURCE ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.c + ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/globals.c + ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/procsup.c ${XTOSKRNL_SOURCE_DIR}/hl/cport.c ${XTOSKRNL_SOURCE_DIR}/hl/efifb.c ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/ioport.c diff --git a/xtoskrnl/ar/amd64/globals.c b/xtoskrnl/ar/amd64/globals.c new file mode 100644 index 0000000..c801e90 --- /dev/null +++ b/xtoskrnl/ar/amd64/globals.c @@ -0,0 +1,19 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/ar/amd64/procsup.c + * DESCRIPTION: AMD64 processor functionality support + * DEVELOPERS: Rafal Kupiec + */ + +#include "xtos.h" + + +/* Initial GDT */ +KGDTENTRY ArInitialGdt[GDT_ENTRIES] = {0}; + +/* Initial IDT */ +KIDTENTRY ArInitialIdt[IDT_ENTRIES] = {0}; + +/* Initial TSS */ +KTSS ArInitialTss; diff --git a/xtoskrnl/ar/amd64/procsup.c b/xtoskrnl/ar/amd64/procsup.c new file mode 100644 index 0000000..969bdab --- /dev/null +++ b/xtoskrnl/ar/amd64/procsup.c @@ -0,0 +1,196 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/ar/amd64/procsup.c + * DESCRIPTION: AMD64 processor functionality support + * DEVELOPERS: Rafal Kupiec + */ + +#include "xtos.h" + + +/** + * Initializes AMD64 processor specific structures. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +ArInitializeProcessor(VOID) +{ + PKGDTENTRY Gdt; + PKTSS Tss; + KDESCRIPTOR GdtDescriptor; + + /* Use initial structures */ + Gdt = ArInitialGdt; + Tss = &ArInitialTss; + + /* Initialize GDT and TSS */ + ArpInitializeGdt(Gdt); + ArpInitializeTss(Tss, Gdt); + + /* Set GDT descriptor */ + GdtDescriptor.Base = Gdt; + GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(PKGDTENTRY)) - 1; + + /* Load GDT and TSS */ + ArLoadGlobalDescriptorTable(&GdtDescriptor.Limit); + ArLoadTaskRegister((UINT32)KGDT_SYS_TSS); +} + +/** + * Initializes the kernel's Global Descriptor Table (GDT). + * + * @param Gdt + * Supplies a pointer to the GDT to use. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +ArpInitializeGdt(IN PKGDTENTRY Gdt) +{ + /* Initialize GDT entries */ + ArpInitializeGdtEntry(Gdt, KGDT_NULL, 0x0, 0x0, 0, KGDT_DPL_SYSTEM, 0); + ArpInitializeGdtEntry(Gdt, KGDT_R0_CODE, 0x0, 0x0, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0); + ArpInitializeGdtEntry(Gdt, KGDT_R0_DATA, 0x0, 0x0, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0); + ArpInitializeGdtEntry(Gdt, KGDT_R3_CODE, 0x0, 0x0, KGDT_TYPE_CODE, KGDT_DPL_USER, 0); + ArpInitializeGdtEntry(Gdt, KGDT_R3_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2); + ArpInitializeGdtEntry(Gdt, KGDT_R3_CMCODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_USER, 2); + ArpInitializeGdtEntry(Gdt, KGDT_R3_CMTEB, 0x0, 0x0FFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2); + ArpInitializeGdtEntry(Gdt, KGDT_R0_LDT, 0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0); + ArpInitializeGdtEntry(Gdt, KGDT_SYS_TSS, 0, sizeof(KTSS), AMD64_TSS, KGDT_DPL_SYSTEM, 0); +} + +/** + * Fills in an AMD64 GDT entry. + * + * @param Gdt + * Supplies a pointer to the GDT. + * + * @param Selector + * Specifies a segment selector of the GDT entry. + * + * @param Base + * Specifies a base address value of the descriptor. + * + * @param Limit + * Specifies a descriptor limit. + * + * @param Type + * Specifies a type of the descriptor. + * + * @param Dpl + * Specifies the descriptor privilege level. + * + * @param SegmentMode + * Specifies a segment mode of the descriptor. + * + * @return This routine does not return any value + * + * @since XT 1.0 + */ +XTAPI +VOID +ArpInitializeGdtEntry(IN PKGDTENTRY Gdt, + IN USHORT Selector, + IN ULONGLONG Base, + IN ULONG Limit, + IN UCHAR Type, + IN UCHAR Dpl, + IN UCHAR SegmentMode) +{ + PKGDTENTRY GdtEntry; + UCHAR Granularity; + + /* Set the granularity flag depending on descriptor limit */ + if(Limit < 0x100000) + { + /* Limit is in 1B blocks */ + Granularity = 0; + } + else + { + /* Limit is in 4KB blocks */ + Granularity = 1; + Limit >>= 12; + } + + /* Get GDT entry */ + GdtEntry = (PKGDTENTRY)((ULONG64)Gdt + (Selector & ~RPL_MASK)); + + /* Set GDT descriptor base */ + GdtEntry->BaseLow = Base & 0xFFFF; + GdtEntry->Bits.BaseMiddle = (Base >> 16) & 0xFF; + GdtEntry->Bits.BaseHigh = (Base >> 24) & 0xFF; + GdtEntry->BaseUpper = Base >> 32; + + /* Set descriptor limit */ + GdtEntry->LimitLow = Limit & 0xFFFF; + GdtEntry->Bits.LimitHigh = (Limit >> 16) & 0xF; + + /* Initialize GDT entry */ + GdtEntry->Bits.DefaultBig = (SegmentMode & 2); + GdtEntry->Bits.Dpl = (Dpl & 0x3); + GdtEntry->Bits.Granularity = Granularity; + GdtEntry->Bits.LongMode = (SegmentMode & 1); + GdtEntry->Bits.Present = (Type != 0); + GdtEntry->Bits.System = 0; + GdtEntry->Bits.Type = (Type & 0x1F); + GdtEntry->MustBeZero = 0; +} + +/** + * Initializes the kernel's Task State Segment (TSS). + * + * @param Tss + * Supplies a pointer to the TSS to use. + * + * @param Gdt + * Supplies a pointer to the GDT to use. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +ArpInitializeTss(IN PKTSS Tss, + IN PKGDTENTRY Gdt) +{ + PKGDTENTRY TssEntry; + + /* Get TSS entry from GDT */ + TssEntry = (PKGDTENTRY)(&(Gdt[KGDT_SYS_TSS / sizeof(KGDTENTRY)])); + + /* Initialize TSS entry */ + TssEntry->BaseLow = (ULONG64)Tss & 0xFFFF; + TssEntry->BaseUpper = (ULONG64)Tss >> 32; + TssEntry->LimitLow = (sizeof(KTSS) - 1) & 0xFFFF; + TssEntry->Bits.BaseMiddle = ((ULONG64)Tss >> 16) & 0xFF; + TssEntry->Bits.BaseHigh = ((ULONG64)Tss >> 24) & 0xFF; + TssEntry->Bits.LimitHigh = (sizeof(KTSS) - 1) >> 16; + TssEntry->Bits.DefaultBig = 0; + TssEntry->Bits.Dpl = 0; + TssEntry->Bits.Granularity = 0; + TssEntry->Bits.LongMode = 0; + TssEntry->Bits.Present = 1; + TssEntry->Bits.System = 0; + TssEntry->Bits.Type = AMD64_TSS; + TssEntry->MustBeZero = 0; + + /* Fill TSS with zeroes */ + RtlZeroMemory(Tss, sizeof(KTSS)); + + /* Setup I/O map and stacks for ring0 & traps */ + Tss->IoMapBase = sizeof(KTSS); + Tss->Rsp0 = KeInitializationBlock->KernelBootStack; + Tss->Ist[1] = KeInitializationBlock->KernelFaultStack; + Tss->Ist[2] = KeInitializationBlock->KernelFaultStack; + Tss->Ist[3] = KeInitializationBlock->KernelFaultStack; +} diff --git a/xtoskrnl/includes/arpfuncs.h b/xtoskrnl/includes/arpfuncs.h new file mode 100644 index 0000000..9522bd6 --- /dev/null +++ b/xtoskrnl/includes/arpfuncs.h @@ -0,0 +1,34 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/arpfuncs.h + * DESCRIPTION: Private routine definitions for architecture library + * DEVELOPERS: Rafal Kupiec + */ + +#ifndef __XTOSKRNL_ARPFUNCS_H +#define __XTOSKRNL_ARPFUNCS_H + +#include + + +XTAPI +VOID +ArpInitializeGdt(IN PKGDTENTRY Gdt); + +XTAPI +VOID +ArpInitializeGdtEntry(IN PKGDTENTRY Gdt, + IN USHORT Selector, + IN ULONGLONG Base, + IN ULONG Limit, + IN UCHAR Type, + IN UCHAR Dpl, + IN UCHAR SegmentMode); + +XTAPI +VOID +ArpInitializeTss(IN PKTSS Tss, + IN PKGDTENTRY Gdt); + +#endif /* __XTOSKRNL_ARPFUNCS_H */ diff --git a/xtoskrnl/includes/globals.h b/xtoskrnl/includes/globals.h index 90503f2..7f3b5d8 100644 --- a/xtoskrnl/includes/globals.h +++ b/xtoskrnl/includes/globals.h @@ -12,6 +12,15 @@ #include +/* Initial GDT */ +EXTERN KGDTENTRY ArInitialGdt[GDT_ENTRIES]; + +/* Initial IDT */ +EXTERN KIDTENTRY ArInitialIdt[IDT_ENTRIES]; + +/* Initial TSS */ +EXTERN KTSS ArInitialTss; + /* FrameBuffer information */ EXTERN HAL_FRAMEBUFFER_DATA HlpFrameBufferData; diff --git a/xtoskrnl/includes/xtos.h b/xtoskrnl/includes/xtos.h index cf39494..5b00abb 100644 --- a/xtoskrnl/includes/xtos.h +++ b/xtoskrnl/includes/xtos.h @@ -11,4 +11,5 @@ /* Kernel specific headers */ #include "globals.h" +#include "arpfuncs.h" #include "kepfuncs.h" diff --git a/xtoskrnl/ke/krnlinit.c b/xtoskrnl/ke/krnlinit.c index ba951df..0928d87 100644 --- a/xtoskrnl/ke/krnlinit.c +++ b/xtoskrnl/ke/krnlinit.c @@ -49,6 +49,9 @@ KeStartXtSystem(IN PKERNEL_INITIALIZATION_BLOCK Parameters) /* Initialize kernel stacks */ KepInitializeStack(Parameters); + /* Initialize boot CPU */ + ArInitializeProcessor(); + /* Architecture specific initialization */ KepArchInitialize();