--- /dev/null
+/** @file\r
+ Header file for CPU Cache info Library.\r
+\r
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef _CPU_CACHE_INFO_LIB_H_\r
+#define _CPU_CACHE_INFO_LIB_H_\r
+\r
+typedef struct {\r
+ //\r
+ // Package number.\r
+ //\r
+ UINT32 Package;\r
+ //\r
+ // Core type of logical processor.\r
+ // Value = CPUID.1Ah:EAX[31:24]\r
+ //\r
+ UINT8 CoreType;\r
+ //\r
+ // Level of the cache that this package's this type of logical processor corresponds to.\r
+ // Value = CPUID.04h:EAX[07:05]\r
+ //\r
+ UINT8 CacheLevel : 3;\r
+ //\r
+ // Type of the cache that this package's this type of logical processor corresponds to.\r
+ // Value = CPUID.04h:EAX[04:00]\r
+ //\r
+ UINT8 CacheType : 5;\r
+ //\r
+ // Ways of associativity.\r
+ // Value = CPUID.04h:EBX[31:22]\r
+ //\r
+ UINT16 CacheWays;\r
+ //\r
+ // Size of single cache that this package's this type of logical processor corresponds to.\r
+ // Value = (CPUID.04h:EBX[31:22] + 1) * (CPUID.04h:EBX[21:12] + 1) *\r
+ // (CPUID.04h:EBX[11:00] + 1) * (CPUID.04h:ECX[31:00] + 1)\r
+ //\r
+ UINT32 CacheSizeinKB;\r
+ //\r
+ // Number of the cache that this package's this type of logical processor corresponds to.\r
+ // Have subtracted the number of caches that are shared.\r
+ //\r
+ UINT16 CacheCount;\r
+} CPU_CACHE_INFO;\r
+\r
+/**\r
+ Get CpuCacheInfo data array.\r
+\r
+ @param[in, out] CpuCacheInfo Pointer to the CpuCacheInfo array.\r
+ @param[in, out] CpuCacheInfoCount As input, point to the length of response CpuCacheInfo array.\r
+ As output, point to the actual length of response CpuCacheInfo array.\r
+\r
+ @retval EFI_SUCCESS Function completed successfully.\r
+ @retval EFI_INVALID_PARAMETER CpuCacheInfoCount is NULL.\r
+ @retval EFI_INVALID_PARAMETER CpuCacheInfo is NULL while CpuCacheInfoCount contains the value\r
+ greater than zero.\r
+ @retval EFI_UNSUPPORTED Processor does not support CPUID_CACHE_PARAMS Leaf.\r
+ @retval EFI_NOT_FOUND EDKII_PEI_MP_SERVICES2_PPI or EFI_MP_SERVICES_PROTOCOL interface\r
+ is not found.\r
+ @retval EFI_OUT_OF_RESOURCES Required resources could not be allocated.\r
+ @retval EFI_BUFFER_TOO_SMALL CpuCacheInfoCount is too small to hold the response CpuCacheInfo\r
+ array. CpuCacheInfoCount has been updated with the length needed\r
+ to complete the request.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetCpuCacheInfo (\r
+ IN OUT CPU_CACHE_INFO *CpuCacheInfo,\r
+ IN OUT UINTN *CpuCacheInfoCount\r
+ );\r
+\r
+#endif\r
--- /dev/null
+/** @file\r
+ Provides cache info for each package, core type, cache level and cache type.\r
+\r
+ Copyright (c) 2020 Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include "InternalCpuCacheInfoLib.h"\r
+\r
+/**\r
+ Print CpuCacheInfo array.\r
+\r
+ @param[in] CpuCacheInfo Pointer to the CpuCacheInfo array.\r
+ @param[in] CpuCacheInfoCount The length of CpuCacheInfo array.\r
+\r
+**/\r
+VOID\r
+CpuCacheInfoPrintCpuCacheInfoTable (\r
+ IN CPU_CACHE_INFO *CpuCacheInfo,\r
+ IN UINTN CpuCacheInfoCount\r
+ )\r
+{\r
+ UINTN Index;\r
+\r
+ DEBUG ((DEBUG_INFO, "+-------+-------------------------------------------------------------------------------+\n"));\r
+ DEBUG ((DEBUG_INFO, "| Index | Packge CoreType CacheLevel CacheType CacheWays CacheSizeinKB CacheCount |\n"));\r
+ DEBUG ((DEBUG_INFO, "+-------+-------------------------------------------------------------------------------+\n"));\r
+\r
+ for (Index = 0; Index < CpuCacheInfoCount; Index++) {\r
+ DEBUG ((DEBUG_INFO, "| %4x | %4x %2x %2x %2x %4x %8x %4x |\n", Index,\r
+ CpuCacheInfo[Index].Package, CpuCacheInfo[Index].CoreType, CpuCacheInfo[Index].CacheLevel,\r
+ CpuCacheInfo[Index].CacheType, CpuCacheInfo[Index].CacheWays, CpuCacheInfo[Index].CacheSizeinKB,\r
+ CpuCacheInfo[Index].CacheCount));\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO, "+-------+-------------------------------------------------------------------------------+\n"));\r
+}\r
+\r
+/**\r
+ Get the total number of package and package ID in the platform.\r
+\r
+ @param[in] ProcessorInfo Pointer to the ProcessorInfo array.\r
+ @param[in] NumberOfProcessors Total number of logical processors in the platform.\r
+ @param[in, out] Package Pointer to the Package array.\r
+\r
+ @retval Return the total number of package and package ID in the platform.\r
+**/\r
+UINT32\r
+CpuCacheInfoGetNumberOfPackages (\r
+ IN CPUID_PROCESSOR_INFO *ProcessorInfo,\r
+ IN UINTN NumberOfProcessors,\r
+ IN OUT UINT32 *Package\r
+ )\r
+{\r
+ UINTN ProcessorIndex;\r
+ UINT32 PackageIndex;\r
+ UINT32 PackageCount;\r
+ UINT32 CurrentPackage;\r
+\r
+ PackageCount = 0;\r
+\r
+ for (ProcessorIndex = 0; ProcessorIndex < NumberOfProcessors; ProcessorIndex++) {\r
+ CurrentPackage = ProcessorInfo[ProcessorIndex].Package;\r
+\r
+ //\r
+ // For the package that already exists in Package array, break out the loop.\r
+ //\r
+ for (PackageIndex = 0; PackageIndex < PackageCount; PackageIndex++) {\r
+ if (CurrentPackage == Package[PackageIndex]) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ //\r
+ // For the new package, save it in Package array.\r
+ //\r
+ if (PackageIndex == PackageCount) {\r
+ ASSERT (PackageCount < MAX_NUM_OF_PACKAGE);\r
+ Package[PackageCount++] = CurrentPackage;\r
+ }\r
+ }\r
+\r
+ return PackageCount;\r
+}\r
+\r
+/**\r
+ Get the number of CoreType of requested package.\r
+\r
+ @param[in] ProcessorInfo Pointer to the ProcessorInfo array.\r
+ @param[in] NumberOfProcessors Total number of logical processors in the platform.\r
+ @param[in] Package The requested package number.\r
+\r
+ @retval Return the number of CoreType of requested package.\r
+**/\r
+UINTN\r
+CpuCacheInfoGetNumberOfCoreTypePerPackage(\r
+ IN CPUID_PROCESSOR_INFO *ProcessorInfo,\r
+ IN UINTN NumberOfProcessors,\r
+ IN UINTN Package\r
+ )\r
+{\r
+ UINTN ProcessorIndex;\r
+ //\r
+ // Core Type value comes from CPUID.1Ah.EAX[31:24].\r
+ // So max number of core types should be MAX_UINT8.\r
+ //\r
+ UINT8 CoreType[MAX_UINT8];\r
+ UINTN CoreTypeIndex;\r
+ UINTN CoreTypeCount;\r
+ UINT8 CurrentCoreType;\r
+\r
+ //\r
+ // CoreType array is empty.\r
+ //\r
+ CoreTypeCount = 0;\r
+\r
+ for (ProcessorIndex = 0; ProcessorIndex < NumberOfProcessors; ProcessorIndex++) {\r
+ CurrentCoreType = ProcessorInfo[ProcessorIndex].CoreType;\r
+\r
+ if (ProcessorInfo[ProcessorIndex].Package != Package) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // For the type that already exists in CoreType array, break out the loop.\r
+ //\r
+ for (CoreTypeIndex = 0; CoreTypeIndex < CoreTypeCount; CoreTypeIndex++) {\r
+ if (CurrentCoreType == CoreType[CoreTypeIndex]) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ //\r
+ // For the new type, save it in CoreType array.\r
+ //\r
+ if (CoreTypeIndex == CoreTypeCount) {\r
+ ASSERT (CoreTypeCount < MAX_UINT8);\r
+ CoreType[CoreTypeCount++] = CurrentCoreType;\r
+ }\r
+ }\r
+\r
+ return CoreTypeCount;\r
+}\r
+\r
+/**\r
+ Collect core and cache information of calling processor via CPUID instructions.\r
+\r
+ @param[in, out] Buffer The pointer to private data buffer.\r
+**/\r
+VOID\r
+EFIAPI\r
+CpuCacheInfoCollectCoreAndCacheData (\r
+ IN OUT VOID *Buffer\r
+ )\r
+{\r
+ UINTN ProcessorIndex;\r
+ UINT32 CpuidMaxInput;\r
+ UINT8 CacheParamLeafIndex;\r
+ CPUID_CACHE_PARAMS_EAX CacheParamEax;\r
+ CPUID_CACHE_PARAMS_EBX CacheParamEbx;\r
+ UINT32 CacheParamEcx;\r
+ CPUID_NATIVE_MODEL_ID_AND_CORE_TYPE_EAX NativeModelIdAndCoreTypeEax;\r
+ COLLECT_CPUID_CACHE_DATA_CONTEXT *Context;\r
+ CPUID_CACHE_DATA *CacheData;\r
+\r
+ Context = (COLLECT_CPUID_CACHE_DATA_CONTEXT *)Buffer;\r
+ ProcessorIndex = CpuCacheInfoWhoAmI (Context->MpServices);\r
+ CacheData = &Context->CacheData[MAX_NUM_OF_CACHE_PARAMS_LEAF * ProcessorIndex];\r
+\r
+ AsmCpuid (CPUID_SIGNATURE, &CpuidMaxInput, NULL, NULL, NULL);\r
+\r
+ //\r
+ // get CoreType if CPUID_HYBRID_INFORMATION leaf is supported.\r
+ //\r
+ Context->ProcessorInfo[ProcessorIndex].CoreType = 0;\r
+ if (CpuidMaxInput >= CPUID_HYBRID_INFORMATION) {\r
+ AsmCpuidEx (CPUID_HYBRID_INFORMATION, CPUID_HYBRID_INFORMATION_SUB_LEAF, &NativeModelIdAndCoreTypeEax.Uint32, NULL, NULL, NULL);\r
+ Context->ProcessorInfo[ProcessorIndex].CoreType = (UINT8) NativeModelIdAndCoreTypeEax.Bits.CoreType;\r
+ }\r
+\r
+ //\r
+ // cache hierarchy starts with an index value of 0.\r
+ //\r
+ CacheParamLeafIndex = 0;\r
+\r
+ while (CacheParamLeafIndex < MAX_NUM_OF_CACHE_PARAMS_LEAF) {\r
+ AsmCpuidEx (CPUID_CACHE_PARAMS, CacheParamLeafIndex, &CacheParamEax.Uint32, &CacheParamEbx.Uint32, &CacheParamEcx, NULL);\r
+\r
+ if (CacheParamEax.Bits.CacheType == 0) {\r
+ break;\r
+ }\r
+\r
+ CacheData[CacheParamLeafIndex].CacheLevel = (UINT8)CacheParamEax.Bits.CacheLevel;\r
+ CacheData[CacheParamLeafIndex].CacheType = (UINT8)CacheParamEax.Bits.CacheType;\r
+ CacheData[CacheParamLeafIndex].CacheWays = (UINT16)CacheParamEbx.Bits.Ways;\r
+ CacheData[CacheParamLeafIndex].CacheShareBits = (UINT16)CacheParamEax.Bits.MaximumAddressableIdsForLogicalProcessors;\r
+ CacheData[CacheParamLeafIndex].CacheSizeinKB = (CacheParamEbx.Bits.Ways + 1) *\r
+ (CacheParamEbx.Bits.LinePartitions + 1) * (CacheParamEbx.Bits.LineSize + 1) * (CacheParamEcx + 1) / SIZE_1KB;\r
+\r
+ CacheParamLeafIndex++;\r
+ }\r
+}\r
+\r
+/**\r
+ Collect CacheInfo data from the CacheData.\r
+\r
+ @param[in] CacheData Pointer to the CacheData array.\r
+ @param[in] ProcessorInfo Pointer to the ProcessorInfo array.\r
+ @param[in] NumberOfProcessors Total number of logical processors in the platform.\r
+ @param[in, out] CacheInfo Pointer to the CacheInfo array.\r
+ @param[in, out] CacheInfoCount As input, point to the length of response CacheInfo array.\r
+ As output, point to the actual length of response CacheInfo array.\r
+\r
+ @retval EFI_SUCCESS Function completed successfully.\r
+ @retval EFI_OUT_OF_RESOURCES Required resources could not be allocated.\r
+ @retval EFI_BUFFER_TOO_SMALL CacheInfoCount is too small to hold the response CacheInfo\r
+ array. CacheInfoCount has been updated with the length needed\r
+ to complete the request.\r
+**/\r
+EFI_STATUS\r
+CpuCacheInfoCollectCpuCacheInfoData (\r
+ IN CPUID_CACHE_DATA *CacheData,\r
+ IN CPUID_PROCESSOR_INFO *ProcessorInfo,\r
+ IN UINTN NumberOfProcessors,\r
+ IN OUT CPU_CACHE_INFO *CacheInfo,\r
+ IN OUT UINTN *CacheInfoCount\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 NumberOfPackage;\r
+ UINT32 Package[MAX_NUM_OF_PACKAGE];\r
+ UINTN PackageIndex;\r
+ UINTN TotalNumberOfCoreType;\r
+ UINTN MaxCacheInfoCount;\r
+ CPU_CACHE_INFO *LocalCacheInfo;\r
+ UINTN CacheInfoIndex;\r
+ UINTN LocalCacheInfoCount;\r
+ UINTN Index;\r
+ UINTN NextIndex;\r
+\r
+ //\r
+ // Get number of Packages and Package ID.\r
+ //\r
+ NumberOfPackage = CpuCacheInfoGetNumberOfPackages (ProcessorInfo, NumberOfProcessors, Package);\r
+\r
+ //\r
+ // Get number of core types for each package and count the total number.\r
+ // E.g. If Package1 and Package2 both have 2 core types, the total number is 4.\r
+ //\r
+ TotalNumberOfCoreType = 0;\r
+ for (PackageIndex = 0; PackageIndex < NumberOfPackage; PackageIndex++) {\r
+ TotalNumberOfCoreType += CpuCacheInfoGetNumberOfCoreTypePerPackage (ProcessorInfo, NumberOfProcessors, Package[PackageIndex]);\r
+ }\r
+\r
+ MaxCacheInfoCount = TotalNumberOfCoreType * MAX_NUM_OF_CACHE_PARAMS_LEAF;\r
+ LocalCacheInfo = AllocatePages (EFI_SIZE_TO_PAGES (MaxCacheInfoCount * sizeof (*LocalCacheInfo)));\r
+ ASSERT (LocalCacheInfo != NULL);\r
+ if (LocalCacheInfo == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ LocalCacheInfoCount = 0;\r
+\r
+ for (Index = 0; Index < NumberOfProcessors * MAX_NUM_OF_CACHE_PARAMS_LEAF; Index++) {\r
+ if (CacheData[Index].CacheSizeinKB == 0) {\r
+ continue;\r
+ }\r
+\r
+ //\r
+ // For the sharing caches, clear their CacheSize.\r
+ //\r
+ for (NextIndex = Index + 1; NextIndex < NumberOfProcessors * MAX_NUM_OF_CACHE_PARAMS_LEAF; NextIndex++) {\r
+ if (CacheData[NextIndex].CacheSizeinKB == 0) {\r
+ continue;\r
+ }\r
+\r
+ if (CacheData[Index].CacheLevel == CacheData[NextIndex].CacheLevel &&\r
+ CacheData[Index].CacheType == CacheData[NextIndex].CacheType &&\r
+ ProcessorInfo[Index / MAX_NUM_OF_CACHE_PARAMS_LEAF].Package == ProcessorInfo[NextIndex / MAX_NUM_OF_CACHE_PARAMS_LEAF].Package &&\r
+ ProcessorInfo[Index / MAX_NUM_OF_CACHE_PARAMS_LEAF].CoreType == ProcessorInfo[NextIndex / MAX_NUM_OF_CACHE_PARAMS_LEAF].CoreType &&\r
+ (ProcessorInfo[Index / MAX_NUM_OF_CACHE_PARAMS_LEAF].ApicId & ~CacheData[Index].CacheShareBits) ==\r
+ (ProcessorInfo[NextIndex / MAX_NUM_OF_CACHE_PARAMS_LEAF].ApicId & ~CacheData[NextIndex].CacheShareBits)) {\r
+ CacheData[NextIndex].CacheSizeinKB = 0; // uses the sharing cache\r
+ }\r
+ }\r
+\r
+ //\r
+ // For the cache that already exists in LocalCacheInfo, increase its CacheCount.\r
+ //\r
+ for (CacheInfoIndex = 0; CacheInfoIndex < LocalCacheInfoCount; CacheInfoIndex++) {\r
+ if (LocalCacheInfo[CacheInfoIndex].Package == ProcessorInfo[Index / MAX_NUM_OF_CACHE_PARAMS_LEAF].Package &&\r
+ LocalCacheInfo[CacheInfoIndex].CoreType == ProcessorInfo[Index / MAX_NUM_OF_CACHE_PARAMS_LEAF].CoreType &&\r
+ LocalCacheInfo[CacheInfoIndex].CacheLevel == CacheData[Index].CacheLevel &&\r
+ LocalCacheInfo[CacheInfoIndex].CacheType == CacheData[Index].CacheType) {\r
+ LocalCacheInfo[CacheInfoIndex].CacheCount++;\r
+ break;\r
+ }\r
+ }\r
+\r
+ //\r
+ // For the new cache with different Package, CoreType, CacheLevel or CacheType, copy its\r
+ // data into LocalCacheInfo buffer.\r
+ //\r
+ if (CacheInfoIndex == LocalCacheInfoCount) {\r
+ ASSERT (LocalCacheInfoCount < MaxCacheInfoCount);\r
+\r
+ LocalCacheInfo[LocalCacheInfoCount].Package = ProcessorInfo[Index / MAX_NUM_OF_CACHE_PARAMS_LEAF].Package;\r
+ LocalCacheInfo[LocalCacheInfoCount].CoreType = ProcessorInfo[Index / MAX_NUM_OF_CACHE_PARAMS_LEAF].CoreType;\r
+ LocalCacheInfo[LocalCacheInfoCount].CacheLevel = CacheData[Index].CacheLevel;\r
+ LocalCacheInfo[LocalCacheInfoCount].CacheType = CacheData[Index].CacheType;\r
+ LocalCacheInfo[LocalCacheInfoCount].CacheWays = CacheData[Index].CacheWays;\r
+ LocalCacheInfo[LocalCacheInfoCount].CacheSizeinKB = CacheData[Index].CacheSizeinKB;\r
+ LocalCacheInfo[LocalCacheInfoCount].CacheCount = 1;\r
+\r
+ LocalCacheInfoCount++;\r
+ }\r
+ }\r
+\r
+ if (*CacheInfoCount < LocalCacheInfoCount) {\r
+ Status = EFI_BUFFER_TOO_SMALL;\r
+ } else {\r
+ CopyMem (CacheInfo, LocalCacheInfo, sizeof (*CacheInfo) * LocalCacheInfoCount);\r
+ DEBUG_CODE (\r
+ CpuCacheInfoPrintCpuCacheInfoTable (CacheInfo, LocalCacheInfoCount);\r
+ );\r
+ Status = EFI_SUCCESS;\r
+ }\r
+\r
+ *CacheInfoCount = LocalCacheInfoCount;\r
+\r
+ FreePages (LocalCacheInfo, EFI_SIZE_TO_PAGES (MaxCacheInfoCount * sizeof (*LocalCacheInfo)));\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Get CpuCacheInfo data array.\r
+\r
+ @param[in, out] CpuCacheInfo Pointer to the CpuCacheInfo array.\r
+ @param[in, out] CpuCacheInfoCount As input, point to the length of response CpuCacheInfo array.\r
+ As output, point to the actual length of response CpuCacheInfo array.\r
+\r
+ @retval EFI_SUCCESS Function completed successfully.\r
+ @retval EFI_INVALID_PARAMETER CpuCacheInfoCount is NULL.\r
+ @retval EFI_INVALID_PARAMETER CpuCacheInfo is NULL while CpuCacheInfoCount contains the value\r
+ greater than zero.\r
+ @retval EFI_UNSUPPORTED Processor does not support CPUID_CACHE_PARAMS Leaf.\r
+ @retval EFI_NOT_FOUND EDKII_PEI_MP_SERVICES2_PPI or EFI_MP_SERVICES_PROTOCOL interface\r
+ is not found.\r
+ @retval EFI_OUT_OF_RESOURCES Required resources could not be allocated.\r
+ @retval EFI_BUFFER_TOO_SMALL CpuCacheInfoCount is too small to hold the response CpuCacheInfo\r
+ array. CpuCacheInfoCount has been updated with the length needed\r
+ to complete the request.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetCpuCacheInfo (\r
+ IN OUT CPU_CACHE_INFO *CpuCacheInfo,\r
+ IN OUT UINTN *CpuCacheInfoCount\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT32 CpuidMaxInput;\r
+ UINT32 NumberOfProcessors;\r
+ UINTN CacheDataCount;\r
+ UINTN ProcessorIndex;\r
+ EFI_PROCESSOR_INFORMATION ProcessorInfo;\r
+ COLLECT_CPUID_CACHE_DATA_CONTEXT Context;\r
+\r
+ if (CpuCacheInfoCount == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (*CpuCacheInfoCount != 0 && CpuCacheInfo == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ AsmCpuid (CPUID_SIGNATURE, &CpuidMaxInput, NULL, NULL, NULL);\r
+ if (CpuidMaxInput < CPUID_CACHE_PARAMS) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ //\r
+ // Initialize COLLECT_CPUID_CACHE_DATA_CONTEXT.MpServices.\r
+ //\r
+ Status = CpuCacheInfoGetMpServices (&Context.MpServices);\r
+ if (EFI_ERROR(Status)) {\r
+ return Status;\r
+ }\r
+\r
+ NumberOfProcessors = CpuCacheInfoGetNumberOfProcessors (Context.MpServices);\r
+\r
+ //\r
+ // Initialize COLLECT_CPUID_CACHE_DATA_CONTEXT.ProcessorInfo.\r
+ //\r
+ Context.ProcessorInfo = AllocatePages (EFI_SIZE_TO_PAGES (NumberOfProcessors * sizeof (*Context.ProcessorInfo)));\r
+ ASSERT (Context.ProcessorInfo != NULL);\r
+ if (Context.ProcessorInfo == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ //\r
+ // Initialize COLLECT_CPUID_CACHE_DATA_CONTEXT.CacheData.\r
+ // CacheData array consists of CPUID_CACHE_DATA data structure for each Cpuid Cache Parameter Leaf\r
+ // per logical processor. The array begin with data of each Cache Parameter Leaf of processor 0, followed\r
+ // by data of each Cache Parameter Leaf of processor 1 ...\r
+ //\r
+ CacheDataCount = NumberOfProcessors * MAX_NUM_OF_CACHE_PARAMS_LEAF;\r
+ Context.CacheData = AllocatePages (EFI_SIZE_TO_PAGES (CacheDataCount * sizeof (*Context.CacheData)));\r
+ ASSERT (Context.CacheData != NULL);\r
+ if (Context.CacheData == NULL) {\r
+ FreePages (Context.ProcessorInfo, EFI_SIZE_TO_PAGES (NumberOfProcessors * sizeof (*Context.ProcessorInfo)));\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ ZeroMem (Context.CacheData, CacheDataCount * sizeof (*Context.CacheData));\r
+\r
+ //\r
+ // Collect Package ID and APIC ID of all processors.\r
+ //\r
+ for (ProcessorIndex = 0; ProcessorIndex < NumberOfProcessors; ProcessorIndex++) {\r
+ CpuCacheInfoGetProcessorInfo (Context.MpServices, ProcessorIndex, &ProcessorInfo);\r
+ Context.ProcessorInfo[ProcessorIndex].Package = ProcessorInfo.Location.Package;\r
+ Context.ProcessorInfo[ProcessorIndex].ApicId = (UINT32) ProcessorInfo.ProcessorId;\r
+ }\r
+\r
+ //\r
+ // Wakeup all processors for CacheData(core type and cache data) collection.\r
+ //\r
+ CpuCacheInfoStartupAllCPUs (Context.MpServices, CpuCacheInfoCollectCoreAndCacheData, &Context);\r
+\r
+ //\r
+ // Collect CpuCacheInfo data from CacheData.\r
+ //\r
+ Status = CpuCacheInfoCollectCpuCacheInfoData (Context.CacheData, Context.ProcessorInfo, NumberOfProcessors, CpuCacheInfo, CpuCacheInfoCount);\r
+\r
+ FreePages (Context.CacheData, EFI_SIZE_TO_PAGES (CacheDataCount * sizeof (*Context.CacheData)));\r
+ FreePages (Context.ProcessorInfo, EFI_SIZE_TO_PAGES (NumberOfProcessors * sizeof (*Context.ProcessorInfo)));\r
+\r
+ return Status;\r
+}\r
--- /dev/null
+// /** @file\r
+// CPU Cache Info Library\r
+//\r
+// Provides cache info for each package, core type, cache level and cache type.\r
+//\r
+// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>\r
+//\r
+// SPDX-License-Identifier: BSD-2-Clause-Patent\r
+//\r
+// **/\r
+\r
+\r
+#string STR_MODULE_ABSTRACT #language en-US "CPU Cache Info Library"\r
+\r
+#string STR_MODULE_DESCRIPTION #language en-US "Provides cache info for each package, core type, cache level and cache type."\r
--- /dev/null
+/** @file\r
+ Provides cache info for each package, core type, cache level and cache type.\r
+\r
+ Copyright (c) 2020 Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <PiDxe.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/CpuCacheInfoLib.h>\r
+#include <InternalCpuCacheInfoLib.h>\r
+\r
+/**\r
+ Get EFI_MP_SERVICES_PROTOCOL pointer.\r
+\r
+ @param[out] MpServices A pointer to the buffer where EFI_MP_SERVICES_PROTOCOL is stored\r
+\r
+ @retval EFI_SUCCESS EFI_MP_SERVICES_PROTOCOL interface is returned\r
+ @retval EFI_NOT_FOUND EFI_MP_SERVICES_PROTOCOL interface is not found\r
+**/\r
+EFI_STATUS\r
+CpuCacheInfoGetMpServices (\r
+ OUT MP_SERVICES *MpServices\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **)&MpServices->Protocol);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Activate all of the logical processors.\r
+\r
+ @param[in] MpServices MP_SERVICES structure.\r
+ @param[in] Procedure A pointer to the function to be run on enabled logical processors.\r
+ @param[in] ProcedureArgument The parameter passed into Procedure for all enabled logical processors.\r
+**/\r
+VOID\r
+CpuCacheInfoStartupAllCPUs (\r
+ IN MP_SERVICES MpServices,\r
+ IN EFI_AP_PROCEDURE Procedure,\r
+ IN VOID *ProcedureArgument\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = MpServices.Protocol->StartupAllAPs (MpServices.Protocol, Procedure, FALSE, NULL, 0, ProcedureArgument, NULL);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ Procedure (ProcedureArgument);\r
+}\r
+\r
+/**\r
+ Get detailed information of the requested logical processor.\r
+\r
+ @param[in] MpServices MP_SERVICES structure.\r
+ @param[in] ProcessorNum The requested logical processor number.\r
+ @param[out] ProcessorInfo A pointer to the buffer where the processor information is stored\r
+**/\r
+VOID\r
+CpuCacheInfoGetProcessorInfo (\r
+ IN MP_SERVICES MpServices,\r
+ IN UINTN ProcessorNum,\r
+ OUT EFI_PROCESSOR_INFORMATION *ProcessorInfo\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = MpServices.Protocol->GetProcessorInfo (MpServices.Protocol, ProcessorNum, ProcessorInfo);\r
+ ASSERT_EFI_ERROR (Status);\r
+}\r
+\r
+/**\r
+ Get the logical processor number.\r
+\r
+ @param[in] MpServices MP_SERVICES structure.\r
+\r
+ @retval Return the logical processor number.\r
+**/\r
+UINT32\r
+CpuCacheInfoWhoAmI (\r
+ IN MP_SERVICES MpServices\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN ProcessorNum;\r
+\r
+ Status = MpServices.Protocol->WhoAmI (MpServices.Protocol, &ProcessorNum);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ return (UINT32)ProcessorNum;\r
+}\r
+\r
+/**\r
+ Get the total number of logical processors in the platform.\r
+\r
+ @param[in] MpServices MP_SERVICES structure.\r
+\r
+ @retval Return the total number of logical processors.\r
+**/\r
+UINT32\r
+CpuCacheInfoGetNumberOfProcessors (\r
+ IN MP_SERVICES MpServices\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN NumberOfProcessor;\r
+ UINTN NumberOfEnabledProcessor;\r
+\r
+ Status = MpServices.Protocol->GetNumberOfProcessors (MpServices.Protocol, &NumberOfProcessor, &NumberOfEnabledProcessor);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ return (UINT32)NumberOfProcessor;\r
+}\r
--- /dev/null
+## @file\r
+# CPU Cache Info Library instance for DXE driver.\r
+#\r
+# Provides cache info for each package, core type, cache level and cache type.\r
+#\r
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>\r
+#\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+##\r
+\r
+[Defines]\r
+ INF_VERSION = 0x00010005\r
+ BASE_NAME = DxeCpuCacheInfoLib\r
+ FILE_GUID = B25C288F-C309-41F1-8325-37E64DC5EA3D\r
+ MODULE_TYPE = DXE_DRIVER\r
+ VERSION_STRING = 1.0\r
+ LIBRARY_CLASS = CpuCacheInfoLib|DXE_DRIVER UEFI_APPLICATION\r
+ MODULE_UNI_FILE = CpuCacheInfoLib.uni\r
+\r
+[Sources]\r
+ InternalCpuCacheInfoLib.h\r
+ CpuCacheInfoLib.c\r
+ DxeCpuCacheInfoLib.c\r
+\r
+[Packages]\r
+ MdePkg/MdePkg.dec\r
+ UefiCpuPkg/UefiCpuPkg.dec\r
+\r
+[LibraryClasses]\r
+ BaseLib\r
+ DebugLib\r
+ BaseMemoryLib\r
+ MemoryAllocationLib\r
+ UefiBootServicesTableLib\r
+\r
+[Protocols]\r
+ gEfiMpServiceProtocolGuid\r
+\r
+[Pcd]\r
+\r
+[Depex]\r
+ TRUE\r
--- /dev/null
+/** @file\r
+ Internal header file for CPU Cache info Library.\r
+\r
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef _INTERNAL_CPU_CACHE_INFO_LIB_H_\r
+#define _INTERNAL_CPU_CACHE_INFO_LIB_H_\r
+\r
+#include <PiPei.h>\r
+#include <Register/Cpuid.h>\r
+#include <Ppi/MpServices2.h>\r
+#include <Protocol/MpService.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/CpuCacheInfoLib.h>\r
+\r
+typedef struct {\r
+ //\r
+ // Package ID, the information comes from\r
+ // EFI_CPU_PHYSICAL_LOCATION.Package\r
+ //\r
+ UINT32 Package;\r
+ //\r
+ // APIC ID, the information comes from\r
+ // EFI_PROCESSOR_INFORMATION.ProcessorId\r
+ //\r
+ UINT32 ApicId;\r
+ //\r
+ // Core type of logical processor.\r
+ // Value = CPUID.1Ah:EAX[31:24]\r
+ //\r
+ UINT8 CoreType;\r
+} CPUID_PROCESSOR_INFO;\r
+\r
+typedef struct {\r
+ //\r
+ // Level of the cache.\r
+ // Value = CPUID.04h:EAX[07:05]\r
+ //\r
+ UINT8 CacheLevel : 3;\r
+ //\r
+ // Type of the cache.\r
+ // Value = CPUID.04h:EAX[04:00]\r
+ //\r
+ UINT8 CacheType : 5;\r
+ //\r
+ // Ways of associativity.\r
+ // Value = CPUID.04h:EBX[31:22]\r
+ //\r
+ UINT16 CacheWays;\r
+ //\r
+ // Cache share bits.\r
+ // Value = CPUID.04h:EAX[25:14]\r
+ //\r
+ UINT16 CacheShareBits;\r
+ //\r
+ // Size of single cache.\r
+ // Value = (CPUID.04h:EBX[31:22] + 1) * (CPUID.04h:EBX[21:12] + 1) *\r
+ // (CPUID.04h:EBX[11:00] + 1) * (CPUID.04h:ECX[31:00] + 1)\r
+ //\r
+ UINT32 CacheSizeinKB;\r
+} CPUID_CACHE_DATA;\r
+\r
+typedef union {\r
+ EDKII_PEI_MP_SERVICES2_PPI *Ppi;\r
+ EFI_MP_SERVICES_PROTOCOL *Protocol;\r
+} MP_SERVICES;\r
+\r
+typedef struct {\r
+ MP_SERVICES MpServices;\r
+ CPUID_PROCESSOR_INFO *ProcessorInfo;\r
+ CPUID_CACHE_DATA *CacheData;\r
+} COLLECT_CPUID_CACHE_DATA_CONTEXT;\r
+\r
+\r
+/*\r
+ Defines the maximum count of Deterministic Cache Parameters Leaf of all APs and BSP.\r
+ To save boot time, skip starting up all APs to calculate each AP's count of Deterministic\r
+ Cache Parameters Leaf, so use a definition instead.\r
+ Anyway, definition value will be checked in CpuCacheInfoCollectCoreAndCacheData function.\r
+*/\r
+#define MAX_NUM_OF_CACHE_PARAMS_LEAF 6\r
+\r
+/*\r
+ Defines the maximum count of packages.\r
+*/\r
+#define MAX_NUM_OF_PACKAGE 100\r
+\r
+/**\r
+ Get EDKII_PEI_MP_SERVICES2_PPI or EFI_MP_SERVICES_PROTOCOL pointer.\r
+\r
+ @param[out] MpServices A pointer to the buffer where EDKII_PEI_MP_SERVICES2_PPI or\r
+ EFI_MP_SERVICES_PROTOCOL is stored\r
+\r
+ @retval EFI_SUCCESS EDKII_PEI_MP_SERVICES2_PPI or EFI_MP_SERVICES_PROTOCOL interface is returned\r
+ @retval EFI_NOT_FOUND EDKII_PEI_MP_SERVICES2_PPI or EFI_MP_SERVICES_PROTOCOL interface is not found\r
+**/\r
+EFI_STATUS\r
+CpuCacheInfoGetMpServices (\r
+ OUT MP_SERVICES *MpServices\r
+ );\r
+\r
+/**\r
+ Activate all of the logical processors.\r
+\r
+ @param[in] MpServices MP_SERVICES structure.\r
+ @param[in] Procedure A pointer to the function to be run on enabled logical processors.\r
+ @param[in] ProcedureArgument The parameter passed into Procedure for all enabled logical processors.\r
+**/\r
+VOID\r
+CpuCacheInfoStartupAllCPUs (\r
+ IN MP_SERVICES MpServices,\r
+ IN EFI_AP_PROCEDURE Procedure,\r
+ IN VOID *ProcedureArgument\r
+ );\r
+\r
+/**\r
+ Get detailed information of the requested logical processor.\r
+\r
+ @param[in] MpServices MP_SERVICES structure.\r
+ @param[in] ProcessorNum The requested logical processor number.\r
+ @param[out] ProcessorInfo A pointer to the buffer where the processor information is stored\r
+**/\r
+VOID\r
+CpuCacheInfoGetProcessorInfo (\r
+ IN MP_SERVICES MpServices,\r
+ IN UINTN ProcessorNum,\r
+ OUT EFI_PROCESSOR_INFORMATION *ProcessorInfo\r
+ );\r
+\r
+/**\r
+ Get the logical processor number.\r
+\r
+ @param[in] MpServices MP_SERVICES structure.\r
+\r
+ @retval Return the logical processor number.\r
+**/\r
+UINT32\r
+CpuCacheInfoWhoAmI (\r
+ IN MP_SERVICES MpServices\r
+ );\r
+\r
+/**\r
+ Get the total number of logical processors in the platform.\r
+\r
+ @param[in] MpServices MP_SERVICES structure.\r
+\r
+ @retval Return the total number of logical processors.\r
+**/\r
+UINT32\r
+CpuCacheInfoGetNumberOfProcessors (\r
+ IN MP_SERVICES MpServices\r
+ );\r
+#endif\r
--- /dev/null
+/** @file\r
+ Provides cache info for each package, core type, cache level and cache type.\r
+\r
+ Copyright (c) 2020 Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <PiPei.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PeiServicesLib.h>\r
+#include <Library/PeiServicesTablePointerLib.h>\r
+#include <Library/CpuCacheInfoLib.h>\r
+#include <InternalCpuCacheInfoLib.h>\r
+\r
+/**\r
+ Get EDKII_PEI_MP_SERVICES2_PPI pointer.\r
+\r
+ @param[out] MpServices A pointer to the buffer where EDKII_PEI_MP_SERVICES2_PPI is stored\r
+\r
+ @retval EFI_SUCCESS EDKII_PEI_MP_SERVICES2_PPI interface is returned\r
+ @retval EFI_NOT_FOUND EDKII_PEI_MP_SERVICES2_PPI interface is not found\r
+**/\r
+EFI_STATUS\r
+CpuCacheInfoGetMpServices (\r
+ OUT MP_SERVICES *MpServices\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = PeiServicesLocatePpi (&gEdkiiPeiMpServices2PpiGuid, 0, NULL, (VOID **)&MpServices->Ppi);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Activate all of the logical processors.\r
+\r
+ @param[in] MpServices MP_SERVICES structure.\r
+ @param[in] Procedure A pointer to the function to be run on enabled logical processors.\r
+ @param[in] ProcedureArgument The parameter passed into Procedure for all enabled logical processors.\r
+**/\r
+VOID\r
+CpuCacheInfoStartupAllCPUs (\r
+ IN MP_SERVICES MpServices,\r
+ IN EFI_AP_PROCEDURE Procedure,\r
+ IN VOID *ProcedureArgument\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = MpServices.Ppi->StartupAllCPUs (MpServices.Ppi, Procedure, 0, ProcedureArgument);\r
+ ASSERT_EFI_ERROR (Status);\r
+}\r
+\r
+/**\r
+ Get detailed information of the requested logical processor.\r
+\r
+ @param[in] MpServices MP_SERVICES structure.\r
+ @param[in] ProcessorNum The requested logical processor number.\r
+ @param[out] ProcessorInfo A pointer to the buffer where the processor information is stored\r
+**/\r
+VOID\r
+CpuCacheInfoGetProcessorInfo (\r
+ IN MP_SERVICES MpServices,\r
+ IN UINTN ProcessorNum,\r
+ OUT EFI_PROCESSOR_INFORMATION *ProcessorInfo\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ Status = MpServices.Ppi->GetProcessorInfo (MpServices.Ppi, ProcessorNum, ProcessorInfo);\r
+ ASSERT_EFI_ERROR (Status);\r
+}\r
+\r
+/**\r
+ Get the logical processor number.\r
+\r
+ @param[in] MpServices MP_SERVICES structure.\r
+\r
+ @retval Return the logical processor number.\r
+**/\r
+UINT32\r
+CpuCacheInfoWhoAmI (\r
+ IN MP_SERVICES MpServices\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN ProcessorNum;\r
+\r
+ Status = MpServices.Ppi->WhoAmI (MpServices.Ppi, &ProcessorNum);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ return (UINT32)ProcessorNum;\r
+}\r
+\r
+/**\r
+ Get the total number of logical processors in the platform.\r
+\r
+ @param[in] MpServices MP_SERVICES structure.\r
+\r
+ @retval Return the total number of logical processors.\r
+**/\r
+UINT32\r
+CpuCacheInfoGetNumberOfProcessors (\r
+ IN MP_SERVICES MpServices\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN NumberOfProcessor;\r
+ UINTN NumberOfEnabledProcessor;\r
+\r
+ Status = MpServices.Ppi->GetNumberOfProcessors (MpServices.Ppi, &NumberOfProcessor, &NumberOfEnabledProcessor);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ return (UINT32)NumberOfProcessor;\r
+}\r
--- /dev/null
+## @file\r
+# CPU Cache Info Library instance for PEI module.\r
+#\r
+# Provides cache info for each package, core type, cache level and cache type.\r
+#\r
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>\r
+#\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+##\r
+\r
+[Defines]\r
+ INF_VERSION = 0x00010005\r
+ BASE_NAME = PeiCpuCacheInfoLib\r
+ FILE_GUID = CFEE2DBE-53B2-4916-84CA-0BA83C3DDA6E\r
+ MODULE_TYPE = PEIM\r
+ VERSION_STRING = 1.0\r
+ LIBRARY_CLASS = CpuCacheInfoLib|PEIM\r
+ MODULE_UNI_FILE = CpuCacheInfoLib.uni\r
+\r
+[Sources]\r
+ InternalCpuCacheInfoLib.h\r
+ CpuCacheInfoLib.c\r
+ PeiCpuCacheInfoLib.c\r
+\r
+[Packages]\r
+ MdePkg/MdePkg.dec\r
+ UefiCpuPkg/UefiCpuPkg.dec\r
+\r
+[LibraryClasses]\r
+ BaseLib\r
+ DebugLib\r
+ BaseMemoryLib\r
+ MemoryAllocationLib\r
+ PeiServicesTablePointerLib\r
+\r
+[Ppis]\r
+ gEdkiiPeiMpServices2PpiGuid\r
+\r
+[Pcd]\r
+\r
+[Depex]\r
+ TRUE\r
## @libraryclass Provides function to support VMGEXIT processing.\r
VmgExitLib|Include/Library/VmgExitLib.h\r
\r
+ ## @libraryclass Provides function to get CPU cache information.\r
+ CpuCacheInfoLib|Include/Library/CpuCacheInfoLib.h\r
+\r
[Guids]\r
gUefiCpuPkgTokenSpaceGuid = { 0xac05bf33, 0x995a, 0x4ed4, { 0xaa, 0xb8, 0xef, 0x7a, 0xe8, 0xf, 0x5c, 0xb0 }}\r
gMsegSmramGuid = { 0x5802bce4, 0xeeee, 0x4e33, { 0xa1, 0x30, 0xeb, 0xad, 0x27, 0xf0, 0xe4, 0x39 }}\r
LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf\r
MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf\r
RegisterCpuFeaturesLib|UefiCpuPkg/Library/RegisterCpuFeaturesLib/PeiRegisterCpuFeaturesLib.inf\r
+ CpuCacheInfoLib|UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.inf\r
\r
[LibraryClasses.IA32.PEIM, LibraryClasses.X64.PEIM]\r
PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf\r
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf\r
MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf\r
RegisterCpuFeaturesLib|UefiCpuPkg/Library/RegisterCpuFeaturesLib/DxeRegisterCpuFeaturesLib.inf\r
+ CpuCacheInfoLib|UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.inf\r
\r
[LibraryClasses.common.DXE_SMM_DRIVER]\r
SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf\r
UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.inf\r
UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.inf\r
UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.inf\r
+ UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.inf\r
+ UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.inf\r
\r
[Components.IA32, Components.X64]\r
UefiCpuPkg/CpuDxe/CpuDxe.inf\r