mirror of
				https://github.com/google/cpu_features.git
				synced 2025-11-04 06:40:54 +01:00 
			
		
		
		
	Override CacheInfo only if new data is available via Deterministic Cache Parameters Leaf
#190
This commit is contained in:
		@@ -1148,31 +1148,46 @@ 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 &&
 | 
					  CacheInfo info = kEmptyCacheInfo;
 | 
				
			||||||
                         info->size < CPU_FEATURES_MAX_CACHE_LEVEL;
 | 
					  for (int index = 0; info.size < CPU_FEATURES_MAX_CACHE_LEVEL; ++index) {
 | 
				
			||||||
       cache_id++) {
 | 
					    const Leaf leaf = SafeCpuIdEx(max_cpuid_leaf, leaf_id, index);
 | 
				
			||||||
    const Leaf leaf = SafeCpuIdEx(max_cpuid_leaf, leaf_id, cache_id);
 | 
					    int cache_type_field = ExtractBitRange(leaf.eax, 4, 0);
 | 
				
			||||||
    CacheType cache_type = ExtractBitRange(leaf.eax, 4, 0);
 | 
					    CacheType cache_type;
 | 
				
			||||||
    if (cache_type == CPU_FEATURE_CACHE_NULL) continue;
 | 
					    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)
 | 
				
			||||||
@@ -1431,7 +1446,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) {
 | 
				
			||||||
@@ -1456,7 +1470,6 @@ CacheInfo GetX86CacheInfo(void) {
 | 
				
			|||||||
  CacheInfo info = kEmptyCacheInfo;
 | 
					  CacheInfo info = kEmptyCacheInfo;
 | 
				
			||||||
  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);
 | 
				
			||||||
  } else if (IsVendor(leaf_0, CPU_FEATURES_VENDOR_AUTHENTIC_AMD) ||
 | 
					  } else if (IsVendor(leaf_0, CPU_FEATURES_VENDOR_AUTHENTIC_AMD) ||
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user