public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
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
> 
> 
> 


      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