From: "Dong, Eric" <eric.dong@intel.com>
To: "devel@edk2.groups.io" <devel@edk2.groups.io>,
"Ni, Ray" <ray.ni@intel.com>
Cc: "Zeng, Star" <star.zeng@intel.com>,
"Qin, Zhiqiang" <zhiqiang.qin@intel.com>
Subject: Re: [edk2-devel] [PATCH v2] UefiCpuPkg/LocalApicLib: Add GetProcessorLocation2ByApicId() API
Date: Thu, 4 Apr 2019 12:28:42 +0000 [thread overview]
Message-ID: <ED077930C258884BBCB450DB737E662259DFB122@shsmsx102.ccr.corp.intel.com> (raw)
In-Reply-To: <20190404074838.62736-1-ray.ni@intel.com>
Reviewed-by: Eric Dong <eric.dong@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.dong@intel.com>; Zeng, Star <star.zeng@intel.com>; Qin,
> Zhiqiang <zhiqiang.qin@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.ni@intel.com>
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Star Zeng <star.zeng@intel.com>
> Cc: Zhiqiang Qin <zhiqiang.qin@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
>
>
>
prev parent reply other threads:[~2019-04-04 12:28 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-04-04 7:48 [PATCH v2] UefiCpuPkg/LocalApicLib: Add GetProcessorLocation2ByApicId() API Ni, Ray
2019-04-04 12:28 ` Dong, Eric [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ED077930C258884BBCB450DB737E662259DFB122@shsmsx102.ccr.corp.intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox