From 6f068513cd1fb6ca549401b1f1d8b738d90b003b Mon Sep 17 00:00:00 2001 From: belliash Date: Mon, 30 Jan 2023 19:07:05 +0100 Subject: [PATCH] Initial processor block initialization --- sdk/xtdk/amd64/ketypes.h | 73 +++++++++ sdk/xtdk/amd64/xtstruct.h | 4 + sdk/xtdk/i686/ketypes.h | 53 +++++++ sdk/xtdk/i686/xtstruct.h | 4 + xtoskrnl/ar/amd64/globals.c | 3 + xtoskrnl/ar/amd64/procsup.c | 225 ++++++++++++++++++--------- xtoskrnl/ar/i686/globals.c | 3 + xtoskrnl/ar/i686/procsup.c | 242 +++++++++++++++++++----------- xtoskrnl/includes/amd64/globals.h | 3 + xtoskrnl/includes/arpfuncs.h | 27 ++-- xtoskrnl/includes/i686/globals.h | 3 + 11 files changed, 469 insertions(+), 171 deletions(-) diff --git a/sdk/xtdk/amd64/ketypes.h b/sdk/xtdk/amd64/ketypes.h index 15bf7c2..babdf24 100644 --- a/sdk/xtdk/amd64/ketypes.h +++ b/sdk/xtdk/amd64/ketypes.h @@ -10,7 +10,9 @@ #define __XTDK_AMD64_KETYPES_H #include +#include #include +#include ARCH_HEADER(xtstruct.h) /* Selector masks */ @@ -41,6 +43,7 @@ #define KGDT_DESCRIPTOR_CODE 0x08 /* GDT descriptor type codes */ +#define KGDT_TYPE_NONE 0x0 #define KGDT_TYPE_CODE (0x10 | KGDT_DESCRIPTOR_CODE | KGDT_DESCRIPTOR_EXECUTE_READ) #define KGDT_TYPE_DATA (0x10 | KGDT_DESCRIPTOR_READ_WRITE) @@ -387,4 +390,74 @@ typedef struct _KTRAP_FRAME ULONG CodePatchCycle; } KTRAP_FRAME, *PKTRAP_FRAME; +/* Special kernel registers structure definition */ +typedef struct _KSPECIAL_REGISTERS +{ + ULONG64 Cr0; + ULONG64 Cr2; + ULONG64 Cr3; + ULONG64 Cr4; + ULONG64 KernelDr0; + ULONG64 KernelDr1; + ULONG64 KernelDr2; + ULONG64 KernelDr3; + ULONG64 KernelDr6; + ULONG64 KernelDr7; + KDESCRIPTOR Gdtr; + KDESCRIPTOR Idtr; + USHORT Tr; + USHORT Ldtr; + ULONG MxCsr; + ULONG64 DebugControl; + ULONG64 LastBranchToRip; + ULONG64 LastBranchFromRip; + ULONG64 LastExceptionToRip; + ULONG64 LastExceptionFromRip; + ULONG64 Cr8; + ULONG64 MsrGsBase; + ULONG64 MsrGsSwap; + ULONG64 MsrStar; + ULONG64 MsrLStar; + ULONG64 MsrCStar; + ULONG64 MsrSyscallMask; +} KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS; + +/* Processor state frame structure definition */ +typedef struct _KPROCESSOR_STATE +{ + KSPECIAL_REGISTERS SpecialRegisters; + CONTEXT ContextFrame; +} KPROCESSOR_STATE, *PKPROCESSOR_STATE; + +/* Processor Control Block (PRCB) structure definition */ +typedef struct _KPROCESSOR_CONTROL_BLOCK +{ + ULONG MxCsr; + UCHAR Number; + ULONG64 RspBase; + ULONG_PTR SetMember; // KAFFINITY + KPROCESSOR_STATE ProcessorState; + PVOID DpcStack; + ULONG_PTR MultiThreadProcessorSet; // KAFFINITY +} KPROCESSOR_CONTROL_BLOCK, *PKPROCESSOR_CONTROL_BLOCK; + +/* Processor Block structure definition */ +typedef struct _KPROCESSOR_BLOCK +{ + union + { + struct + { + PKGDTENTRY GdtBase; + PKTSS TssBase; + PKPROCESSOR_BLOCK Self; + PKPROCESSOR_CONTROL_BLOCK CurrentPrcb; + + }; + }; + PKIDTENTRY IdtBase; + KIRQL Irql; + KPROCESSOR_CONTROL_BLOCK Prcb; +} KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK; + #endif /* __XTDK_AMD64_KETYPES_H */ diff --git a/sdk/xtdk/amd64/xtstruct.h b/sdk/xtdk/amd64/xtstruct.h index 3814624..43ec0e2 100644 --- a/sdk/xtdk/amd64/xtstruct.h +++ b/sdk/xtdk/amd64/xtstruct.h @@ -25,6 +25,10 @@ typedef struct _KDESCRIPTOR KDESCRIPTOR, *PKDESCRIPTOR; typedef struct _KEXCEPTION_FRAME KEXCEPTION_FRAME, *PKEXCEPTION_FRAME; typedef struct _KGDTENTRY KGDTENTRY, *PKGDTENTRY; typedef struct _KIDTENTRY KIDTENTRY, *PKIDTENTRY; +typedef struct _KPROCESSOR_BLOCK KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK; +typedef struct _KPROCESSOR_CONTROL_BLOCK KPROCESSOR_CONTROL_BLOCK, *PKPROCESSOR_CONTROL_BLOCK; +typedef struct _KPROCESSOR_STATE KPROCESSOR_STATE, *PKPROCESSOR_STATE; +typedef struct _KSPECIAL_REGISTERS KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS; typedef struct _KSWITCH_FRAME KSWITCH_FRAME, *PKSWITCH_FRAME; typedef struct _KTRAP_FRAME KTRAP_FRAME, *PKTRAP_FRAME; typedef struct _KTSS KTSS, *PKTSS; diff --git a/sdk/xtdk/i686/ketypes.h b/sdk/xtdk/i686/ketypes.h index d63f071..dbd6e7b 100644 --- a/sdk/xtdk/i686/ketypes.h +++ b/sdk/xtdk/i686/ketypes.h @@ -9,8 +9,10 @@ #ifndef __XTDK_I686_KETYPES_H #define __XTDK_I686_KETYPES_H +#include #include #include +#include ARCH_HEADER(xtstruct.h) /* Selector masks */ @@ -30,6 +32,7 @@ #define KGDT_R0_LDT 0x0048 #define KGDT_DF_TSS 0x0050 #define KGDT_NMI_TSS 0x0058 +#define KGDT_VDBS 0x0068 /* GDT descriptor privilege levels */ #define KGDT_DPL_SYSTEM 0 @@ -44,6 +47,7 @@ #define KGDT_DESCRIPTOR_CODE 0x08 /* GDT descriptor type codes */ +#define KGDT_TYPE_NONE 0x0 #define KGDT_TYPE_CODE (0x10 | KGDT_DESCRIPTOR_CODE | KGDT_DESCRIPTOR_EXECUTE_READ) #define KGDT_TYPE_DATA (0x10 | KGDT_DESCRIPTOR_READ_WRITE) @@ -279,4 +283,53 @@ typedef struct _KTRAP_FRAME ULONG V86Gs; } KTRAP_FRAME, *PKTRAP_FRAME; +/* Special kernel registers structure definition */ +typedef struct _KSPECIAL_REGISTERS +{ + ULONG Cr0; + ULONG Cr2; + ULONG Cr3; + ULONG Cr4; + ULONG KernelDr0; + ULONG KernelDr1; + ULONG KernelDr2; + ULONG KernelDr3; + ULONG KernelDr6; + ULONG KernelDr7; + KDESCRIPTOR Gdtr; + KDESCRIPTOR Idtr; + USHORT Tr; + USHORT Ldtr; + ULONG Reserved[6]; +} KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS; + +/* Processor state frame structure definition */ +typedef struct _KPROCESSOR_STATE +{ + CONTEXT ContextFrame; + KSPECIAL_REGISTERS SpecialRegisters; +} KPROCESSOR_STATE, *PKPROCESSOR_STATE; + +/* Processor Control Block (PRCB) structure definition */ +typedef struct _KPROCESSOR_CONTROL_BLOCK +{ + UCHAR Number; + ULONG_PTR SetMember; + KPROCESSOR_STATE ProcessorState; + ULONG_PTR MultiThreadProcessorSet; + PVOID DpcStack; +} KPROCESSOR_CONTROL_BLOCK, *PKPROCESSOR_CONTROL_BLOCK; + +/* Processor Block structure definition */ +typedef struct _KPROCESSOR_BLOCK +{ + PKPROCESSOR_BLOCK Self; + PKPROCESSOR_CONTROL_BLOCK CurrentPrcb; + KIRQL Irql; + PKIDTENTRY IdtBase; + PKGDTENTRY GdtBase; + PKTSS TssBase; + KPROCESSOR_CONTROL_BLOCK Prcb; +} KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK; + #endif /* __XTDK_I686_KETYPES_H */ diff --git a/sdk/xtdk/i686/xtstruct.h b/sdk/xtdk/i686/xtstruct.h index 7702a45..61fee73 100644 --- a/sdk/xtdk/i686/xtstruct.h +++ b/sdk/xtdk/i686/xtstruct.h @@ -27,6 +27,10 @@ typedef struct _KEXCEPTION_FRAME KEXCEPTION_FRAME, *PKEXCEPTION_FRAME; typedef struct _KGDTENTRY KGDTENTRY, *PKGDTENTRY; typedef struct _KIDTENTRY KIDTENTRY, *PKIDTENTRY; typedef struct _KIIO_ACCESS_MAP KIIO_ACCESS_MAP, *PKIIO_ACCESS_MAP; +typedef struct _KPROCESSOR_BLOCK KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK; +typedef struct _KPROCESSOR_CONTROL_BLOCK KPROCESSOR_CONTROL_BLOCK, *PKPROCESSOR_CONTROL_BLOCK; +typedef struct _KPROCESSOR_STATE KPROCESSOR_STATE, *PKPROCESSOR_STATE; +typedef struct _KSPECIAL_REGISTERS KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS; typedef struct _KTRAP_FRAME KTRAP_FRAME, *PKTRAP_FRAME; typedef struct _KTSS KTSS, *PKTSS; diff --git a/xtoskrnl/ar/amd64/globals.c b/xtoskrnl/ar/amd64/globals.c index 4a070a7..9e902ca 100644 --- a/xtoskrnl/ar/amd64/globals.c +++ b/xtoskrnl/ar/amd64/globals.c @@ -15,5 +15,8 @@ KGDTENTRY ArInitialGdt[GDT_ENTRIES] = {0}; /* Initial IDT */ KIDTENTRY ArInitialIdt[IDT_ENTRIES] = {0}; +/* Initial Processor Block */ +KPROCESSOR_BLOCK ArInitialProcessorBlock; + /* Initial TSS */ KTSS ArInitialTss; diff --git a/xtoskrnl/ar/amd64/procsup.c b/xtoskrnl/ar/amd64/procsup.c index 969bdab..7172011 100644 --- a/xtoskrnl/ar/amd64/procsup.c +++ b/xtoskrnl/ar/amd64/procsup.c @@ -20,25 +20,45 @@ XTAPI VOID ArInitializeProcessor(VOID) { + KDESCRIPTOR GdtDescriptor, IdtDescriptor; + PKPROCESSOR_BLOCK ProcessorBlock; PKGDTENTRY Gdt; + PKIDTENTRY Idt; PKTSS Tss; - KDESCRIPTOR GdtDescriptor; /* Use initial structures */ Gdt = ArInitialGdt; + Idt = ArInitialIdt; Tss = &ArInitialTss; - /* Initialize GDT and TSS */ - ArpInitializeGdt(Gdt); - ArpInitializeTss(Tss, Gdt); + /* Load processor block */ + ProcessorBlock = CONTAIN_RECORD(&ArInitialProcessorBlock.Prcb, KPROCESSOR_BLOCK, Prcb); - /* Set GDT descriptor */ + /* Initialize processor block */ + ArpInitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, (PVOID)KeInitializationBlock->KernelFaultStack); + + /* Initialize GDT and TSS */ + ArpInitializeGdt(ProcessorBlock); + ArpInitializeTss(ProcessorBlock); + + /* Set GDT and IDT descriptors */ GdtDescriptor.Base = Gdt; GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(PKGDTENTRY)) - 1; + IdtDescriptor.Base = Idt; + IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(PKIDTENTRY)) - 1; - /* Load GDT and TSS */ + /* Load GDT, IDT and TSS */ ArLoadGlobalDescriptorTable(&GdtDescriptor.Limit); - ArLoadTaskRegister((UINT32)KGDT_SYS_TSS); + ArLoadInterruptDescriptorTable(&IdtDescriptor.Limit); + ArLoadTaskRegister((UINT)KGDT_SYS_TSS); + + /* Set GS base */ + ArWriteModelSpecificRegister(X86_MSR_GSBASE, (ULONGLONG)ProcessorBlock); + ArWriteModelSpecificRegister(X86_MSR_KERNEL_GSBASE, (ULONGLONG)ProcessorBlock); + + /* Enter passive IRQ level */ + ProcessorBlock->Irql = PASSIVE_LEVEL; + ArWriteControlRegister(8, PASSIVE_LEVEL); } /** @@ -53,18 +73,123 @@ ArInitializeProcessor(VOID) */ XTAPI VOID -ArpInitializeGdt(IN PKGDTENTRY Gdt) +ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock) { /* 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); + ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0); + ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_CODE, 0x0, 0x0, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0); + ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_DATA, 0x0, 0x0, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0); + ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CODE, 0x0, 0x0, KGDT_TYPE_CODE, KGDT_DPL_USER, 0); + ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2); + ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CMCODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_USER, 2); + ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CMTEB, 0x0, 0x0FFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2); + ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0); + ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_SYS_TSS, (ULONGLONG)ProcessorBlock->TssBase, sizeof(KTSS), AMD64_TSS, KGDT_DPL_SYSTEM, 0); +} + +/** + * Initializes processor block. + * + * @param ProcessorBlock + * Supplies a pointer to the processor block to initialize. + * + * @param Gdt + * Supplies a pointer to the GDT for this processor block. + * + * @param Idt + * Supplies a pointer to the IDT for this processor block. + * + * @param Tss + * Supplies a pointer to the TSS for this processor block. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, + IN PKGDTENTRY Gdt, + IN PKIDTENTRY Idt, + IN PKTSS Tss, + IN PVOID DpcStack) +{ + /* Fill processor block with zeroes */ + RtlZeroMemory(ProcessorBlock, sizeof(KPROCESSOR_BLOCK)); + + /* Set processor block and processor control block */ + ProcessorBlock->Self = ProcessorBlock; + ProcessorBlock->CurrentPrcb = &ProcessorBlock->Prcb; + + /* Set GDT, IDT and TSS descriptors */ + ProcessorBlock->GdtBase = (PVOID)Gdt; + ProcessorBlock->IdtBase = Idt; + ProcessorBlock->TssBase = Tss; + ProcessorBlock->Prcb.RspBase = Tss->Rsp0; + + /* Setup DPC stack */ + ProcessorBlock->Prcb.DpcStack = DpcStack; + + /* Setup processor control block */ + ProcessorBlock->Prcb.Number = 0; + ProcessorBlock->Prcb.SetMember = 1ULL; + ProcessorBlock->Prcb.MultiThreadProcessorSet = 1ULL; + + /* Clear DR6 and DR7 registers */ + ProcessorBlock->Prcb.ProcessorState.SpecialRegisters.KernelDr6 = 0; + ProcessorBlock->Prcb.ProcessorState.SpecialRegisters.KernelDr7 = 0; + + /* Set initial MXCSR register value */ + ProcessorBlock->Prcb.MxCsr = INITIAL_MXCSR; +} + +/** + * 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 PKPROCESSOR_BLOCK ProcessorBlock) +{ + PKGDTENTRY TssEntry; + + /* Get TSS entry from GDT */ + TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_SYS_TSS / sizeof(KGDTENTRY)])); + + /* Initialize TSS entry */ + TssEntry->BaseLow = (ULONGLONG)ProcessorBlock->TssBase & 0xFFFF; + TssEntry->BaseUpper = (ULONGLONG)ProcessorBlock->TssBase >> 32; + TssEntry->LimitLow = (sizeof(KTSS) - 1) & 0xFFFF; + TssEntry->Bits.BaseMiddle = ((ULONGLONG)ProcessorBlock->TssBase >> 16) & 0xFF; + TssEntry->Bits.BaseHigh = ((ULONGLONG)ProcessorBlock->TssBase >> 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(ProcessorBlock->TssBase, sizeof(KTSS)); + + /* Setup I/O map and stacks for ring0 & traps */ + ProcessorBlock->TssBase->IoMapBase = sizeof(KTSS); + ProcessorBlock->TssBase->Rsp0 = KeInitializationBlock->KernelBootStack; + ProcessorBlock->TssBase->Ist[1] = KeInitializationBlock->KernelFaultStack; + ProcessorBlock->TssBase->Ist[2] = KeInitializationBlock->KernelFaultStack; + ProcessorBlock->TssBase->Ist[3] = KeInitializationBlock->KernelFaultStack; } /** @@ -97,13 +222,13 @@ 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) +ArpSetGdtEntry(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; @@ -122,7 +247,7 @@ ArpInitializeGdtEntry(IN PKGDTENTRY Gdt, } /* Get GDT entry */ - GdtEntry = (PKGDTENTRY)((ULONG64)Gdt + (Selector & ~RPL_MASK)); + GdtEntry = (PKGDTENTRY)((ULONGLONG)Gdt + (Selector & ~RPL_MASK)); /* Set GDT descriptor base */ GdtEntry->BaseLow = Base & 0xFFFF; @@ -144,53 +269,3 @@ ArpInitializeGdtEntry(IN PKGDTENTRY Gdt, 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/ar/i686/globals.c b/xtoskrnl/ar/i686/globals.c index 963fb5d..0e0e73b 100644 --- a/xtoskrnl/ar/i686/globals.c +++ b/xtoskrnl/ar/i686/globals.c @@ -15,5 +15,8 @@ KGDTENTRY ArInitialGdt[GDT_ENTRIES] = {0}; /* Initial IDT */ KIDTENTRY ArInitialIdt[IDT_ENTRIES] = {0}; +/* Initial Processor Block */ +KPROCESSOR_BLOCK ArInitialProcessorBlock; + /* Initial TSS */ KTSS ArInitialTss; diff --git a/xtoskrnl/ar/i686/procsup.c b/xtoskrnl/ar/i686/procsup.c index 5e69328..9f65861 100644 --- a/xtoskrnl/ar/i686/procsup.c +++ b/xtoskrnl/ar/i686/procsup.c @@ -20,25 +20,43 @@ XTAPI VOID ArInitializeProcessor(VOID) { + KDESCRIPTOR GdtDescriptor, IdtDescriptor; + PKPROCESSOR_BLOCK ProcessorBlock; PKGDTENTRY Gdt; + PKIDTENTRY Idt; PKTSS Tss; - KDESCRIPTOR GdtDescriptor; /* Use initial structures */ Gdt = ArInitialGdt; + Idt = ArInitialIdt; Tss = &ArInitialTss; - /* Initialize GDT and TSS */ - ArpInitializeGdt(Gdt); - ArpInitializeTss(Tss, Gdt); + /* Load processor block */ + ProcessorBlock = CONTAIN_RECORD(&ArInitialProcessorBlock.Prcb, KPROCESSOR_BLOCK, Prcb); - /* Set GDT descriptor */ + /* Initialize processor block */ + ArpInitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, (PVOID)KeInitializationBlock->KernelFaultStack); + + /* Initialize GDT and TSS */ + ArpInitializeGdt(ProcessorBlock); + ArpInitializeTss(ProcessorBlock); + + /* Set GDT and IDT descriptors */ GdtDescriptor.Base = Gdt; GdtDescriptor.Limit = (GDT_ENTRIES * sizeof(PKGDTENTRY)) - 1; + IdtDescriptor.Base = Idt; + IdtDescriptor.Limit = (IDT_ENTRIES * sizeof(PKIDTENTRY)) - 1; - /* Load GDT and TSS */ + /* Load GDT, IDT and TSS */ ArLoadGlobalDescriptorTable(&GdtDescriptor.Limit); - ArLoadTaskRegister((UINT32)KGDT_SYS_TSS); + ArLoadInterruptDescriptorTable(&IdtDescriptor.Limit); + ArLoadTaskRegister((UINT)KGDT_SYS_TSS); + + /* Load FS segment */ + ArLoadSegment(SEGMENT_FS, KGDT_R0_PCR); + + /* Enter passive IRQ level */ + ProcessorBlock->Irql = PASSIVE_LEVEL; } /** @@ -53,21 +71,131 @@ ArInitializeProcessor(VOID) */ XTAPI VOID -ArpInitializeGdt(IN PKGDTENTRY Gdt) +ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock) { /* Initialize GDT entries */ - ArpInitializeGdtEntry(Gdt, KGDT_NULL, 0x0, 0x0, 0, KGDT_DPL_SYSTEM, 0); - ArpInitializeGdtEntry(Gdt, KGDT_R0_CODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 2); - ArpInitializeGdtEntry(Gdt, KGDT_R0_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2); - ArpInitializeGdtEntry(Gdt, KGDT_R3_CODE, 0x0, 0xFFFFFFFF, KGDT_TYPE_CODE, KGDT_DPL_USER, 2); - ArpInitializeGdtEntry(Gdt, KGDT_R3_DATA, 0x0, 0xFFFFFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2); - ArpInitializeGdtEntry(Gdt, KGDT_R3_TEB, 0x0, 0xFFF, KGDT_TYPE_DATA | KGDT_DESCRIPTOR_ACCESSED, KGDT_DPL_USER, 2); - ArpInitializeGdtEntry(Gdt, KGDT_R0_LDT, 0x0, 0x0, 0, KGDT_DPL_SYSTEM, 0); - ArpInitializeGdtEntry(Gdt, KGDT_VDM_TILE, 0x0400, 0xFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 0); - ArpInitializeGdtEntry(Gdt, KGDT_R0_PCR, 0x0, 0x1, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2); - ArpInitializeGdtEntry(Gdt, KGDT_SYS_TSS, 0x0, sizeof(KTSS) - 1, I686_TSS, KGDT_DPL_SYSTEM, 0); - ArpInitializeGdtEntry(Gdt, KGDT_DF_TSS, 0x20000, 0xFFFF, I686_TSS, KGDT_DPL_SYSTEM, 0); - ArpInitializeGdtEntry(Gdt, KGDT_NMI_TSS, 0x20000, 0xFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0); + ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_NULL, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0); + ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_CODE, 0x0, 0xFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 2); + ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_DATA, 0x0, 0xFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2); + ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_CODE, 0x0, 0xFF, KGDT_TYPE_CODE, KGDT_DPL_USER, 2); + ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_DATA, 0x0, 0xFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 2); + ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R3_TEB, 0x0, 0xFFF, KGDT_TYPE_DATA | KGDT_DESCRIPTOR_ACCESSED, KGDT_DPL_USER, 2); + ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_LDT, 0x0, 0x0, KGDT_TYPE_NONE, KGDT_DPL_SYSTEM, 0); + ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDM_TILE, 0x0400, 0xFFFF, KGDT_TYPE_DATA, KGDT_DPL_USER, 0); + ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_R0_PCR, (ULONGLONG)ProcessorBlock, sizeof(KPROCESSOR_BLOCK), KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 2); + ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_SYS_TSS, (ULONGLONG)ProcessorBlock->TssBase, sizeof(KTSS) - 1, I686_TSS, KGDT_DPL_SYSTEM, 0); + ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_DF_TSS, 0x20000, 0xFFFF, I686_TSS, KGDT_DPL_SYSTEM, 0); + ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_NMI_TSS, 0x20000, 0xFFFF, KGDT_TYPE_CODE, KGDT_DPL_SYSTEM, 0); + ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDBS, 0xB8000, 0x3FFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0); +} + +/** + * Initializes processor block. + * + * @param ProcessorBlock + * Supplies a pointer to the processor block to initialize. + * + * @param Gdt + * Supplies a pointer to the GDT for this processor block. + * + * @param Idt + * Supplies a pointer to the IDT for this processor block. + * + * @param Tss + * Supplies a pointer to the TSS for this processor block. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, + IN PKGDTENTRY Gdt, + IN PKIDTENTRY Idt, + IN PKTSS Tss, + IN PVOID DpcStack) +{ + /* Fill PCR with zeroes */ + RtlZeroMemory(ProcessorBlock, sizeof(KPROCESSOR_BLOCK)); + + /* Set processor block and processor control block */ + ProcessorBlock->Self = ProcessorBlock; + ProcessorBlock->CurrentPrcb = &ProcessorBlock->Prcb; + + /* Set GDT, IDT and TSS descriptors */ + ProcessorBlock->GdtBase = Gdt; + ProcessorBlock->IdtBase = Idt; + ProcessorBlock->TssBase = Tss; + + /* Setup DPC stack */ + ProcessorBlock->Prcb.DpcStack = DpcStack; + + /* Setup processor control block */ + ProcessorBlock->Prcb.Number = 0; + ProcessorBlock->Prcb.SetMember = 1; + ProcessorBlock->Prcb.MultiThreadProcessorSet = 1; + + /* Clear DR6 and DR7 registers */ + ProcessorBlock->Prcb.ProcessorState.SpecialRegisters.KernelDr6 = 0; + ProcessorBlock->Prcb.ProcessorState.SpecialRegisters.KernelDr7 = 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 PKPROCESSOR_BLOCK ProcessorBlock) +{ + PKGDTENTRY TssEntry; + + /* Get TSS entry from GDT */ + TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_SYS_TSS / sizeof(KGDTENTRY)])); + + /* Initialize TSS entry */ + TssEntry->Bits.Dpl = 0; + TssEntry->Bits.Present = 1; + TssEntry->Bits.Type = I686_TSS; + TssEntry->LimitLow = sizeof(KTSS) - 1; + TssEntry->Bits.LimitHigh = 0; + + /* Clear I/O map */ + RtlFillMemory(ProcessorBlock->TssBase->IoMaps[0].IoMap, IOPM_FULL_SIZE, 0xFF); + + /* Fill Interrupt Direction Maps with zeroes */ + RtlZeroMemory(ProcessorBlock->TssBase->IoMaps[0].DirectionMap, IOPM_DIRECTION_MAP_SIZE); + + /* Enable DPMI support */ + ProcessorBlock->TssBase->IoMaps[0].DirectionMap[0] = 4; + ProcessorBlock->TssBase->IoMaps[0].DirectionMap[3] = 0x18; + ProcessorBlock->TssBase->IoMaps[0].DirectionMap[4] = 0x18; + + /* Fill default Interrupt Direction Map with zeroes */ + RtlZeroMemory(ProcessorBlock->TssBase->IntDirectionMap, IOPM_DIRECTION_MAP_SIZE); + + /* Enable DPMI support */ + ProcessorBlock->TssBase->IntDirectionMap[0] = 4; + ProcessorBlock->TssBase->IntDirectionMap[3] = 0x18; + ProcessorBlock->TssBase->IntDirectionMap[4] = 0x18; + + /* Set I/O map base and disable traps */ + ProcessorBlock->TssBase->IoMapBase = 0x68; + ProcessorBlock->TssBase->Flags = 0; + + /* Set LDT and SS */ + ProcessorBlock->TssBase->LDT = KGDT_R0_LDT; + ProcessorBlock->TssBase->Ss0 = KGDT_R0_DATA; } /** @@ -100,13 +228,13 @@ 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) +ArpSetGdtEntry(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; @@ -125,7 +253,7 @@ ArpInitializeGdtEntry(IN PKGDTENTRY Gdt, } /* Get GDT entry */ - GdtEntry = (PKGDTENTRY)((ULONG64)Gdt + (Selector & ~RPL_MASK)); + GdtEntry = (PKGDTENTRY)((ULONGLONG)Gdt + (Selector & ~RPL_MASK)); /* Set GDT descriptor base */ GdtEntry->BaseLow = Base & 0xFFFF; @@ -145,61 +273,3 @@ ArpInitializeGdtEntry(IN PKGDTENTRY Gdt, GdtEntry->Bits.System = 0; GdtEntry->Bits.Type = (Type & 0x1F); } - -/** - * 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->Bits.Dpl = 0; - TssEntry->Bits.Present = 1; - TssEntry->Bits.Type = I686_TSS; - TssEntry->LimitLow = sizeof(KTSS) - 1; - TssEntry->Bits.LimitHigh = 0; - - /* Clear I/O map */ - RtlFillMemory(Tss->IoMaps[0].IoMap, IOPM_FULL_SIZE, 0xFF); - - /* Fill Interrupt Direction Maps with zeroes */ - RtlZeroMemory(Tss->IoMaps[0].DirectionMap, IOPM_DIRECTION_MAP_SIZE); - - /* Enable DPMI support */ - Tss->IoMaps[0].DirectionMap[0] = 4; - Tss->IoMaps[0].DirectionMap[3] = 0x18; - Tss->IoMaps[0].DirectionMap[4] = 0x18; - - /* Fill default Interrupt Direction Map with zeroes */ - RtlZeroMemory(Tss->IntDirectionMap, IOPM_DIRECTION_MAP_SIZE); - - /* Enable DPMI support */ - Tss->IntDirectionMap[0] = 4; - Tss->IntDirectionMap[3] = 0x18; - Tss->IntDirectionMap[4] = 0x18; - - /* Set I/O map base and disable traps */ - Tss->IoMapBase = 0x68; - Tss->Flags = 0; - - /* Set LDT and SS */ - Tss->LDT = KGDT_R0_LDT; - Tss->Ss0 = KGDT_R0_DATA; -} diff --git a/xtoskrnl/includes/amd64/globals.h b/xtoskrnl/includes/amd64/globals.h index e655193..733b55a 100644 --- a/xtoskrnl/includes/amd64/globals.h +++ b/xtoskrnl/includes/amd64/globals.h @@ -18,6 +18,9 @@ EXTERN KGDTENTRY ArInitialGdt[GDT_ENTRIES]; /* Initial IDT */ EXTERN KIDTENTRY ArInitialIdt[IDT_ENTRIES]; +/* Initial Processor Block */ +EXTERN KPROCESSOR_BLOCK ArInitialProcessorBlock; + /* Initial TSS */ EXTERN KTSS ArInitialTss; diff --git a/xtoskrnl/includes/arpfuncs.h b/xtoskrnl/includes/arpfuncs.h index 9522bd6..3c0b765 100644 --- a/xtoskrnl/includes/arpfuncs.h +++ b/xtoskrnl/includes/arpfuncs.h @@ -14,21 +14,28 @@ XTAPI VOID -ArpInitializeGdt(IN PKGDTENTRY Gdt); +ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock); XTAPI VOID -ArpInitializeGdtEntry(IN PKGDTENTRY Gdt, - IN USHORT Selector, - IN ULONGLONG Base, - IN ULONG Limit, - IN UCHAR Type, - IN UCHAR Dpl, - IN UCHAR SegmentMode); +ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, + IN PKGDTENTRY Gdt, + IN PKIDTENTRY Idt, + IN PKTSS Tss, + IN PVOID DpcStack); XTAPI VOID -ArpInitializeTss(IN PKTSS Tss, - IN PKGDTENTRY Gdt); +ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock); + +XTAPI +VOID +ArpSetGdtEntry(IN PKGDTENTRY Gdt, + IN USHORT Selector, + IN ULONGLONG Base, + IN ULONG Limit, + IN UCHAR Type, + IN UCHAR Dpl, + IN UCHAR SegmentMode); #endif /* __XTOSKRNL_ARPFUNCS_H */ diff --git a/xtoskrnl/includes/i686/globals.h b/xtoskrnl/includes/i686/globals.h index b37f593..ff89338 100644 --- a/xtoskrnl/includes/i686/globals.h +++ b/xtoskrnl/includes/i686/globals.h @@ -18,6 +18,9 @@ EXTERN KGDTENTRY ArInitialGdt[GDT_ENTRIES]; /* Initial IDT */ EXTERN KIDTENTRY ArInitialIdt[IDT_ENTRIES]; +/* Initial Processor Block */ +EXTERN KPROCESSOR_BLOCK ArInitialProcessorBlock; + /* Initial TSS */ EXTERN KTSS ArInitialTss;