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,7 +222,7 @@ ArpInitializeGdt(IN PKGDTENTRY Gdt)
*/
XTAPI
VOID
ArpInitializeGdtEntry(IN PKGDTENTRY Gdt,
ArpSetGdtEntry(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONGLONG Base,
IN ULONG Limit,
@ -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,7 +228,7 @@ ArpInitializeGdt(IN PKGDTENTRY Gdt)
*/
XTAPI
VOID
ArpInitializeGdtEntry(IN PKGDTENTRY Gdt,
ArpSetGdtEntry(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONGLONG Base,
IN ULONG Limit,
@ -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,11 +14,23 @@
XTAPI
VOID
ArpInitializeGdt(IN PKGDTENTRY Gdt);
ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock);
XTAPI
VOID
ArpInitializeGdtEntry(IN PKGDTENTRY Gdt,
ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock,
IN PKGDTENTRY Gdt,
IN PKIDTENTRY Idt,
IN PKTSS Tss,
IN PVOID DpcStack);
XTAPI
VOID
ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock);
XTAPI
VOID
ArpSetGdtEntry(IN PKGDTENTRY Gdt,
IN USHORT Selector,
IN ULONGLONG Base,
IN ULONG Limit,
@ -26,9 +38,4 @@ ArpInitializeGdtEntry(IN PKGDTENTRY Gdt,
IN UCHAR Dpl,
IN UCHAR SegmentMode);
XTAPI
VOID
ArpInitializeTss(IN PKTSS Tss,
IN PKGDTENTRY Gdt);
#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;