diff --git a/xtoskrnl/includes/amd64/ke.h b/xtoskrnl/includes/amd64/ke.h index 1229d72..1b5ac7b 100644 --- a/xtoskrnl/includes/amd64/ke.h +++ b/xtoskrnl/includes/amd64/ke.h @@ -41,6 +41,10 @@ KepInitializeThreadContext(IN PKTHREAD Thread, IN PVOID StartContext, IN PCONTEXT ContextRecord); +XTAPI +VOID +KepSaveProcessorState(OUT PKPROCESSOR_STATE CpuState); + XTAPI VOID KepStartKernel(VOID); diff --git a/xtoskrnl/includes/i686/ke.h b/xtoskrnl/includes/i686/ke.h index 76e1e3d..0678716 100644 --- a/xtoskrnl/includes/i686/ke.h +++ b/xtoskrnl/includes/i686/ke.h @@ -41,6 +41,10 @@ KepInitializeThreadContext(IN PKTHREAD Thread, IN PVOID StartContext, IN PCONTEXT ContextRecord); +XTAPI +VOID +KepSaveProcessorState(OUT PKPROCESSOR_STATE CpuState); + XTAPI VOID KepStartKernel(VOID); diff --git a/xtoskrnl/ke/amd64/krnlinit.c b/xtoskrnl/ke/amd64/krnlinit.c index 3698a77..1232255 100644 --- a/xtoskrnl/ke/amd64/krnlinit.c +++ b/xtoskrnl/ke/amd64/krnlinit.c @@ -35,6 +35,9 @@ KepInitializeKernel(VOID) /* Initialize CPU power state structures */ PoInitializeProcessorControlBlock(Prcb); + /* Save processor state */ + KepSaveProcessorState(&Prcb->ProcessorState); + /* Initialize Idle process */ RtlInitializeListHead(&KepProcessListHead); PageDirectory[0] = 0; diff --git a/xtoskrnl/ke/amd64/proc.c b/xtoskrnl/ke/amd64/proc.c index 4d7d26b..0f275ce 100644 --- a/xtoskrnl/ke/amd64/proc.c +++ b/xtoskrnl/ke/amd64/proc.c @@ -51,3 +51,50 @@ KeGetCurrentThread(VOID) { return (PKTHREAD)ArReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Prcb.CurrentThread)); } + +/** + * Saves the current processor state. + * + * @param State + * Supplies a pointer to the processor state structure. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +KepSaveProcessorState(OUT PKPROCESSOR_STATE CpuState) +{ + /* Save CR registers */ + CpuState->SpecialRegisters.Cr0 = ArReadControlRegister(0); + CpuState->SpecialRegisters.Cr2 = ArReadControlRegister(2); + CpuState->SpecialRegisters.Cr3 = ArReadControlRegister(3); + CpuState->SpecialRegisters.Cr4 = ArReadControlRegister(4); + CpuState->SpecialRegisters.Cr8 = ArReadControlRegister(8); + + /* Save DR registers */ + CpuState->SpecialRegisters.KernelDr0 = ArReadDebugRegister(0); + CpuState->SpecialRegisters.KernelDr1 = ArReadDebugRegister(1); + CpuState->SpecialRegisters.KernelDr2 = ArReadDebugRegister(2); + CpuState->SpecialRegisters.KernelDr3 = ArReadDebugRegister(3); + CpuState->SpecialRegisters.KernelDr6 = ArReadDebugRegister(6); + CpuState->SpecialRegisters.KernelDr7 = ArReadDebugRegister(7); + + /* Save MSR registers */ + CpuState->SpecialRegisters.MsrGsBase = ArReadModelSpecificRegister(X86_MSR_GSBASE); + CpuState->SpecialRegisters.MsrGsSwap = ArReadModelSpecificRegister(X86_MSR_KERNEL_GSBASE); + CpuState->SpecialRegisters.MsrCStar = ArReadModelSpecificRegister(X86_MSR_CSTAR); + CpuState->SpecialRegisters.MsrLStar = ArReadModelSpecificRegister(X86_MSR_LSTAR); + CpuState->SpecialRegisters.MsrStar = ArReadModelSpecificRegister(X86_MSR_STAR); + CpuState->SpecialRegisters.MsrSyscallMask = ArReadModelSpecificRegister(X86_MSR_FMASK); + + /* Save XMM control/status register */ + CpuState->SpecialRegisters.MxCsr = ArReadMxCsrRegister(); + + /* Save GDT, IDT, LDT and TaskRegister */ + ArStoreGlobalDescriptorTable(&CpuState->SpecialRegisters.Gdtr.Limit); + ArStoreInterruptDescriptorTable(&CpuState->SpecialRegisters.Idtr.Limit); + ArStoreLocalDescriptorTable(&CpuState->SpecialRegisters.Ldtr); + ArStoreTaskRegister(&CpuState->SpecialRegisters.Tr); +} diff --git a/xtoskrnl/ke/i686/krnlinit.c b/xtoskrnl/ke/i686/krnlinit.c index 5b0d6f7..0356add 100644 --- a/xtoskrnl/ke/i686/krnlinit.c +++ b/xtoskrnl/ke/i686/krnlinit.c @@ -35,6 +35,9 @@ KepInitializeKernel(VOID) /* Initialize CPU power state structures */ PoInitializeProcessorControlBlock(Prcb); + /* Save processor state */ + KepSaveProcessorState(&Prcb->ProcessorState); + /* Initialize Idle process */ RtlInitializeListHead(&KepProcessListHead); PageDirectory[0] = 0; diff --git a/xtoskrnl/ke/i686/proc.c b/xtoskrnl/ke/i686/proc.c index 9893dca..1844dbd 100644 --- a/xtoskrnl/ke/i686/proc.c +++ b/xtoskrnl/ke/i686/proc.c @@ -51,3 +51,41 @@ KeGetCurrentThread(VOID) { return (PKTHREAD)ArReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, Prcb.CurrentThread)); } + +/** + * Saves the current processor state. + * + * @param State + * Supplies a pointer to the processor state structure. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +KepSaveProcessorState(OUT PKPROCESSOR_STATE CpuState) +{ + /* Save CR registers */ + CpuState->SpecialRegisters.Cr0 = ArReadControlRegister(0); + CpuState->SpecialRegisters.Cr2 = ArReadControlRegister(2); + CpuState->SpecialRegisters.Cr3 = ArReadControlRegister(3); + CpuState->SpecialRegisters.Cr4 = ArReadControlRegister(4); + + /* Save DR registers */ + CpuState->SpecialRegisters.KernelDr0 = ArReadDebugRegister(0); + CpuState->SpecialRegisters.KernelDr1 = ArReadDebugRegister(1); + CpuState->SpecialRegisters.KernelDr2 = ArReadDebugRegister(2); + CpuState->SpecialRegisters.KernelDr3 = ArReadDebugRegister(3); + CpuState->SpecialRegisters.KernelDr6 = ArReadDebugRegister(6); + CpuState->SpecialRegisters.KernelDr7 = ArReadDebugRegister(7); + + /* Save XMM control/status register */ + CpuState->SpecialRegisters.MxCsr = ArReadMxCsrRegister(); + + /* Save GDT, IDT, LDT and TaskRegister */ + ArStoreGlobalDescriptorTable(&CpuState->SpecialRegisters.Gdtr.Limit); + ArStoreInterruptDescriptorTable(&CpuState->SpecialRegisters.Idtr.Limit); + ArStoreLocalDescriptorTable(&CpuState->SpecialRegisters.Ldtr); + ArStoreTaskRegister(&CpuState->SpecialRegisters.Tr); +}