mirror of
https://github.com/anrieff/libcpuid
synced 2024-11-10 22:59:13 +00:00
Fixed issue #4: Advanced Power Management Features
- Move detection of constant_tsc to common; it is spec'd in Intel docs - Fix broken interpretation of EAX in leaf 80000000h: it shows max 800000xx-value, not max xx-value. This causes, for example, to seek for extended features on Pentium II, where the extended leafs aren't supported by the CPU at all. This is only in common feature detection. AMD detection is fine. - Add detection of a few new features in AMD leaf 80000007h: cbp (core performance boost), aperfmperf (APERF/MPERF MSRs supported), pfi (processor feedback interface) and pa (processor accumulator). "make test" is broken right now, to be fixed in a subsequent commit.
This commit is contained in:
parent
798bcc80b2
commit
f750dde2c0
3 changed files with 20 additions and 2 deletions
|
@ -183,14 +183,20 @@ static void load_features_common(struct cpu_raw_data_t* raw, struct cpu_id_t* da
|
||||||
const struct feature_map_t matchtable_ecx81[] = {
|
const struct feature_map_t matchtable_ecx81[] = {
|
||||||
{ 0, CPU_FEATURE_LAHF_LM },
|
{ 0, CPU_FEATURE_LAHF_LM },
|
||||||
};
|
};
|
||||||
|
const struct feature_map_t matchtable_edx87[] = {
|
||||||
|
{ 8, CPU_FEATURE_CONSTANT_TSC },
|
||||||
|
};
|
||||||
if (raw->basic_cpuid[0][0] >= 1) {
|
if (raw->basic_cpuid[0][0] >= 1) {
|
||||||
match_features(matchtable_edx1, COUNT_OF(matchtable_edx1), raw->basic_cpuid[1][3], data);
|
match_features(matchtable_edx1, COUNT_OF(matchtable_edx1), raw->basic_cpuid[1][3], data);
|
||||||
match_features(matchtable_ecx1, COUNT_OF(matchtable_ecx1), raw->basic_cpuid[1][2], data);
|
match_features(matchtable_ecx1, COUNT_OF(matchtable_ecx1), raw->basic_cpuid[1][2], data);
|
||||||
}
|
}
|
||||||
if (raw->ext_cpuid[0][0] >= 1) {
|
if (raw->ext_cpuid[0][0] >= 0x80000001) {
|
||||||
match_features(matchtable_edx81, COUNT_OF(matchtable_edx81), raw->ext_cpuid[1][3], data);
|
match_features(matchtable_edx81, COUNT_OF(matchtable_edx81), raw->ext_cpuid[1][3], data);
|
||||||
match_features(matchtable_ecx81, COUNT_OF(matchtable_ecx81), raw->ext_cpuid[1][2], data);
|
match_features(matchtable_ecx81, COUNT_OF(matchtable_ecx81), raw->ext_cpuid[1][2], data);
|
||||||
}
|
}
|
||||||
|
if (raw->ext_cpuid[0][0] >= 0x80000007) {
|
||||||
|
match_features(matchtable_edx87, COUNT_OF(matchtable_edx87), raw->ext_cpuid[7][3], data);
|
||||||
|
}
|
||||||
if (data->flags[CPU_FEATURE_SSE]) {
|
if (data->flags[CPU_FEATURE_SSE]) {
|
||||||
/* apply guesswork to check if the SSE unit width is 128 bit */
|
/* apply guesswork to check if the SSE unit width is 128 bit */
|
||||||
switch (data->vendor) {
|
switch (data->vendor) {
|
||||||
|
@ -547,6 +553,10 @@ const char* cpu_feature_str(cpu_feature_t feature)
|
||||||
{ CPU_FEATURE_TBM, "tbm" },
|
{ CPU_FEATURE_TBM, "tbm" },
|
||||||
{ CPU_FEATURE_F16C, "f16c" },
|
{ CPU_FEATURE_F16C, "f16c" },
|
||||||
{ CPU_FEATURE_RDRAND, "rdrand" },
|
{ CPU_FEATURE_RDRAND, "rdrand" },
|
||||||
|
{ CPU_FEATURE_CPB, "cpb" },
|
||||||
|
{ CPU_FEATURE_APERFMPERF, "aperfmperf" },
|
||||||
|
{ CPU_FEATURE_PFI, "pfi" },
|
||||||
|
{ CPU_FEATURE_PA, "pa" },
|
||||||
};
|
};
|
||||||
unsigned i, n = COUNT_OF(matchtable);
|
unsigned i, n = COUNT_OF(matchtable);
|
||||||
if (n != NUM_CPU_FEATURES) {
|
if (n != NUM_CPU_FEATURES) {
|
||||||
|
|
|
@ -350,6 +350,10 @@ typedef enum {
|
||||||
CPU_FEATURE_F16C, /*!< 16-bit FP convert instruction support */
|
CPU_FEATURE_F16C, /*!< 16-bit FP convert instruction support */
|
||||||
CPU_FEATURE_RDRAND, /*!< RdRand instruction */
|
CPU_FEATURE_RDRAND, /*!< RdRand instruction */
|
||||||
CPU_FEATURE_X2APIC, /*!< x2APIC, APIC_BASE.EXTD, MSRs 0000_0800h...0000_0BFFh 64-bit ICR (+030h but not +031h), no DFR (+00Eh), SELF_IPI (+040h) also see standard level 0000_000Bh */
|
CPU_FEATURE_X2APIC, /*!< x2APIC, APIC_BASE.EXTD, MSRs 0000_0800h...0000_0BFFh 64-bit ICR (+030h but not +031h), no DFR (+00Eh), SELF_IPI (+040h) also see standard level 0000_000Bh */
|
||||||
|
CPU_FEATURE_CPB, /*!< Core performance boost */
|
||||||
|
CPU_FEATURE_APERFMPERF, /*!< MPERF/APERF MSRs support */
|
||||||
|
CPU_FEATURE_PFI, /*!< Processor Feedback Interface support */
|
||||||
|
CPU_FEATURE_PA, /*!< Processor accumulator */
|
||||||
/* termination: */
|
/* termination: */
|
||||||
NUM_CPU_FEATURES,
|
NUM_CPU_FEATURES,
|
||||||
} cpu_feature_t;
|
} cpu_feature_t;
|
||||||
|
|
|
@ -302,7 +302,11 @@ static void load_amd_features(struct cpu_raw_data_t* raw, struct cpu_id_t* data)
|
||||||
{ 5, CPU_FEATURE_STC },
|
{ 5, CPU_FEATURE_STC },
|
||||||
{ 6, CPU_FEATURE_100MHZSTEPS },
|
{ 6, CPU_FEATURE_100MHZSTEPS },
|
||||||
{ 7, CPU_FEATURE_HWPSTATE },
|
{ 7, CPU_FEATURE_HWPSTATE },
|
||||||
{ 8, CPU_FEATURE_CONSTANT_TSC },
|
/* id 8 is handled in common */
|
||||||
|
{ 9, CPU_FEATURE_CPB },
|
||||||
|
{ 10, CPU_FEATURE_APERFMPERF },
|
||||||
|
{ 11, CPU_FEATURE_PFI },
|
||||||
|
{ 12, CPU_FEATURE_PA },
|
||||||
};
|
};
|
||||||
if (raw->ext_cpuid[0][0] >= 0x80000001) {
|
if (raw->ext_cpuid[0][0] >= 0x80000001) {
|
||||||
match_features(matchtable_edx81, COUNT_OF(matchtable_edx81), raw->ext_cpuid[1][3], data);
|
match_features(matchtable_edx81, COUNT_OF(matchtable_edx81), raw->ext_cpuid[1][3], data);
|
||||||
|
|
Loading…
Reference in a new issue