From: "Ni, Ray" <ray.ni@intel.com>
To: "Lou, Yun" <yun.lou@intel.com>,
"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: "Dong, Eric" <eric.dong@intel.com>,
Laszlo Ersek <lersek@redhat.com>,
"Kumar, Rahul1" <rahul1.kumar@intel.com>
Subject: Re: [PATCH v5 2/2] UefiCpuPkg/CpuCacheInfoLib: Add new CpuCacheInfoLib.
Date: Wed, 13 Jan 2021 04:01:44 +0000 [thread overview]
Message-ID: <CO1PR11MB4930610E3C242A49EF79EC1E8CA90@CO1PR11MB4930.namprd11.prod.outlook.com> (raw)
In-Reply-To: <20210107032246.3101-2-yun.lou@intel.com>
Laszlo,
Have you given Acked-by or Reviewed-by before? I cannot find it.
This version is good to me. I will create pull request once MdePkg maintainers
and you approve.
Thanks,
Ray
> -----Original Message-----
> From: Lou, Yun <yun.lou@intel.com>
> Sent: Thursday, January 7, 2021 11:23 AM
> To: devel@edk2.groups.io
> Cc: Lou, Yun <yun.lou@intel.com>; Ni, Ray <ray.ni@intel.com>; Dong, Eric
> <eric.dong@intel.com>; Laszlo Ersek <lersek@redhat.com>; Kumar, Rahul1
> <rahul1.kumar@intel.com>
> Subject: [PATCH v5 2/2] UefiCpuPkg/CpuCacheInfoLib: Add new
> CpuCacheInfoLib.
>
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3105
>
> This new library uses a platform agnostic algorithm to get CPU
> cache information. It provides user with an API(GetCpuCacheInfo)
> to get detailed CPU cache information by each package, each core
> type included in this package, and each cache level & type.
> This library can be used by code that produces SMBIOS_TABLE_TYPE7
> SMBIOS table.
>
> Signed-off-by: Jason Lou <yun.lou@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Rahul Kumar <rahul1.kumar@intel.com>
> ---
> UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.c | 440
> ++++++++++++++++++++
> UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.c | 120 ++++++
> UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.c | 119 ++++++
> UefiCpuPkg/Include/Library/CpuCacheInfoLib.h | 76 ++++
> UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.uni | 15 +
> UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.inf | 43 ++
> UefiCpuPkg/Library/CpuCacheInfoLib/InternalCpuCacheInfoLib.h | 159
> +++++++
> UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.inf | 43 ++
> UefiCpuPkg/UefiCpuPkg.dec | 3 +
> UefiCpuPkg/UefiCpuPkg.dsc | 4 +
> 10 files changed, 1022 insertions(+)
>
> diff --git a/UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.c
> b/UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.c
> new file mode 100644
> index 000000000000..ec506cda471c
> --- /dev/null
> +++ b/UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.c
> @@ -0,0 +1,440 @@
> +/** @file
>
> + Provides cache info for each package, core type, cache level and cache type.
>
> +
>
> + Copyright (c) 2020 Intel Corporation. All rights reserved.<BR>
>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +
>
> +**/
>
> +
>
> +#include "InternalCpuCacheInfoLib.h"
>
> +
>
> +/**
>
> + Print CpuCacheInfo array.
>
> +
>
> + @param[in] CpuCacheInfo Pointer to the CpuCacheInfo array.
>
> + @param[in] CpuCacheInfoCount The length of CpuCacheInfo array.
>
> +
>
> +**/
>
> +VOID
>
> +CpuCacheInfoPrintCpuCacheInfoTable (
>
> + IN CPU_CACHE_INFO *CpuCacheInfo,
>
> + IN UINTN CpuCacheInfoCount
>
> + )
>
> +{
>
> + UINTN Index;
>
> +
>
> + DEBUG ((DEBUG_INFO, "+-------+----------------------------------------------------------
> ---------------------+\n"));
>
> + DEBUG ((DEBUG_INFO, "| Index | Packge CoreType CacheLevel CacheType
> CacheWays CacheSizeinKB CacheCount |\n"));
>
> + DEBUG ((DEBUG_INFO, "+-------+----------------------------------------------------------
> ---------------------+\n"));
>
> +
>
> + for (Index = 0; Index < CpuCacheInfoCount; Index++) {
>
> + DEBUG ((DEBUG_INFO, "| %4x
> | %4x %2x %2x %2x %4x %8x %4x |\n", Index,
>
> + CpuCacheInfo[Index].Package, CpuCacheInfo[Index].CoreType,
> CpuCacheInfo[Index].CacheLevel,
>
> + CpuCacheInfo[Index].CacheType, CpuCacheInfo[Index].CacheWays,
> CpuCacheInfo[Index].CacheSizeinKB,
>
> + CpuCacheInfo[Index].CacheCount));
>
> + }
>
> +
>
> + DEBUG ((DEBUG_INFO, "+-------+----------------------------------------------------------
> ---------------------+\n"));
>
> +}
>
> +
>
> +/**
>
> + Get the total number of package and package ID in the platform.
>
> +
>
> + @param[in] ProcessorInfo Pointer to the ProcessorInfo array.
>
> + @param[in] NumberOfProcessors Total number of logical processors in
> the platform.
>
> + @param[in, out] Package Pointer to the Package array.
>
> +
>
> + @retval Return the total number of package and package ID in the platform.
>
> +**/
>
> +UINT32
>
> +CpuCacheInfoGetNumberOfPackages (
>
> + IN CPUID_PROCESSOR_INFO *ProcessorInfo,
>
> + IN UINTN NumberOfProcessors,
>
> + IN OUT UINT32 *Package
>
> + )
>
> +{
>
> + UINTN ProcessorIndex;
>
> + UINT32 PackageIndex;
>
> + UINT32 PackageCount;
>
> + UINT32 CurrentPackage;
>
> +
>
> + PackageCount = 0;
>
> +
>
> + for (ProcessorIndex = 0; ProcessorIndex < NumberOfProcessors;
> ProcessorIndex++) {
>
> + CurrentPackage = ProcessorInfo[ProcessorIndex].Package;
>
> +
>
> + //
>
> + // For the package that already exists in Package array, break out the loop.
>
> + //
>
> + for (PackageIndex = 0; PackageIndex < PackageCount; PackageIndex++) {
>
> + if (CurrentPackage == Package[PackageIndex]) {
>
> + break;
>
> + }
>
> + }
>
> +
>
> + //
>
> + // For the new package, save it in Package array.
>
> + //
>
> + if (PackageIndex == PackageCount) {
>
> + ASSERT (PackageCount < MAX_NUM_OF_PACKAGE);
>
> + Package[PackageCount++] = CurrentPackage;
>
> + }
>
> + }
>
> +
>
> + return PackageCount;
>
> +}
>
> +
>
> +/**
>
> + Get the number of CoreType of requested package.
>
> +
>
> + @param[in] ProcessorInfo Pointer to the ProcessorInfo array.
>
> + @param[in] NumberOfProcessors Total number of logical processors in the
> platform.
>
> + @param[in] Package The requested package number.
>
> +
>
> + @retval Return the number of CoreType of requested package.
>
> +**/
>
> +UINTN
>
> +CpuCacheInfoGetNumberOfCoreTypePerPackage(
>
> + IN CPUID_PROCESSOR_INFO *ProcessorInfo,
>
> + IN UINTN NumberOfProcessors,
>
> + IN UINTN Package
>
> + )
>
> +{
>
> + UINTN ProcessorIndex;
>
> + //
>
> + // Core Type value comes from CPUID.1Ah.EAX[31:24].
>
> + // So max number of core types should be MAX_UINT8.
>
> + //
>
> + UINT8 CoreType[MAX_UINT8];
>
> + UINTN CoreTypeIndex;
>
> + UINTN CoreTypeCount;
>
> + UINT8 CurrentCoreType;
>
> +
>
> + //
>
> + // CoreType array is empty.
>
> + //
>
> + CoreTypeCount = 0;
>
> +
>
> + for (ProcessorIndex = 0; ProcessorIndex < NumberOfProcessors;
> ProcessorIndex++) {
>
> + CurrentCoreType = ProcessorInfo[ProcessorIndex].CoreType;
>
> +
>
> + if (ProcessorInfo[ProcessorIndex].Package != Package) {
>
> + continue;
>
> + }
>
> +
>
> + //
>
> + // For the type that already exists in CoreType array, break out the loop.
>
> + //
>
> + for (CoreTypeIndex = 0; CoreTypeIndex < CoreTypeCount; CoreTypeIndex++)
> {
>
> + if (CurrentCoreType == CoreType[CoreTypeIndex]) {
>
> + break;
>
> + }
>
> + }
>
> +
>
> + //
>
> + // For the new type, save it in CoreType array.
>
> + //
>
> + if (CoreTypeIndex == CoreTypeCount) {
>
> + ASSERT (CoreTypeCount < MAX_UINT8);
>
> + CoreType[CoreTypeCount++] = CurrentCoreType;
>
> + }
>
> + }
>
> +
>
> + return CoreTypeCount;
>
> +}
>
> +
>
> +/**
>
> + Collect core and cache information of calling processor via CPUID
> instructions.
>
> +
>
> + @param[in] Buffer The pointer to private data buffer.
>
> +**/
>
> +VOID
>
> +CpuCacheInfoCollectCoreAndCacheData (
>
> + IN OUT VOID *Buffer
>
> + )
>
> +{
>
> + UINTN ProcessorIndex;
>
> + UINT32 CpuidMaxInput;
>
> + UINT8 CacheParamLeafIndex;
>
> + CPUID_CACHE_PARAMS_EAX CacheParamEax;
>
> + CPUID_CACHE_PARAMS_EBX CacheParamEbx;
>
> + UINT32 CacheParamEcx;
>
> + CPUID_NATIVE_MODEL_ID_AND_CORE_TYPE_EAX
> NativeModelIdAndCoreTypeEax;
>
> + COLLECT_CPUID_CACHE_DATA_CONTEXT *Context;
>
> + CPUID_CACHE_DATA *CacheData;
>
> +
>
> + Context = (COLLECT_CPUID_CACHE_DATA_CONTEXT *)Buffer;
>
> + ProcessorIndex = CpuCacheInfoWhoAmI (Context->MpServices);
>
> + CacheData = &Context->CacheData[MAX_NUM_OF_CACHE_PARAMS_LEAF
> * ProcessorIndex];
>
> +
>
> + AsmCpuid (CPUID_SIGNATURE, &CpuidMaxInput, NULL, NULL, NULL);
>
> +
>
> + //
>
> + // get CoreType if CPUID_HYBRID_INFORMATION leaf is supported.
>
> + //
>
> + Context->ProcessorInfo[ProcessorIndex].CoreType = 0;
>
> + if (CpuidMaxInput >= CPUID_HYBRID_INFORMATION) {
>
> + AsmCpuidEx (CPUID_HYBRID_INFORMATION,
> CPUID_HYBRID_INFORMATION_SUB_LEAF,
> &NativeModelIdAndCoreTypeEax.Uint32, NULL, NULL, NULL);
>
> + Context->ProcessorInfo[ProcessorIndex].CoreType = (UINT8)
> NativeModelIdAndCoreTypeEax.Bits.CoreType;
>
> + }
>
> +
>
> + //
>
> + // cache hierarchy starts with an index value of 0.
>
> + //
>
> + CacheParamLeafIndex = 0;
>
> +
>
> + while (CacheParamLeafIndex < MAX_NUM_OF_CACHE_PARAMS_LEAF) {
>
> + AsmCpuidEx (CPUID_CACHE_PARAMS, CacheParamLeafIndex,
> &CacheParamEax.Uint32, &CacheParamEbx.Uint32, &CacheParamEcx, NULL);
>
> +
>
> + if (CacheParamEax.Bits.CacheType == 0) {
>
> + break;
>
> + }
>
> +
>
> + CacheData[CacheParamLeafIndex].CacheLevel =
> (UINT8)CacheParamEax.Bits.CacheLevel;
>
> + CacheData[CacheParamLeafIndex].CacheType =
> (UINT8)CacheParamEax.Bits.CacheType;
>
> + CacheData[CacheParamLeafIndex].CacheWays =
> (UINT16)CacheParamEbx.Bits.Ways;
>
> + CacheData[CacheParamLeafIndex].CacheShareBits =
> (UINT16)CacheParamEax.Bits.MaximumAddressableIdsForLogicalProcessors;
>
> + CacheData[CacheParamLeafIndex].CacheSizeinKB =
> (CacheParamEbx.Bits.Ways + 1) *
>
> + (CacheParamEbx.Bits.LinePartitions + 1) * (CacheParamEbx.Bits.LineSize
> + 1) * (CacheParamEcx + 1) / SIZE_1KB;
>
> +
>
> + CacheParamLeafIndex++;
>
> + }
>
> +}
>
> +
>
> +/**
>
> + Collect CacheInfo data from the CacheData.
>
> +
>
> + @param[in] CacheData Pointer to the CacheData array.
>
> + @param[in] ProcessorInfo Pointer to the ProcessorInfo array.
>
> + @param[in] NumberOfProcessors Total number of logical processors in
> the platform.
>
> + @param[in, out] CacheInfo Pointer to the CacheInfo array.
>
> + @param[in, out] CacheInfoCount As input, point to the length of response
> CacheInfo array.
>
> + As output, point to the actual length of response
> CacheInfo array.
>
> +
>
> + @retval EFI_SUCCESS Function completed successfully.
>
> + @retval EFI_OUT_OF_RESOURCES Required resources could not be
> allocated.
>
> + @retval EFI_BUFFER_TOO_SMALL CacheInfoCount is too small to hold
> the response CacheInfo
>
> + array. CacheInfoCount has been updated with the
> length needed
>
> + to complete the request.
>
> +**/
>
> +EFI_STATUS
>
> +CpuCacheInfoCollectCpuCacheInfoData (
>
> + IN CPUID_CACHE_DATA *CacheData,
>
> + IN CPUID_PROCESSOR_INFO *ProcessorInfo,
>
> + IN UINTN NumberOfProcessors,
>
> + IN OUT CPU_CACHE_INFO *CacheInfo,
>
> + IN OUT UINTN *CacheInfoCount
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> + UINT32 NumberOfPackage;
>
> + UINT32 Package[MAX_NUM_OF_PACKAGE];
>
> + UINTN PackageIndex;
>
> + UINTN TotalNumberOfCoreType;
>
> + UINTN MaxCacheInfoCount;
>
> + CPU_CACHE_INFO *LocalCacheInfo;
>
> + UINTN CacheInfoIndex;
>
> + UINTN LocalCacheInfoCount;
>
> + UINTN Index;
>
> + UINTN NextIndex;
>
> +
>
> + //
>
> + // Get number of Packages and Package ID.
>
> + //
>
> + NumberOfPackage = CpuCacheInfoGetNumberOfPackages (ProcessorInfo,
> NumberOfProcessors, Package);
>
> +
>
> + //
>
> + // Get number of core types for each package and count the total number.
>
> + // E.g. If Package1 and Package2 both have 2 core types, the total number is
> 4.
>
> + //
>
> + TotalNumberOfCoreType = 0;
>
> + for (PackageIndex = 0; PackageIndex < NumberOfPackage; PackageIndex++)
> {
>
> + TotalNumberOfCoreType +=
> CpuCacheInfoGetNumberOfCoreTypePerPackage (ProcessorInfo,
> NumberOfProcessors, Package[PackageIndex]);
>
> + }
>
> +
>
> + MaxCacheInfoCount = TotalNumberOfCoreType *
> MAX_NUM_OF_CACHE_PARAMS_LEAF;
>
> + LocalCacheInfo = AllocatePages (EFI_SIZE_TO_PAGES (MaxCacheInfoCount *
> sizeof (*LocalCacheInfo)));
>
> + ASSERT (LocalCacheInfo != NULL);
>
> + if (LocalCacheInfo == NULL) {
>
> + return EFI_OUT_OF_RESOURCES;
>
> + }
>
> +
>
> + LocalCacheInfoCount = 0;
>
> +
>
> + for (Index = 0; Index < NumberOfProcessors *
> MAX_NUM_OF_CACHE_PARAMS_LEAF; Index++) {
>
> + if (CacheData[Index].CacheSizeinKB == 0) {
>
> + continue;
>
> + }
>
> +
>
> + //
>
> + // For the sharing caches, clear their CacheSize.
>
> + //
>
> + for (NextIndex = Index + 1; NextIndex < NumberOfProcessors *
> MAX_NUM_OF_CACHE_PARAMS_LEAF; NextIndex++) {
>
> + if (CacheData[NextIndex].CacheSizeinKB == 0) {
>
> + continue;
>
> + }
>
> +
>
> + if (CacheData[Index].CacheLevel == CacheData[NextIndex].CacheLevel &&
>
> + CacheData[Index].CacheType == CacheData[NextIndex].CacheType &&
>
> + ProcessorInfo[Index / MAX_NUM_OF_CACHE_PARAMS_LEAF].Package
> == ProcessorInfo[NextIndex / MAX_NUM_OF_CACHE_PARAMS_LEAF].Package
> &&
>
> + ProcessorInfo[Index / MAX_NUM_OF_CACHE_PARAMS_LEAF].CoreType
> == ProcessorInfo[NextIndex / MAX_NUM_OF_CACHE_PARAMS_LEAF].CoreType
> &&
>
> + (ProcessorInfo[Index / MAX_NUM_OF_CACHE_PARAMS_LEAF].ApicId &
> ~CacheData[Index].CacheShareBits) ==
>
> + (ProcessorInfo[NextIndex /
> MAX_NUM_OF_CACHE_PARAMS_LEAF].ApicId &
> ~CacheData[NextIndex].CacheShareBits)) {
>
> + CacheData[NextIndex].CacheSizeinKB = 0; // uses the sharing cache
>
> + }
>
> + }
>
> +
>
> + //
>
> + // For the cache that already exists in LocalCacheInfo, increase its
> CacheCount.
>
> + //
>
> + for (CacheInfoIndex = 0; CacheInfoIndex < LocalCacheInfoCount;
> CacheInfoIndex++) {
>
> + if (LocalCacheInfo[CacheInfoIndex].Package == ProcessorInfo[Index /
> MAX_NUM_OF_CACHE_PARAMS_LEAF].Package &&
>
> + LocalCacheInfo[CacheInfoIndex].CoreType == ProcessorInfo[Index /
> MAX_NUM_OF_CACHE_PARAMS_LEAF].CoreType &&
>
> + LocalCacheInfo[CacheInfoIndex].CacheLevel ==
> CacheData[Index].CacheLevel &&
>
> + LocalCacheInfo[CacheInfoIndex].CacheType ==
> CacheData[Index].CacheType) {
>
> + LocalCacheInfo[CacheInfoIndex].CacheCount++;
>
> + break;
>
> + }
>
> + }
>
> +
>
> + //
>
> + // For the new cache with different Package, CoreType, CacheLevel or
> CacheType, copy its
>
> + // data into LocalCacheInfo buffer.
>
> + //
>
> + if (CacheInfoIndex == LocalCacheInfoCount) {
>
> + ASSERT (LocalCacheInfoCount < MaxCacheInfoCount);
>
> +
>
> + LocalCacheInfo[LocalCacheInfoCount].Package = ProcessorInfo[Index /
> MAX_NUM_OF_CACHE_PARAMS_LEAF].Package;
>
> + LocalCacheInfo[LocalCacheInfoCount].CoreType = ProcessorInfo[Index /
> MAX_NUM_OF_CACHE_PARAMS_LEAF].CoreType;
>
> + LocalCacheInfo[LocalCacheInfoCount].CacheLevel =
> CacheData[Index].CacheLevel;
>
> + LocalCacheInfo[LocalCacheInfoCount].CacheType =
> CacheData[Index].CacheType;
>
> + LocalCacheInfo[LocalCacheInfoCount].CacheWays =
> CacheData[Index].CacheWays;
>
> + LocalCacheInfo[LocalCacheInfoCount].CacheSizeinKB =
> CacheData[Index].CacheSizeinKB;
>
> + LocalCacheInfo[LocalCacheInfoCount].CacheCount = 1;
>
> +
>
> + LocalCacheInfoCount++;
>
> + }
>
> + }
>
> +
>
> + if (*CacheInfoCount < LocalCacheInfoCount) {
>
> + Status = EFI_BUFFER_TOO_SMALL;
>
> + } else {
>
> + CopyMem (CacheInfo, LocalCacheInfo, sizeof (*CacheInfo) *
> LocalCacheInfoCount);
>
> + DEBUG_CODE (
>
> + CpuCacheInfoPrintCpuCacheInfoTable (CacheInfo, LocalCacheInfoCount);
>
> + );
>
> + Status = EFI_SUCCESS;
>
> + }
>
> +
>
> + *CacheInfoCount = LocalCacheInfoCount;
>
> +
>
> + FreePages (LocalCacheInfo, EFI_SIZE_TO_PAGES (MaxCacheInfoCount *
> sizeof (*LocalCacheInfo)));
>
> +
>
> + return Status;
>
> +}
>
> +
>
> +/**
>
> + Get CpuCacheInfo data array.
>
> +
>
> + @param[in, out] CpuCacheInfo Pointer to the CpuCacheInfo array.
>
> + @param[in, out] CpuCacheInfoCount As input, point to the length of
> response CpuCacheInfo array.
>
> + As output, point to the actual length of response
> CpuCacheInfo array.
>
> +
>
> + @retval EFI_SUCCESS Function completed successfully.
>
> + @retval EFI_INVALID_PARAMETER CpuCacheInfoCount is NULL.
>
> + @retval EFI_INVALID_PARAMETER CpuCacheInfo is NULL while
> CpuCacheInfoCount contains the value
>
> + greater than zero.
>
> + @retval EFI_UNSUPPORTED Processor does not support
> CPUID_CACHE_PARAMS Leaf.
>
> + @retval EFI_NOT_FOUND EDKII_PEI_MP_SERVICES2_PPI or
> EFI_MP_SERVICES_PROTOCOL interface
>
> + is not found.
>
> + @retval EFI_OUT_OF_RESOURCES Required resources could not be
> allocated.
>
> + @retval EFI_BUFFER_TOO_SMALL CpuCacheInfoCount is too small to
> hold the response CpuCacheInfo
>
> + array. CpuCacheInfoCount has been updated with
> the length needed
>
> + to complete the request.
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +GetCpuCacheInfo (
>
> + IN OUT CPU_CACHE_INFO *CpuCacheInfo,
>
> + IN OUT UINTN *CpuCacheInfoCount
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> + UINT32 CpuidMaxInput;
>
> + UINT32 NumberOfProcessors;
>
> + UINTN CacheDataCount;
>
> + UINTN ProcessorIndex;
>
> + EFI_PROCESSOR_INFORMATION ProcessorInfo;
>
> + COLLECT_CPUID_CACHE_DATA_CONTEXT Context;
>
> +
>
> + if (CpuCacheInfoCount == NULL) {
>
> + return EFI_INVALID_PARAMETER;
>
> + }
>
> +
>
> + if (*CpuCacheInfoCount != 0 && CpuCacheInfo == NULL) {
>
> + return EFI_INVALID_PARAMETER;
>
> + }
>
> +
>
> + AsmCpuid (CPUID_SIGNATURE, &CpuidMaxInput, NULL, NULL, NULL);
>
> + if (CpuidMaxInput < CPUID_CACHE_PARAMS) {
>
> + return EFI_UNSUPPORTED;
>
> + }
>
> +
>
> + //
>
> + // Initialize COLLECT_CPUID_CACHE_DATA_CONTEXT.MpServices.
>
> + //
>
> + Status = CpuCacheInfoGetMpServices (&Context.MpServices);
>
> + if (EFI_ERROR(Status)) {
>
> + return Status;
>
> + }
>
> +
>
> + NumberOfProcessors = CpuCacheInfoGetNumberOfProcessors
> (Context.MpServices);
>
> +
>
> + //
>
> + // Initialize COLLECT_CPUID_CACHE_DATA_CONTEXT.ProcessorInfo.
>
> + //
>
> + Context.ProcessorInfo = AllocatePages (EFI_SIZE_TO_PAGES
> (NumberOfProcessors * sizeof (*Context.ProcessorInfo)));
>
> + ASSERT (Context.ProcessorInfo != NULL);
>
> + if (Context.ProcessorInfo == NULL) {
>
> + return EFI_OUT_OF_RESOURCES;
>
> + }
>
> + //
>
> + // Initialize COLLECT_CPUID_CACHE_DATA_CONTEXT.CacheData.
>
> + // CacheData array consists of CPUID_CACHE_DATA data structure for each
> Cpuid Cache Parameter Leaf
>
> + // per logical processor. The array begin with data of each Cache Parameter
> Leaf of processor 0, followed
>
> + // by data of each Cache Parameter Leaf of processor 1 ...
>
> + //
>
> + CacheDataCount = NumberOfProcessors *
> MAX_NUM_OF_CACHE_PARAMS_LEAF;
>
> + Context.CacheData = AllocatePages (EFI_SIZE_TO_PAGES (CacheDataCount *
> sizeof (*Context.CacheData)));
>
> + ASSERT (Context.CacheData != NULL);
>
> + if (Context.CacheData == NULL) {
>
> + FreePages (Context.ProcessorInfo, EFI_SIZE_TO_PAGES
> (NumberOfProcessors * sizeof (*Context.ProcessorInfo)));
>
> + return EFI_OUT_OF_RESOURCES;
>
> + }
>
> +
>
> + ZeroMem (Context.CacheData, CacheDataCount * sizeof
> (*Context.CacheData));
>
> +
>
> + //
>
> + // Collect Package ID and APIC ID of all processors.
>
> + //
>
> + for (ProcessorIndex = 0; ProcessorIndex < NumberOfProcessors;
> ProcessorIndex++) {
>
> + CpuCacheInfoGetProcessorInfo (Context.MpServices, ProcessorIndex,
> &ProcessorInfo);
>
> + Context.ProcessorInfo[ProcessorIndex].Package =
> ProcessorInfo.Location.Package;
>
> + Context.ProcessorInfo[ProcessorIndex].ApicId = (UINT32)
> ProcessorInfo.ProcessorId;
>
> + }
>
> +
>
> + //
>
> + // Wakeup all processors for CacheData(core type and cache data) collection.
>
> + //
>
> + CpuCacheInfoStartupAllCPUs (Context.MpServices,
> CpuCacheInfoCollectCoreAndCacheData, &Context);
>
> +
>
> + //
>
> + // Collect CpuCacheInfo data from CacheData.
>
> + //
>
> + Status = CpuCacheInfoCollectCpuCacheInfoData (Context.CacheData,
> Context.ProcessorInfo, NumberOfProcessors, CpuCacheInfo,
> CpuCacheInfoCount);
>
> +
>
> + FreePages (Context.CacheData, EFI_SIZE_TO_PAGES (CacheDataCount *
> sizeof (*Context.CacheData)));
>
> + FreePages (Context.ProcessorInfo, EFI_SIZE_TO_PAGES
> (NumberOfProcessors * sizeof (*Context.ProcessorInfo)));
>
> +
>
> + return Status;
>
> +}
>
> diff --git a/UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.c
> b/UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.c
> new file mode 100644
> index 000000000000..bb788e36146b
> --- /dev/null
> +++ b/UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.c
> @@ -0,0 +1,120 @@
> +/** @file
>
> + Provides cache info for each package, core type, cache level and cache type.
>
> +
>
> + Copyright (c) 2020 Intel Corporation. All rights reserved.<BR>
>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +
>
> +**/
>
> +
>
> +#include <PiDxe.h>
>
> +#include <Library/BaseLib.h>
>
> +#include <Library/DebugLib.h>
>
> +#include <Library/UefiBootServicesTableLib.h>
>
> +#include <Library/CpuCacheInfoLib.h>
>
> +#include <InternalCpuCacheInfoLib.h>
>
> +
>
> +/**
>
> + Get EFI_MP_SERVICES_PROTOCOL pointer.
>
> +
>
> + @param[out] MpServices A pointer to the buffer where
> EFI_MP_SERVICES_PROTOCOL is stored
>
> +
>
> + @retval EFI_SUCCESS EFI_MP_SERVICES_PROTOCOL interface is
> returned
>
> + @retval EFI_NOT_FOUND EFI_MP_SERVICES_PROTOCOL interface is not
> found
>
> +**/
>
> +EFI_STATUS
>
> +CpuCacheInfoGetMpServices (
>
> + OUT MP_SERVICES *MpServices
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> +
>
> + Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID
> **)&MpServices->Protocol);
>
> + ASSERT_EFI_ERROR (Status);
>
> +
>
> + return Status;
>
> +}
>
> +
>
> +/**
>
> + Activate all of the logical processors.
>
> +
>
> + @param[in] MpServices MP_SERVICES structure.
>
> + @param[in] Procedure A pointer to the function to be run on enabled
> logical processors.
>
> + @param[in] ProcedureArgument The parameter passed into Procedure for
> all enabled logical processors.
>
> +**/
>
> +VOID
>
> +CpuCacheInfoStartupAllCPUs (
>
> + IN MP_SERVICES MpServices,
>
> + IN EFI_AP_PROCEDURE Procedure,
>
> + IN VOID *ProcedureArgument
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> +
>
> + Status = MpServices.Protocol->StartupAllAPs (MpServices.Protocol,
> Procedure, FALSE, NULL, 0, ProcedureArgument, NULL);
>
> + ASSERT_EFI_ERROR (Status);
>
> +
>
> + Procedure (ProcedureArgument);
>
> +}
>
> +
>
> +/**
>
> + Get detailed information of the requested logical processor.
>
> +
>
> + @param[in] MpServices MP_SERVICES structure.
>
> + @param[in] ProcessorNum The requested logical processor number.
>
> + @param[out] ProcessorInfo A pointer to the buffer where the processor
> information is stored
>
> +**/
>
> +VOID
>
> +CpuCacheInfoGetProcessorInfo (
>
> + IN MP_SERVICES MpServices,
>
> + IN UINTN ProcessorNum,
>
> + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfo
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> +
>
> + Status = MpServices.Protocol->GetProcessorInfo (MpServices.Protocol,
> ProcessorNum, ProcessorInfo);
>
> + ASSERT_EFI_ERROR (Status);
>
> +}
>
> +
>
> +/**
>
> + Get the logical processor number.
>
> +
>
> + @param[in] MpServices MP_SERVICES structure.
>
> +
>
> + @retval Return the logical processor number.
>
> +**/
>
> +UINT32
>
> +CpuCacheInfoWhoAmI (
>
> + IN MP_SERVICES MpServices
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> + UINTN ProcessorNum;
>
> +
>
> + Status = MpServices.Protocol->WhoAmI (MpServices.Protocol,
> &ProcessorNum);
>
> + ASSERT_EFI_ERROR (Status);
>
> +
>
> + return (UINT32)ProcessorNum;
>
> +}
>
> +
>
> +/**
>
> + Get the total number of logical processors in the platform.
>
> +
>
> + @param[in] MpServices MP_SERVICES structure.
>
> +
>
> + @retval Return the total number of logical processors.
>
> +**/
>
> +UINT32
>
> +CpuCacheInfoGetNumberOfProcessors (
>
> + IN MP_SERVICES MpServices
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> + UINTN NumberOfProcessor;
>
> + UINTN NumberOfEnabledProcessor;
>
> +
>
> + Status = MpServices.Protocol->GetNumberOfProcessors
> (MpServices.Protocol, &NumberOfProcessor, &NumberOfEnabledProcessor);
>
> + ASSERT_EFI_ERROR (Status);
>
> +
>
> + return (UINT32)NumberOfProcessor;
>
> +}
>
> diff --git a/UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.c
> b/UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.c
> new file mode 100644
> index 000000000000..06c160421b00
> --- /dev/null
> +++ b/UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.c
> @@ -0,0 +1,119 @@
> +/** @file
>
> + Provides cache info for each package, core type, cache level and cache type.
>
> +
>
> + Copyright (c) 2020 Intel Corporation. All rights reserved.<BR>
>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +
>
> +**/
>
> +
>
> +#include <PiPei.h>
>
> +#include <Library/BaseLib.h>
>
> +#include <Library/DebugLib.h>
>
> +#include <Library/PeiServicesLib.h>
>
> +#include <Library/PeiServicesTablePointerLib.h>
>
> +#include <Library/CpuCacheInfoLib.h>
>
> +#include <InternalCpuCacheInfoLib.h>
>
> +
>
> +/**
>
> + Get EDKII_PEI_MP_SERVICES2_PPI pointer.
>
> +
>
> + @param[out] MpServices A pointer to the buffer where
> EDKII_PEI_MP_SERVICES2_PPI is stored
>
> +
>
> + @retval EFI_SUCCESS EDKII_PEI_MP_SERVICES2_PPI interface is returned
>
> + @retval EFI_NOT_FOUND EDKII_PEI_MP_SERVICES2_PPI interface is not
> found
>
> +**/
>
> +EFI_STATUS
>
> +CpuCacheInfoGetMpServices (
>
> + OUT MP_SERVICES *MpServices
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> +
>
> + Status = PeiServicesLocatePpi (&gEdkiiPeiMpServices2PpiGuid, 0, NULL,
> (VOID **)&MpServices->Ppi);
>
> + ASSERT_EFI_ERROR (Status);
>
> +
>
> + return Status;
>
> +}
>
> +
>
> +/**
>
> + Activate all of the logical processors.
>
> +
>
> + @param[in] MpServices MP_SERVICES structure.
>
> + @param[in] Procedure A pointer to the function to be run on enabled
> logical processors.
>
> + @param[in] ProcedureArgument The parameter passed into Procedure for
> all enabled logical processors.
>
> +**/
>
> +VOID
>
> +CpuCacheInfoStartupAllCPUs (
>
> + IN MP_SERVICES MpServices,
>
> + IN EFI_AP_PROCEDURE Procedure,
>
> + IN VOID *ProcedureArgument
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> +
>
> + Status = MpServices.Ppi->StartupAllCPUs (MpServices.Ppi, Procedure, 0,
> ProcedureArgument);
>
> + ASSERT_EFI_ERROR (Status);
>
> +}
>
> +
>
> +/**
>
> + Get detailed information of the requested logical processor.
>
> +
>
> + @param[in] MpServices MP_SERVICES structure.
>
> + @param[in] ProcessorNum The requested logical processor number.
>
> + @param[out] ProcessorInfo A pointer to the buffer where the processor
> information is stored
>
> +**/
>
> +VOID
>
> +CpuCacheInfoGetProcessorInfo (
>
> + IN MP_SERVICES MpServices,
>
> + IN UINTN ProcessorNum,
>
> + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfo
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> +
>
> + Status = MpServices.Ppi->GetProcessorInfo (MpServices.Ppi, ProcessorNum,
> ProcessorInfo);
>
> + ASSERT_EFI_ERROR (Status);
>
> +}
>
> +
>
> +/**
>
> + Get the logical processor number.
>
> +
>
> + @param[in] MpServices MP_SERVICES structure.
>
> +
>
> + @retval Return the logical processor number.
>
> +**/
>
> +UINT32
>
> +CpuCacheInfoWhoAmI (
>
> + IN MP_SERVICES MpServices
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> + UINTN ProcessorNum;
>
> +
>
> + Status = MpServices.Ppi->WhoAmI (MpServices.Ppi, &ProcessorNum);
>
> + ASSERT_EFI_ERROR (Status);
>
> +
>
> + return (UINT32)ProcessorNum;
>
> +}
>
> +
>
> +/**
>
> + Get the total number of logical processors in the platform.
>
> +
>
> + @param[in] MpServices MP_SERVICES structure.
>
> +
>
> + @retval Return the total number of logical processors.
>
> +**/
>
> +UINT32
>
> +CpuCacheInfoGetNumberOfProcessors (
>
> + IN MP_SERVICES MpServices
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> + UINTN NumberOfProcessor;
>
> + UINTN NumberOfEnabledProcessor;
>
> +
>
> + Status = MpServices.Ppi->GetNumberOfProcessors (MpServices.Ppi,
> &NumberOfProcessor, &NumberOfEnabledProcessor);
>
> + ASSERT_EFI_ERROR (Status);
>
> +
>
> + return (UINT32)NumberOfProcessor;
>
> +}
>
> diff --git a/UefiCpuPkg/Include/Library/CpuCacheInfoLib.h
> b/UefiCpuPkg/Include/Library/CpuCacheInfoLib.h
> new file mode 100644
> index 000000000000..a23b8b12b5ee
> --- /dev/null
> +++ b/UefiCpuPkg/Include/Library/CpuCacheInfoLib.h
> @@ -0,0 +1,76 @@
> +/** @file
>
> + Header file for CPU Cache info Library.
>
> +
>
> + Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +
>
> +**/
>
> +
>
> +#ifndef _CPU_CACHE_INFO_LIB_H_
>
> +#define _CPU_CACHE_INFO_LIB_H_
>
> +
>
> +typedef struct {
>
> + //
>
> + // Package number.
>
> + //
>
> + UINT32 Package;
>
> + //
>
> + // Core type of logical processor.
>
> + // Value = CPUID.1Ah:EAX[31:24]
>
> + //
>
> + UINT8 CoreType;
>
> + //
>
> + // Level of the cache that this package's this type of logical processor
> corresponds to.
>
> + // Value = CPUID.04h:EAX[07:05]
>
> + //
>
> + UINT8 CacheLevel : 3;
>
> + //
>
> + // Type of the cache that this package's this type of logical processor
> corresponds to.
>
> + // Value = CPUID.04h:EAX[04:00]
>
> + //
>
> + UINT8 CacheType : 5;
>
> + //
>
> + // Ways of associativity.
>
> + // Value = CPUID.04h:EBX[31:22]
>
> + //
>
> + UINT16 CacheWays;
>
> + //
>
> + // Size of single cache that this package's this type of logical processor
> corresponds to.
>
> + // Value = (CPUID.04h:EBX[31:22] + 1) * (CPUID.04h:EBX[21:12] + 1) *
>
> + // (CPUID.04h:EBX[11:00] + 1) * (CPUID.04h:ECX[31:00] + 1)
>
> + //
>
> + UINT32 CacheSizeinKB;
>
> + //
>
> + // Number of the cache that this package's this type of logical processor
> corresponds to.
>
> + // Have subtracted the number of caches that are shared.
>
> + //
>
> + UINT16 CacheCount;
>
> +} CPU_CACHE_INFO;
>
> +
>
> +/**
>
> + Get CpuCacheInfo data array.
>
> +
>
> + @param[in, out] CpuCacheInfo Pointer to the CpuCacheInfo array.
>
> + @param[in, out] CpuCacheInfoCount As input, point to the length of
> response CpuCacheInfo array.
>
> + As output, point to the actual length of response
> CpuCacheInfo array.
>
> +
>
> + @retval EFI_SUCCESS Function completed successfully.
>
> + @retval EFI_INVALID_PARAMETER CpuCacheInfoCount is NULL.
>
> + @retval EFI_INVALID_PARAMETER CpuCacheInfo is NULL while
> CpuCacheInfoCount contains the value
>
> + greater than zero.
>
> + @retval EFI_UNSUPPORTED Processor does not support
> CPUID_CACHE_PARAMS Leaf.
>
> + @retval EFI_NOT_FOUND EDKII_PEI_MP_SERVICES2_PPI or
> EFI_MP_SERVICES_PROTOCOL interface
>
> + is not found.
>
> + @retval EFI_OUT_OF_RESOURCES Required resources could not be
> allocated.
>
> + @retval EFI_BUFFER_TOO_SMALL CpuCacheInfoCount is too small to
> hold the response CpuCacheInfo
>
> + array. CpuCacheInfoCount has been updated with
> the length needed
>
> + to complete the request.
>
> +**/
>
> +EFI_STATUS
>
> +EFIAPI
>
> +GetCpuCacheInfo (
>
> + IN OUT CPU_CACHE_INFO *CpuCacheInfo,
>
> + IN OUT UINTN *CpuCacheInfoCount
>
> + );
>
> +
>
> +#endif
>
> diff --git a/UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.uni
> b/UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.uni
> new file mode 100644
> index 000000000000..1bc801f15f84
> --- /dev/null
> +++ b/UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.uni
> @@ -0,0 +1,15 @@
> +// /** @file
>
> +// CPU Cache Info Library
>
> +//
>
> +// Provides cache info for each package, core type, cache level and cache type.
>
> +//
>
> +// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
>
> +//
>
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +//
>
> +// **/
>
> +
>
> +
>
> +#string STR_MODULE_ABSTRACT #language en-US "CPU Cache Info
> Library"
>
> +
>
> +#string STR_MODULE_DESCRIPTION #language en-US "Provides cache
> info for each package, core type, cache level and cache type."
>
> diff --git a/UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.inf
> b/UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.inf
> new file mode 100644
> index 000000000000..1fd45380b871
> --- /dev/null
> +++ b/UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.inf
> @@ -0,0 +1,43 @@
> +## @file
>
> +# CPU Cache Info Library instance for DXE driver.
>
> +#
>
> +# Provides cache info for each package, core type, cache level and cache type.
>
> +#
>
> +# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
>
> +#
>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +#
>
> +##
>
> +
>
> +[Defines]
>
> + INF_VERSION = 0x00010005
>
> + BASE_NAME = DxeCpuCacheInfoLib
>
> + FILE_GUID = B25C288F-C309-41F1-8325-37E64DC5EA3D
>
> + MODULE_TYPE = DXE_DRIVER
>
> + VERSION_STRING = 1.0
>
> + LIBRARY_CLASS = CpuCacheInfoLib|DXE_DRIVER
> UEFI_APPLICATION
>
> + MODULE_UNI_FILE = CpuCacheInfoLib.uni
>
> +
>
> +[Sources]
>
> + InternalCpuCacheInfoLib.h
>
> + CpuCacheInfoLib.c
>
> + DxeCpuCacheInfoLib.c
>
> +
>
> +[Packages]
>
> + MdePkg/MdePkg.dec
>
> + UefiCpuPkg/UefiCpuPkg.dec
>
> +
>
> +[LibraryClasses]
>
> + BaseLib
>
> + DebugLib
>
> + BaseMemoryLib
>
> + MemoryAllocationLib
>
> + UefiBootServicesTableLib
>
> +
>
> +[Protocols]
>
> + gEfiMpServiceProtocolGuid
>
> +
>
> +[Pcd]
>
> +
>
> +[Depex]
>
> + TRUE
>
> diff --git a/UefiCpuPkg/Library/CpuCacheInfoLib/InternalCpuCacheInfoLib.h
> b/UefiCpuPkg/Library/CpuCacheInfoLib/InternalCpuCacheInfoLib.h
> new file mode 100644
> index 000000000000..de56db9c0cbe
> --- /dev/null
> +++ b/UefiCpuPkg/Library/CpuCacheInfoLib/InternalCpuCacheInfoLib.h
> @@ -0,0 +1,159 @@
> +/** @file
>
> + Internal header file for CPU Cache info Library.
>
> +
>
> + Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +
>
> +**/
>
> +
>
> +#ifndef _INTERNAL_CPU_CACHE_INFO_LIB_H_
>
> +#define _INTERNAL_CPU_CACHE_INFO_LIB_H_
>
> +
>
> +#include <PiPei.h>
>
> +#include <Register/Cpuid.h>
>
> +#include <Ppi/MpServices2.h>
>
> +#include <Protocol/MpService.h>
>
> +#include <Library/BaseLib.h>
>
> +#include <Library/DebugLib.h>
>
> +#include <Library/BaseMemoryLib.h>
>
> +#include <Library/MemoryAllocationLib.h>
>
> +#include <Library/CpuCacheInfoLib.h>
>
> +
>
> +typedef struct {
>
> + //
>
> + // Package ID, the information comes from
>
> + // EFI_CPU_PHYSICAL_LOCATION.Package
>
> + //
>
> + UINT32 Package;
>
> + //
>
> + // APIC ID, the information comes from
>
> + // EFI_PROCESSOR_INFORMATION.ProcessorId
>
> + //
>
> + UINT32 ApicId;
>
> + //
>
> + // Core type of logical processor.
>
> + // Value = CPUID.1Ah:EAX[31:24]
>
> + //
>
> + UINT8 CoreType;
>
> +} CPUID_PROCESSOR_INFO;
>
> +
>
> +typedef struct {
>
> + //
>
> + // Level of the cache.
>
> + // Value = CPUID.04h:EAX[07:05]
>
> + //
>
> + UINT8 CacheLevel : 3;
>
> + //
>
> + // Type of the cache.
>
> + // Value = CPUID.04h:EAX[04:00]
>
> + //
>
> + UINT8 CacheType : 5;
>
> + //
>
> + // Ways of associativity.
>
> + // Value = CPUID.04h:EBX[31:22]
>
> + //
>
> + UINT16 CacheWays;
>
> + //
>
> + // Cache share bits.
>
> + // Value = CPUID.04h:EAX[25:14]
>
> + //
>
> + UINT16 CacheShareBits;
>
> + //
>
> + // Size of single cache.
>
> + // Value = (CPUID.04h:EBX[31:22] + 1) * (CPUID.04h:EBX[21:12] + 1) *
>
> + // (CPUID.04h:EBX[11:00] + 1) * (CPUID.04h:ECX[31:00] + 1)
>
> + //
>
> + UINT32 CacheSizeinKB;
>
> +} CPUID_CACHE_DATA;
>
> +
>
> +typedef union {
>
> + EDKII_PEI_MP_SERVICES2_PPI *Ppi;
>
> + EFI_MP_SERVICES_PROTOCOL *Protocol;
>
> +} MP_SERVICES;
>
> +
>
> +typedef struct {
>
> + MP_SERVICES MpServices;
>
> + CPUID_PROCESSOR_INFO *ProcessorInfo;
>
> + CPUID_CACHE_DATA *CacheData;
>
> +} COLLECT_CPUID_CACHE_DATA_CONTEXT;
>
> +
>
> +
>
> +/*
>
> + Defines the maximum count of Deterministic Cache Parameters Leaf of all
> APs and BSP.
>
> + To save boot time, skip starting up all APs to calculate each AP's count of
> Deterministic
>
> + Cache Parameters Leaf, so use a definition instead.
>
> + Anyway, definition value will be checked in
> CpuCacheInfoCollectCoreAndCacheData function.
>
> +*/
>
> +#define MAX_NUM_OF_CACHE_PARAMS_LEAF 6
>
> +
>
> +/*
>
> + Defines the maximum count of packages.
>
> +*/
>
> +#define MAX_NUM_OF_PACKAGE 100
>
> +
>
> +/**
>
> + Get EDKII_PEI_MP_SERVICES2_PPI or EFI_MP_SERVICES_PROTOCOL pointer.
>
> +
>
> + @param[out] MpServices A pointer to the buffer where
> EDKII_PEI_MP_SERVICES2_PPI or
>
> + EFI_MP_SERVICES_PROTOCOL is stored
>
> +
>
> + @retval EFI_SUCCESS EDKII_PEI_MP_SERVICES2_PPI or
> EFI_MP_SERVICES_PROTOCOL interface is returned
>
> + @retval EFI_NOT_FOUND EDKII_PEI_MP_SERVICES2_PPI or
> EFI_MP_SERVICES_PROTOCOL interface is not found
>
> +**/
>
> +EFI_STATUS
>
> +CpuCacheInfoGetMpServices (
>
> + OUT MP_SERVICES *MpServices
>
> + );
>
> +
>
> +/**
>
> + Activate all of the logical processors.
>
> +
>
> + @param[in] MpServices MP_SERVICES structure.
>
> + @param[in] Procedure A pointer to the function to be run on enabled
> logical processors.
>
> + @param[in] ProcedureArgument The parameter passed into Procedure for
> all enabled logical processors.
>
> +**/
>
> +VOID
>
> +CpuCacheInfoStartupAllCPUs (
>
> + IN MP_SERVICES MpServices,
>
> + IN EFI_AP_PROCEDURE Procedure,
>
> + IN VOID *ProcedureArgument
>
> + );
>
> +
>
> +/**
>
> + Get detailed information of the requested logical processor.
>
> +
>
> + @param[in] MpServices MP_SERVICES structure.
>
> + @param[in] ProcessorNum The requested logical processor number.
>
> + @param[out] ProcessorInfo A pointer to the buffer where the processor
> information is stored
>
> +**/
>
> +VOID
>
> +CpuCacheInfoGetProcessorInfo (
>
> + IN MP_SERVICES MpServices,
>
> + IN UINTN ProcessorNum,
>
> + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfo
>
> + );
>
> +
>
> +/**
>
> + Get the logical processor number.
>
> +
>
> + @param[in] MpServices MP_SERVICES structure.
>
> +
>
> + @retval Return the logical processor number.
>
> +**/
>
> +UINT32
>
> +CpuCacheInfoWhoAmI (
>
> + IN MP_SERVICES MpServices
>
> + );
>
> +
>
> +/**
>
> + Get the total number of logical processors in the platform.
>
> +
>
> + @param[in] MpServices MP_SERVICES structure.
>
> +
>
> + @retval Return the total number of logical processors.
>
> +**/
>
> +UINT32
>
> +CpuCacheInfoGetNumberOfProcessors (
>
> + IN MP_SERVICES MpServices
>
> + );
>
> +#endif
>
> diff --git a/UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.inf
> b/UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.inf
> new file mode 100644
> index 000000000000..c8aa33c95a8f
> --- /dev/null
> +++ b/UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.inf
> @@ -0,0 +1,43 @@
> +## @file
>
> +# CPU Cache Info Library instance for PEI module.
>
> +#
>
> +# Provides cache info for each package, core type, cache level and cache type.
>
> +#
>
> +# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
>
> +#
>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +#
>
> +##
>
> +
>
> +[Defines]
>
> + INF_VERSION = 0x00010005
>
> + BASE_NAME = PeiCpuCacheInfoLib
>
> + FILE_GUID = CFEE2DBE-53B2-4916-84CA-0BA83C3DDA6E
>
> + MODULE_TYPE = PEIM
>
> + VERSION_STRING = 1.0
>
> + LIBRARY_CLASS = CpuCacheInfoLib|PEIM
>
> + MODULE_UNI_FILE = CpuCacheInfoLib.uni
>
> +
>
> +[Sources]
>
> + InternalCpuCacheInfoLib.h
>
> + CpuCacheInfoLib.c
>
> + PeiCpuCacheInfoLib.c
>
> +
>
> +[Packages]
>
> + MdePkg/MdePkg.dec
>
> + UefiCpuPkg/UefiCpuPkg.dec
>
> +
>
> +[LibraryClasses]
>
> + BaseLib
>
> + DebugLib
>
> + BaseMemoryLib
>
> + MemoryAllocationLib
>
> + PeiServicesTablePointerLib
>
> +
>
> +[Ppis]
>
> + gEdkiiPeiMpServices2PpiGuid
>
> +
>
> +[Pcd]
>
> +
>
> +[Depex]
>
> + TRUE
>
> diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
> index d83c084467b3..a639ce5412e4 100644
> --- a/UefiCpuPkg/UefiCpuPkg.dec
> +++ b/UefiCpuPkg/UefiCpuPkg.dec
> @@ -56,6 +56,9 @@ [LibraryClasses.IA32, LibraryClasses.X64]
> ## @libraryclass Provides function to support VMGEXIT processing.
>
> VmgExitLib|Include/Library/VmgExitLib.h
>
>
>
> + ## @libraryclass Provides function to get CPU cache information.
>
> + CpuCacheInfoLib|Include/Library/CpuCacheInfoLib.h
>
> +
>
> [Guids]
>
> gUefiCpuPkgTokenSpaceGuid = { 0xac05bf33, 0x995a, 0x4ed4, { 0xaa, 0xb8,
> 0xef, 0x7a, 0xe8, 0xf, 0x5c, 0xb0 }}
>
> gMsegSmramGuid = { 0x5802bce4, 0xeeee, 0x4e33, { 0xa1, 0x30,
> 0xeb, 0xad, 0x27, 0xf0, 0xe4, 0x39 }}
>
> diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc
> index b2b6d78a71b0..5834eafaa200 100644
> --- a/UefiCpuPkg/UefiCpuPkg.dsc
> +++ b/UefiCpuPkg/UefiCpuPkg.dsc
> @@ -75,6 +75,7 @@ [LibraryClasses.common.PEIM]
> LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf
>
> MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
>
>
> RegisterCpuFeaturesLib|UefiCpuPkg/Library/RegisterCpuFeaturesLib/PeiRegist
> erCpuFeaturesLib.inf
>
> +
> CpuCacheInfoLib|UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.inf
>
>
>
> [LibraryClasses.IA32.PEIM, LibraryClasses.X64.PEIM]
>
>
> PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiS
> ervicesTablePointerLibIdt.inf
>
> @@ -86,6 +87,7 @@ [LibraryClasses.common.DXE_DRIVER]
>
> CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpu
> ExceptionHandlerLib.inf
>
> MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
>
>
> RegisterCpuFeaturesLib|UefiCpuPkg/Library/RegisterCpuFeaturesLib/DxeRegist
> erCpuFeaturesLib.inf
>
> +
> CpuCacheInfoLib|UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.inf
>
>
>
> [LibraryClasses.common.DXE_SMM_DRIVER]
>
>
> SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTab
> leLib.inf
>
> @@ -109,6 +111,8 @@ [Components]
> UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.inf
>
> UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.inf
>
> UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.inf
>
> + UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.inf
>
> + UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.inf
>
>
>
> [Components.IA32, Components.X64]
>
> UefiCpuPkg/CpuDxe/CpuDxe.inf
>
> --
> 2.28.0.windows.1
next prev parent reply other threads:[~2021-01-13 4:01 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-01-07 3:22 [PATCH v5 1/2] MdePkg/Cpuid.h: Add CPUID_HYBRID_INFORMATION Leaf(1Ah) Jason Lou
2021-01-07 3:22 ` [PATCH v5 2/2] UefiCpuPkg/CpuCacheInfoLib: Add new CpuCacheInfoLib Jason Lou
2021-01-13 3:59 ` Ni, Ray
2021-01-13 4:01 ` Ni, Ray [this message]
2021-01-13 4:11 ` Laszlo Ersek
2021-01-13 6:03 ` Ni, Ray
2021-01-12 1:57 ` 回复: [edk2-devel] [PATCH v5 1/2] MdePkg/Cpuid.h: Add CPUID_HYBRID_INFORMATION Leaf(1Ah) gaoliming
2021-01-13 3:54 ` Ni, Ray
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=CO1PR11MB4930610E3C242A49EF79EC1E8CA90@CO1PR11MB4930.namprd11.prod.outlook.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