diff --git a/libcpuid/recog_amd.c b/libcpuid/recog_amd.c index 364ef63..3f9d0d0 100644 --- a/libcpuid/recog_amd.c +++ b/libcpuid/recog_amd.c @@ -687,13 +687,18 @@ void cpuid_get_list_amd(struct cpu_list_t* list) cpu_purpose_t cpuid_identify_purpose_amd(struct cpu_raw_data_t* raw) { - //FIXME: ext_cpuid[0x26] => index 38 is past the end of the array (which contains 32 elements) - //TODO: leaf CPUID_Fn80000026 needs to be added in cpu_raw_data_t - (void)(raw); -#if 0 - /* Check for hybrid architecture - From Processor Programming Reference (PPR) for AMD Family 19h Model 70h, Revision A0 Processors - Available at https://www.amd.com/system/files/TechDocs/57019-A0-PUB_3.00.zip + int i; + + /* Check if Extended CPU Topology is supported */ + if (raw->amd_fn80000026h[0][EAX] == 0x0) + return PURPOSE_GENERAL; + + /* Check for heterogeneous cores + From AMD64 Architecture Programmer’s Manual - Volume 3: General-Purpose and System Instructions + Available at https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/programmer-references/24594.pdf + + - CPUID_Fn80000026_EAX [Extended CPU Topology][30] is HeterogeneousCores. + Set to 1 if all components at the current hierarchy level do not consist of the cores that report the same core type (CoreType). - CPUID_Fn80000026_ECX [Extended CPU Topology][15:8] is LevelType. LevelType 01h is Core. @@ -701,14 +706,16 @@ cpu_purpose_t cpuid_identify_purpose_amd(struct cpu_raw_data_t* raw) - CPUID_Fn80000026_EBX [Extended CPU Topology][31:28] is CoreType. Only valid while LevelType=Core. */ - if (EXTRACTS_BITS(raw->ext_cpuid[0x26][ECX], 15, 8) == 0x1) { - debugf(3, "Detected AMD CPU hybrid architecture\n"); - switch (EXTRACTS_BITS(raw->ext_cpuid[0x26][EBX], 31, 28)) { - case 0x0: return PURPOSE_PERFORMANCE; - case 0x1: return PURPOSE_EFFICIENCY; - default: return PURPOSE_GENERAL; + for (i = 0; (raw->amd_fn80000026h[i][EBX] != 0x0) && (raw->amd_fn80000026h[i][ECX] != 0x0) && (i < MAX_AMDFN80000026H_LEVEL); i++) { + if ((EXTRACTS_BIT(raw->amd_fn80000026h[i][EAX], 30) == 0x1) && (EXTRACTS_BITS(raw->amd_fn80000026h[i][ECX], 15, 8) == 0x1)) { + debugf(3, "Detected AMD CPU with heterogeneous cores\n"); + switch (EXTRACTS_BITS(raw->amd_fn80000026h[i][EBX], 31, 28)) { + case 0x0: return PURPOSE_PERFORMANCE; + case 0x1: return PURPOSE_EFFICIENCY; + default: return PURPOSE_GENERAL; + } } } -#endif + return PURPOSE_GENERAL; }