**/\r
VOID\r
CpuCacheInfoPrintCpuCacheInfoTable (\r
- IN CPU_CACHE_INFO *CpuCacheInfo,\r
- IN UINTN CpuCacheInfoCount\r
+ IN CPU_CACHE_INFO *CpuCacheInfo,\r
+ IN UINTN CpuCacheInfoCount\r
)\r
{\r
- UINTN Index;\r
+ UINTN Index;\r
\r
DEBUG ((DEBUG_INFO, "+-------+--------------------------------------------------------------------------------------+\n"));\r
DEBUG ((DEBUG_INFO, "| Index | Packge CoreType CacheLevel CacheType CacheWays (FA|DM) 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 ( %x| %x) %8x %4x |\n",\r
- Index, CpuCacheInfo[Index].Package, CpuCacheInfo[Index].CoreType, CpuCacheInfo[Index].CacheLevel,\r
- CpuCacheInfo[Index].CacheType, CpuCacheInfo[Index].CacheWays, CpuCacheInfo[Index].FullyAssociativeCache,\r
- CpuCacheInfo[Index].DirectMappedCache, CpuCacheInfo[Index].CacheSizeinKB, CpuCacheInfo[Index].CacheCount));\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "| %4x | %4x %2x %2x %2x %4x ( %x| %x) %8x %4x |\n",\r
+ Index,\r
+ CpuCacheInfo[Index].Package,\r
+ CpuCacheInfo[Index].CoreType,\r
+ CpuCacheInfo[Index].CacheLevel,\r
+ CpuCacheInfo[Index].CacheType,\r
+ CpuCacheInfo[Index].CacheWays,\r
+ CpuCacheInfo[Index].FullyAssociativeCache,\r
+ CpuCacheInfo[Index].DirectMappedCache,\r
+ CpuCacheInfo[Index].CacheSizeinKB,\r
+ CpuCacheInfo[Index].CacheCount\r
+ ));\r
}\r
\r
DEBUG ((DEBUG_INFO, "+-------+--------------------------------------------------------------------------------------+\n"));\r
}\r
\r
+/**\r
+ Function to compare CPU package ID, core type, cache level and cache type for use in QuickSort.\r
+\r
+ @param[in] Buffer1 pointer to CPU_CACHE_INFO poiner to compare\r
+ @param[in] Buffer2 pointer to second CPU_CACHE_INFO pointer to compare\r
+\r
+ @retval 0 Buffer1 equal to Buffer2\r
+ @retval 1 Buffer1 is greater than Buffer2\r
+ @retval -1 Buffer1 is less than Buffer2\r
+**/\r
+INTN\r
+EFIAPI\r
+CpuCacheInfoCompare (\r
+ IN CONST VOID *Buffer1,\r
+ IN CONST VOID *Buffer2\r
+ )\r
+{\r
+ CPU_CACHE_INFO_COMPARATOR Comparator1, Comparator2;\r
+\r
+ ZeroMem (&Comparator1, sizeof (Comparator1));\r
+ ZeroMem (&Comparator2, sizeof (Comparator2));\r
+\r
+ Comparator1.Bits.Package = ((CPU_CACHE_INFO *)Buffer1)->Package;\r
+ Comparator1.Bits.CoreType = ((CPU_CACHE_INFO *)Buffer1)->CoreType;\r
+ Comparator1.Bits.CacheLevel = ((CPU_CACHE_INFO *)Buffer1)->CacheLevel;\r
+ Comparator1.Bits.CacheType = ((CPU_CACHE_INFO *)Buffer1)->CacheType;\r
+\r
+ Comparator2.Bits.Package = ((CPU_CACHE_INFO *)Buffer2)->Package;\r
+ Comparator2.Bits.CoreType = ((CPU_CACHE_INFO *)Buffer2)->CoreType;\r
+ Comparator2.Bits.CacheLevel = ((CPU_CACHE_INFO *)Buffer2)->CacheLevel;\r
+ Comparator2.Bits.CacheType = ((CPU_CACHE_INFO *)Buffer2)->CacheType;\r
+\r
+ if (Comparator1.Uint64 == Comparator2.Uint64) {\r
+ return 0;\r
+ } else if (Comparator1.Uint64 > Comparator2.Uint64) {\r
+ return 1;\r
+ } else {\r
+ return -1;\r
+ }\r
+}\r
+\r
/**\r
Get the total number of package and package ID in the platform.\r
\r
**/\r
UINT32\r
CpuCacheInfoGetNumberOfPackages (\r
- IN CPUID_PROCESSOR_INFO *ProcessorInfo,\r
- IN UINTN NumberOfProcessors,\r
- IN OUT UINT32 *Package\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
+ UINTN ProcessorIndex;\r
+ UINT32 PackageIndex;\r
+ UINT32 PackageCount;\r
+ UINT32 CurrentPackage;\r
\r
PackageCount = 0;\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
+CpuCacheInfoGetNumberOfCoreTypePerPackage (\r
+ IN CPUID_PROCESSOR_INFO *ProcessorInfo,\r
+ IN UINTN NumberOfProcessors,\r
+ IN UINTN Package\r
)\r
{\r
- UINTN ProcessorIndex;\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
+ UINT8 CoreType[MAX_UINT8];\r
+ UINTN CoreTypeIndex;\r
+ UINTN CoreTypeCount;\r
+ UINT8 CurrentCoreType;\r
\r
//\r
// CoreType array is empty.\r
VOID\r
EFIAPI\r
CpuCacheInfoCollectCoreAndCacheData (\r
- IN OUT VOID *Buffer\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_CACHE_PARAMS_EDX CacheParamEdx;\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
+ 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_CACHE_PARAMS_EDX CacheParamEdx;\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
+ CacheData = &Context->CacheData[MAX_NUM_OF_CACHE_PARAMS_LEAF * ProcessorIndex];\r
\r
AsmCpuid (CPUID_SIGNATURE, &CpuidMaxInput, NULL, NULL, NULL);\r
\r
Context->ProcessorInfo[ProcessorIndex].CoreType = 0;\r
if (CpuidMaxInput >= CPUID_HYBRID_INFORMATION) {\r
AsmCpuidEx (CPUID_HYBRID_INFORMATION, CPUID_HYBRID_INFORMATION_MAIN_LEAF, &NativeModelIdAndCoreTypeEax.Uint32, NULL, NULL, NULL);\r
- Context->ProcessorInfo[ProcessorIndex].CoreType = (UINT8) NativeModelIdAndCoreTypeEax.Bits.CoreType;\r
+ Context->ProcessorInfo[ProcessorIndex].CoreType = (UINT8)NativeModelIdAndCoreTypeEax.Bits.CoreType;\r
}\r
\r
//\r
CacheData[CacheParamLeafIndex].CacheType = (UINT8)CacheParamEax.Bits.CacheType;\r
CacheData[CacheParamLeafIndex].CacheWays = (UINT16)CacheParamEbx.Bits.Ways;\r
CacheData[CacheParamLeafIndex].FullyAssociativeCache = (UINT8)CacheParamEax.Bits.FullyAssociativeCache;\r
- CacheData[CacheParamLeafIndex].DirectMappedCache = (UINT8)CacheParamEdx.Bits.ComplexCacheIndexing;\r
+ CacheData[CacheParamLeafIndex].DirectMappedCache = (UINT8)(CacheParamEdx.Bits.ComplexCacheIndexing == 0);\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
+ (CacheParamEbx.Bits.LinePartitions + 1) * (CacheParamEbx.Bits.LineSize + 1) * (CacheParamEcx + 1) / SIZE_1KB;\r
\r
CacheParamLeafIndex++;\r
}\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
+ 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
+ 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
+ CPU_CACHE_INFO SortBuffer;\r
\r
//\r
// Get number of Packages and Package ID.\r
}\r
\r
MaxCacheInfoCount = TotalNumberOfCoreType * MAX_NUM_OF_CACHE_PARAMS_LEAF;\r
- LocalCacheInfo = AllocatePages (EFI_SIZE_TO_PAGES (MaxCacheInfoCount * sizeof (*LocalCacheInfo)));\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
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
+ 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
+ {\r
CacheData[NextIndex].CacheSizeinKB = 0; // uses the sharing cache\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
+ 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
+ {\r
LocalCacheInfo[CacheInfoIndex].CacheCount++;\r
break;\r
}\r
if (*CacheInfoCount < LocalCacheInfoCount) {\r
Status = EFI_BUFFER_TOO_SMALL;\r
} else {\r
+ //\r
+ // Sort LocalCacheInfo array by CPU package ID, core type, cache level and cache type.\r
+ //\r
+ QuickSort (LocalCacheInfo, LocalCacheInfoCount, sizeof (*LocalCacheInfo), CpuCacheInfoCompare, (VOID *)&SortBuffer);\r
CopyMem (CacheInfo, LocalCacheInfo, sizeof (*CacheInfo) * LocalCacheInfoCount);\r
DEBUG_CODE (\r
CpuCacheInfoPrintCpuCacheInfoTable (CacheInfo, LocalCacheInfoCount);\r
- );\r
+ );\r
Status = EFI_SUCCESS;\r
}\r
\r
}\r
\r
/**\r
- Get CpuCacheInfo data array.\r
+ Get CpuCacheInfo data array. The array is sorted by CPU package ID, core type, cache level and cache type.\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
EFI_STATUS\r
EFIAPI\r
GetCpuCacheInfo (\r
- IN OUT CPU_CACHE_INFO *CpuCacheInfo,\r
- IN OUT UINTN *CpuCacheInfoCount\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
+ 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
+ if ((*CpuCacheInfoCount != 0) && (CpuCacheInfo == NULL)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
if (Context.ProcessorInfo == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\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
+ 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
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
+ Context.ProcessorInfo[ProcessorIndex].ApicId = (UINT32)ProcessorInfo.ProcessorId;\r
}\r
\r
//\r