- Stored the informations from the cpuid instruction within the KPCR of each processor.

svn path=/trunk/; revision=11648
This commit is contained in:
Hartmut Birr 2004-11-13 23:08:35 +00:00
parent 59881376cd
commit ea6e7df66a
4 changed files with 61 additions and 55 deletions

View file

@ -1,4 +1,4 @@
/* $Id: sysinfo.c,v 1.58 2004/11/06 16:04:58 ekohl Exp $ /* $Id: sysinfo.c,v 1.59 2004/11/13 23:08:35 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -23,9 +23,6 @@ ULONGLONG STDCALL KeQueryInterruptTime(VOID);
VOID MmPrintMemoryStatistic(VOID); VOID MmPrintMemoryStatistic(VOID);
extern ULONG Ke386CpuidFlags;
extern ULONG Ke386Cpuid;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
/* /*
@ -375,7 +372,7 @@ QSI_DEF(SystemProcessorInformation)
{ {
PSYSTEM_PROCESSOR_INFORMATION Spi PSYSTEM_PROCESSOR_INFORMATION Spi
= (PSYSTEM_PROCESSOR_INFORMATION) Buffer; = (PSYSTEM_PROCESSOR_INFORMATION) Buffer;
PKPCR Pcr;
*ReqSize = sizeof (SYSTEM_PROCESSOR_INFORMATION); *ReqSize = sizeof (SYSTEM_PROCESSOR_INFORMATION);
/* /*
* Check user buffer's size * Check user buffer's size
@ -384,11 +381,12 @@ QSI_DEF(SystemProcessorInformation)
{ {
return (STATUS_INFO_LENGTH_MISMATCH); return (STATUS_INFO_LENGTH_MISMATCH);
} }
Pcr = KeGetCurrentKPCR();
Spi->ProcessorArchitecture = 0; /* Intel Processor */ Spi->ProcessorArchitecture = 0; /* Intel Processor */
Spi->ProcessorLevel = ((Ke386Cpuid >> 8) & 0xf); Spi->ProcessorLevel = Pcr->PrcbData.CpuType;
Spi->ProcessorRevision = (Ke386Cpuid & 0xf) | ((Ke386Cpuid << 4) & 0xf00); Spi->ProcessorRevision = Pcr->PrcbData.CpuStep;
Spi->Unknown = 0; Spi->Unknown = 0;
Spi->FeatureBits = Ke386CpuidFlags; Spi->FeatureBits = Pcr->PrcbData.FeatureBits;
DPRINT("Arch %d Level %d Rev 0x%x\n", Spi->ProcessorArchitecture, DPRINT("Arch %d Level %d Rev 0x%x\n", Spi->ProcessorArchitecture,
Spi->ProcessorLevel, Spi->ProcessorRevision); Spi->ProcessorLevel, Spi->ProcessorRevision);

View file

