1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-06-27 15:33:15 +00:00

cpu_features: Override CacheInfo only if new data is available via Deterministic Cache Parameters Leaf

This commit is contained in:
Carles Fernandez 2021-10-27 18:17:10 +02:00
parent 3986c330bd
commit caa5aa6c34
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D

View File

@ -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". // 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" // For newer AMD CPUs uses "CPUID, eax=0x8000001D"
static void ParseCacheInfo(const int max_cpuid_leaf, uint32_t leaf_id, 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); const Leaf leaf = SafeCpuIdEx(max_cpuid_leaf, leaf_id, index);
CacheType cache_type = ExtractBitRange(leaf.eax, 4, 0); int cache_type_field = ExtractBitRange(leaf.eax, 4, 0);
if (cache_type == CPU_FEATURE_CACHE_NULL) continue; 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 level = ExtractBitRange(leaf.eax, 7, 5);
int line_size = ExtractBitRange(leaf.ebx, 11, 0) + 1; int line_size = ExtractBitRange(leaf.ebx, 11, 0) + 1;
int partitioning = ExtractBitRange(leaf.ebx, 21, 12) + 1; int partitioning = ExtractBitRange(leaf.ebx, 21, 12) + 1;
int ways = ExtractBitRange(leaf.ebx, 31, 22) + 1; int ways = ExtractBitRange(leaf.ebx, 31, 22) + 1;
int tlb_entries = leaf.ecx + 1; int tlb_entries = leaf.ecx + 1;
int cache_size = (ways * partitioning * line_size * (tlb_entries)); int cache_size = ways * partitioning * line_size * tlb_entries;
info->levels[info->size] = (CacheLevelInfo){.level = level, info.levels[info.size] = (CacheLevelInfo){.level = level,
.cache_type = cache_type, .cache_type = cache_type,
.cache_size = cache_size, .cache_size = cache_size,
.ways = ways, .ways = ways,
.line_size = line_size, .line_size = line_size,
.tlb_entries = tlb_entries, .tlb_entries = tlb_entries,
.partitioning = partitioning}; .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) #if defined(CPU_FEATURES_OS_DARWIN)
@ -1466,7 +1483,6 @@ static void ParseExtraAMDCpuId(X86Info* info, OsPreserves os_preserves)
} }
static const X86Info kEmptyX86Info; static const X86Info kEmptyX86Info;
static const CacheInfo kEmptyCacheInfo;
static const OsPreserves kEmptyOsPreserves; static const OsPreserves kEmptyOsPreserves;
X86Info GetX86Info(void) X86Info GetX86Info(void)
@ -1496,7 +1512,6 @@ CacheInfo GetX86CacheInfo(void)
const Leaf leaf_0 = CpuId(0); const Leaf leaf_0 = CpuId(0);
if (IsVendor(leaf_0, CPU_FEATURES_VENDOR_GENUINE_INTEL)) if (IsVendor(leaf_0, CPU_FEATURES_VENDOR_GENUINE_INTEL))
{ {
info.size = 0;
ParseLeaf2(leaf_0.eax, &info); ParseLeaf2(leaf_0.eax, &info);
ParseCacheInfo(leaf_0.eax, 4, &info); ParseCacheInfo(leaf_0.eax, 4, &info);
} }