/* get_cpu_info * * Extract CPU vendor, family, model, stepping info from /proc/cpuinfo * * Returns 0 on success or a negativ error code * * TBD: Should there be a cpuid alternative for this if /proc is not mounted?
*/ int get_cpu_info(struct cpupower_cpu_info *cpu_info)
{
FILE *fp; char value[64]; unsignedint proc, x; unsignedint unknown = 0xffffff; unsignedint cpuid_level, ext_cpuid_level;
fp = fopen("/proc/cpuinfo", "r"); if (!fp) return -EIO;
while (!feof(fp)) { if (!fgets(value, 64, fp)) continue;
value[63 - 1] = '\0';
if (!strncmp(value, "processor\t: ", 12))
sscanf(value, "processor\t: %u", &proc);
if (proc != (unsignedint)base_cpu) continue;
/* Get CPU vendor */ if (!strncmp(value, "vendor_id", 9)) { for (x = 1; x < X86_VENDOR_MAX; x++) { if (strstr(value, cpu_vendor_table[x]))
cpu_info->vendor = x;
} /* Get CPU family, etc. */
} elseif (!strncmp(value, "cpu family\t: ", 13)) {
sscanf(value, "cpu family\t: %u",
&cpu_info->family);
} elseif (!strncmp(value, "model\t\t: ", 9)) {
sscanf(value, "model\t\t: %u",
&cpu_info->model);
} elseif (!strncmp(value, "stepping\t: ", 10)) {
sscanf(value, "stepping\t: %u",
&cpu_info->stepping);
/* Exit -> all values must have been set */ if (cpu_info->vendor == X86_VENDOR_UNKNOWN ||
cpu_info->family == unknown ||
cpu_info->model == unknown ||
cpu_info->stepping == unknown) {
ret = -EINVAL; goto out;
}
ret = 0; goto out;
}
}
ret = -ENODEV;
out:
fclose(fp); /* Get some useful CPU capabilities from cpuid */ if (cpu_info->vendor != X86_VENDOR_AMD &&
cpu_info->vendor != X86_VENDOR_HYGON &&
cpu_info->vendor != X86_VENDOR_INTEL) return ret;
/* Aperf/Mperf registers support */ if (cpuid_level >= 6 && (cpuid_ecx(6) & 0x1))
cpu_info->caps |= CPUPOWER_CAP_APERF;
/* AMD or Hygon Boost state enable/disable register */ if (cpu_info->vendor == X86_VENDOR_AMD ||
cpu_info->vendor == X86_VENDOR_HYGON) { if (ext_cpuid_level >= 0x80000007) { if (cpuid_edx(0x80000007) & (1 << 9)) {
cpu_info->caps |= CPUPOWER_CAP_AMD_CPB;
if (cpu_info->family >= 0x17)
cpu_info->caps |= CPUPOWER_CAP_AMD_CPB_MSR;
}
if ((cpuid_edx(0x80000007) & (1 << 7)) &&
cpu_info->family != 0x14) { /* HW pstate was not implemented in family 0x14 */
cpu_info->caps |= CPUPOWER_CAP_AMD_HW_PSTATE;
if (cpu_info->family >= 0x17)
cpu_info->caps |= CPUPOWER_CAP_AMD_PSTATEDEF;
}
}
if (cpupower_amd_pstate_enabled()) {
cpu_info->caps |= CPUPOWER_CAP_AMD_PSTATE;
/* * If AMD P-State is enabled, the firmware will treat * AMD P-State function as high priority.
*/
cpu_info->caps &= ~CPUPOWER_CAP_AMD_CPB;
cpu_info->caps &= ~CPUPOWER_CAP_AMD_CPB_MSR;
cpu_info->caps &= ~CPUPOWER_CAP_AMD_HW_PSTATE;
cpu_info->caps &= ~CPUPOWER_CAP_AMD_PSTATEDEF;
}
}
if (cpu_info->vendor == X86_VENDOR_INTEL) { if (cpuid_level >= 6 &&
(cpuid_eax(6) & (1 << 1)))
cpu_info->caps |= CPUPOWER_CAP_INTEL_IDA;
}
if (cpu_info->vendor == X86_VENDOR_INTEL) { /* Intel's perf-bias MSR support */ if (cpuid_level >= 6 && (cpuid_ecx(6) & (1 << 3)))
cpu_info->caps |= CPUPOWER_CAP_PERF_BIAS;
/* Intel's Turbo Ratio Limit support */ if (cpu_info->family == 6) { switch (cpu_info->model) { case 0x1A: /* Core i7, Xeon 5500 series * Bloomfield, Gainstown NHM-EP
*/ case 0x1E: /* Core i7 and i5 Processor * Clarksfield, Lynnfield, Jasper Forest
*/ case 0x1F: /* Core i7 and i5 Processor - Nehalem */ case 0x25: /* Westmere Client * Clarkdale, Arrandale
*/ case 0x2C: /* Westmere EP - Gulftown */
cpu_info->caps |= CPUPOWER_CAP_HAS_TURBO_RATIO; break; case 0x2A: /* SNB */ case 0x2D: /* SNB Xeon */ case 0x3A: /* IVB */ case 0x3E: /* IVB Xeon */
cpu_info->caps |= CPUPOWER_CAP_HAS_TURBO_RATIO;
cpu_info->caps |= CPUPOWER_CAP_IS_SNB; break; case 0x2E: /* Nehalem-EX Xeon - Beckton */ case 0x2F: /* Westmere-EX Xeon - Eagleton */ default: break;
}
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.