From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [63.128.21.124]) by mx.groups.io with SMTP id smtpd.web11.3582.1610511087651506217 for ; Tue, 12 Jan 2021 20:11:28 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=jFAj5r6P; spf=pass (domain: redhat.com, ip: 63.128.21.124, mailfrom: lersek@redhat.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1610511086; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=C/+GWL9TmhUH+jZXc5JtoivTBg0Wlia7XqOFC0sVpEM=; b=jFAj5r6Pxz7TO+g8inFBYIXi7YP09I+Yyc6SR7Xm9yOQqwB2nRhH+QnlMZN5YenByybR7c 8UiWB+WZl9Hvosqr9Tndg03EUiICMbvwnWQOpoitgeFO82ibiiyijRzJLt0mqr4A8kwYU4 0/mgkpagoZjdKvzZrP2ZTmM2uRjN0Eg= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-586-o5IZ6RNBOmqWyB4XjvZJVg-1; Tue, 12 Jan 2021 23:11:22 -0500 X-MC-Unique: o5IZ6RNBOmqWyB4XjvZJVg-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 7E990107ACF9; Wed, 13 Jan 2021 04:11:21 +0000 (UTC) Received: from lacos-laptop-7.usersys.redhat.com (ovpn-112-31.ams2.redhat.com [10.36.112.31]) by smtp.corp.redhat.com (Postfix) with ESMTP id 96AEE6267D; Wed, 13 Jan 2021 04:11:19 +0000 (UTC) Subject: Re: [PATCH v5 2/2] UefiCpuPkg/CpuCacheInfoLib: Add new CpuCacheInfoLib. To: "Ni, Ray" , "Lou, Yun" , "devel@edk2.groups.io" Cc: "Dong, Eric" , "Kumar, Rahul1" References: <20210107032246.3101-1-yun.lou@intel.com> <20210107032246.3101-2-yun.lou@intel.com> From: "Laszlo Ersek" Message-ID: <9ed7dca1-581a-9da6-3d6b-49e3fd51bd01@redhat.com> Date: Wed, 13 Jan 2021 05:11:18 +0100 MIME-Version: 1.0 In-Reply-To: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=lersek@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Hello Ray, On 01/13/21 05:01, Ni, Ray wrote: > Laszlo, > Have you given Acked-by or Reviewed-by before? I cannot find it. Please see our previous discussion here (under v1 of the series): https://edk2.groups.io/g/devel/message/67700 https://edk2.groups.io/g/devel/message/67739 https://edk2.groups.io/g/devel/message/67761 Accordingly ("I defer this review to the other UefiCpuPkg reviewers / maintainers"), I have not commented on v2 and later. Also, I can see that SMBIOS_TABLE_TYPE7 is now mentioned in the commit message; thanks for that. > This version is good to me. I will create pull request once MdePkg maintainers > and you approve. Please go ahead, from my side. Thanks! Laszlo > > Thanks, > Ray > >> -----Original Message----- >> From: Lou, Yun >> Sent: Thursday, January 7, 2021 11:23 AM >> To: devel@edk2.groups.io >> Cc: Lou, Yun ; Ni, Ray ; Dong, Eric >> ; Laszlo Ersek ; Kumar, Rahul1 >> >> 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 >> Cc: Ray Ni >> Cc: Eric Dong >> Cc: Laszlo Ersek >> Cc: Rahul Kumar >> --- >> 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.
>> >> + 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.
>> >> + SPDX-License-Identifier: BSD-2-Clause-Patent >> >> + >> >> +**/ >> >> + >> >> +#include >> >> +#include >> >> +#include >> >> +#include >> >> +#include >> >> +#include >> >> + >> >> +/** >> >> + 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.
>> >> + SPDX-License-Identifier: BSD-2-Clause-Patent >> >> + >> >> +**/ >> >> + >> >> +#include >> >> +#include >> >> +#include >> >> +#include >> >> +#include >> >> +#include >> >> +#include >> >> + >> >> +/** >> >> + 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.
>> >> + 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.
>> >> +// >> >> +// 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.
>> >> +# >> >> +# 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.
>> >> + SPDX-License-Identifier: BSD-2-Clause-Patent >> >> + >> >> +**/ >> >> + >> >> +#ifndef _INTERNAL_CPU_CACHE_INFO_LIB_H_ >> >> +#define _INTERNAL_CPU_CACHE_INFO_LIB_H_ >> >> + >> >> +#include >> >> +#include >> >> +#include >> >> +#include >> >> +#include >> >> +#include >> >> +#include >> >> +#include >> >> +#include >> >> + >> >> +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.
>> >> +# >> >> +# 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 >