From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 3211121A143C1 for ; Tue, 20 Jun 2017 19:08:25 -0700 (PDT) Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 20 Jun 2017 19:09:48 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.39,366,1493708400"; d="scan'208";a="117373679" Received: from fmsmsx105.amr.corp.intel.com ([10.18.124.203]) by fmsmga006.fm.intel.com with ESMTP; 20 Jun 2017 19:09:48 -0700 Received: from fmsmsx158.amr.corp.intel.com (10.18.116.75) by FMSMSX105.amr.corp.intel.com (10.18.124.203) with Microsoft SMTP Server (TLS) id 14.3.319.2; Tue, 20 Jun 2017 19:09:47 -0700 Received: from shsmsx104.ccr.corp.intel.com (10.239.4.70) by fmsmsx158.amr.corp.intel.com (10.18.116.75) with Microsoft SMTP Server (TLS) id 14.3.319.2; Tue, 20 Jun 2017 19:09:47 -0700 Received: from shsmsx102.ccr.corp.intel.com ([169.254.2.146]) by SHSMSX104.ccr.corp.intel.com ([10.239.4.70]) with mapi id 14.03.0319.002; Wed, 21 Jun 2017 10:09:45 +0800 From: "Fan, Jeff" To: Leo Duran , "edk2-devel@lists.01.org" CC: "Justen, Jordan L" , "Gao, Liming" , Brijesh Singh Thread-Topic: [PATCH v5 2/2] UefiCpuPkg: Modify GetProcessorLocationByApicId() to support AMD. Thread-Index: AQHS5wKNT7YtNoM52EG8BF1MntcH5qIumDPg Date: Wed, 21 Jun 2017 02:09:44 +0000 Message-ID: <542CF652F8836A4AB8DBFAAD40ED192A4C610A9F@shsmsx102.ccr.corp.intel.com> References: <1497660109-18243-1-git-send-email-leo.duran@amd.com> <1497660109-18243-3-git-send-email-leo.duran@amd.com> In-Reply-To: <1497660109-18243-3-git-send-email-leo.duran@amd.com> Accept-Language: zh-CN, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiYjlkYzNlN2YtMWU3Ny00MjAzLWFjNGQtZGY5MWZlZWVhMDlkIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX0lDIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE2LjUuOS4zIiwiVHJ1c3RlZExhYmVsSGFzaCI6InBUZkxpSVJlTkh4RzYwZGM3eDlPUVAyWDByNUpKU3FJMk9SM0hWN0V3ODA9In0= x-ctpclassification: CTP_IC x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [PATCH v5 2/2] UefiCpuPkg: Modify GetProcessorLocationByApicId() to support AMD. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 21 Jun 2017 02:08:25 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Jeff Fan I noticed this serial of patches depend on another SEV patch on UefiCpuPkg(= I have reviewed-by it before).=20 I will push them together in a couple of days if you have no other comments= . Thanks! Jeff -----Original Message----- From: Leo Duran [mailto:leo.duran@amd.com]=20 Sent: Saturday, June 17, 2017 8:42 AM To: edk2-devel@lists.01.org Cc: Leo Duran; Justen, Jordan L; Fan, Jeff; Gao, Liming; Brijesh Singh Subject: [PATCH v5 2/2] UefiCpuPkg: Modify GetProcessorLocationByApicId() t= o support AMD. Cc: Jordan Justen Cc: Jeff Fan Cc: Liming Gao Cc: Brijesh Singh Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Leo Duran --- UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c | 157 ++++++++++++++++-= ---- .../BaseXApicX2ApicLib/BaseXApicX2ApicLib.c | 157 ++++++++++++++++-= ---- 2 files changed, 250 insertions(+), 64 deletions(-) diff --git a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c b/UefiCpuPkg/Li= brary/BaseXApicLib/BaseXApicLib.c index f81bbb2..2091e5e 100644 --- a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c +++ b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c @@ -4,6 +4,8 @@ This local APIC library instance supports xAPIC mode only. =20 Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.
+ Copyright (c) 2017, AMD Inc. All rights reserved.
+ This program and the accompanying materials are licensed and made available under the terms and conditions of the BS= D License which accompanies this distribution. The full text of the license may b= e found at @@ -15,6 +17,7 @@ **/ =20 #include +#include #include #include =20 @@ -30,6 +33,28 @@ // =20 /** + Determine if the standard CPU signature is "AuthenticAMD". + + @retval TRUE The CPU signature matches. + @retval FALSE The CPU signature does not match. + +**/ +BOOLEAN +StandardSignatureIsAuthenticAMD ( + VOID + ) +{ + UINT32 RegEbx; + UINT32 RegEcx; + UINT32 RegEdx; + + AsmCpuid(CPUID_SIGNATURE, NULL, &RegEbx, &RegEcx, &RegEdx); + return (RegEbx =3D=3D CPUID_SIGNATURE_AUTHENTIC_AMD_EBX && + RegEcx =3D=3D CPUID_SIGNATURE_AUTHENTIC_AMD_ECX && + RegEdx =3D=3D CPUID_SIGNATURE_AUTHENTIC_AMD_EDX); +} + +/** Determine if the CPU supports the Local APIC Base Address MSR. =20 @retval TRUE The CPU supports the Local APIC Base Address MSR. @@ -966,20 +991,30 @@ GetProcessorLocationByApicId ( OUT UINT32 *Thread OPTIONAL ) { - BOOLEAN TopologyLeafSupported; - UINTN ThreadBits; - UINTN CoreBits; - CPUID_VERSION_INFO_EBX VersionInfoEbx; - CPUID_VERSION_INFO_EDX VersionInfoEdx; - CPUID_CACHE_PARAMS_EAX CacheParamsEax; - CPUID_EXTENDED_TOPOLOGY_EAX ExtendedTopologyEax; - CPUID_EXTENDED_TOPOLOGY_EBX ExtendedTopologyEbx; - CPUID_EXTENDED_TOPOLOGY_ECX ExtendedTopologyEcx; - UINT32 MaxCpuIdIndex; - UINT32 SubIndex; - UINTN LevelType; - UINT32 MaxLogicProcessorsPerPackage; - UINT32 MaxCoresPerPackage; + BOOLEAN TopologyLeafSupported; + CPUID_VERSION_INFO_EBX VersionInfoEbx; + CPUID_VERSION_INFO_EDX VersionInfoEdx; + CPUID_CACHE_PARAMS_EAX CacheParamsEax; + CPUID_EXTENDED_TOPOLOGY_EAX ExtendedTopologyEax; + CPUID_EXTENDED_TOPOLOGY_EBX ExtendedTopologyEbx; + CPUID_EXTENDED_TOPOLOGY_ECX ExtendedTopologyEcx; + CPUID_AMD_EXTENDED_CPU_SIG_ECX AmdExtendedCpuSigEcx; + CPUID_AMD_PROCESSOR_TOPOLOGY_EBX AmdProcessorTopologyEbx; + CPUID_AMD_PROCESSOR_TOPOLOGY_ECX AmdProcessorTopologyEcx; + CPUID_AMD_VIR_PHY_ADDRESS_SIZE_ECX AmdVirPhyAddressSizeEcx; + UINT32 MaxStandardCpuIdIndex; + UINT32 MaxExtendedCpuIdIndex; + UINT32 SubIndex; + UINTN LevelType; + UINT32 MaxLogicProcessorsPerPackage; + UINT32 MaxCoresPerPackage; + UINT32 MaxThreadPerPackageMask; + UINT32 ActualThreadPerPackageMask; + UINT32 MaxCoresPerNode; + UINT32 CorePerNodeMask; + UINT32 ApicIdShift; + UINTN ThreadBits; + UINTN CoreBits; =20 // // Check if the processor is capable of supporting more than one logical= processor. @@ -987,10 +1022,10 @@ GetProcessorLocationByApicId ( AsmCpuid(CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32); if (VersionInfoEdx.Bits.HTT =3D=3D 0) { if (Thread !=3D NULL) { - *Thread =3D 0; + *Thread =3D 0; } if (Core !=3D NULL) { - *Core =3D 0; + *Core =3D 0; } if (Package !=3D NULL) { *Package =3D 0; @@ -998,24 +1033,24 @@ GetProcessorLocationByApicId ( return; } =20 + // + // Assume three-level mapping of APIC ID: Package|Core|Thread. + // ThreadBits =3D 0; CoreBits =3D 0; =20 // - // Assume three-level mapping of APIC ID: Package:Core:SMT. + // Get max index of CPUID // - TopologyLeafSupported =3D FALSE; - - // - // Get the max index of basic CPUID - // - AsmCpuid(CPUID_SIGNATURE, &MaxCpuIdIndex, NULL, NULL, NULL); + AsmCpuid(CPUID_SIGNATURE, &MaxStandardCpuIdIndex, NULL, NULL, NULL); + AsmCpuid(CPUID_EXTENDED_FUNCTION, &MaxExtendedCpuIdIndex, NULL, NULL, NU= LL); =20 // // If the extended topology enumeration leaf is available, it // is the preferred mechanism for enumerating topology. // - if (MaxCpuIdIndex >=3D CPUID_EXTENDED_TOPOLOGY) { + TopologyLeafSupported =3D FALSE; + if (MaxStandardCpuIdIndex >=3D CPUID_EXTENDED_TOPOLOGY) { AsmCpuidEx( CPUID_EXTENDED_TOPOLOGY, 0, @@ -1065,27 +1100,85 @@ GetProcessorLocationByApicId ( } =20 if (!TopologyLeafSupported) { + // + // Get logical processor count + // AsmCpuid(CPUID_VERSION_INFO, NULL, &VersionInfoEbx.Uint32, NULL, NULL)= ; MaxLogicProcessorsPerPackage =3D VersionInfoEbx.Bits.MaximumAddressabl= eIdsForLogicalProcessors; - if (MaxCpuIdIndex >=3D CPUID_CACHE_PARAMS) { - AsmCpuidEx(CPUID_CACHE_PARAMS, 0, &CacheParamsEax.Uint32, NULL, NULL= , NULL); - MaxCoresPerPackage =3D CacheParamsEax.Bits.MaximumAddressableIdsForL= ogicalProcessors + 1; + + // + // Assume single-core processor + // + MaxCoresPerPackage =3D 1; + + // + // Check for topology extensions on AMD processor + // + if (StandardSignatureIsAuthenticAMD()) { + if (MaxExtendedCpuIdIndex >=3D CPUID_AMD_PROCESSOR_TOPOLOGY) { + AsmCpuid(CPUID_EXTENDED_CPU_SIG, NULL, NULL, &AmdExtendedCpuSigEcx= .Uint32, NULL); + if (AmdExtendedCpuSigEcx.Bits.TopologyExtensions !=3D 0) { + AsmCpuid(CPUID_AMD_PROCESSOR_TOPOLOGY, NULL, &AmdProcessorTopolo= gyEbx.Uint32, + &AmdProcessorTopologyEcx.Uint32, NULL); + // + // Get cores per processor package + // + MaxCoresPerPackage =3D MaxLogicProcessorsPerPackage / (AmdProces= sorTopologyEbx.Bits.ThreadsPerCore + 1); + + // + // Account for actual thread count (e.g., SMT disabled) + // + AsmCpuid(CPUID_VIR_PHY_ADDRESS_SIZE, NULL, NULL, &AmdVirPhyAddre= ssSizeEcx.Uint32, NULL); + MaxThreadPerPackageMask =3D 1 << AmdVirPhyAddressSizeEcx.Bits.Ap= icIdCoreIdSize; + ActualThreadPerPackageMask =3D 1; + while (ActualThreadPerPackageMask < MaxLogicProcessorsPerPackage= ) { + ActualThreadPerPackageMask <<=3D 1; + } + + // + // Adjust APIC Id to report concatenation of Package|Core|Thread= . + // + if (ActualThreadPerPackageMask < MaxThreadPerPackageMask) { + MaxCoresPerNode =3D MaxCoresPerPackage / (AmdProcessorTopology= Ecx.Bits.NodesPerProcessor + 1); + + CorePerNodeMask =3D 1; + while (CorePerNodeMask < MaxCoresPerNode) { + CorePerNodeMask <<=3D 1; + } + CorePerNodeMask -=3D 1; + + ApicIdShift =3D 0; + do { + ApicIdShift +=3D 1; + ActualThreadPerPackageMask <<=3D 1; + } while (ActualThreadPerPackageMask < MaxThreadPerPackageMask)= ; + + InitialApicId =3D ((InitialApicId & ~CorePerNodeMask) >> ApicI= dShift) | (InitialApicId & CorePerNodeMask); + } + } + } } else { // - // Must be a single-core processor. + // Extract core count based on CACHE information // - MaxCoresPerPackage =3D 1; + if (MaxStandardCpuIdIndex >=3D CPUID_CACHE_PARAMS) { + AsmCpuidEx(CPUID_CACHE_PARAMS, 0, &CacheParamsEax.Uint32, NULL, NU= LL, NULL); + if (CacheParamsEax.Uint32 !=3D 0) { + MaxCoresPerPackage =3D CacheParamsEax.Bits.MaximumAddressableIds= ForLogicalProcessors + 1; + } + } } =20 ThreadBits =3D (UINTN)(HighBitSet32(MaxLogicProcessorsPerPackage / Max= CoresPerPackage - 1) + 1); - CoreBits =3D (UINTN)(HighBitSet32(MaxCoresPerPackage - 1) + 1); } + CoreBits =3D (UINTN)(HighBitSet32(MaxCoresPerPackage - 1) + 1); + } =20 if (Thread !=3D NULL) { - *Thread =3D InitialApicId & ((1 << ThreadBits) - 1); + *Thread =3D InitialApicId & ((1 << ThreadBits) - 1); } if (Core !=3D NULL) { - *Core =3D (InitialApicId >> ThreadBits) & ((1 << CoreBits) - 1); + *Core =3D (InitialApicId >> ThreadBits) & ((1 << CoreBits) - 1); } if (Package !=3D NULL) { *Package =3D (InitialApicId >> (ThreadBits + CoreBits)); diff --git a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c b/U= efiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c index e690d2a..d5d4efa 100644 --- a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c +++ b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c @@ -5,6 +5,8 @@ which have xAPIC and x2APIC modes. =20 Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.
+ Copyright (c) 2017, AMD Inc. All rights reserved.
+ This program and the accompanying materials are licensed and made available under the terms and conditions of the BS= D License which accompanies this distribution. The full text of the license may b= e found at @@ -16,6 +18,7 @@ **/ =20 #include +#include #include #include =20 @@ -31,6 +34,28 @@ // =20 /** + Determine if the standard CPU signature is "AuthenticAMD". + + @retval TRUE The CPU signature matches. + @retval FALSE The CPU signature does not match. + +**/ +BOOLEAN +StandardSignatureIsAuthenticAMD ( + VOID + ) +{ + UINT32 RegEbx; + UINT32 RegEcx; + UINT32 RegEdx; + + AsmCpuid(CPUID_SIGNATURE, NULL, &RegEbx, &RegEcx, &RegEdx); + return (RegEbx =3D=3D CPUID_SIGNATURE_AUTHENTIC_AMD_EBX && + RegEcx =3D=3D CPUID_SIGNATURE_AUTHENTIC_AMD_ECX && + RegEdx =3D=3D CPUID_SIGNATURE_AUTHENTIC_AMD_EDX); +} + +/** Determine if the CPU supports the Local APIC Base Address MSR. =20 @retval TRUE The CPU supports the Local APIC Base Address MSR. @@ -1061,20 +1086,30 @@ GetProcessorLocationByApicId ( OUT UINT32 *Thread OPTIONAL ) { - BOOLEAN TopologyLeafSupported; - UINTN ThreadBits; - UINTN CoreBits; - CPUID_VERSION_INFO_EBX VersionInfoEbx; - CPUID_VERSION_INFO_EDX VersionInfoEdx; - CPUID_CACHE_PARAMS_EAX CacheParamsEax; - CPUID_EXTENDED_TOPOLOGY_EAX ExtendedTopologyEax; - CPUID_EXTENDED_TOPOLOGY_EBX ExtendedTopologyEbx; - CPUID_EXTENDED_TOPOLOGY_ECX ExtendedTopologyEcx; - UINT32 MaxCpuIdIndex; - UINT32 SubIndex; - UINTN LevelType; - UINT32 MaxLogicProcessorsPerPackage; - UINT32 MaxCoresPerPackage; + BOOLEAN TopologyLeafSupported; + CPUID_VERSION_INFO_EBX VersionInfoEbx; + CPUID_VERSION_INFO_EDX VersionInfoEdx; + CPUID_CACHE_PARAMS_EAX CacheParamsEax; + CPUID_EXTENDED_TOPOLOGY_EAX ExtendedTopologyEax; + CPUID_EXTENDED_TOPOLOGY_EBX ExtendedTopologyEbx; + CPUID_EXTENDED_TOPOLOGY_ECX ExtendedTopologyEcx; + CPUID_AMD_EXTENDED_CPU_SIG_ECX AmdExtendedCpuSigEcx; + CPUID_AMD_PROCESSOR_TOPOLOGY_EBX AmdProcessorTopologyEbx; + CPUID_AMD_PROCESSOR_TOPOLOGY_ECX AmdProcessorTopologyEcx; + CPUID_AMD_VIR_PHY_ADDRESS_SIZE_ECX AmdVirPhyAddressSizeEcx; + UINT32 MaxStandardCpuIdIndex; + UINT32 MaxExtendedCpuIdIndex; + UINT32 SubIndex; + UINTN LevelType; + UINT32 MaxLogicProcessorsPerPackage; + UINT32 MaxCoresPerPackage; + UINT32 MaxThreadPerPackageMask; + UINT32 ActualThreadPerPackageMask; + UINT32 MaxCoresPerNode; + UINT32 CorePerNodeMask; + UINT32 ApicIdShift; + UINTN ThreadBits; + UINTN CoreBits; =20 // // Check if the processor is capable of supporting more than one logical= processor. @@ -1082,10 +1117,10 @@ GetProcessorLocationByApicId ( AsmCpuid(CPUID_VERSION_INFO, NULL, NULL, NULL, &VersionInfoEdx.Uint32); if (VersionInfoEdx.Bits.HTT =3D=3D 0) { if (Thread !=3D NULL) { - *Thread =3D 0; + *Thread =3D 0; } if (Core !=3D NULL) { - *Core =3D 0; + *Core =3D 0; } if (Package !=3D NULL) { *Package =3D 0; @@ -1093,24 +1128,24 @@ GetProcessorLocationByApicId ( return; } =20 + // + // Assume three-level mapping of APIC ID: Package|Core|Thread. + // ThreadBits =3D 0; CoreBits =3D 0; =20 // - // Assume three-level mapping of APIC ID: Package:Core:SMT. + // Get max index of CPUID // - TopologyLeafSupported =3D FALSE; - - // - // Get the max index of basic CPUID - // - AsmCpuid(CPUID_SIGNATURE, &MaxCpuIdIndex, NULL, NULL, NULL); + AsmCpuid(CPUID_SIGNATURE, &MaxStandardCpuIdIndex, NULL, NULL, NULL); + AsmCpuid(CPUID_EXTENDED_FUNCTION, &MaxExtendedCpuIdIndex, NULL, NULL, NU= LL); =20 // // If the extended topology enumeration leaf is available, it // is the preferred mechanism for enumerating topology. // - if (MaxCpuIdIndex >=3D CPUID_EXTENDED_TOPOLOGY) { + TopologyLeafSupported =3D FALSE; + if (MaxStandardCpuIdIndex >=3D CPUID_EXTENDED_TOPOLOGY) { AsmCpuidEx( CPUID_EXTENDED_TOPOLOGY, 0, @@ -1160,27 +1195,85 @@ GetProcessorLocationByApicId ( } =20 if (!TopologyLeafSupported) { + // + // Get logical processor count + // AsmCpuid(CPUID_VERSION_INFO, NULL, &VersionInfoEbx.Uint32, NULL, NULL)= ; MaxLogicProcessorsPerPackage =3D VersionInfoEbx.Bits.MaximumAddressabl= eIdsForLogicalProcessors; - if (MaxCpuIdIndex >=3D CPUID_CACHE_PARAMS) { - AsmCpuidEx(CPUID_CACHE_PARAMS, 0, &CacheParamsEax.Uint32, NULL, NULL= , NULL); - MaxCoresPerPackage =3D CacheParamsEax.Bits.MaximumAddressableIdsForL= ogicalProcessors + 1; + + // + // Assume single-core processor + // + MaxCoresPerPackage =3D 1; + + // + // Check for topology extensions on AMD processor + // + if (StandardSignatureIsAuthenticAMD()) { + if (MaxExtendedCpuIdIndex >=3D CPUID_AMD_PROCESSOR_TOPOLOGY) { + AsmCpuid(CPUID_EXTENDED_CPU_SIG, NULL, NULL, &AmdExtendedCpuSigEcx= .Uint32, NULL); + if (AmdExtendedCpuSigEcx.Bits.TopologyExtensions !=3D 0) { + AsmCpuid(CPUID_AMD_PROCESSOR_TOPOLOGY, NULL, &AmdProcessorTopolo= gyEbx.Uint32, + &AmdProcessorTopologyEcx.Uint32, NULL); + // + // Get cores per processor package + // + MaxCoresPerPackage =3D MaxLogicProcessorsPerPackage / (AmdProces= sorTopologyEbx.Bits.ThreadsPerCore + 1); + + // + // Account for actual thread count (e.g., SMT disabled) + // + AsmCpuid(CPUID_VIR_PHY_ADDRESS_SIZE, NULL, NULL, &AmdVirPhyAddre= ssSizeEcx.Uint32, NULL); + MaxThreadPerPackageMask =3D 1 << AmdVirPhyAddressSizeEcx.Bits.Ap= icIdCoreIdSize; + ActualThreadPerPackageMask =3D 1; + while (ActualThreadPerPackageMask < MaxLogicProcessorsPerPackage= ) { + ActualThreadPerPackageMask <<=3D 1; + } + + // + // Adjust APIC Id to report concatenation of Package|Core|Thread= . + // + if (ActualThreadPerPackageMask < MaxThreadPerPackageMask) { + MaxCoresPerNode =3D MaxCoresPerPackage / (AmdProcessorTopology= Ecx.Bits.NodesPerProcessor + 1); + + CorePerNodeMask =3D 1; + while (CorePerNodeMask < MaxCoresPerNode) { + CorePerNodeMask <<=3D 1; + } + CorePerNodeMask -=3D 1; + + ApicIdShift =3D 0; + do { + ApicIdShift +=3D 1; + ActualThreadPerPackageMask <<=3D 1; + } while (ActualThreadPerPackageMask < MaxThreadPerPackageMask)= ; + + InitialApicId =3D ((InitialApicId & ~CorePerNodeMask) >> ApicI= dShift) | (InitialApicId & CorePerNodeMask); + } + } + } } else { // - // Must be a single-core processor. + // Extract core count based on CACHE information // - MaxCoresPerPackage =3D 1; + if (MaxStandardCpuIdIndex >=3D CPUID_CACHE_PARAMS) { + AsmCpuidEx(CPUID_CACHE_PARAMS, 0, &CacheParamsEax.Uint32, NULL, NU= LL, NULL); + if (CacheParamsEax.Uint32 !=3D 0) { + MaxCoresPerPackage =3D CacheParamsEax.Bits.MaximumAddressableIds= ForLogicalProcessors + 1; + } + } } =20 ThreadBits =3D (UINTN)(HighBitSet32(MaxLogicProcessorsPerPackage / Max= CoresPerPackage - 1) + 1); - CoreBits =3D (UINTN)(HighBitSet32(MaxCoresPerPackage - 1) + 1); } + CoreBits =3D (UINTN)(HighBitSet32(MaxCoresPerPackage - 1) + 1); + } =20 if (Thread !=3D NULL) { - *Thread =3D InitialApicId & ((1 << ThreadBits) - 1); + *Thread =3D InitialApicId & ((1 << ThreadBits) - 1); } if (Core !=3D NULL) { - *Core =3D (InitialApicId >> ThreadBits) & ((1 << CoreBits) - 1); + *Core =3D (InitialApicId >> ThreadBits) & ((1 << CoreBits) - 1); } if (Package !=3D NULL) { *Package =3D (InitialApicId >> (ThreadBits + CoreBits)); --=20 2.7.4