@ -35,16 +35,14 @@
ULONG KiPcrInitDone = 0; ULONG KiPcrInitDone = 0;
static ULONG PcrsAllocated = 0; static ULONG PcrsAllocated = 0;
ULONG Ke386CpuidFlags, Ke386CpuidFlags2, Ke386CpuidExFlags; static ULONG Ke386CpuidFlags2, Ke386CpuidExFlags;
ULONG Ke386Cpuid = 0x300;
ULONG Ke386CacheAlignment; ULONG Ke386CacheAlignment;
CHAR Ke386CpuidVendor[13] = {0,};
CHAR Ke386CpuidModel[49] = {0,}; CHAR Ke386CpuidModel[49] = {0,};
ULONG Ke386L1CacheSize; ULONG Ke386L1CacheSize;
ULONG Ke386L2CacheSize;
BOOLEAN Ke386NoExecute = FALSE; BOOLEAN Ke386NoExecute = FALSE;
BOOLEAN Ke386Pae = FALSE; BOOLEAN Ke386Pae = FALSE;
BOOLEAN Ke386PaeEnabled = FALSE; BOOLEAN Ke386PaeEnabled = FALSE;
BOOLEAN Ke386GlobalPagesEnabled = FALSE;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
@ -53,39 +51,43 @@ Ki386GetCpuId(VOID)
{ {
ULONG OrigFlags, Flags, FinalFlags; ULONG OrigFlags, Flags, FinalFlags;
ULONG MaxCpuidLevel; ULONG MaxCpuidLevel;
ULONG Dummy, Ebx, Ecx, Edx; ULONG Dummy, Eax, Ebx, Ecx, Edx;
PKPCR Pcr = KeGetCurrentKPCR();
Ke386CpuidFlags = Ke386CpuidFlags2 = Ke386CpuidExFlags = 0; Ke386CpuidFlags2 = Ke386CpuidExFlags = 0;
Ke386CacheAlignment = 32; Ke386CacheAlignment = 32;
/* Try to toggle the id bit in eflags. */ /* Try to toggle the id bit in eflags. */
__asm__ ("pushfl\n\t" Ke386SaveFlags(OrigFlags);
"popl %0\n\t"
: "=r" (OrigFlags));
Flags = OrigFlags ^ X86_EFLAGS_ID; Flags = OrigFlags ^ X86_EFLAGS_ID;
__asm__ ("pushl %1\n\t" Ke386RestoreFlags(Flags);
"popfl\n\t" Ke386SaveFlags(FinalFlags);
"pushfl\n\t"
"popl %0\n\t"
: "=r" (FinalFlags)
: "r" (Flags));
if ((OrigFlags & X86_EFLAGS_ID) == (FinalFlags & X86_EFLAGS_ID)) if ((OrigFlags & X86_EFLAGS_ID) == (FinalFlags & X86_EFLAGS_ID))
{ {
/* No cpuid supported. */ /* No cpuid supported. */
Pcr->PrcbData.CpuID = FALSE;
Pcr->PrcbData.CpuType = 3;
return; return;
} }
Pcr->PrcbData.CpuID = TRUE;
/* Get the vendor name and the maximum cpuid level supported. */ /* Get the vendor name and the maximum cpuid level supported. */
Ki386Cpuid(0, &MaxCpuidLevel, (PULONG)&Ke386CpuidVendor[0], (PULONG)&Ke386CpuidVendor[8], (PULONG)&Ke386CpuidVendor[4]); Ki386Cpuid(0, &MaxCpuidLevel, (PULONG)&Pcr->PrcbData.VendorString[0], (PULONG)&Pcr->PrcbData.VendorString[8], (PULONG)&Pcr->PrcbData.VendorString[4]);
if (MaxCpuidLevel > 0) if (MaxCpuidLevel > 0)
{ {
/* Get the feature flags. */ /* Get the feature flags. */
Ki386Cpuid(1, &Ke386Cpuid, &Ebx, &Ke386CpuidFlags2, &Ke386CpuidFlags); Ki386Cpuid(1, &Eax, &Ebx, &Ke386CpuidFlags2, &Pcr->PrcbData.FeatureBits);
/* Get the cache alignment, if it is available */ /* Get the cache alignment, if it is available */
if (Ke386CpuidFlags & (1<<19)) if (Pcr->PrcbData.FeatureBits & (1<<19))
{ {
Ke386CacheAlignment = ((Ebx >> 8) & 0xff) * 8; Ke386CacheAlignment = ((Ebx >> 8) & 0xff) * 8;
} }
Pcr->PrcbData.CpuType = (Eax >> 8) & 0xf;
Pcr->PrcbData.CpuStep = (Eax & 0xf) | ((Eax << 4) & 0xf00);
}
else
{
Pcr->PrcbData.CpuType = 4;
} }
/* Get the maximum extended cpuid level supported. */ /* Get the maximum extended cpuid level supported. */
@ -99,7 +101,7 @@ Ki386GetCpuId(VOID)
/* Get the model name. */ /* Get the model name. */
if (MaxCpuidLevel >= 0x80000004) if (MaxCpuidLevel >= 0x80000004)
{ {
PULONG v = (PULONG)&Ke386CpuidModel; PULONG v = (PULONG)Ke386CpuidModel;
Ki386Cpuid(0x80000002, v, v + 1, v + 2, v + 3); Ki386Cpuid(0x80000002, v, v + 1, v + 2, v + 3);
Ki386Cpuid(0x80000003, v + 4, v + 5, v + 6, v + 7); Ki386Cpuid(0x80000003, v + 4, v + 5, v + 6, v + 7);
Ki386Cpuid(0x80000004, v + 8, v + 9, v + 10, v + 11); Ki386Cpuid(0x80000004, v + 8, v + 9, v + 10, v + 11);
@ -120,7 +122,7 @@ Ki386GetCpuId(VOID)
if (MaxCpuidLevel >= 0x80000006) if (MaxCpuidLevel >= 0x80000006)
{ {
Ki386Cpuid(0x80000006, &Dummy, &Dummy, &Ecx, &Dummy); Ki386Cpuid(0x80000006, &Dummy, &Dummy, &Ecx, &Dummy);
Ke386L2CacheSize = Ecx >> 16; Pcr->L2CacheSize = Ecx >> 16;
} }
} }
@ -164,14 +166,14 @@ KeApplicationProcessorInit(VOID)
DPRINT("KeApplicationProcessorInit()\n"); DPRINT("KeApplicationProcessorInit()\n");
if (Ke386CpuidFlags & X86_FEATURE_PGE) if (Ke386GlobalPagesEnabled)
{ {
/* Enable global pages */ /* Enable global pages */
Ke386SetCr4(Ke386GetCr4() | X86_CR4_PGE); Ke386SetCr4(Ke386GetCr4() | X86_CR4_PGE);
} }
/* Enable PAE mode */ /* Enable PAE mode */
if (Ke386CpuidFlags & X86_FEATURE_PAE) if (Ke386PaeEnabled)
{ {
MiEnablePAE(NULL); MiEnablePAE(NULL);
} }
@ -186,6 +188,8 @@ KeApplicationProcessorInit(VOID)
*/ */
KiInitializeGdt(Pcr); KiInitializeGdt(Pcr);
/* Get processor information. */
Ki386GetCpuId();
/* /*
* It is now safe to process interrupts * It is now safe to process interrupts
@ -250,10 +254,11 @@ KeInit1(PCHAR CommandLine, PULONG LastKernelAddress)
/* Get processor information. */ /* Get processor information. */
Ki386GetCpuId(); Ki386GetCpuId();
if (Ke386CpuidFlags & X86_FEATURE_PGE) if (KPCR->PrcbData.FeatureBits & X86_FEATURE_PGE)
{ {
ULONG Flags; ULONG Flags;
/* Enable global pages */ /* Enable global pages */
Ke386GlobalPagesEnabled = TRUE;
Ke386SaveFlags(Flags); Ke386SaveFlags(Flags);
Ke386DisableInterrupts(); Ke386DisableInterrupts();
Ke386SetCr4(Ke386GetCr4() | X86_CR4_PGE); Ke386SetCr4(Ke386GetCr4() | X86_CR4_PGE);
@ -288,8 +293,8 @@ KeInit1(PCHAR CommandLine, PULONG LastKernelAddress)
* FIXME: * FIXME:
* Make the detection of the noexecute feature more portable. * Make the detection of the noexecute feature more portable.
*/ */
if(((Ke386Cpuid >> 8) & 0xf) == 0xf && if(KPCR->PrcbData.CpuType == 0xf &&
0 == strcmp("AuthenticAMD", Ke386CpuidVendor)) 0 == strcmp("AuthenticAMD", KPCR->PrcbData.VendorString))
{ {
if (NoExecute) if (NoExecute)
{ {
@ -311,7 +316,7 @@ KeInit1(PCHAR CommandLine, PULONG LastKernelAddress)
/* Enable PAE mode */ /* Enable PAE mode */
if ((Pae && (Ke386CpuidFlags & X86_FEATURE_PAE)) || NoExecute) if ((Pae && (KPCR->PrcbData.FeatureBits & X86_FEATURE_PAE)) || NoExecute)
{ {
MiEnablePAE((PVOID*)LastKernelAddress); MiEnablePAE((PVOID*)LastKernelAddress);
Ke386PaeEnabled = TRUE; Ke386PaeEnabled = TRUE;
@ -321,11 +326,13 @@ KeInit1(PCHAR CommandLine, PULONG LastKernelAddress)
VOID INIT_FUNCTION VOID INIT_FUNCTION
KeInit2(VOID) KeInit2(VOID)
{ {
PKPCR Pcr = KeGetCurrentKPCR();
KeInitializeBugCheck(); KeInitializeBugCheck();
KeInitializeDispatcher(); KeInitializeDispatcher();
KeInitializeTimerImpl(); KeInitializeTimerImpl();
if (Ke386CpuidFlags & X86_FEATURE_PAE) if (Pcr->PrcbData.FeatureBits & X86_FEATURE_PAE)
{ {
DPRINT1("CPU supports PAE mode\n"); DPRINT1("CPU supports PAE mode\n");
if (Ke386Pae) if (Ke386Pae)
@ -341,9 +348,9 @@ KeInit2(VOID)
DPRINT1("CPU doesn't run in PAE mode\n"); DPRINT1("CPU doesn't run in PAE mode\n");
} }
} }
if (Ke386CpuidVendor[0]) if (Pcr->PrcbData.VendorString[0])
{ {
DPRINT1("CPU Vendor: %s\n", Ke386CpuidVendor); DPRINT1("CPU Vendor: %s\n", Pcr->PrcbData.VendorString);
} }
if (Ke386CpuidModel[0]) if (Ke386CpuidModel[0])
{ {
@ -355,30 +362,32 @@ KeInit2(VOID)
{ {
DPRINT1("Ke386L1CacheSize: %dkB\n", Ke386L1CacheSize); DPRINT1("Ke386L1CacheSize: %dkB\n", Ke386L1CacheSize);
} }
if (Ke386L2CacheSize) if (Pcr->L2CacheSize)
{ {
DPRINT1("Ke386L2CacheSize: %dkB\n", Ke386L2CacheSize); DPRINT1("Ke386L2CacheSize: %dkB\n", Pcr->L2CacheSize);
} }
} }
VOID INIT_FUNCTION VOID INIT_FUNCTION
Ki386SetProcessorFeatures(VOID) Ki386SetProcessorFeatures(VOID)
{ {
PKPCR Pcr = KeGetCurrentKPCR();
SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] = FALSE; SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] = FALSE;
SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_EMULATED] = FALSE; SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_EMULATED] = FALSE;
SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] = SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] =
(Ke386CpuidFlags & X86_FEATURE_CX8); (Pcr->PrcbData.FeatureBits & X86_FEATURE_CX8);
SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] = SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] =
(Ke386CpuidFlags & X86_FEATURE_MMX); (Pcr->PrcbData.FeatureBits & X86_FEATURE_MMX);
SharedUserData->ProcessorFeatures[PF_PPC_MOVEMEM_64BIT_OK] = FALSE; SharedUserData->ProcessorFeatures[PF_PPC_MOVEMEM_64BIT_OK] = FALSE;
SharedUserData->ProcessorFeatures[PF_ALPHA_BYTE_INSTRUCTIONS] = FALSE; SharedUserData->ProcessorFeatures[PF_ALPHA_BYTE_INSTRUCTIONS] = FALSE;
SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] = SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] =
(Ke386CpuidFlags & X86_FEATURE_SSE); (Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE);
SharedUserData->ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] = SharedUserData->ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] =
(Ke386CpuidExFlags & X86_EXT_FEATURE_3DNOW); (Ke386CpuidExFlags & X86_EXT_FEATURE_3DNOW);
SharedUserData->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] = SharedUserData->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] =
(Ke386CpuidFlags & X86_FEATURE_TSC); (Pcr->PrcbData.FeatureBits & X86_FEATURE_TSC);
SharedUserData->ProcessorFeatures[PF_PAE_ENABLED] = Ke386PaeEnabled; SharedUserData->ProcessorFeatures[PF_PAE_ENABLED] = Ke386PaeEnabled;
SharedUserData->ProcessorFeatures[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = SharedUserData->ProcessorFeatures[PF_XMMI64_INSTRUCTIONS_AVAILABLE] =
(Ke386CpuidFlags & X86_FEATURE_SSE2); (Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE2);
} }

