From 3119b7e07ae595a256e42cb99ffb7ea6857a88cb Mon Sep 17 00:00:00 2001 From: Ahmed Samy Date: Mon, 23 Sep 2013 08:20:08 +0000 Subject: [PATCH] cpuid: prefix every function with cpuid_ Also merge extended features and non-extended in 1 function. Suggested-by: Peter Hutterer Signed-off-by: Ahmed Samy --- ccan/cpuid/cpuid.c | 114 +++++++++++++++++++++----------------- ccan/cpuid/cpuid.h | 133 ++++++++++++++++----------------------------- 2 files changed, 111 insertions(+), 136 deletions(-) diff --git a/ccan/cpuid/cpuid.c b/ccan/cpuid/cpuid.c index 6f2c5a53..6ab0e50f 100644 --- a/ccan/cpuid/cpuid.c +++ b/ccan/cpuid/cpuid.c @@ -58,19 +58,49 @@ static void ___cpuid(cpuid_t info, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, } #endif -int highest_ext_func_supported(void) -{ - static int highest; +static struct { + int feature; + unsigned mask; + int instruction; /* 0 = ecx, 1 = edx. */ +} features[] = { + { CF_MMX, 1 << 23, 1 }, + { CF_SSE, 1 << 25, 1 }, + { CF_SSE2, 1 << 26, 1 }, + { CF_SSE3, 1 << 9, 0 }, + { CF_FPU, 1 << 0, 1 }, + + { CF_TSC, 1 << 4, 1 }, + { CF_MSR, 1 << 5, 1 }, + + { CF_SSSE3, 1 << 9, 0 }, + { CF_AVX, 1 << 28, 0 }, + + /* Extended ones. */ + { CEF_x64, 1 << 30, 1 }, + { CEF_FPU, 1 << 0, 1 }, + { CEF_DE, 1 << 2, 1 }, + { CEF_SYSCALLRET, 1 << 11, 1 }, + { CEF_CMOV, 1 << 15, 1 }, + + { CEF_SSE4a, 1 << 6, 0 }, + { CEF_FMA4, 1 << 16, 0 }, + { CEF_XOP, 1 << 11, 0 } +}; - if (!highest) { - asm volatile( - "cpuid\n\t" - : "=a" (highest) - : "a" (CPU_HIGHEST_EXTENDED_FUNCTION_SUPPORTED) - ); +static int has_feature(int feature, uint32_t ecx, uint32_t edx) +{ + int i; + + for (i = 0; i < sizeof(features) / sizeof(features[0]); ++i) { + if (features[i].feature == feature) { + if (features[i].instruction == 0) + return (ecx & features[i].mask); + else + return (edx & features[i].mask); + } } - return highest; + return 0; } int cpuid_test_feature(cpuid_t feature) @@ -78,48 +108,19 @@ int cpuid_test_feature(cpuid_t feature) if (feature > CPU_VIRT_PHYS_ADDR_SIZES || feature < CPU_EXTENDED_PROC_INFO_FEATURE_BITS) return 0; - return (feature <= highest_ext_func_supported()); -} - -int cpuid_has_feature(cpufeature_t feature) -{ - uint32_t eax, ebx, ecx, edx; - - ___cpuid(CPU_PROCINFO_AND_FEATUREBITS, &eax, &ebx, &ecx, &edx); - switch (feature) { - case CF_MMX: - case CF_SSE: - case CF_SSE2: - return (edx & ((int)feature)) != 0; - case CF_SSE3: - case CF_SSSE3: - case CF_SSE41: - case CF_SSE42: - case CF_AVX: - case CF_FMA: - return (ecx & ((int)feature)) != 0; - } - - return 0; + return (feature <= cpuid_highest_ext_func_supported()); } -int cpuid_has_ext_feature(cpuextfeature_t extfeature) +int cpuid_has_feature(int feature, int extended) { uint32_t eax, ebx, ecx, edx; - if (!cpuid_test_feature(CPU_EXTENDED_PROC_INFO_FEATURE_BITS)) - return 0; - ___cpuid(CPU_EXTENDED_PROC_INFO_FEATURE_BITS, &eax, &ebx, &ecx, &edx); - switch (extfeature) { - case CEF_x64: - return (edx & ((int)extfeature)) != 0; - case CEF_SSE4a: - case CEF_FMA4: - case CEF_XOP: - return (ecx & ((int)extfeature)) != 0; - } + if (extended == 0) + ___cpuid(CPU_PROCINFO_AND_FEATUREBITS, &eax, &ebx, &ecx, &edx); + else + ___cpuid(CPU_EXTENDED_PROC_INFO_FEATURE_BITS, &eax, &ebx, &ecx, &edx); - return 0; + return has_feature(feature, ecx, edx); } static const char *cpuids[] = { @@ -141,7 +142,7 @@ static const char *cpuids[] = { "KVMKVMKVMKVM" }; -cputype_t get_cpu_type(void) +cputype_t cpuid_get_cpu_type(void) { static cputype_t cputype; if (cputype == CT_NONE) { @@ -165,11 +166,26 @@ cputype_t get_cpu_type(void) return cputype; } -const char *get_cpu_type_string(const cputype_t cputype) +const char *cpuid_get_cpu_type_string(const cputype_t cputype) { return cpuids[(int)cputype]; } +int cpuid_highest_ext_func_supported(void) +{ + static int highest; + + if (!highest) { + asm volatile( + "cpuid\n\t" + : "=a" (highest) + : "a" (CPU_HIGHEST_EXTENDED_FUNCTION_SUPPORTED) + ); + } + + return highest; +} + void cpuid(cpuid_t info, void *buf) { /* Sanity checks, make sure we're not trying to do something @@ -186,7 +202,7 @@ void cpuid(cpuid_t info, void *buf) ___cpuid(CPU_PROC_BRAND_STRING_INTERNAL1, &ubuf[8], &ubuf[9], &ubuf[10], &ubuf[11]); return; } else if (info == CPU_HIGHEST_EXTENDED_FUNCTION_SUPPORTED) { - *ubuf = highest_ext_func_supported(); + *ubuf = cpuid_highest_ext_func_supported(); return; } diff --git a/ccan/cpuid/cpuid.h b/ccan/cpuid/cpuid.h index 8c0b9b10..28613946 100644 --- a/ccan/cpuid/cpuid.h +++ b/ccan/cpuid/cpuid.h @@ -73,63 +73,26 @@ typedef enum cpuid { CPU_VIRT_PHYS_ADDR_SIZES = 0x80000008 } cpuid_t; -/** - * enum cpufeature - * - * This is used by cpuid_has_feature(). - * - * CF_MMX: - * Test for MMX support. - * - * CF_SSE*: - * Test for SSE* support. - * - * CF_AVX: - * Test for AVX support. - * - * CF_FMA: - * Test for FMA support. - */ - -typedef enum cpufeature { - CF_MMX = 1 << 23, - CF_SSE = 1 << 25, - CF_SSE2 = 1 << 26, - CF_SSE3 = 1 << 0, - - CF_SSSE3 = 1 << 9, - CF_SSE41 = 1 << 19, - CF_SSE42 = 1 << 20, - - CF_AVX = 1 << 28, - CF_FMA = 1 << 12 -} cpufeature_t; - -/** - * enum cpuextfeature - Test for an extended feature provided by the CPU - * - * This is used by cpuid_has_ext_feature() - * - * CEF_x64: - * Test for 64-bits. - * - * CEF_SSE4a: - * CEF_FMA4: - * CEF_XOP: - * Test for SSE4a/FMA4/XOP - */ -typedef enum cpuextfeature { - CEF_x64 = 1 << 29, - CEF_SSE4a = 1 << 6, - CEF_FMA4 = 1 << 16, - CEF_XOP = 1 << 11 -} cpuextfeature_t; +#define CF_MMX 0 +#define CF_SSE 1 +#define CF_SSE2 2 +#define CF_SSE3 3 +#define CF_FPU 4 +#define CF_TSC 5 +#define CF_MSR 6 +#define CF_SSSE3 7 +#define CF_AVX 8 +#define CF_FMA 9 + +#define CEF_x64 10 +#define CEF_FPU 11 +#define CEF_DE 12 +#define CEF_SYSCALLRET 13 +#define CEF_CMOV 14 +#define CEF_SSE4a 15 +#define CEF_FMA4 16 +#define CEF_XOP 17 -/** - * enum cputype - CPU type - * - * Warning, do not change this order or odd stuff may happen. - */ typedef enum cputype { CT_NONE, CT_AMDK5, @@ -149,18 +112,20 @@ typedef enum cputype { } cputype_t; /** - * get_cpu_type - Get CPU Type + * cpuid_get_cpu_type - Get CPU Type * * Returns the CPU Type as cputype_t. + * + * See also: cpuid_get_cpu_type_string() */ -cputype_t get_cpu_type(void); +cputype_t cpuid_get_cpu_type(void); /** - * get_cpu_type_string - Get CPU Type string + * cpuid_get_cpu_type_string - Get CPU Type string * * Returns the CPU type string based off cputype_t. */ -const char *get_cpu_type_string(const cputype_t cputype); +const char *cpuid_get_cpu_type_string(const cputype_t cputype); /** * cpuid_is_supported - test if the CPUID instruction is supported @@ -174,7 +139,7 @@ const char *get_cpu_type_string(const cputype_t cputype); int cpuid_is_supported(void); /** - * highest_ext_func_supported - Get the highest extended function supported + * cpuid_highest_ext_func_supported - Get the highest extended function supported * * * Returns the highest extended function supported. @@ -187,7 +152,7 @@ int cpuid_is_supported(void); * * See also: cpuid() */ -int highest_ext_func_supported(void); +int cpuid_highest_ext_func_supported(void); /** * cpuid - Get Some information from the CPU. @@ -240,34 +205,28 @@ int cpuid_test_feature(cpuid_t feature); /** * cpuid_has_feature - Test if @feature is supported * - * Test if the CPU supports MMX/SSE* etc + * Test if the CPU supports MMX/SSE* etc. + * For the extended parameter, usually you want to pass it as + * 0 if you're not passing CEF_*. * - * Returns 1 if the feature is available, 0 otherwise. - */ -#define cpuid_has_mmx() cpuid_has_feature(CF_MMX) -#define cpuid_has_sse() cpuid_has_feature(CF_SSE) -#define cpuid_has_sse2() cpuid_has_feature(CF_SSE2) -#define cpuid_has_sse3() cpuid_has_feature(CF_SSE3) -#define cpuid_has_ssse3() cpuid_has_feature(CF_SSSE3) -#define cpuid_has_sse41() cpuid_has_feature(CF_SSE41) -#define cpuid_has_sse42() cpuid_has_feature(CF_SSE42) -#define cpuid_has_avx() cpuid_has_feature(CF_AVX) -#define cpuid_has_fma() cpuid_has_feature(CF_FMA) -int cpuid_has_feature(cpufeature_t feature); - -/** - * cpuid_has_ext_feature - Test if @extfeature is an extended feature - * that's supported by the CPU. - * - * Test if the CPU supports this extended feature. + * For more information about the CPU extended features, have a look + * at: + * http://en.wikipedia.org/wiki/CPUID * - * Returns 1 if available, 0 otherwise. + * Returns 1 if the feature is available, 0 otherwise. */ -#define cpuid_has_x64() cpuid_has_ext_feature(CEF_x64) -#define cpuid_has_sse4a() cpuid_has_ext_feature(CEF_SSE4a) -#define cpuid_has_fma4() cpuid_has_ext_feature(CEF_FMA4) -#define cpuid_has_xop() cpuid_has_ext_feature(CEF_XOP) -int cpuid_has_ext_feature(cpuextfeature_t extfeature); +#define cpuid_has_mmx() cpuid_has_feature(CF_MMX, 0) +#define cpuid_has_sse() cpuid_has_feature(CF_SSE, 0) +#define cpuid_has_sse2() cpuid_has_feature(CF_SSE2, 0) +#define cpuid_has_sse3() cpuid_has_feature(CF_SSE3, 0) +#define cpuid_has_ssse3() cpuid_has_feature(CF_SSSE3, 0) +#define cpuid_has_avx() cpuid_has_feature(CF_AVX, 0) +#define cpuid_has_fma() cpuid_has_feature(CF_FMA, 0) +#define cpuid_has_x64() cpuid_has_feature(CEF_x64, 1) +#define cpuid_has_sse4a() cpuid_has_feature(CEF_SSE4a, 1) +#define cpuid_has_fma4() cpuid_has_feature(CEF_FMA4, 1) +#define cpuid_has_xop() cpuid_has_feature(CEF_XOP, 1) +int cpuid_has_feature(int feature, int extended); #endif -- 2.39.2