From caa5aa6c34cebeb6f9bf4411ecd5b9386141e513 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 27 Oct 2021 18:17:10 +0200 Subject: [PATCH] cpu_features: Override CacheInfo only if new data is available via Deterministic Cache Parameters Leaf --- .../cpu_features/src/cpuinfo_x86.c | 35 +++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_x86.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_x86.c index 3863163ae..f7b79f54c 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_x86.c +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_x86.c @@ -1164,31 +1164,48 @@ static void ParseLeaf2(const int max_cpuid_leaf, CacheInfo* info) } } +static const CacheInfo kEmptyCacheInfo; + // For newer Intel CPUs uses "CPUID, eax=0x00000004". +// https://www.felixcloutier.com/x86/cpuid#input-eax-=-04h--returns-deterministic-cache-parameters-for-each-level // For newer AMD CPUs uses "CPUID, eax=0x8000001D" static void ParseCacheInfo(const int max_cpuid_leaf, uint32_t leaf_id, - CacheInfo* info) + CacheInfo* old_info) { - for (int cache_id = 0; cache_id < CPU_FEATURES_MAX_CACHE_LEVEL; cache_id++) + CacheInfo info = kEmptyCacheInfo; + for (int index = 0; info.size < CPU_FEATURES_MAX_CACHE_LEVEL; ++index) { - const Leaf leaf = SafeCpuIdEx(max_cpuid_leaf, leaf_id, cache_id); - CacheType cache_type = ExtractBitRange(leaf.eax, 4, 0); - if (cache_type == CPU_FEATURE_CACHE_NULL) continue; + const Leaf leaf = SafeCpuIdEx(max_cpuid_leaf, leaf_id, index); + int cache_type_field = ExtractBitRange(leaf.eax, 4, 0); + CacheType cache_type; + if (cache_type_field == 0) + break; + else if (cache_type_field == 1) + cache_type = CPU_FEATURE_CACHE_DATA; + else if (cache_type_field == 2) + cache_type = CPU_FEATURE_CACHE_INSTRUCTION; + else if (cache_type_field == 3) + cache_type = CPU_FEATURE_CACHE_UNIFIED; + else + break; // Should not occur as per documentation. int level = ExtractBitRange(leaf.eax, 7, 5); int line_size = ExtractBitRange(leaf.ebx, 11, 0) + 1; int partitioning = ExtractBitRange(leaf.ebx, 21, 12) + 1; int ways = ExtractBitRange(leaf.ebx, 31, 22) + 1; int tlb_entries = leaf.ecx + 1; - int cache_size = (ways * partitioning * line_size * (tlb_entries)); - info->levels[info->size] = (CacheLevelInfo){.level = level, + int cache_size = ways * partitioning * line_size * tlb_entries; + info.levels[info.size] = (CacheLevelInfo){.level = level, .cache_type = cache_type, .cache_size = cache_size, .ways = ways, .line_size = line_size, .tlb_entries = tlb_entries, .partitioning = partitioning}; - info->size++; + ++info.size; } + // Override CacheInfo if we successfully extracted Deterministic Cache + // Parameters. + if (info.size > 0) *old_info = info; } #if defined(CPU_FEATURES_OS_DARWIN) @@ -1466,7 +1483,6 @@ static void ParseExtraAMDCpuId(X86Info* info, OsPreserves os_preserves) } static const X86Info kEmptyX86Info; -static const CacheInfo kEmptyCacheInfo; static const OsPreserves kEmptyOsPreserves; X86Info GetX86Info(void) @@ -1496,7 +1512,6 @@ CacheInfo GetX86CacheInfo(void) const Leaf leaf_0 = CpuId(0); if (IsVendor(leaf_0, CPU_FEATURES_VENDOR_GENUINE_INTEL)) { - info.size = 0; ParseLeaf2(leaf_0.eax, &info); ParseCacheInfo(leaf_0.eax, 4, &info); }