From patchwork Sat Feb 6 22:17:10 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Monjalon X-Patchwork-Id: 10420 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id BF124A56E; Sat, 6 Feb 2016 23:18:41 +0100 (CET) Received: from mail-wm0-f44.google.com (mail-wm0-f44.google.com [74.125.82.44]) by dpdk.org (Postfix) with ESMTP id 3BD6595B5 for ; Sat, 6 Feb 2016 23:18:39 +0100 (CET) Received: by mail-wm0-f44.google.com with SMTP id 128so112320833wmz.1 for ; Sat, 06 Feb 2016 14:18:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=TI4oNmMPYzBy2NJ2xjQ329EvYcTjPhDlQx615NYy8rI=; b=JqBnFNTLx0VtJ+A8hk1n1f0VhCgy3twFfKTKo8DDmJVMEfmoWpLWcxjNb0nju9xXHk 8E/ghWqsy41oX9UjyKwm7fKkLpB1WRsToms+TuaAbMtha3blNeqP5x1GkczRZ/J6jbu+ wn5BWgW2E1XzgZOVcEkIrRhqLC3mLvem1SNiaYcURJeaQLSxQBdbNe3zzVOmA/A8J8+L b2y3UWNIIg6hbdcP6xwD/XFbVy0uAmpCQbW23uXo3kWSvKowdFuOk1O/iR3Bb7PZmAUe shRtDOSFMo0jeoKxZvIX5KdQJhrb14pMt9IPmdPdzoS9rcekY4ahjuCkee4uY1E4NuAr lIgg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=TI4oNmMPYzBy2NJ2xjQ329EvYcTjPhDlQx615NYy8rI=; b=L/IMIIiEtZcnbr/L5swqRjD2n2ZLzm+z3mxBF7Xt9VnHsNB1g/QPriIPX84C/Trl8L xrqFvqafdItuNicX6I68JjYV9+9jboZir+/uvjkLWtfe3UwznbrfAPNIPTvmoJ2Iq5Lb eU2ARy6mhBt+24mX68v+CQqgAmnqpwZOd/wbA8fAWaetT+FieXezJaOAnnihMPURJaJM bKbz1n9J0/2N2kwvmxIUJZQnbhgIB/T8PBYkVgoc7gxWdCviQwvyyC6xr46qCYC6ql5p ySrFqSI7JPImXDybkZNaJMoapy9X8UE/B2zztp6yMqZ+HxhFgv6RrVLQRZeb5kzM6YgB HsLQ== X-Gm-Message-State: AG10YOTg1TqGsIW1+Wlp22Uan9tbkeZRpCtVHVu+rJIhXQ3yZ/OaprZ5p91lWP9Dt7DzxNEs X-Received: by 10.194.21.163 with SMTP id w3mr20329183wje.58.1454797119120; Sat, 06 Feb 2016 14:18:39 -0800 (PST) Received: from localhost.localdomain (136-92-190-109.dsl.ovh.fr. [109.190.92.136]) by smtp.gmail.com with ESMTPSA id e9sm22167710wja.25.2016.02.06.14.18.37 (version=TLSv1/SSLv3 cipher=OTHER); Sat, 06 Feb 2016 14:18:38 -0800 (PST) From: Thomas Monjalon To: david.marchand@6wind.com, ferruh.yigit@intel.com Date: Sat, 6 Feb 2016 23:17:10 +0100 Message-Id: <1454797033-24057-3-git-send-email-thomas.monjalon@6wind.com> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1454797033-24057-1-git-send-email-thomas.monjalon@6wind.com> References: <1454453993-3903-1-git-send-email-thomas.monjalon@6wind.com> <1454797033-24057-1-git-send-email-thomas.monjalon@6wind.com> Cc: dev@dpdk.org, viktorin@rehivetech.com Subject: [dpdk-dev] [PATCH v2 2/5] eal: move CPU flag functions out of headers X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 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 --- MAINTAINERS | 4 + app/test/test_hash_scaling.c | 2 + lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 - lib/librte_eal/common/arch/arm/rte_cpuflags.c | 125 ++++++++++++++++++--- lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c | 79 +++++++++++++ lib/librte_eal/common/arch/tile/rte_cpuflags.c | 11 ++ lib/librte_eal/common/arch/x86/rte_cpuflags.c | 83 ++++++++++++++ lib/librte_eal/common/eal_common_cpuflags.c | 3 + .../common/include/arch/arm/rte_cpuflags_32.h | 80 +------------ .../common/include/arch/arm/rte_cpuflags_64.h | 81 +------------ .../common/include/arch/ppc_64/rte_cpuflags.h | 66 +---------- .../common/include/arch/tile/rte_cpuflags.h | 31 +---- .../common/include/arch/x86/rte_cpuflags.h | 68 +---------- .../common/include/generic/rte_cpuflags.h | 50 +-------- lib/librte_eal/linuxapp/eal/rte_eal_version.map | 1 - 15 files changed, 300 insertions(+), 385 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index b90aeea..628bc05 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 744e5e3..1c4c75d 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 9bea0e2..1a96203 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 62e0791..cd7a7b1 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 a270ccc..b7e0b72 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 4ca0a7b..a2b6c51 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 3346fde..0138257 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 8c0576d..a4c5a29 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 2ec0c2e..eb02d9b 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 b36040b..810e8a0 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 85c4c1a..7cc2b3c 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 a415857..1849b52 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 120ea24..26204fa 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 3ca2e36..c1da357 100644 --- a/lib/librte_eal/common/include/generic/rte_cpuflags.h +++ b/lib/librte_eal/common/include/generic/rte_cpuflags.h @@ -39,10 +39,7 @@ * Architecture specific API to determine available CPU features at runtime. */ -#include -#include #include -#include /** * Enumeration of all CPU features supported @@ -50,49 +47,6 @@ 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 * * @param feature @@ -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 48e8e4f..440fac2 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;