From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from NAM02-BL2-obe.outbound.protection.outlook.com (mail-bl2nam02on0079.outbound.protection.outlook.com [104.47.38.79]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 3E42D2095D220 for ; Wed, 21 Jun 2017 10:45:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amdcloud.onmicrosoft.com; s=selector1-amd-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=qpEH6Cp9pHmveGC/XJdOCCQDFjsM3fvTo3E0kgYHosg=; b=letCMgy/bBxeWSM7/IclHQCF26DuW3ySx5d66yxhsObevApKDlzGNR988V/v9HMugYojUtFiuSsldqcZOPyLFMzkaGkpTPvordOGGRbKAMYbZgA8jSpg2XSlcfK3rv1jM0zIMjAfY8GlVWoFshZ+8uR91vO/L6mGO054kDTJPMk= Received: from DM5PR12MB1243.namprd12.prod.outlook.com (10.168.237.22) by BY2PR12MB0148.namprd12.prod.outlook.com (10.162.82.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1199.15; Wed, 21 Jun 2017 17:46:30 +0000 Received: from DM5PR12MB1243.namprd12.prod.outlook.com ([10.168.237.22]) by DM5PR12MB1243.namprd12.prod.outlook.com ([10.168.237.22]) with mapi id 15.01.1178.018; Wed, 21 Jun 2017 17:46:29 +0000 From: "Duran, Leo" To: "'Fan, Jeff'" , "edk2-devel@lists.01.org" CC: "Justen, Jordan L" , "Gao, Liming" , "Singh, Brijesh" Thread-Topic: [PATCH v5 2/2] UefiCpuPkg: Modify GetProcessorLocationByApicId() to support AMD. Thread-Index: AQHS5wKK5iBGL0M2Yk+jKQkNL6eU26IumOAAgAEFdiA= Date: Wed, 21 Jun 2017 17:46:28 +0000 Message-ID: References: <1497660109-18243-1-git-send-email-leo.duran@amd.com> <1497660109-18243-3-git-send-email-leo.duran@amd.com> <542CF652F8836A4AB8DBFAAD40ED192A4C610A9F@shsmsx102.ccr.corp.intel.com> In-Reply-To: <542CF652F8836A4AB8DBFAAD40ED192A4C610A9F@shsmsx102.ccr.corp.intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: intel.com; dkim=none (message not signed) header.d=none;intel.com; dmarc=none action=none header.from=amd.com; x-originating-ip: [165.204.77.1] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; BY2PR12MB0148; 20:3FQB4qfZHJtbH6cO9iZqId+6H8b4+NOKWih+SMXxUNWC9idtf0iF25soGT3e1eW6i+PM8WeVkvlyhqkr/TqQFtMAUKvk03cXR0SZfxZuIbv884z5E9rk/EzKbsk/aUvI+DU5u1vKA4mecq8D2FjjJyA9WGyHkWo/NQv1s+e+WfbgAyXrgMNXvJTSEkx5jzvHPrDrM7byKfakf6OyUI5nloTAxz0eIPk4N76aUJq+2+hOezDf9aZx/i3sRdyDcFVR x-forefront-antispam-report: SFV:SKI; SCL:-1SFV:NSPM; SFS:(10009020)(6009001)(6029001)(39410400002)(39450400003)(39860400002)(39840400002)(39850400002)(39400400002)(13464003)(377454003)(53946003)(77096006)(53936002)(122556002)(6246003)(9686003)(55016002)(74316002)(54906002)(99286003)(6436002)(478600001)(189998001)(5660300001)(86362001)(2900100001)(14454004)(2906002)(7696004)(3280700002)(38730400002)(6506006)(2501003)(53546010)(3660700001)(305945005)(229853002)(2950100002)(25786009)(33656002)(3846002)(6116002)(76176999)(102836003)(50986999)(54356999)(8936002)(81166006)(8676002)(7736002)(66066001)(4326008)(579004)(19627235001); DIR:OUT; SFP:1101; SCL:1; SRVR:BY2PR12MB0148; H:DM5PR12MB1243.namprd12.prod.outlook.com; FPR:; SPF:None; MLV:sfv; LANG:en; x-ms-office365-filtering-correlation-id: fba2f28b-01cc-4a25-c77f-08d4b8cd7257 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: UriScan:; BCL:0; PCL:0; RULEID:(300000500055)(300135000095)(300000501055)(300135300095)(22001)(300000502055)(300135100095)(2017030254075)(48565401081)(300000503055)(300135400095)(201703131423075)(201703031133081)(300000504055)(300135200095)(300000505055)(300135600095)(300000506048)(300135500095); SRVR:BY2PR12MB0148; x-ms-traffictypediagnostic: BY2PR12MB0148: x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(767451399110)(162533806227266)(228905959029699); x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(601004)(2401047)(8121501046)(5005006)(10201501046)(3002001)(100000703101)(100105400095)(93006095)(93001095)(6055026)(6041248)(20161123555025)(20161123562025)(20161123564025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123558100)(20161123560025)(6072148)(100000704101)(100105200095)(100000705101)(100105500095); SRVR:BY2PR12MB0148; BCL:0; PCL:0; RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095); SRVR:BY2PR12MB0148; x-forefront-prvs: 0345CFD558 spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-originalarrivaltime: 21 Jun 2017 17:46:29.0838 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY2PR12MB0148 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 17:45:09 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Excellent, Jeff. Thanks, Leo. > -----Original Message----- > From: Fan, Jeff [mailto:jeff.fan@intel.com] > Sent: Tuesday, June 20, 2017 9:10 PM > To: Duran, Leo ; edk2-devel@lists.01.org > Cc: Justen, Jordan L ; Gao, Liming > ; Singh, Brijesh > Subject: RE: [PATCH v5 2/2] UefiCpuPkg: Modify > GetProcessorLocationByApicId() to support AMD. >=20 > Reviewed-by: Jeff Fan >=20 > I noticed this serial of patches depend on another SEV patch on UefiCpuPk= g( > I have reviewed-by it before). > I will push them together in a couple of days if you have no other commen= ts. >=20 > Thanks! > Jeff >=20 > -----Original Message----- > From: Leo Duran [mailto:leo.duran@amd.com] > 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() > to support AMD. >=20 > 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(-) >=20 > diff --git a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c > b/UefiCpuPkg/Library/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 = BSD > License > which accompanies this distribution. The full text of the license may= be > 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 logic= al > 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, > + NULL); >=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.MaximumAddressableIdsForLogicalProcessors; > - if (MaxCpuIdIndex >=3D CPUID_CACHE_PARAMS) { > - AsmCpuidEx(CPUID_CACHE_PARAMS, 0, &CacheParamsEax.Uint32, > NULL, NULL, NULL); > - MaxCoresPerPackage =3D > CacheParamsEax.Bits.MaximumAddressableIdsForLogicalProcessors + 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, > &AmdProcessorTopologyEbx.Uint32, > + &AmdProcessorTopologyEcx.Uint32, NULL); > + // > + // Get cores per processor package > + // > + MaxCoresPerPackage =3D MaxLogicProcessorsPerPackage / > + (AmdProcessorTopologyEbx.Bits.ThreadsPerCore + 1); > + > + // > + // Account for actual thread count (e.g., SMT disabled) > + // > + AsmCpuid(CPUID_VIR_PHY_ADDRESS_SIZE, NULL, NULL, > &AmdVirPhyAddressSizeEcx.Uint32, NULL); > + MaxThreadPerPackageMask =3D 1 << > AmdVirPhyAddressSizeEcx.Bits.ApicIdCoreIdSize; > + ActualThreadPerPackageMask =3D 1; > + while (ActualThreadPerPackageMask < > MaxLogicProcessorsPerPackage) { > + ActualThreadPerPackageMask <<=3D 1; > + } > + > + // > + // Adjust APIC Id to report concatenation of Package|Core|Thre= ad. > + // > + if (ActualThreadPerPackageMask < MaxThreadPerPackageMask) { > + MaxCoresPerNode =3D MaxCoresPerPackage / > + (AmdProcessorTopologyEcx.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) >> Api= cIdShift) | > (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, NULL, NULL); > + if (CacheParamsEax.Uint32 !=3D 0) { > + MaxCoresPerPackage =3D > CacheParamsEax.Bits.MaximumAddressableIdsForLogicalProcessors + 1; > + } > + } > } >=20 > ThreadBits =3D (UINTN)(HighBitSet32(MaxLogicProcessorsPerPackage / > MaxCoresPerPackage - 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/UefiCpuPkg/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 = BSD > License > which accompanies this distribution. The full text of the license may= be > 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 logic= al > 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, > + NULL); >=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.MaximumAddressableIdsForLogicalProcessors; > - if (MaxCpuIdIndex >=3D CPUID_CACHE_PARAMS) { > - AsmCpuidEx(CPUID_CACHE_PARAMS, 0, &CacheParamsEax.Uint32, > NULL, NULL, NULL); > - MaxCoresPerPackage =3D > CacheParamsEax.Bits.MaximumAddressableIdsForLogicalProcessors + 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, > &AmdProcessorTopologyEbx.Uint32, > + &AmdProcessorTopologyEcx.Uint32, NULL); > + // > + // Get cores per processor package > + // > + MaxCoresPerPackage =3D MaxLogicProcessorsPerPackage / > + (AmdProcessorTopologyEbx.Bits.ThreadsPerCore + 1); > + > + // > + // Account for actual thread count (e.g., SMT disabled) > + // > + AsmCpuid(CPUID_VIR_PHY_ADDRESS_SIZE, NULL, NULL, > &AmdVirPhyAddressSizeEcx.Uint32, NULL); > + MaxThreadPerPackageMask =3D 1 << > AmdVirPhyAddressSizeEcx.Bits.ApicIdCoreIdSize; > + ActualThreadPerPackageMask =3D 1; > + while (ActualThreadPerPackageMask < > MaxLogicProcessorsPerPackage) { > + ActualThreadPerPackageMask <<=3D 1; > + } > + > + // > + // Adjust APIC Id to report concatenation of Package|Core|Thre= ad. > + // > + if (ActualThreadPerPackageMask < MaxThreadPerPackageMask) { > + MaxCoresPerNode =3D MaxCoresPerPackage / > + (AmdProcessorTopologyEcx.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) >> Api= cIdShift) | > (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, NULL, NULL); > + if (CacheParamsEax.Uint32 !=3D 0) { > + MaxCoresPerPackage =3D > CacheParamsEax.Bits.MaximumAddressableIdsForLogicalProcessors + 1; > + } > + } > } >=20 > ThreadBits =3D (UINTN)(HighBitSet32(MaxLogicProcessorsPerPackage / > MaxCoresPerPackage - 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)); > -- > 2.7.4