- if (MaxCpuIdIndex >= CPUID_CACHE_PARAMS) {\r
- AsmCpuidEx(CPUID_CACHE_PARAMS, 0, &CacheParamsEax.Uint32, NULL, NULL, NULL);\r
- MaxCoresPerPackage = CacheParamsEax.Bits.MaximumAddressableIdsForLogicalProcessors + 1;\r
+\r
+ //\r
+ // Assume single-core processor\r
+ //\r
+ MaxCoresPerPackage = 1;\r
+\r
+ //\r
+ // Check for topology extensions on AMD processor\r
+ //\r
+ if (StandardSignatureIsAuthenticAMD()) {\r
+ if (MaxExtendedCpuIdIndex >= CPUID_AMD_PROCESSOR_TOPOLOGY) {\r
+ AsmCpuid(CPUID_EXTENDED_CPU_SIG, NULL, NULL, &AmdExtendedCpuSigEcx.Uint32, NULL);\r
+ if (AmdExtendedCpuSigEcx.Bits.TopologyExtensions != 0) {\r
+ AsmCpuid(CPUID_AMD_PROCESSOR_TOPOLOGY, NULL, &AmdProcessorTopologyEbx.Uint32,\r
+ &AmdProcessorTopologyEcx.Uint32, NULL);\r
+ //\r
+ // Get cores per processor package\r
+ //\r
+ MaxCoresPerPackage = MaxLogicProcessorsPerPackage / (AmdProcessorTopologyEbx.Bits.ThreadsPerCore + 1);\r
+\r
+ //\r
+ // Account for actual thread count (e.g., SMT disabled)\r
+ //\r
+ AsmCpuid(CPUID_VIR_PHY_ADDRESS_SIZE, NULL, NULL, &AmdVirPhyAddressSizeEcx.Uint32, NULL);\r
+ MaxThreadPerPackageMask = 1 << AmdVirPhyAddressSizeEcx.Bits.ApicIdCoreIdSize;\r
+ ActualThreadPerPackageMask = 1;\r
+ while (ActualThreadPerPackageMask < MaxLogicProcessorsPerPackage) {\r
+ ActualThreadPerPackageMask <<= 1;\r
+ }\r
+\r
+ //\r
+ // Adjust APIC Id to report concatenation of Package|Core|Thread.\r
+ //\r
+ if (ActualThreadPerPackageMask < MaxThreadPerPackageMask) {\r
+ MaxCoresPerNode = MaxCoresPerPackage / (AmdProcessorTopologyEcx.Bits.NodesPerProcessor + 1);\r
+\r
+ CorePerNodeMask = 1;\r
+ while (CorePerNodeMask < MaxCoresPerNode) {\r
+ CorePerNodeMask <<= 1;\r
+ }\r
+ CorePerNodeMask -= 1;\r
+\r
+ ApicIdShift = 0;\r
+ do {\r
+ ApicIdShift += 1;\r
+ ActualThreadPerPackageMask <<= 1;\r
+ } while (ActualThreadPerPackageMask < MaxThreadPerPackageMask);\r
+\r
+ InitialApicId = ((InitialApicId & ~CorePerNodeMask) >> ApicIdShift) | (InitialApicId & CorePerNodeMask);\r
+ }\r
+ }\r
+ }\r