From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 134.134.136.126, mailfrom: eric.dong@intel.com) Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by groups.io with SMTP; Thu, 04 Apr 2019 05:28:46 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 04 Apr 2019 05:28:46 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.60,308,1549958400"; d="scan'208";a="132928712" Received: from fmsmsx105.amr.corp.intel.com ([10.18.124.203]) by orsmga006.jf.intel.com with ESMTP; 04 Apr 2019 05:28:45 -0700 Received: from fmsmsx115.amr.corp.intel.com (10.18.116.19) by FMSMSX105.amr.corp.intel.com (10.18.124.203) with Microsoft SMTP Server (TLS) id 14.3.408.0; Thu, 4 Apr 2019 05:28:45 -0700 Received: from shsmsx106.ccr.corp.intel.com (10.239.4.159) by fmsmsx115.amr.corp.intel.com (10.18.116.19) with Microsoft SMTP Server (TLS) id 14.3.408.0; Thu, 4 Apr 2019 05:28:45 -0700 Received: from shsmsx102.ccr.corp.intel.com ([169.254.2.206]) by SHSMSX106.ccr.corp.intel.com ([169.254.10.21]) with mapi id 14.03.0415.000; Thu, 4 Apr 2019 20:28:43 +0800 From: "Dong, Eric" To: "devel@edk2.groups.io" , "Ni, Ray" CC: "Zeng, Star" , "Qin, Zhiqiang" Subject: Re: [edk2-devel] [PATCH v2] UefiCpuPkg/LocalApicLib: Add GetProcessorLocation2ByApicId() API Thread-Topic: [edk2-devel] [PATCH v2] UefiCpuPkg/LocalApicLib: Add GetProcessorLocation2ByApicId() API Thread-Index: AQHU6rptXyFiUm4GxEqk4HARVtA1IqYr7lEQ Date: Thu, 4 Apr 2019 12:28:42 +0000 Message-ID: References: <20190404074838.62736-1-ray.ni@intel.com> In-Reply-To: <20190404074838.62736-1-ray.ni@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiY2ZlODNiZjktZGJlOS00NjljLWEwNjMtYTRkNzVmNzZlNzQyIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoibUc3RnZQY1BiSnVGdVpZQWUraGpNeWltcGdnWHZkd0UwK2VFT1NMYWJqWEhmZUg0V3VzYm9kUTlGZXpwclVKRSJ9 x-ctpclassification: CTP_NT dlp-product: dlpe-windows dlp-version: 11.0.400.15 dlp-reaction: no-action x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Return-Path: eric.dong@intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Eric Dong > -----Original Message----- > From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of Ni= , > Ray > Sent: Thursday, April 4, 2019 3:49 PM > To: devel@edk2.groups.io > Cc: Dong, Eric ; Zeng, Star ; = Qin, > Zhiqiang > Subject: [edk2-devel] [PATCH v2] UefiCpuPkg/LocalApicLib: Add > GetProcessorLocation2ByApicId() API >=20 > GetProcessorLocation2ByApicId() extracts the > package/die/tile/module/core/thread ID from the initial APIC ID. >=20 > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Ray Ni > Cc: Eric Dong > Cc: Star Zeng > Cc: Zhiqiang Qin > --- > UefiCpuPkg/Include/Library/LocalApicLib.h | 29 +++- > .../Library/BaseXApicLib/BaseXApicLib.c | 125 +++++++++++++++++- > .../BaseXApicX2ApicLib/BaseXApicX2ApicLib.c | 125 +++++++++++++++++- > 3 files changed, 276 insertions(+), 3 deletions(-) >=20 > diff --git a/UefiCpuPkg/Include/Library/LocalApicLib.h > b/UefiCpuPkg/Include/Library/LocalApicLib.h > index ad1c26df60..ffe60c56fc 100644 > --- a/UefiCpuPkg/Include/Library/LocalApicLib.h > +++ b/UefiCpuPkg/Include/Library/LocalApicLib.h > @@ -4,7 +4,7 @@ > Local APIC library assumes local APIC is enabled. It does not > handles cases where local APIC is disabled. >=20 > - Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved. > + Copyright (c) 2010 - 2019, Intel Corporation. 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 ma= y be found > at @@ -432,5 +432,32 @@ GetProcessorLocationByApicId ( > OUT UINT32 *Thread OPTIONAL > ); >=20 > +/** > + Get Package ID/Module ID/Tile ID/Die ID/Core ID/Thread ID of a proces= sor. > + > + The algorithm assumes the target system has symmetry across physical > + package boundaries with respect to the number of threads per core, > + number of cores per module, number of modules per tile, number of > + tiles per die, number of dies per package. > + > + @param[in] InitialApicId Initial APIC ID of the target logical proc= essor. > + @param[out] Package Returns the processor package ID. > + @param[out] Die Returns the processor die ID. > + @param[out] Tile Returns the processor tile ID. > + @param[out] Module Returns the processor module ID. > + @param[out] Core Returns the processor core ID. > + @param[out] Thread Returns the processor thread ID. > +**/ > +VOID > +EFIAPI > +GetProcessorLocation2ByApicId ( > + IN UINT32 InitialApicId, > + OUT UINT32 *Package OPTIONAL, > + OUT UINT32 *Die OPTIONAL, > + OUT UINT32 *Tile OPTIONAL, > + OUT UINT32 *Module OPTIONAL, > + OUT UINT32 *Core OPTIONAL, > + OUT UINT32 *Thread OPTIONAL > + ); > #endif >=20 > diff --git a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c > b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c > index 7d66d89dfd..fd8c494a9f 100644 > --- a/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c > +++ b/UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.c > @@ -3,7 +3,7 @@ >=20 > This local APIC library instance supports xAPIC mode only. >=20 > - Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved. > + Copyright (c) 2010 - 2019, Intel Corporation. All rights > + reserved.
> Copyright (c) 2017, AMD Inc. All rights reserved.
>=20 > This program and the accompanying materials @@ -1156,3 +1156,126 @@ > GetProcessorLocationByApicId ( > *Package =3D (InitialApicId >> (ThreadBits + CoreBits)); > } > } > + > +/** > + Get Package ID/Die ID/Tile ID/Module ID/Core ID/Thread ID of a proces= sor. > + > + The algorithm assumes the target system has symmetry across physical > + package boundaries with respect to the number of threads per core, > + number of cores per module, number of modules per tile, number of > + tiles per die, number of dies per package. > + > + @param[in] InitialApicId Initial APIC ID of the target logical proc= essor. > + @param[out] Package Returns the processor package ID. > + @param[out] Die Returns the processor die ID. > + @param[out] Tile Returns the processor tile ID. > + @param[out] Module Returns the processor module ID. > + @param[out] Core Returns the processor core ID. > + @param[out] Thread Returns the processor thread ID. > +**/ > +VOID > +EFIAPI > +GetProcessorLocation2ByApicId ( > + IN UINT32 InitialApicId, > + OUT UINT32 *Package OPTIONAL, > + OUT UINT32 *Die OPTIONAL, > + OUT UINT32 *Tile OPTIONAL, > + OUT UINT32 *Module OPTIONAL, > + OUT UINT32 *Core OPTIONAL, > + OUT UINT32 *Thread OPTIONAL > + ) > +{ > + CPUID_EXTENDED_TOPOLOGY_EAX ExtendedTopologyEax; > + CPUID_EXTENDED_TOPOLOGY_ECX ExtendedTopologyEcx; > + UINT32 MaxStandardCpuIdIndex; > + UINT32 Index; > + UINTN LevelType; > + UINT32 > Bits[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 2]; > + UINT32 > *Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 2]; > + > + for (LevelType =3D 0; LevelType < ARRAY_SIZE (Bits); LevelType++) { > + Bits[LevelType] =3D 0; > + } > + > + // > + // Get max index of CPUID > + // > + AsmCpuid (CPUID_SIGNATURE, &MaxStandardCpuIdIndex, NULL, NULL, > NULL); > + if (MaxStandardCpuIdIndex < CPUID_V2_EXTENDED_TOPOLOGY) { > + if (Die !=3D NULL) { > + *Die =3D 0; > + } > + if (Tile !=3D NULL) { > + *Tile =3D 0; > + } > + if (Module !=3D NULL) { > + *Module =3D 0; > + } > + GetProcessorLocationByApicId (InitialApicId, Package, Core, Thread)= ; > + return; > + } > + > + // > + // If the V2 extended topology enumeration leaf is available, it // > + is the preferred mechanism for enumerating topology. > + // > + for (Index =3D 0; ; Index++) { > + AsmCpuidEx( > + CPUID_V2_EXTENDED_TOPOLOGY, > + Index, > + &ExtendedTopologyEax.Uint32, > + NULL, > + &ExtendedTopologyEcx.Uint32, > + NULL > + ); > + > + LevelType =3D ExtendedTopologyEcx.Bits.LevelType; > + > + // > + // first level reported should be SMT. > + // > + ASSERT ((Index !=3D 0) || (LevelType =3D=3D > CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT)); > + if (LevelType =3D=3D CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID) { > + break; > + } > + ASSERT (LevelType < ARRAY_SIZE (Bits)); > + Bits[LevelType] =3D ExtendedTopologyEax.Bits.ApicIdShift; > + } > + > + for (LevelType =3D CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE; > LevelType < ARRAY_SIZE (Bits); LevelType++) { > + // > + // If there are more levels between level-1 (low-level) and level-2= (high-level), > the unknown levels will be ignored > + // and treated as an extension of the last known level (i.e., level= -1 in this > case). > + // > + if (Bits[LevelType] =3D=3D 0) { > + Bits[LevelType] =3D Bits[LevelType - 1]; > + } > + } > + > + Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 1] =3D Package; > + Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE ] =3D Die; > + Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_TILE ] =3D Tile; > + Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_MODULE ] =3D > Module; > + Location[CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE ] =3D Core; > + Location[CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT ] =3D Thread; > + > + Bits[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 1] =3D 32; > + > + for ( LevelType =3D CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT > + ; LevelType <=3D CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 1 > + ; LevelType ++ > + ) { > + if (Location[LevelType] !=3D NULL) { > + // > + // Bits[i] holds the number of bits to shift right on x2APIC ID t= o get a unique > + // topology ID of the next level type. > + // > + *Location[LevelType] =3D InitialApicId >> Bits[LevelType - 1]; > + > + // > + // Bits[i] - Bits[i-1] holds the number of bits for the next ONE = level type. > + // > + *Location[LevelType] &=3D (1 << (Bits[LevelType] - Bits[LevelType= - 1])) - 1; > + } > + } > +} > diff --git a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c > b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c > index 6b89faf3df..79338186fb 100644 > --- a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c > +++ b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c > @@ -4,7 +4,7 @@ > This local APIC library instance supports x2APIC capable processors > which have xAPIC and x2APIC modes. >=20 > - Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved. > + Copyright (c) 2010 - 2019, Intel Corporation. All rights > + reserved.
> Copyright (c) 2017, AMD Inc. All rights reserved.
>=20 > This program and the accompanying materials @@ -1251,3 +1251,126 @@ > GetProcessorLocationByApicId ( > *Package =3D (InitialApicId >> (ThreadBits + CoreBits)); > } > } > + > +/** > + Get Package ID/Die ID/Tile ID/Module ID/Core ID/Thread ID of a proces= sor. > + > + The algorithm assumes the target system has symmetry across physical > + package boundaries with respect to the number of threads per core, > + number of cores per module, number of modules per tile, number of > + tiles per die, number of dies per package. > + > + @param[in] InitialApicId Initial APIC ID of the target logical proc= essor. > + @param[out] Package Returns the processor package ID. > + @param[out] Die Returns the processor die ID. > + @param[out] Tile Returns the processor tile ID. > + @param[out] Module Returns the processor module ID. > + @param[out] Core Returns the processor core ID. > + @param[out] Thread Returns the processor thread ID. > +**/ > +VOID > +EFIAPI > +GetProcessorLocation2ByApicId ( > + IN UINT32 InitialApicId, > + OUT UINT32 *Package OPTIONAL, > + OUT UINT32 *Die OPTIONAL, > + OUT UINT32 *Tile OPTIONAL, > + OUT UINT32 *Module OPTIONAL, > + OUT UINT32 *Core OPTIONAL, > + OUT UINT32 *Thread OPTIONAL > + ) > +{ > + CPUID_EXTENDED_TOPOLOGY_EAX ExtendedTopologyEax; > + CPUID_EXTENDED_TOPOLOGY_ECX ExtendedTopologyEcx; > + UINT32 MaxStandardCpuIdIndex; > + UINT32 Index; > + UINTN LevelType; > + UINT32 > Bits[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 2]; > + UINT32 > *Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 2]; > + > + for (LevelType =3D 0; LevelType < ARRAY_SIZE (Bits); LevelType++) { > + Bits[LevelType] =3D 0; > + } > + > + // > + // Get max index of CPUID > + // > + AsmCpuid (CPUID_SIGNATURE, &MaxStandardCpuIdIndex, NULL, NULL, > NULL); > + if (MaxStandardCpuIdIndex < CPUID_V2_EXTENDED_TOPOLOGY) { > + if (Die !=3D NULL) { > + *Die =3D 0; > + } > + if (Tile !=3D NULL) { > + *Tile =3D 0; > + } > + if (Module !=3D NULL) { > + *Module =3D 0; > + } > + GetProcessorLocationByApicId (InitialApicId, Package, Core, Thread)= ; > + return; > + } > + > + // > + // If the V2 extended topology enumeration leaf is available, it // > + is the preferred mechanism for enumerating topology. > + // > + for (Index =3D 0; ; Index++) { > + AsmCpuidEx( > + CPUID_V2_EXTENDED_TOPOLOGY, > + Index, > + &ExtendedTopologyEax.Uint32, > + NULL, > + &ExtendedTopologyEcx.Uint32, > + NULL > + ); > + > + LevelType =3D ExtendedTopologyEcx.Bits.LevelType; > + > + // > + // first level reported should be SMT. > + // > + ASSERT ((Index !=3D 0) || (LevelType =3D=3D > CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT)); > + if (LevelType =3D=3D CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID) { > + break; > + } > + ASSERT (LevelType < ARRAY_SIZE (Bits)); > + Bits[LevelType] =3D ExtendedTopologyEax.Bits.ApicIdShift; > + } > + > + for (LevelType =3D CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE; > LevelType < ARRAY_SIZE (Bits); LevelType++) { > + // > + // If there are more levels between level-1 (low-level) and level-2= (high-level), > the unknown levels will be ignored > + // and treated as an extension of the last known level (i.e., level= -1 in this > case). > + // > + if (Bits[LevelType] =3D=3D 0) { > + Bits[LevelType] =3D Bits[LevelType - 1]; > + } > + } > + > + Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 1] =3D Package; > + Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE ] =3D Die; > + Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_TILE ] =3D Tile; > + Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_MODULE ] =3D > Module; > + Location[CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE ] =3D Core; > + Location[CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT ] =3D Thread; > + > + Bits[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 1] =3D 32; > + > + for ( LevelType =3D CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT > + ; LevelType <=3D CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 1 > + ; LevelType ++ > + ) { > + if (Location[LevelType] !=3D NULL) { > + // > + // Bits[i] holds the number of bits to shift right on x2APIC ID t= o get a unique > + // topology ID of the next level type. > + // > + *Location[LevelType] =3D InitialApicId >> Bits[LevelType - 1]; > + > + // > + // Bits[i] - Bits[i-1] holds the number of bits for the next ONE = level type. > + // > + *Location[LevelType] &=3D (1 << (Bits[LevelType] - Bits[LevelType= - 1])) - 1; > + } > + } > +} > -- > 2.21.0.windows.1 >=20 >=20 >=20