diff options
author | Joursoir <chat@joursoir.net> | 2023-04-28 17:11:44 +0400 |
---|---|---|
committer | Joursoir <chat@joursoir.net> | 2023-04-28 17:11:44 +0400 |
commit | 8e585d790a158c213b1d5084496e153912b80027 (patch) | |
tree | 9a720990f859368af572a84c4c6703edac5d043c | |
parent | d0a85a1816903f41b2bc2e30efbb7a3199670cea (diff) | |
download | cpui-drv-8e585d790a158c213b1d5084496e153912b80027.tar.gz cpui-drv-8e585d790a158c213b1d5084496e153912b80027.tar.bz2 cpui-drv-8e585d790a158c213b1d5084496e153912b80027.zip |
add CPU features detection
-rw-r--r-- | cpui-drv.c | 45 |
1 files changed, 45 insertions, 0 deletions
@@ -2,6 +2,17 @@ #include <linux/module.h> +enum feature_information { + FEATURES_01_ECX = 0, + FEATURES_01_EDX, + FEATURES_6_EAX, + FEATURES_7_0_EBX, + FEATURES_7_ECX, + FEATURES_7_EDX, + FEATURES_7_1_EAX, + FEATURES_LAST, +}; + struct cpui_info { uint32_t cpuid_max; char vendor_string[13]; @@ -9,6 +20,8 @@ struct cpui_info { uint8_t family; uint8_t model; uint8_t stepping; + + uint32_t features[FEATURES_LAST]; }; static struct cpui_info __cpu; @@ -64,6 +77,36 @@ static void detect_cpu(struct cpui_info *cpu) } } +static void get_cpu_features(struct cpui_info *cpu) +{ + uint32_t eax, ebx, ecx, edx; + + if (cpu->cpuid_max >= 0x01) { + cpuid(0x01, &eax, &ebx, &ecx, &edx); + cpu->features[FEATURES_01_ECX] = ecx; + cpu->features[FEATURES_01_EDX] = edx; + } + + /* Thermal and Power Management Leaf */ + if (cpu->cpuid_max >= 0x06) { + cpuid(0x01, &eax, &ebx, &ecx, &edx); + cpu->features[FEATURES_6_EAX] = eax; + } + + /* Structured Extended Feature Flags Enumeration Leaf */ + if (cpu->cpuid_max >= 0x07) { + cpuid_count(0x07, 0, &eax, &ebx, &ecx, &edx); + cpu->features[FEATURES_7_0_EBX] = ebx; + cpu->features[FEATURES_7_ECX] = ecx; + cpu->features[FEATURES_7_EDX] = edx; + + if (eax >= 1) { + cpuid_count(0x07, 1, &eax, &ebx, &ecx, &edx); + cpu->features[FEATURES_7_1_EAX] = eax; + } + } +} + static int __init cpui_init(void) { if (!have_cpuid_p()) { @@ -76,6 +119,8 @@ static int __init cpui_init(void) detect_cpu(&__cpu); pr_info("Maximum Input Value for Basic CPUID Information = %d\n", __cpu.cpuid_max); pr_info("Identity string = %s\n", __cpu.vendor_string); + + get_cpu_features(&__cpu); return 0; } |