detect hyper-threading, determine number of logical processors per
phyiscal processor and it's apic id
Modified: trunk/reactos/ntoskrnl/include/internal/i386/ke.h
Modified: trunk/reactos/ntoskrnl/ke/i386/kernel.c
_____
Modified: trunk/reactos/ntoskrnl/include/internal/i386/ke.h
--- trunk/reactos/ntoskrnl/include/internal/i386/ke.h 2005-03-07
00:04:21 UTC (rev 13863)
+++ trunk/reactos/ntoskrnl/include/internal/i386/ke.h 2005-03-07
00:35:49 UTC (rev 13864)
@@ -99,6 +99,7 @@
#define X86_FEATURE_FXSR 0x01000000 /* FXSAVE/FXRSTOR
instructions present */
#define X86_FEATURE_SSE 0x02000000 /* SSE extension present */
#define X86_FEATURE_SSE2 0x04000000 /* SSE2 extension present */
+#define X86_FEATURE_HT 0x10000000 /* Hyper-Threading present
*/
#define X86_EXT_FEATURE_SSE3 0x00000001 /* SSE3 extension present */
#define X86_EXT_FEATURE_3DNOW 0x40000000 /* 3DNOW! extension present
*/
_____
Modified: trunk/reactos/ntoskrnl/ke/i386/kernel.c
--- trunk/reactos/ntoskrnl/ke/i386/kernel.c 2005-03-07 00:04:21 UTC
(rev 13863)
+++ trunk/reactos/ntoskrnl/ke/i386/kernel.c 2005-03-07 00:35:49 UTC
(rev 13864)
@@ -18,7 +18,7 @@
ULONG KiPcrInitDone = 0;
static ULONG PcrsAllocated = 0;
-static ULONG Ke386CpuidFlags2, Ke386CpuidExFlags;
+static ULONG Ke386CpuidFlags2, Ke386CpuidExFlags, Ke386CpuidExMisc;
ULONG Ke386CacheAlignment;
CHAR Ke386CpuidModel[49] = {0,};
ULONG Ke386L1CacheSize;
@@ -34,7 +34,7 @@
{
ULONG OrigFlags, Flags, FinalFlags;
ULONG MaxCpuidLevel;
- ULONG Dummy, Eax, Ebx, Ecx, Edx;
+ ULONG Dummy, Eax, Ecx, Edx;
PKPCR Pcr = KeGetCurrentKPCR();
Ke386CpuidFlags2 = Ke386CpuidExFlags = 0;
@@ -45,6 +45,10 @@
Flags = OrigFlags ^ X86_EFLAGS_ID;
Ke386RestoreFlags(Flags);
Ke386SaveFlags(FinalFlags);
+
+ Pcr->PrcbData.LogicalProcessorsPerPhysicalProcessor = 1;
+ Pcr->PrcbData.InitialApicId = 0xff;
+
if ((OrigFlags & X86_EFLAGS_ID) == (FinalFlags & X86_EFLAGS_ID))
{
/* No cpuid supported. */
@@ -59,14 +63,24 @@
if (MaxCpuidLevel > 0)
{
/* Get the feature flags. */
- Ki386Cpuid(1, &Eax, &Ebx, &Ke386CpuidFlags2,
&Pcr->PrcbData.FeatureBits);
+ Ki386Cpuid(1, &Eax, &Ke386CpuidExMisc, &Ke386CpuidFlags2,
&Pcr->PrcbData.FeatureBits);
/* Get the cache alignment, if it is available */
if (Pcr->PrcbData.FeatureBits & (1<<19))
{
- Ke386CacheAlignment = ((Ebx >> 8) & 0xff) * 8;
+ Ke386CacheAlignment = ((Ke386CpuidExMisc >> 8) & 0xff) * 8;
}
Pcr->PrcbData.CpuType = (Eax >> 8) & 0xf;
Pcr->PrcbData.CpuStep = (Eax & 0xf) | ((Eax << 4) & 0xf00);
+
+ Pcr->PrcbData.InitialApicId = (Ke386CpuidExMisc >> 24) & 0xff;
+
+ /* detect Hyper-Threading on Pentium 4 CPUs or later */
+ if ((Pcr->PrcbData.CpuType == 0xf || (Eax & 0x0f00000)) &&
+ !strncmp(Pcr->PrcbData.VendorString, "GenuineIntel", 12)
&&
+ Pcr->PrcbData.FeatureBits & X86_FEATURE_HT)
+ {
+ Pcr->PrcbData.LogicalProcessorsPerPhysicalProcessor =
(Ke386CpuidExMisc >> 16) & 0xff;
+ }
}
else
{