mirror of
https://github.com/anrieff/libcpuid
synced 2025-10-03 11:01:30 +00:00
Add cpu_feature_level_t enumerated values for x86 CPUs
I had to fix run_tests.py to update all test files properly. Fix #177
This commit is contained in:
parent
c5885699f0
commit
959edc34e7
229 changed files with 388 additions and 12 deletions
|
@ -1628,7 +1628,17 @@ const char* cpu_feature_level_str(cpu_feature_level_t level)
|
|||
{
|
||||
const struct { cpu_feature_level_t level; const char* name; }
|
||||
matchtable[] = {
|
||||
{ FEATURE_LEVEL_UNKNOWN, "unknown" },
|
||||
{ FEATURE_LEVEL_UNKNOWN, "unknown" },
|
||||
/* x86 */
|
||||
{ CPU_FEATURE_LEVEL_I386, "i386" },
|
||||
{ CPU_FEATURE_LEVEL_I486, "i486" },
|
||||
{ CPU_FEATURE_LEVEL_I586, "i586" },
|
||||
{ CPU_FEATURE_LEVEL_I686, "i686" },
|
||||
{ CPU_FEATURE_LEVEL_X86_64_V1, "x86-64-v1" },
|
||||
{ CPU_FEATURE_LEVEL_X86_64_V2, "x86-64-v2" },
|
||||
{ CPU_FEATURE_LEVEL_X86_64_V3, "x86-64-v3" },
|
||||
{ CPU_FEATURE_LEVEL_X86_64_V4, "x86-64-v4" },
|
||||
/* ARM */
|
||||
{ FEATURE_LEVEL_ARM_V1, "ARMv1" },
|
||||
{ FEATURE_LEVEL_ARM_V2, "ARMv2" },
|
||||
{ FEATURE_LEVEL_ARM_V3, "ARMv3" },
|
||||
|
@ -1664,7 +1674,7 @@ const char* cpu_feature_level_str(cpu_feature_level_t level)
|
|||
{ FEATURE_LEVEL_ARM_V9_4_A, "ARMv9.4-A" },
|
||||
};
|
||||
unsigned i, n = COUNT_OF(matchtable);
|
||||
if (n != (NUM_CPU_FEATURE_LEVELS - FEATURE_LEVEL_ARM_V1) + 1) {
|
||||
if (n != (NUM_CPU_FEATURE_LEVELS - FEATURE_LEVEL_ARM_V1) + (CPU_FEATURE_LEVEL_X86_64_V4 - CPU_FEATURE_LEVEL_I386) + 2) {
|
||||
warnf("Warning: incomplete library, feature level matchtable size differs from the actual number of levels.\n");
|
||||
}
|
||||
for (i = 0; i < n; i++)
|
||||
|
|
|
@ -190,7 +190,17 @@ typedef enum {
|
|||
* @brief CPU architecture
|
||||
*/
|
||||
typedef enum {
|
||||
/* TODO: add x86 levels */
|
||||
/* x86: https://en.wikipedia.org/wiki/X86-64#Microarchitecture_levels */
|
||||
CPU_FEATURE_LEVEL_I386, /*!< i386 */
|
||||
CPU_FEATURE_LEVEL_I486, /*!< i486 */
|
||||
CPU_FEATURE_LEVEL_I586, /*!< i586 */
|
||||
CPU_FEATURE_LEVEL_I686, /*!< i686 */
|
||||
CPU_FEATURE_LEVEL_X86_64_V1, /*!< x86-64-v1 */
|
||||
CPU_FEATURE_LEVEL_X86_64_V2, /*!< x86-64-v2 */
|
||||
CPU_FEATURE_LEVEL_X86_64_V3, /*!< x86-64-v3 */
|
||||
CPU_FEATURE_LEVEL_X86_64_V4, /*!< x86-64-v4 */
|
||||
|
||||
/* ARM: https://en.wikipedia.org/wiki/ARM_architecture_family#Cores */
|
||||
FEATURE_LEVEL_ARM_V1 = 100, /*!< ARMv1 */
|
||||
FEATURE_LEVEL_ARM_V2, /*!< ARMv2 */
|
||||
FEATURE_LEVEL_ARM_V3, /*!< ARMv3 */
|
||||
|
|
|
@ -413,3 +413,104 @@ void decode_deterministic_cache_info_x86(uint32_t cache_regs[][NUM_REGS],
|
|||
assign_cache_data(1, type, size, ways, linesize, data);
|
||||
}
|
||||
}
|
||||
|
||||
void decode_architecture_version_x86(struct cpu_id_t* data)
|
||||
{
|
||||
bool is_compliant, has_all_features;
|
||||
int i, j;
|
||||
cpu_feature_level_t feature_level = FEATURE_LEVEL_UNKNOWN;
|
||||
|
||||
const struct { const int family; const cpu_feature_level_t feature_level; }
|
||||
architecture_matchtable_ia_32[] = {
|
||||
{ 4, CPU_FEATURE_LEVEL_I486 },
|
||||
{ 5, CPU_FEATURE_LEVEL_I586 },
|
||||
{ 6, CPU_FEATURE_LEVEL_I686 },
|
||||
{ 15, CPU_FEATURE_LEVEL_I686 }, // Intel Pentium 4, AMD K8
|
||||
};
|
||||
|
||||
const cpu_feature_t architecture_x86_64_v1[] = {
|
||||
CPU_FEATURE_CMOV,
|
||||
CPU_FEATURE_CX8,
|
||||
CPU_FEATURE_FPU,
|
||||
CPU_FEATURE_FXSR,
|
||||
CPU_FEATURE_MMX,
|
||||
CPU_FEATURE_SSE,
|
||||
CPU_FEATURE_SSE2,
|
||||
-1
|
||||
};
|
||||
|
||||
const cpu_feature_t architecture_x86_64_v2[] = {
|
||||
CPU_FEATURE_CX16,
|
||||
CPU_FEATURE_LAHF_LM,
|
||||
CPU_FEATURE_POPCNT,
|
||||
CPU_FEATURE_PNI,
|
||||
CPU_FEATURE_SSE4_1,
|
||||
CPU_FEATURE_SSE4_2,
|
||||
CPU_FEATURE_SSSE3,
|
||||
-1
|
||||
};
|
||||
|
||||
const cpu_feature_t architecture_x86_64_v3[] = {
|
||||
CPU_FEATURE_AVX,
|
||||
CPU_FEATURE_AVX2,
|
||||
CPU_FEATURE_BMI1,
|
||||
CPU_FEATURE_BMI2,
|
||||
CPU_FEATURE_F16C,
|
||||
CPU_FEATURE_FMA3,
|
||||
CPU_FEATURE_ABM,
|
||||
CPU_FEATURE_MOVBE,
|
||||
CPU_FEATURE_OSXSAVE,
|
||||
-1
|
||||
};
|
||||
|
||||
const cpu_feature_t architecture_x86_64_v4[] = {
|
||||
CPU_FEATURE_AVX512F,
|
||||
CPU_FEATURE_AVX512BW,
|
||||
CPU_FEATURE_AVX512CD,
|
||||
CPU_FEATURE_AVX512DQ,
|
||||
CPU_FEATURE_AVX512VL,
|
||||
-1
|
||||
};
|
||||
|
||||
const struct { const cpu_feature_t* features_array; const cpu_feature_level_t feature_level; }
|
||||
architecture_matchtable_x86_64[] = {
|
||||
{ architecture_x86_64_v1, CPU_FEATURE_LEVEL_X86_64_V1 },
|
||||
{ architecture_x86_64_v2, CPU_FEATURE_LEVEL_X86_64_V2 },
|
||||
{ architecture_x86_64_v3, CPU_FEATURE_LEVEL_X86_64_V3 },
|
||||
{ architecture_x86_64_v4, CPU_FEATURE_LEVEL_X86_64_V4 },
|
||||
};
|
||||
|
||||
if (!data->flags[CPU_FEATURE_LM]) {
|
||||
/* Check Intel Architecture, 32-bit */
|
||||
for (i = 0; i < COUNT_OF(architecture_matchtable_ia_32); i++) {
|
||||
is_compliant = (data->x86.family == architecture_matchtable_ia_32[i].family);
|
||||
debugf(3, "Check if CPU is %s compliant: %s for family %i\n", cpu_feature_level_str(architecture_matchtable_ia_32[i].feature_level), is_compliant ? "yes" : "no", architecture_matchtable_ia_32[i].family);
|
||||
if (is_compliant) {
|
||||
feature_level = architecture_matchtable_ia_32[i].feature_level;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Check Intel Architecture, 64-bit */
|
||||
for (i = 0; i < COUNT_OF(architecture_matchtable_x86_64); i++) {
|
||||
debugf(3, "Check if CPU is %s compliant:\n", cpu_feature_level_str(architecture_matchtable_x86_64[i].feature_level));
|
||||
has_all_features = true;
|
||||
for (j = 0; architecture_matchtable_x86_64[i].features_array[j] != -1; j++) {
|
||||
is_compliant = data->flags[ architecture_matchtable_x86_64[i].features_array[j] ];
|
||||
has_all_features = has_all_features && is_compliant;
|
||||
debugf(3, " - feature %s is %s\n", cpu_feature_str(architecture_matchtable_x86_64[i].features_array[j]), is_compliant ? "present" : "absent");
|
||||
}
|
||||
if (is_compliant)
|
||||
feature_level = architecture_matchtable_x86_64[i].feature_level;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
data->feature_level = feature_level;
|
||||
if (feature_level == FEATURE_LEVEL_UNKNOWN)
|
||||
warnf("Warning: CPU with CPUID signature %02X_%02XH has an unkown architecture version (LM=%i).\n", data->x86.ext_family, data->x86.ext_model, data->flags[CPU_FEATURE_LM]);
|
||||
else
|
||||
debugf(2, "x86 architecture version is %s\n", cpu_feature_level_str(feature_level));
|
||||
}
|
||||
|
|
|
@ -134,4 +134,7 @@ void decode_deterministic_cache_info_x86(uint32_t cache_regs[][NUM_REGS],
|
|||
struct cpu_id_t* data,
|
||||
struct internal_id_info_t* internal);
|
||||
|
||||
/* generic way to get microarchitecture levels for x86 CPUs */
|
||||
void decode_architecture_version_x86(struct cpu_id_t* data);
|
||||
|
||||
#endif /* __LIBCPUID_UTIL_H__ */
|
||||
|
|
|
@ -676,6 +676,7 @@ int cpuid_identify_amd(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct
|
|||
decode_amd_cache_info(raw, data);
|
||||
decode_amd_number_of_cores(raw, data);
|
||||
decode_amd_codename(data, internal);
|
||||
decode_architecture_version_x86(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -207,6 +207,7 @@ int cpuid_identify_centaur(struct cpu_raw_data_t* raw, struct cpu_id_t* data, st
|
|||
if (raw->basic_cpuid[0][EAX] >= 4)
|
||||
decode_deterministic_cache_info_x86(raw->intel_fn4, MAX_INTELFN4_LEVEL, data, internal);
|
||||
decode_number_of_cores_x86(raw, data);
|
||||
decode_architecture_version_x86(data);
|
||||
|
||||
brand = get_brand_code_and_bits(data);
|
||||
model_code = get_model_code(data, brand);
|
||||
|
|
|
@ -1100,6 +1100,7 @@ int cpuid_identify_intel(struct cpu_raw_data_t* raw, struct cpu_id_t* data, stru
|
|||
if ((raw->basic_cpuid[0][EAX] < 11) || (decode_intel_extended_topology(raw, data) == 0))
|
||||
decode_number_of_cores_x86(raw, data);
|
||||
data->purpose = cpuid_identify_purpose_intel(raw);
|
||||
decode_architecture_version_x86(data);
|
||||
|
||||
brand = get_brand_code_and_bits(data);
|
||||
model_code = get_model_code(data);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue