In fact the info is fetch through /proc/cpuinfo and not through cpuid for now. This call can fetch: cpu_info->vendor cpu_info->family cpu_info->model cpu_info->stepping cpu_info->cpuid_level cpu_info->ext_cpuid_level Signed-off-by: Thomas Renninger <trenn@xxxxxxx> CC: Dominik Brodowski <linux@xxxxxxxxxxxxxxxxxxxx> CC: cpufreq@xxxxxxxxxxxxxxx --- lib/cpuid.h | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 86 insertions(+), 0 deletions(-) diff --git a/lib/cpuid.h b/lib/cpuid.h index 5f179db..c00c58d 100644 --- a/lib/cpuid.h +++ b/lib/cpuid.h @@ -3,6 +3,22 @@ #include <stdint.h> +enum cpupower_cpu_vendor {X86_VENDOR_UNKNOWN = 0, X86_VENDOR_INTEL, + X86_VENDOR_AMD, X86_VENDOR_MAX}; + +static const char *cpu_vendor_table[] = { + "Unknown", "GenuineIntel", "AuthenticAMD", +}; + +struct cpupower_cpu_info { + enum cpupower_cpu_vendor vendor; + unsigned int family; + unsigned int model; + unsigned int stepping; + unsigned int cpuid_level; + uint32_t ext_cpuid_level; +}; + static inline void __cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) { @@ -62,4 +78,74 @@ static inline unsigned int cpuid_edx(unsigned int op) return edx; } +/* 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(unsigned int cpu, struct cpupower_cpu_info *cpu_info) +{ + FILE *fp; + char value[64]; + unsigned int proc, x; + unsigned int unknown = 0xffffff; + + cpu_info->vendor = X86_VENDOR_UNKNOWN; + cpu_info->family = unknown; + cpu_info->model = unknown; + cpu_info->stepping = unknown; + cpu_info->cpuid_level = cpuid_eax(0); + cpu_info->ext_cpuid_level = cpuid_eax(0x80000000); + + + 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 != 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. */ + else if (!strncmp(value, "cpu family\t: ", 13)) { + sscanf(value, "cpu family\t: %u", + &cpu_info->family); + } + else if (!strncmp(value, "model\t\t: ", 9)) { + sscanf(value, "model\t\t: %u", + &cpu_info->model); + } + else if (!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) + return -EINVAL; + + return 0; + } + } + return -ENODEV; +} + #endif /* _CPUFREQ_CPUID_H */ -- 1.6.4.2 -- To unsubscribe from this list: send the line "unsubscribe cpufreq" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html