From: Thomas Monjalon Date: Tue, 2 Feb 2016 23:10:23 +0000 (+0100) Subject: eal: move CPU flag functions out of headers X-Git-Tag: spdx-start~7628 X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=ba560ac30c59a2e2ffd5a108525d322cac6475c1;p=dpdk.git eal: move CPU flag functions out of headers The patch c344eab3ee has moved the hardware definition of CPU flags. Now the functions checking these hardware flags are also moved. The function rte_cpu_get_flag_enabled() is no more inline. The benefits are: - remove rte_cpu_feature_table from the ABI (recently added) - hide hardware details from the API - allow to adapt structures per arch (done in next patch) Signed-off-by: Thomas Monjalon Acked-by: Jerin Jacob --- diff --git a/MAINTAINERS b/MAINTAINERS index b90aeea76e..628bc05718 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -131,6 +131,7 @@ F: doc/guides/sample_app_ug/multi_process.rst ARM v7 M: Jan Viktorin M: Jianbo Liu +F: lib/librte_eal/common/arch/arm/ F: lib/librte_eal/common/include/arch/arm/ ARM v8 @@ -141,16 +142,19 @@ F: lib/librte_acl/acl_run_neon.* EZchip TILE-Gx M: Zhigang Lu +F: lib/librte_eal/common/arch/tile/ F: lib/librte_eal/common/include/arch/tile/ F: drivers/net/mpipe/ IBM POWER M: Chao Zhu +F: lib/librte_eal/common/arch/ppc_64/ F: lib/librte_eal/common/include/arch/ppc_64/ Intel x86 M: Bruce Richardson M: Konstantin Ananyev +F: lib/librte_eal/common/arch/x86/ F: lib/librte_eal/common/include/arch/x86/ Linux EAL (with overlaps) diff --git a/app/test/test_hash_scaling.c b/app/test/test_hash_scaling.c index 744e5e36b7..1c4c75d634 100644 --- a/app/test/test_hash_scaling.c +++ b/app/test/test_hash_scaling.c @@ -31,6 +31,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include + #include #include #include diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map index 9bea0e273c..1a9620344e 100644 --- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map +++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map @@ -142,6 +142,5 @@ DPDK_2.3 { rte_cpu_get_flag_name; rte_eal_pci_map_device; rte_eal_pci_unmap_device; - rte_cpu_feature_table; } DPDK_2.2; diff --git a/lib/librte_eal/common/arch/arm/rte_cpuflags.c b/lib/librte_eal/common/arch/arm/rte_cpuflags.c index 62e079186d..cd7a7b1692 100644 --- a/lib/librte_eal/common/arch/arm/rte_cpuflags.c +++ b/lib/librte_eal/common/arch/arm/rte_cpuflags.c @@ -2,6 +2,7 @@ * BSD LICENSE * * Copyright (C) Cavium networks Ltd. 2015. + * Copyright(c) 2015 RehiveTech. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,19 +33,51 @@ #include "rte_cpuflags.h" -#ifdef RTE_ARCH_64 -const struct feature_entry rte_cpu_feature_table[] = { - FEAT_DEF(FP, 0x00000001, 0, REG_HWCAP, 0) - FEAT_DEF(NEON, 0x00000001, 0, REG_HWCAP, 1) - FEAT_DEF(EVTSTRM, 0x00000001, 0, REG_HWCAP, 2) - FEAT_DEF(AES, 0x00000001, 0, REG_HWCAP, 3) - FEAT_DEF(PMULL, 0x00000001, 0, REG_HWCAP, 4) - FEAT_DEF(SHA1, 0x00000001, 0, REG_HWCAP, 5) - FEAT_DEF(SHA2, 0x00000001, 0, REG_HWCAP, 6) - FEAT_DEF(CRC32, 0x00000001, 0, REG_HWCAP, 7) - FEAT_DEF(AARCH64, 0x00000001, 0, REG_PLATFORM, 1) +#include +#include +#include +#include +#include + +#ifndef AT_HWCAP +#define AT_HWCAP 16 +#endif + +#ifndef AT_HWCAP2 +#define AT_HWCAP2 26 +#endif + +#ifndef AT_PLATFORM +#define AT_PLATFORM 15 +#endif + +enum cpu_register_t { + REG_HWCAP = 0, + REG_HWCAP2, + REG_PLATFORM, +}; + +typedef uint32_t cpuid_registers_t[4]; + +/** + * Struct to hold a processor feature entry + */ +struct feature_entry { + uint32_t leaf; /**< cpuid leaf */ + uint32_t subleaf; /**< cpuid subleaf */ + uint32_t reg; /**< cpuid register */ + uint32_t bit; /**< cpuid register bit */ +#define CPU_FLAG_NAME_MAX_LEN 64 + char name[CPU_FLAG_NAME_MAX_LEN]; /**< String for printing */ }; -#else + +#define FEAT_DEF(name, leaf, subleaf, reg, bit) \ + [RTE_CPUFLAG_##name] = {leaf, subleaf, reg, bit, #name }, + +#ifdef RTE_ARCH_ARMv7 +#define PLATFORM_STR "v7l" +typedef Elf32_auxv_t _Elfx_auxv_t; + const struct feature_entry rte_cpu_feature_table[] = { FEAT_DEF(SWP, 0x00000001, 0, REG_HWCAP, 0) FEAT_DEF(HALF, 0x00000001, 0, REG_HWCAP, 1) @@ -75,7 +108,73 @@ const struct feature_entry rte_cpu_feature_table[] = { FEAT_DEF(CRC32, 0x00000001, 0, REG_HWCAP2, 4) FEAT_DEF(V7L, 0x00000001, 0, REG_PLATFORM, 0) }; -#endif + +#elif defined RTE_ARCH_ARM64 +#define PLATFORM_STR "aarch64" +typedef Elf64_auxv_t _Elfx_auxv_t; + +const struct feature_entry rte_cpu_feature_table[] = { + FEAT_DEF(FP, 0x00000001, 0, REG_HWCAP, 0) + FEAT_DEF(NEON, 0x00000001, 0, REG_HWCAP, 1) + FEAT_DEF(EVTSTRM, 0x00000001, 0, REG_HWCAP, 2) + FEAT_DEF(AES, 0x00000001, 0, REG_HWCAP, 3) + FEAT_DEF(PMULL, 0x00000001, 0, REG_HWCAP, 4) + FEAT_DEF(SHA1, 0x00000001, 0, REG_HWCAP, 5) + FEAT_DEF(SHA2, 0x00000001, 0, REG_HWCAP, 6) + FEAT_DEF(CRC32, 0x00000001, 0, REG_HWCAP, 7) + FEAT_DEF(AARCH64, 0x00000001, 0, REG_PLATFORM, 1) +}; +#endif /* RTE_ARCH */ + +/* + * Read AUXV software register and get cpu features for ARM + */ +static void +rte_cpu_get_features(__attribute__((unused)) uint32_t leaf, + __attribute__((unused)) uint32_t subleaf, cpuid_registers_t out) +{ + int auxv_fd; + _Elfx_auxv_t auxv; + + auxv_fd = open("/proc/self/auxv", O_RDONLY); + assert(auxv_fd); + while (read(auxv_fd, &auxv, sizeof(auxv)) == sizeof(auxv)) { + if (auxv.a_type == AT_HWCAP) { + out[REG_HWCAP] = auxv.a_un.a_val; + } else if (auxv.a_type == AT_HWCAP2) { + out[REG_HWCAP2] = auxv.a_un.a_val; + } else if (auxv.a_type == AT_PLATFORM) { + if (!strcmp((const char *)auxv.a_un.a_val, PLATFORM_STR)) + out[REG_PLATFORM] = 0x0001; + } + } +} + +/* + * Checks if a particular flag is available on current machine. + */ +int +rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature) +{ + const struct feature_entry *feat; + cpuid_registers_t regs = {0}; + + if (feature >= RTE_CPUFLAG_NUMFLAGS) + /* Flag does not match anything in the feature tables */ + return -ENOENT; + + feat = &rte_cpu_feature_table[feature]; + + if (!feat->leaf) + /* This entry in the table wasn't filled out! */ + return -EFAULT; + + /* get the cpuid leaf containing the desired feature */ + rte_cpu_get_features(feat->leaf, feat->subleaf, regs); + + /* check if the feature is enabled */ + return (regs[feat->reg] >> feat->bit) & 1; +} const char * rte_cpu_get_flag_name(enum rte_cpu_flag_t feature) diff --git a/lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c b/lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c index a270ccc019..b7e0b72032 100644 --- a/lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c +++ b/lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c @@ -32,6 +32,38 @@ #include "rte_cpuflags.h" +#include +#include +#include +#include + +/* Symbolic values for the entries in the auxiliary table */ +#define AT_HWCAP 16 +#define AT_HWCAP2 26 + +/* software based registers */ +enum cpu_register_t { + REG_HWCAP = 0, + REG_HWCAP2, +}; + +typedef uint32_t cpuid_registers_t[4]; + +/** + * Struct to hold a processor feature entry + */ +struct feature_entry { + uint32_t leaf; /**< cpuid leaf */ + uint32_t subleaf; /**< cpuid subleaf */ + uint32_t reg; /**< cpuid register */ + uint32_t bit; /**< cpuid register bit */ +#define CPU_FLAG_NAME_MAX_LEN 64 + char name[CPU_FLAG_NAME_MAX_LEN]; /**< String for printing */ +}; + +#define FEAT_DEF(name, leaf, subleaf, reg, bit) \ + [RTE_CPUFLAG_##name] = {leaf, subleaf, reg, bit, #name }, + const struct feature_entry rte_cpu_feature_table[] = { FEAT_DEF(PPC_LE, 0x00000001, 0, REG_HWCAP, 0) FEAT_DEF(TRUE_LE, 0x00000001, 0, REG_HWCAP, 1) @@ -69,6 +101,53 @@ const struct feature_entry rte_cpu_feature_table[] = { FEAT_DEF(ARCH_2_07, 0x00000001, 0, REG_HWCAP2, 31) }; +/* + * Read AUXV software register and get cpu features for Power + */ +static void +rte_cpu_get_features(__attribute__((unused)) uint32_t leaf, + __attribute__((unused)) uint32_t subleaf, cpuid_registers_t out) +{ + int auxv_fd; + Elf64_auxv_t auxv; + + auxv_fd = open("/proc/self/auxv", O_RDONLY); + assert(auxv_fd); + while (read(auxv_fd, &auxv, + sizeof(Elf64_auxv_t)) == sizeof(Elf64_auxv_t)) { + if (auxv.a_type == AT_HWCAP) + out[REG_HWCAP] = auxv.a_un.a_val; + else if (auxv.a_type == AT_HWCAP2) + out[REG_HWCAP2] = auxv.a_un.a_val; + } +} + +/* + * Checks if a particular flag is available on current machine. + */ +int +rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature) +{ + const struct feature_entry *feat; + cpuid_registers_t regs = {0}; + + if (feature >= RTE_CPUFLAG_NUMFLAGS) + /* Flag does not match anything in the feature tables */ + return -ENOENT; + + feat = &rte_cpu_feature_table[feature]; + + if (!feat->leaf) + /* This entry in the table wasn't filled out! */ + return -EFAULT; + + /* get the cpuid leaf containing the desired feature */ + rte_cpu_get_features(feat->leaf, feat->subleaf, regs); + + /* check if the feature is enabled */ + return (regs[feat->reg] >> feat->bit) & 1; +} + const char * rte_cpu_get_flag_name(enum rte_cpu_flag_t feature) { diff --git a/lib/librte_eal/common/arch/tile/rte_cpuflags.c b/lib/librte_eal/common/arch/tile/rte_cpuflags.c index 4ca0a7b936..a2b6c51a2b 100644 --- a/lib/librte_eal/common/arch/tile/rte_cpuflags.c +++ b/lib/librte_eal/common/arch/tile/rte_cpuflags.c @@ -32,5 +32,16 @@ #include "rte_cpuflags.h" +#include + const struct feature_entry rte_cpu_feature_table[] = { }; + +/* + * Checks if a particular flag is available on current machine. + */ +int +rte_cpu_get_flag_enabled(__attribute__((unused)) enum rte_cpu_flag_t feature) +{ + return -ENOENT; +} diff --git a/lib/librte_eal/common/arch/x86/rte_cpuflags.c b/lib/librte_eal/common/arch/x86/rte_cpuflags.c index 3346fde249..01382571e7 100644 --- a/lib/librte_eal/common/arch/x86/rte_cpuflags.c +++ b/lib/librte_eal/common/arch/x86/rte_cpuflags.c @@ -33,6 +33,34 @@ #include "rte_cpuflags.h" +#include +#include +#include + +enum cpu_register_t { + RTE_REG_EAX = 0, + RTE_REG_EBX, + RTE_REG_ECX, + RTE_REG_EDX, +}; + +typedef uint32_t cpuid_registers_t[4]; + +/** + * Struct to hold a processor feature entry + */ +struct feature_entry { + uint32_t leaf; /**< cpuid leaf */ + uint32_t subleaf; /**< cpuid subleaf */ + uint32_t reg; /**< cpuid register */ + uint32_t bit; /**< cpuid register bit */ +#define CPU_FLAG_NAME_MAX_LEN 64 + char name[CPU_FLAG_NAME_MAX_LEN]; /**< String for printing */ +}; + +#define FEAT_DEF(name, leaf, subleaf, reg, bit) \ + [RTE_CPUFLAG_##name] = {leaf, subleaf, reg, bit, #name }, + const struct feature_entry rte_cpu_feature_table[] = { FEAT_DEF(SSE3, 0x00000001, 0, RTE_REG_ECX, 0) FEAT_DEF(PCLMULQDQ, 0x00000001, 0, RTE_REG_ECX, 1) @@ -128,6 +156,61 @@ const struct feature_entry rte_cpu_feature_table[] = { FEAT_DEF(INVTSC, 0x80000007, 0, RTE_REG_EDX, 8) }; +/* + * Execute CPUID instruction and get contents of a specific register + * + * This function, when compiled with GCC, will generate architecture-neutral + * code, as per GCC manual. + */ +static void +rte_cpu_get_features(uint32_t leaf, uint32_t subleaf, cpuid_registers_t out) +{ +#if defined(__i386__) && defined(__PIC__) + /* %ebx is a forbidden register if we compile with -fPIC or -fPIE */ + asm volatile("movl %%ebx,%0 ; cpuid ; xchgl %%ebx,%0" + : "=r" (out[RTE_REG_EBX]), + "=a" (out[RTE_REG_EAX]), + "=c" (out[RTE_REG_ECX]), + "=d" (out[RTE_REG_EDX]) + : "a" (leaf), "c" (subleaf)); +#else + asm volatile("cpuid" + : "=a" (out[RTE_REG_EAX]), + "=b" (out[RTE_REG_EBX]), + "=c" (out[RTE_REG_ECX]), + "=d" (out[RTE_REG_EDX]) + : "a" (leaf), "c" (subleaf)); +#endif +} + +int +rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature) +{ + const struct feature_entry *feat; + cpuid_registers_t regs; + + if (feature >= RTE_CPUFLAG_NUMFLAGS) + /* Flag does not match anything in the feature tables */ + return -ENOENT; + + feat = &rte_cpu_feature_table[feature]; + + if (!feat->leaf) + /* This entry in the table wasn't filled out! */ + return -EFAULT; + + rte_cpu_get_features(feat->leaf & 0xffff0000, 0, regs); + if (((regs[RTE_REG_EAX] ^ feat->leaf) & 0xffff0000) || + regs[RTE_REG_EAX] < feat->leaf) + return 0; + + /* get the cpuid leaf containing the desired feature */ + rte_cpu_get_features(feat->leaf, feat->subleaf, regs); + + /* check if the feature is enabled */ + return (regs[feat->reg] >> feat->bit) & 1; +} + const char * rte_cpu_get_flag_name(enum rte_cpu_flag_t feature) { diff --git a/lib/librte_eal/common/eal_common_cpuflags.c b/lib/librte_eal/common/eal_common_cpuflags.c index 8c0576d439..a4c5a29f8c 100644 --- a/lib/librte_eal/common/eal_common_cpuflags.c +++ b/lib/librte_eal/common/eal_common_cpuflags.c @@ -30,6 +30,9 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +#include + #include #include diff --git a/lib/librte_eal/common/include/arch/arm/rte_cpuflags_32.h b/lib/librte_eal/common/include/arch/arm/rte_cpuflags_32.h index 2ec0c2ec6f..eb02d9b95a 100644 --- a/lib/librte_eal/common/include/arch/arm/rte_cpuflags_32.h +++ b/lib/librte_eal/common/include/arch/arm/rte_cpuflags_32.h @@ -37,35 +37,6 @@ extern "C" { #endif -#include -#include -#include -#include -#include - -#include "generic/rte_cpuflags.h" - -extern const struct feature_entry rte_cpu_feature_table[]; - -#ifndef AT_HWCAP -#define AT_HWCAP 16 -#endif - -#ifndef AT_HWCAP2 -#define AT_HWCAP2 26 -#endif - -#ifndef AT_PLATFORM -#define AT_PLATFORM 15 -#endif - -/* software based registers */ -enum cpu_register_t { - REG_HWCAP = 0, - REG_HWCAP2, - REG_PLATFORM, -}; - /** * Enumeration of all CPU features supported */ @@ -102,56 +73,7 @@ enum rte_cpu_flag_t { RTE_CPUFLAG_NUMFLAGS,/**< This should always be the last! */ }; -/* - * Read AUXV software register and get cpu features for ARM - */ -static inline void -rte_cpu_get_features(__attribute__((unused)) uint32_t leaf, - __attribute__((unused)) uint32_t subleaf, cpuid_registers_t out) -{ - int auxv_fd; - Elf32_auxv_t auxv; - - auxv_fd = open("/proc/self/auxv", O_RDONLY); - assert(auxv_fd); - while (read(auxv_fd, &auxv, - sizeof(Elf32_auxv_t)) == sizeof(Elf32_auxv_t)) { - if (auxv.a_type == AT_HWCAP) - out[REG_HWCAP] = auxv.a_un.a_val; - else if (auxv.a_type == AT_HWCAP2) - out[REG_HWCAP2] = auxv.a_un.a_val; - else if (auxv.a_type == AT_PLATFORM) { - if (!strcmp((const char *)auxv.a_un.a_val, "v7l")) - out[REG_PLATFORM] = 0x0001; - } - } -} - -/* - * Checks if a particular flag is available on current machine. - */ -static inline int -rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature) -{ - const struct feature_entry *feat; - cpuid_registers_t regs = {0}; - - if (feature >= RTE_CPUFLAG_NUMFLAGS) - /* Flag does not match anything in the feature tables */ - return -ENOENT; - - feat = &rte_cpu_feature_table[feature]; - - if (!feat->leaf) - /* This entry in the table wasn't filled out! */ - return -EFAULT; - - /* get the cpuid leaf containing the desired feature */ - rte_cpu_get_features(feat->leaf, feat->subleaf, regs); - - /* check if the feature is enabled */ - return (regs[feat->reg] >> feat->bit) & 1; -} +#include "generic/rte_cpuflags.h" #ifdef __cplusplus } diff --git a/lib/librte_eal/common/include/arch/arm/rte_cpuflags_64.h b/lib/librte_eal/common/include/arch/arm/rte_cpuflags_64.h index b36040b2c0..810e8a018b 100644 --- a/lib/librte_eal/common/include/arch/arm/rte_cpuflags_64.h +++ b/lib/librte_eal/common/include/arch/arm/rte_cpuflags_64.h @@ -37,35 +37,6 @@ extern "C" { #endif -#include -#include -#include -#include -#include - -#include "generic/rte_cpuflags.h" - -extern const struct feature_entry rte_cpu_feature_table[]; - -#ifndef AT_HWCAP -#define AT_HWCAP 16 -#endif - -#ifndef AT_HWCAP2 -#define AT_HWCAP2 26 -#endif - -#ifndef AT_PLATFORM -#define AT_PLATFORM 15 -#endif - -/* software based registers */ -enum cpu_register_t { - REG_HWCAP = 0, - REG_HWCAP2, - REG_PLATFORM, -}; - /** * Enumeration of all CPU features supported */ @@ -83,57 +54,7 @@ enum rte_cpu_flag_t { RTE_CPUFLAG_NUMFLAGS,/**< This should always be the last! */ }; -/* - * Read AUXV software register and get cpu features for ARM - */ -static inline void -rte_cpu_get_features(__attribute__((unused)) uint32_t leaf, - __attribute__((unused)) uint32_t subleaf, - cpuid_registers_t out) -{ - int auxv_fd; - Elf64_auxv_t auxv; - - auxv_fd = open("/proc/self/auxv", O_RDONLY); - assert(auxv_fd); - while (read(auxv_fd, &auxv, - sizeof(Elf64_auxv_t)) == sizeof(Elf64_auxv_t)) { - if (auxv.a_type == AT_HWCAP) { - out[REG_HWCAP] = auxv.a_un.a_val; - } else if (auxv.a_type == AT_HWCAP2) { - out[REG_HWCAP2] = auxv.a_un.a_val; - } else if (auxv.a_type == AT_PLATFORM) { - if (!strcmp((const char *)auxv.a_un.a_val, "aarch64")) - out[REG_PLATFORM] = 0x0001; - } - } -} - -/* - * Checks if a particular flag is available on current machine. - */ -static inline int -rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature) -{ - const struct feature_entry *feat; - cpuid_registers_t regs = {0}; - - if (feature >= RTE_CPUFLAG_NUMFLAGS) - /* Flag does not match anything in the feature tables */ - return -ENOENT; - - feat = &rte_cpu_feature_table[feature]; - - if (!feat->leaf) - /* This entry in the table wasn't filled out! */ - return -EFAULT; - - /* get the cpuid leaf containing the desired feature */ - rte_cpu_get_features(feat->leaf, feat->subleaf, regs); - - /* check if the feature is enabled */ - return (regs[feat->reg] >> feat->bit) & 1; -} +#include "generic/rte_cpuflags.h" #ifdef __cplusplus } diff --git a/lib/librte_eal/common/include/arch/ppc_64/rte_cpuflags.h b/lib/librte_eal/common/include/arch/ppc_64/rte_cpuflags.h index 85c4c1a98a..7cc2b3c531 100644 --- a/lib/librte_eal/common/include/arch/ppc_64/rte_cpuflags.h +++ b/lib/librte_eal/common/include/arch/ppc_64/rte_cpuflags.h @@ -37,25 +37,6 @@ extern "C" { #endif -#include -#include -#include -#include - -#include "generic/rte_cpuflags.h" - -extern const struct feature_entry rte_cpu_feature_table[]; - -/* Symbolic values for the entries in the auxiliary table */ -#define AT_HWCAP 16 -#define AT_HWCAP2 26 - -/* software based registers */ -enum cpu_register_t { - REG_HWCAP = 0, - REG_HWCAP2, -}; - /** * Enumeration of all CPU features supported */ @@ -98,52 +79,7 @@ enum rte_cpu_flag_t { RTE_CPUFLAG_NUMFLAGS,/**< This should always be the last! */ }; -/* - * Read AUXV software register and get cpu features for Power - */ -static inline void -rte_cpu_get_features(__attribute__((unused)) uint32_t leaf, - __attribute__((unused)) uint32_t subleaf, cpuid_registers_t out) -{ - int auxv_fd; - Elf64_auxv_t auxv; - - auxv_fd = open("/proc/self/auxv", O_RDONLY); - assert(auxv_fd); - while (read(auxv_fd, &auxv, - sizeof(Elf64_auxv_t)) == sizeof(Elf64_auxv_t)) { - if (auxv.a_type == AT_HWCAP) - out[REG_HWCAP] = auxv.a_un.a_val; - else if (auxv.a_type == AT_HWCAP2) - out[REG_HWCAP2] = auxv.a_un.a_val; - } -} - -/* - * Checks if a particular flag is available on current machine. - */ -static inline int -rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature) -{ - const struct feature_entry *feat; - cpuid_registers_t regs = {0}; - - if (feature >= RTE_CPUFLAG_NUMFLAGS) - /* Flag does not match anything in the feature tables */ - return -ENOENT; - - feat = &rte_cpu_feature_table[feature]; - - if (!feat->leaf) - /* This entry in the table wasn't filled out! */ - return -EFAULT; - - /* get the cpuid leaf containing the desired feature */ - rte_cpu_get_features(feat->leaf, feat->subleaf, regs); - - /* check if the feature is enabled */ - return (regs[feat->reg] >> feat->bit) & 1; -} +#include "generic/rte_cpuflags.h" #ifdef __cplusplus } diff --git a/lib/librte_eal/common/include/arch/tile/rte_cpuflags.h b/lib/librte_eal/common/include/arch/tile/rte_cpuflags.h index a415857c7e..1849b520cd 100644 --- a/lib/librte_eal/common/include/arch/tile/rte_cpuflags.h +++ b/lib/librte_eal/common/include/arch/tile/rte_cpuflags.h @@ -37,18 +37,6 @@ extern "C" { #endif -#include -#include -#include -#include - -#include "generic/rte_cpuflags.h" - -/* software based registers */ -enum cpu_register_t { - REG_DUMMY = 0 -}; - /** * Enumeration of all CPU features supported */ @@ -56,24 +44,7 @@ enum rte_cpu_flag_t { RTE_CPUFLAG_NUMFLAGS /**< This should always be the last! */ }; -/* - * Read AUXV software register and get cpu features for Power - */ -static inline void -rte_cpu_get_features(__attribute__((unused)) uint32_t leaf, - __attribute__((unused)) uint32_t subleaf, - __attribute__((unused)) cpuid_registers_t out) -{ -} - -/* - * Checks if a particular flag is available on current machine. - */ -static inline int -rte_cpu_get_flag_enabled(__attribute__((unused)) enum rte_cpu_flag_t feature) -{ - return -ENOENT; -} +#include "generic/rte_cpuflags.h" #ifdef __cplusplus } diff --git a/lib/librte_eal/common/include/arch/x86/rte_cpuflags.h b/lib/librte_eal/common/include/arch/x86/rte_cpuflags.h index 120ea24be3..26204fabbc 100644 --- a/lib/librte_eal/common/include/arch/x86/rte_cpuflags.h +++ b/lib/librte_eal/common/include/arch/x86/rte_cpuflags.h @@ -38,15 +38,6 @@ extern "C" { #endif -#include -#include -#include -#include - -#include "generic/rte_cpuflags.h" - -extern const struct feature_entry rte_cpu_feature_table[]; - enum rte_cpu_flag_t { /* (EAX 01h) ECX features*/ RTE_CPUFLAG_SSE3 = 0, /**< SSE3 */ @@ -153,64 +144,7 @@ enum rte_cpu_flag_t { RTE_CPUFLAG_NUMFLAGS, /**< This should always be the last! */ }; -enum cpu_register_t { - RTE_REG_EAX = 0, - RTE_REG_EBX, - RTE_REG_ECX, - RTE_REG_EDX, -}; - -static inline void -rte_cpu_get_features(uint32_t leaf, uint32_t subleaf, cpuid_registers_t out) -{ -#if defined(__i386__) && defined(__PIC__) - /* %ebx is a forbidden register if we compile with -fPIC or -fPIE */ - asm volatile("movl %%ebx,%0 ; cpuid ; xchgl %%ebx,%0" - : "=r" (out[RTE_REG_EBX]), - "=a" (out[RTE_REG_EAX]), - "=c" (out[RTE_REG_ECX]), - "=d" (out[RTE_REG_EDX]) - : "a" (leaf), "c" (subleaf)); -#else - - asm volatile("cpuid" - : "=a" (out[RTE_REG_EAX]), - "=b" (out[RTE_REG_EBX]), - "=c" (out[RTE_REG_ECX]), - "=d" (out[RTE_REG_EDX]) - : "a" (leaf), "c" (subleaf)); - -#endif -} - -static inline int -rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature) -{ - const struct feature_entry *feat; - cpuid_registers_t regs; - - - if (feature >= RTE_CPUFLAG_NUMFLAGS) - /* Flag does not match anything in the feature tables */ - return -ENOENT; - - feat = &rte_cpu_feature_table[feature]; - - if (!feat->leaf) - /* This entry in the table wasn't filled out! */ - return -EFAULT; - - rte_cpu_get_features(feat->leaf & 0xffff0000, 0, regs); - if (((regs[RTE_REG_EAX] ^ feat->leaf) & 0xffff0000) || - regs[RTE_REG_EAX] < feat->leaf) - return 0; - - /* get the cpuid leaf containing the desired feature */ - rte_cpu_get_features(feat->leaf, feat->subleaf, regs); - - /* check if the feature is enabled */ - return (regs[feat->reg] >> feat->bit) & 1; -} +#include "generic/rte_cpuflags.h" #ifdef __cplusplus } diff --git a/lib/librte_eal/common/include/generic/rte_cpuflags.h b/lib/librte_eal/common/include/generic/rte_cpuflags.h index 3ca2e3660e..c1da357cd4 100644 --- a/lib/librte_eal/common/include/generic/rte_cpuflags.h +++ b/lib/librte_eal/common/include/generic/rte_cpuflags.h @@ -39,59 +39,13 @@ * Architecture specific API to determine available CPU features at runtime. */ -#include -#include #include -#include /** * Enumeration of all CPU features supported */ enum rte_cpu_flag_t; -/** - * Enumeration of CPU registers - */ -#ifdef __DOXYGEN__ -enum cpu_register_t; -#endif - -typedef uint32_t cpuid_registers_t[4]; - -#define CPU_FLAG_NAME_MAX_LEN 64 - -/** - * Struct to hold a processor feature entry - */ -struct feature_entry { - uint32_t leaf; /**< cpuid leaf */ - uint32_t subleaf; /**< cpuid subleaf */ - uint32_t reg; /**< cpuid register */ - uint32_t bit; /**< cpuid register bit */ - char name[CPU_FLAG_NAME_MAX_LEN]; /**< String for printing */ -}; - -#define FEAT_DEF(name, leaf, subleaf, reg, bit) \ - [RTE_CPUFLAG_##name] = {leaf, subleaf, reg, bit, #name }, - -/** - * An array that holds feature entries - * - * Defined in arch-specific rte_cpuflags.h. - */ -#ifdef __DOXYGEN__ -static const struct feature_entry cpu_feature_table[]; -#endif - -/** - * Execute CPUID instruction and get contents of a specific register - * - * This function, when compiled with GCC, will generate architecture-neutral - * code, as per GCC manual. - */ -static inline void -rte_cpu_get_features(uint32_t leaf, uint32_t subleaf, cpuid_registers_t out); - /** * Get name of CPU flag * @@ -114,10 +68,8 @@ rte_cpu_get_flag_name(enum rte_cpu_flag_t feature); * 0 if flag is not available * -ENOENT if flag is invalid */ -#ifdef __DOXYGEN__ -static inline int +int rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature); -#endif /** * This function checks that the currently used CPU supports the CPU features diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map index 48e8e4f1f1..440fac2191 100644 --- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map +++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map @@ -145,6 +145,5 @@ DPDK_2.3 { rte_cpu_get_flag_name; rte_eal_pci_map_device; rte_eal_pci_unmap_device; - rte_cpu_feature_table; } DPDK_2.2;