Reviewed-by: Eric Dong <eric.d...@intel.com> > -----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 <eric.d...@intel.com>; Zeng, Star <star.z...@intel.com>; Qin, > Zhiqiang <zhiqiang....@intel.com> > Subject: [edk2-devel] [PATCH v2] UefiCpuPkg/LocalApicLib: Add > GetProcessorLocation2ByApicId() API > > GetProcessorLocation2ByApicId() extracts the > package/die/tile/module/core/thread ID from the initial APIC ID. > > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Ray Ni <ray...@intel.com> > Cc: Eric Dong <eric.d...@intel.com> > Cc: Star Zeng <star.z...@intel.com> > Cc: Zhiqiang Qin <zhiqiang....@intel.com> > --- > UefiCpuPkg/Include/Library/LocalApicLib.h | 29 +++- > .../Library/BaseXApicLib/BaseXApicLib.c | 125 +++++++++++++++++- > .../BaseXApicX2ApicLib/BaseXApicX2ApicLib.c | 125 +++++++++++++++++- > 3 files changed, 276 insertions(+), 3 deletions(-) > > 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. > > - Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR> > + Copyright (c) 2010 - 2019, Intel Corporation. All rights > + reserved.<BR> > 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 @@ -432,5 +432,32 @@ GetProcessorLocationByApicId ( > OUT UINT32 *Thread OPTIONAL > ); > > +/** > + Get Package ID/Module ID/Tile ID/Die ID/Core ID/Thread ID of a processor. > + > + 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 processor. > + @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 > > 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 @@ > > This local APIC library instance supports xAPIC mode only. > > - Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR> > + Copyright (c) 2010 - 2019, Intel Corporation. All rights > + reserved.<BR> > Copyright (c) 2017, AMD Inc. All rights reserved.<BR> > > This program and the accompanying materials @@ -1156,3 +1156,126 @@ > GetProcessorLocationByApicId ( > *Package = (InitialApicId >> (ThreadBits + CoreBits)); > } > } > + > +/** > + Get Package ID/Die ID/Tile ID/Module ID/Core ID/Thread ID of a processor. > + > + 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 processor. > + @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 = 0; LevelType < ARRAY_SIZE (Bits); LevelType++) { > + Bits[LevelType] = 0; > + } > + > + // > + // Get max index of CPUID > + // > + AsmCpuid (CPUID_SIGNATURE, &MaxStandardCpuIdIndex, NULL, NULL, > NULL); > + if (MaxStandardCpuIdIndex < CPUID_V2_EXTENDED_TOPOLOGY) { > + if (Die != NULL) { > + *Die = 0; > + } > + if (Tile != NULL) { > + *Tile = 0; > + } > + if (Module != NULL) { > + *Module = 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 = 0; ; Index++) { > + AsmCpuidEx( > + CPUID_V2_EXTENDED_TOPOLOGY, > + Index, > + &ExtendedTopologyEax.Uint32, > + NULL, > + &ExtendedTopologyEcx.Uint32, > + NULL > + ); > + > + LevelType = ExtendedTopologyEcx.Bits.LevelType; > + > + // > + // first level reported should be SMT. > + // > + ASSERT ((Index != 0) || (LevelType == > CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT)); > + if (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID) { > + break; > + } > + ASSERT (LevelType < ARRAY_SIZE (Bits)); > + Bits[LevelType] = ExtendedTopologyEax.Bits.ApicIdShift; > + } > + > + for (LevelType = 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] == 0) { > + Bits[LevelType] = Bits[LevelType - 1]; > + } > + } > + > + Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 1] = Package; > + Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE ] = Die; > + Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_TILE ] = Tile; > + Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_MODULE ] = > Module; > + Location[CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE ] = Core; > + Location[CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT ] = Thread; > + > + Bits[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 1] = 32; > + > + for ( LevelType = CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT > + ; LevelType <= CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 1 > + ; LevelType ++ > + ) { > + if (Location[LevelType] != NULL) { > + // > + // Bits[i] holds the number of bits to shift right on x2APIC ID to get > a unique > + // topology ID of the next level type. > + // > + *Location[LevelType] = InitialApicId >> Bits[LevelType - 1]; > + > + // > + // Bits[i] - Bits[i-1] holds the number of bits for the next ONE level > type. > + // > + *Location[LevelType] &= (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. > > - Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR> > + Copyright (c) 2010 - 2019, Intel Corporation. All rights > + reserved.<BR> > Copyright (c) 2017, AMD Inc. All rights reserved.<BR> > > This program and the accompanying materials @@ -1251,3 +1251,126 @@ > GetProcessorLocationByApicId ( > *Package = (InitialApicId >> (ThreadBits + CoreBits)); > } > } > + > +/** > + Get Package ID/Die ID/Tile ID/Module ID/Core ID/Thread ID of a processor. > + > + 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 processor. > + @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 = 0; LevelType < ARRAY_SIZE (Bits); LevelType++) { > + Bits[LevelType] = 0; > + } > + > + // > + // Get max index of CPUID > + // > + AsmCpuid (CPUID_SIGNATURE, &MaxStandardCpuIdIndex, NULL, NULL, > NULL); > + if (MaxStandardCpuIdIndex < CPUID_V2_EXTENDED_TOPOLOGY) { > + if (Die != NULL) { > + *Die = 0; > + } > + if (Tile != NULL) { > + *Tile = 0; > + } > + if (Module != NULL) { > + *Module = 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 = 0; ; Index++) { > + AsmCpuidEx( > + CPUID_V2_EXTENDED_TOPOLOGY, > + Index, > + &ExtendedTopologyEax.Uint32, > + NULL, > + &ExtendedTopologyEcx.Uint32, > + NULL > + ); > + > + LevelType = ExtendedTopologyEcx.Bits.LevelType; > + > + // > + // first level reported should be SMT. > + // > + ASSERT ((Index != 0) || (LevelType == > CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT)); > + if (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID) { > + break; > + } > + ASSERT (LevelType < ARRAY_SIZE (Bits)); > + Bits[LevelType] = ExtendedTopologyEax.Bits.ApicIdShift; > + } > + > + for (LevelType = 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] == 0) { > + Bits[LevelType] = Bits[LevelType - 1]; > + } > + } > + > + Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 1] = Package; > + Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE ] = Die; > + Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_TILE ] = Tile; > + Location[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_MODULE ] = > Module; > + Location[CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE ] = Core; > + Location[CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT ] = Thread; > + > + Bits[CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 1] = 32; > + > + for ( LevelType = CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT > + ; LevelType <= CPUID_V2_EXTENDED_TOPOLOGY_LEVEL_TYPE_DIE + 1 > + ; LevelType ++ > + ) { > + if (Location[LevelType] != NULL) { > + // > + // Bits[i] holds the number of bits to shift right on x2APIC ID to get > a unique > + // topology ID of the next level type. > + // > + *Location[LevelType] = InitialApicId >> Bits[LevelType - 1]; > + > + // > + // Bits[i] - Bits[i-1] holds the number of bits for the next ONE level > type. > + // > + *Location[LevelType] &= (1 << (Bits[LevelType] - Bits[LevelType - 1])) > - 1; > + } > + } > +} > -- > 2.21.0.windows.1 > > >
-=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#49): https://edk2.groups.io/g/devel/message/49 Mute This Topic: https://groups.io/mt/30894207/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-