View file

@ -10,7 +10,7 @@
.globl _KeFlushCurrentTb@0 .globl _KeFlushCurrentTb@0
_KeFlushCurrentTb@0: _KeFlushCurrentTb@0:
/* Check for global page support */ /* Check for global page support */
testl $X86_FEATURE_PGE, (_Ke386CpuidFlags) testb $0xff, (_Ke386GlobalPagesEnabled)
jz .L1 jz .L1
/* Modifying the PSE, PGE or PAE Flag in CR4 causes the TLB to be flushed */ /* Modifying the PSE, PGE or PAE Flag in CR4 causes the TLB to be flushed */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: page.c,v 1.76 2004/11/11 22:23:52 ion Exp $ /* $Id: page.c,v 1.77 2004/11/13 23:08:35 hbirr Exp $
* *
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/i386/page.c * FILE: ntoskrnl/mm/i386/page.c
@ -77,10 +77,9 @@ __inline LARGE_INTEGER PTE_TO_PAGE(ULONG npage)
} }
#endif #endif
extern ULONG Ke386CpuidFlags;
extern ULONG Ke386Cpuid;
extern BOOLEAN Ke386Pae; extern BOOLEAN Ke386Pae;
extern BOOLEAN Ke386NoExecute; extern BOOLEAN Ke386NoExecute;
extern BOOLEAN Ke386GlobalPagesEnabled;
/* FUNCTIONS ***************************************************************/ /* FUNCTIONS ***************************************************************/
@ -541,7 +540,7 @@ MmGetPageTableForProcessForPAE(PEPROCESS Process, PVOID Address, BOOLEAN Create)
KEBUGCHECK(0); KEBUGCHECK(0);
} }
Entry = PAE_PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE; Entry = PAE_PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE;
if (Ke386CpuidFlags & X86_FEATURE_PGE) if (Ke386GlobalPagesEnabled)
{ {
Entry |= PA_GLOBAL; Entry |= PA_GLOBAL;
} }
@ -638,7 +637,7 @@ MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
KEBUGCHECK(0); KEBUGCHECK(0);
} }
Entry = PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE; Entry = PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE;
if (Ke386CpuidFlags & X86_FEATURE_PGE) if (Ke386GlobalPagesEnabled)
{ {
Entry |= PA_GLOBAL; Entry |= PA_GLOBAL;
} }
@ -1500,7 +1499,7 @@ MmCreateVirtualMappingForKernel(PVOID Address,
NoExecute = TRUE; NoExecute = TRUE;
} }
Attributes &= 0xfff; Attributes &= 0xfff;
if (Ke386CpuidFlags & X86_FEATURE_PGE) if (Ke386GlobalPagesEnabled)
{ {
Attributes |= PA_GLOBAL; Attributes |= PA_GLOBAL;
} }
@ -1747,7 +1746,7 @@ MmCreateVirtualMappingUnsafe(PEPROCESS Process,
if (Address >= (PVOID)KERNEL_BASE) if (Address >= (PVOID)KERNEL_BASE)
{ {
Attributes &= ~PA_USER; Attributes &= ~PA_USER;
if (Ke386CpuidFlags & X86_FEATURE_PGE) if (Ke386GlobalPagesEnabled)
{ {
Attributes |= PA_GLOBAL; Attributes |= PA_GLOBAL;
} }
@ -1985,7 +1984,7 @@ MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG flProtect)
if (Address >= (PVOID)KERNEL_BASE) if (Address >= (PVOID)KERNEL_BASE)
{ {
Attributes &= ~PA_USER; Attributes &= ~PA_USER;
if (Ke386CpuidFlags & X86_FEATURE_PGE) if (Ke386GlobalPagesEnabled)
{ {
Attributes |= PA_GLOBAL; Attributes |= PA_GLOBAL;
} }
@ -2180,7 +2179,7 @@ MmInitGlobalKernelPageDirectory(VOID)
0LL == MmGlobalKernelPageDirectoryForPAE[i] && 0LL != CurrentPageDirectory[i]) 0LL == MmGlobalKernelPageDirectoryForPAE[i] && 0LL != CurrentPageDirectory[i])
{ {
ExfpInterlockedExchange64(&MmGlobalKernelPageDirectoryForPAE[i], &CurrentPageDirectory[i]); ExfpInterlockedExchange64(&MmGlobalKernelPageDirectoryForPAE[i], &CurrentPageDirectory[i]);
if (Ke386CpuidFlags & X86_FEATURE_PGE) if (Ke386GlobalPagesEnabled)
{ {
MmGlobalKernelPageDirectoryForPAE[i] |= PA_GLOBAL; MmGlobalKernelPageDirectoryForPAE[i] |= PA_GLOBAL;
} }
@ -2196,7 +2195,7 @@ MmInitGlobalKernelPageDirectory(VOID)
0 == MmGlobalKernelPageDirectory[i] && 0 != CurrentPageDirectory[i]) 0 == MmGlobalKernelPageDirectory[i] && 0 != CurrentPageDirectory[i])
{ {
MmGlobalKernelPageDirectory[i] = CurrentPageDirectory[i]; MmGlobalKernelPageDirectory[i] = CurrentPageDirectory[i];
if (Ke386CpuidFlags & X86_FEATURE_PGE) if (Ke386GlobalPagesEnabled)
{ {
MmGlobalKernelPageDirectory[i] |= PA_GLOBAL; MmGlobalKernelPageDirectory[i] |= PA_GLOBAL;
} }