Initial processor block initialization
All checks were successful
ci/woodpecker/push/build Pipeline was successful

This commit is contained in:
Rafal Kupiec 2023-01-30 19:07:05 +01:00
parent ebe6792f2b
commit 6f068513cd
Signed by: belliash
GPG Key ID: 4E829243E0CFE6B4
11 changed files with 469 additions and 171 deletions

View File

@ -10,7 +10,9 @@
#define __XTDK_AMD64_KETYPES_H
#include <xtbase.h>
#include <xtstruct.h>
#include <xttypes.h>
#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 */

View File

@ -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;

View File

@ -9,8 +9,10 @@
#ifndef __XTDK_I686_KETYPES_H
#define __XTDK_I686_KETYPES_H
#include <xtbase.h>
#include <xtstruct.h>
#include <xttypes.h>
#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 */

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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 */

View File

@ -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;