All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 0/5] clean-up cpuflags
@ 2016-02-02 22:59 Thomas Monjalon
  2016-02-02 22:59 ` [PATCH v1 1/5] eal: get CPU flag name Thomas Monjalon
                   ` (7 more replies)
  0 siblings, 8 replies; 19+ messages in thread
From: Thomas Monjalon @ 2016-02-02 22:59 UTC (permalink / raw)
  To: david.marchand, ferruh.yigit; +Cc: dev, viktorin

Following the work of Ferruh, I suggest this cleanup to remove as much
as possible of the code from the cpuflags headers.
The goal is to un-inline these functions (not performance sensitive)
and remove the CPU flags table from the ABI (just added recently).
The bonus is to stop mimic x86 in ARM and PPC implementations.

WARNING: it has not been tested nor compiled on Tilera, ARM and POWER8.
Please help, thank you.

Thomas Monjalon (5):
  eal: get CPU flag name
  eal: move CPU flag functions out of headers
  eal/arm: adapt CPU flags check to the arch
  eal/ppc: adapt CPU flags check to the arch
  eal: remove compiler optimization workaround

 app/test/test_hash_scaling.c                       |   2 +
 lib/librte_eal/bsdapp/eal/rte_eal_version.map      |   2 +-
 lib/librte_eal/common/arch/arm/rte_cpuflags.c      | 170 ++++++++++++++++-----
 lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c   | 145 +++++++++++++-----
 lib/librte_eal/common/arch/tile/rte_cpuflags.c     |  11 ++
 lib/librte_eal/common/arch/x86/rte_cpuflags.c      |  91 +++++++++++
 lib/librte_eal/common/eal_common_cpuflags.c        |  18 +--
 .../common/include/arch/arm/rte_cpuflags_32.h      |  78 ----------
 .../common/include/arch/arm/rte_cpuflags_64.h      |  79 ----------
 .../common/include/arch/ppc_64/rte_cpuflags.h      |  64 --------
 .../common/include/arch/tile/rte_cpuflags.h        |  29 ----
 .../common/include/arch/x86/rte_cpuflags.h         |  66 --------
 .../common/include/generic/rte_cpuflags.h          |  56 ++-----
 lib/librte_eal/linuxapp/eal/rte_eal_version.map    |   3 +-
 14 files changed, 364 insertions(+), 450 deletions(-)

-- 
2.5.2

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v1 1/5] eal: get CPU flag name
  2016-02-02 22:59 [PATCH v1 0/5] clean-up cpuflags Thomas Monjalon
@ 2016-02-02 22:59 ` Thomas Monjalon
  2016-02-02 23:10 ` [PATCH v1 2/5] eal: move CPU flag functions out of headers Thomas Monjalon
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 19+ messages in thread
From: Thomas Monjalon @ 2016-02-02 22:59 UTC (permalink / raw)
  To: david.marchand, ferruh.yigit; +Cc: dev, viktorin

The new function rte_cpu_get_flag_name() is added to the EAL API.
It is implemented (duplicated) in each arch because the next patch
will remove the public exposure of the feature tables.

Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 lib/librte_eal/bsdapp/eal/rte_eal_version.map        |  1 +
 lib/librte_eal/common/arch/arm/rte_cpuflags.c        |  7 +++++++
 lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c     |  8 ++++++++
 lib/librte_eal/common/arch/x86/rte_cpuflags.c        |  8 ++++++++
 lib/librte_eal/common/eal_common_cpuflags.c          |  2 +-
 lib/librte_eal/common/include/generic/rte_cpuflags.h | 14 ++++++++++++--
 lib/librte_eal/linuxapp/eal/rte_eal_version.map      |  2 ++
 7 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 6fa9c67..1280cb2 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -140,5 +140,6 @@ DPDK_2.3 {
 	global:
 
 	rte_cpu_feature_table;
+	rte_cpu_get_flag_name;
 
 } 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 4348574..62e0791 100644
--- a/lib/librte_eal/common/arch/arm/rte_cpuflags.c
+++ b/lib/librte_eal/common/arch/arm/rte_cpuflags.c
@@ -77,3 +77,10 @@ const struct feature_entry rte_cpu_feature_table[] = {
 };
 #endif
 
+const char *
+rte_cpu_get_flag_name(enum rte_cpu_flag_t feature)
+{
+	if (feature >= RTE_CPUFLAG_NUMFLAGS)
+		return NULL;
+	return rte_cpu_feature_table[feature].name;
+}
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 7f4e6dd..a270ccc 100644
--- a/lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c
+++ b/lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c
@@ -68,3 +68,11 @@ const struct feature_entry rte_cpu_feature_table[] = {
 	FEAT_DEF(HTM, 0x00000001, 0, REG_HWCAP2,  30)
 	FEAT_DEF(ARCH_2_07, 0x00000001, 0, REG_HWCAP2,  31)
 };
+
+const char *
+rte_cpu_get_flag_name(enum rte_cpu_flag_t feature)
+{
+	if (feature >= RTE_CPUFLAG_NUMFLAGS)
+		return NULL;
+	return rte_cpu_feature_table[feature].name;
+}
diff --git a/lib/librte_eal/common/arch/x86/rte_cpuflags.c b/lib/librte_eal/common/arch/x86/rte_cpuflags.c
index 22dc572..3346fde 100644
--- a/lib/librte_eal/common/arch/x86/rte_cpuflags.c
+++ b/lib/librte_eal/common/arch/x86/rte_cpuflags.c
@@ -127,3 +127,11 @@ const struct feature_entry rte_cpu_feature_table[] = {
 
 	FEAT_DEF(INVTSC, 0x80000007, 0, RTE_REG_EDX,  8)
 };
+
+const char *
+rte_cpu_get_flag_name(enum rte_cpu_flag_t feature)
+{
+	if (feature >= RTE_CPUFLAG_NUMFLAGS)
+		return NULL;
+	return rte_cpu_feature_table[feature].name;
+}
diff --git a/lib/librte_eal/common/eal_common_cpuflags.c b/lib/librte_eal/common/eal_common_cpuflags.c
index 9ba9b1e..8c0576d 100644
--- a/lib/librte_eal/common/eal_common_cpuflags.c
+++ b/lib/librte_eal/common/eal_common_cpuflags.c
@@ -79,7 +79,7 @@ rte_cpu_check_supported(void)
 			fprintf(stderr,
 			        "ERROR: This system does not support \"%s\".\n"
 			        "Please check that RTE_MACHINE is set correctly.\n",
-			        rte_cpu_feature_table[compile_time_flags[i]].name);
+			        rte_cpu_get_flag_name(compile_time_flags[i]));
 			exit(1);
 		}
 	}
diff --git a/lib/librte_eal/common/include/generic/rte_cpuflags.h b/lib/librte_eal/common/include/generic/rte_cpuflags.h
index 5738a2a..3ca2e36 100644
--- a/lib/librte_eal/common/include/generic/rte_cpuflags.h
+++ b/lib/librte_eal/common/include/generic/rte_cpuflags.h
@@ -47,9 +47,7 @@
 /**
  * Enumeration of all CPU features supported
  */
-#ifdef __DOXYGEN__
 enum rte_cpu_flag_t;
-#endif
 
 /**
  * Enumeration of CPU registers
@@ -95,6 +93,18 @@ static inline void
 rte_cpu_get_features(uint32_t leaf, uint32_t subleaf, cpuid_registers_t out);
 
 /**
+ * Get name of CPU flag
+ *
+ * @param feature
+ *     CPU flag ID
+ * @return
+ *     flag name
+ *     NULL if flag ID is invalid
+ */
+const char *
+rte_cpu_get_flag_name(enum rte_cpu_flag_t feature);
+
+/**
  * Function for checking a CPU flag availability
  *
  * @param feature
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index aa4fcbd..d8a5978 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -143,4 +143,6 @@ DPDK_2.3 {
 	global:
 
 	rte_cpu_feature_table;
+	rte_cpu_get_flag_name;
+
 } DPDK_2.2;
-- 
2.5.2

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v1 2/5] eal: move CPU flag functions out of headers
  2016-02-02 22:59 [PATCH v1 0/5] clean-up cpuflags Thomas Monjalon
  2016-02-02 22:59 ` [PATCH v1 1/5] eal: get CPU flag name Thomas Monjalon
@ 2016-02-02 23:10 ` Thomas Monjalon
  2016-02-02 23:10 ` [PATCH v1 3/5] eal/arm: adapt CPU flags check to the arch Thomas Monjalon
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 19+ messages in thread
From: Thomas Monjalon @ 2016-02-02 23:10 UTC (permalink / raw)
  To: david.marchand, ferruh.yigit; +Cc: dev, viktorin

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 <thomas.monjalon@6wind.com>
---
 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      | 99 ++++++++++++++++++++++
 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      | 78 -----------------
 .../common/include/arch/arm/rte_cpuflags_64.h      | 79 -----------------
 .../common/include/arch/ppc_64/rte_cpuflags.h      | 64 --------------
 .../common/include/arch/tile/rte_cpuflags.h        | 29 -------
 .../common/include/arch/x86/rte_cpuflags.h         | 66 ---------------
 .../common/include/generic/rte_cpuflags.h          | 50 +----------
 lib/librte_eal/linuxapp/eal/rte_eal_version.map    |  1 -
 14 files changed, 278 insertions(+), 367 deletions(-)

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 <stdio.h>
+
 #include <rte_cycles.h>
 #include <rte_hash.h>
 #include <rte_hash_crc.h>
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 1280cb2..f0aa698 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -139,7 +139,6 @@ DPDK_2.2 {
 DPDK_2.3 {
 	global:
 
-	rte_cpu_feature_table;
 	rte_cpu_get_flag_name;
 
 } 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..664f527 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,6 +33,46 @@
 
 #include "rte_cpuflags.h"
 
+#include <elf.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <unistd.h>
+#include <string.h>
+
+#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,
+};
+
+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 },
+
 #ifdef RTE_ARCH_64
 const struct feature_entry rte_cpu_feature_table[] = {
 	FEAT_DEF(FP,		0x00000001, 0, REG_HWCAP,  0)
@@ -77,6 +118,64 @@ const struct feature_entry rte_cpu_feature_table[] = {
 };
 #endif
 
+/*
+ * 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;
+#ifdef RTE_ARCH_64
+	Elf64_auxv_t auxv;
+#else
+	Elf32_auxv_t auxv;
+#endif
+
+	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) {
+#ifdef RTE_ARCH_64
+			if (!strcmp((const char *)auxv.a_un.a_val, "aarch64"))
+#else
+			if (!strcmp((const char *)auxv.a_un.a_val, "v7l"))
+#endif
+				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 <elf.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <unistd.h>
+
+/* 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 <errno.h>
+
 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 <stdio.h>
+#include <errno.h>
+#include <stdint.h>
+
+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 <stdio.h>
+
 #include <rte_common.h>
 #include <rte_cpuflags.h>
 
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..373fd46 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,8 @@
 extern "C" {
 #endif
 
-#include <elf.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <unistd.h>
-#include <string.h>
-
 #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,57 +75,6 @@ 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;
-}
-
 #ifdef __cplusplus
 }
 #endif
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..4cf4759 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,8 @@
 extern "C" {
 #endif
 
-#include <elf.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <unistd.h>
-#include <string.h>
-
 #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,58 +56,6 @@ 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;
-}
-
 #ifdef __cplusplus
 }
 #endif
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..04d4c27 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,8 @@
 extern "C" {
 #endif
 
-#include <elf.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <unistd.h>
-
 #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,53 +81,6 @@ 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;
-}
-
 #ifdef __cplusplus
 }
 #endif
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..994884b 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,8 @@
 extern "C" {
 #endif
 
-#include <elf.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <unistd.h>
-
 #include "generic/rte_cpuflags.h"
 
-/* software based registers */
-enum cpu_register_t {
-	REG_DUMMY = 0
-};
-
 /**
  * Enumeration of all CPU features supported
  */
@@ -56,25 +46,6 @@ 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;
-}
-
 #ifdef __cplusplus
 }
 #endif
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..117fed2 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,8 @@
 extern "C" {
 #endif
 
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <stdint.h>
-
 #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,65 +146,6 @@ 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;
-}
-
 #ifdef __cplusplus
 }
 #endif
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 <stdlib.h>
-#include <stdio.h>
 #include <errno.h>
-#include <stdint.h>
 
 /**
  * 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 d8a5978..b06825a 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -142,7 +142,6 @@ DPDK_2.2 {
 DPDK_2.3 {
 	global:
 
-	rte_cpu_feature_table;
 	rte_cpu_get_flag_name;
 
 } DPDK_2.2;
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v1 3/5] eal/arm: adapt CPU flags check to the arch
  2016-02-02 22:59 [PATCH v1 0/5] clean-up cpuflags Thomas Monjalon
  2016-02-02 22:59 ` [PATCH v1 1/5] eal: get CPU flag name Thomas Monjalon
  2016-02-02 23:10 ` [PATCH v1 2/5] eal: move CPU flag functions out of headers Thomas Monjalon
@ 2016-02-02 23:10 ` Thomas Monjalon
  2016-02-02 23:10 ` [PATCH v1 4/5] eal/ppc: " Thomas Monjalon
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 19+ messages in thread
From: Thomas Monjalon @ 2016-02-02 23:10 UTC (permalink / raw)
  To: david.marchand, ferruh.yigit; +Cc: dev, viktorin

The structure feature_entry does not need leaf/subleaf
which were copied from x86 CPUID implementation.

On x86, a valid flag is detected with the non-zero leaf value.
This check is replaced by a check with a dummy "none" register.

Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 lib/librte_eal/common/arch/arm/rte_cpuflags.c | 110 ++++++++++++--------------
 1 file changed, 50 insertions(+), 60 deletions(-)

diff --git a/lib/librte_eal/common/arch/arm/rte_cpuflags.c b/lib/librte_eal/common/arch/arm/rte_cpuflags.c
index 664f527..fba0a61 100644
--- a/lib/librte_eal/common/arch/arm/rte_cpuflags.c
+++ b/lib/librte_eal/common/arch/arm/rte_cpuflags.c
@@ -52,69 +52,66 @@
 #endif
 
 enum cpu_register_t {
-	REG_HWCAP = 0,
+	REG_NONE = 0,
+	REG_HWCAP,
 	REG_HWCAP2,
+	REG_MAX
 };
 
-typedef uint32_t cpuid_registers_t[4];
+typedef uint32_t hwcap_registers_t[REG_MAX];
 
-/**
- * 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 */
+	uint32_t reg;
+	uint32_t bit;
 #define CPU_FLAG_NAME_MAX_LEN 64
-	char name[CPU_FLAG_NAME_MAX_LEN];       /**< String for printing */
+	char name[CPU_FLAG_NAME_MAX_LEN];
 };
 
-#define FEAT_DEF(name, leaf, subleaf, reg, bit) \
-	[RTE_CPUFLAG_##name] = {leaf, subleaf, reg, bit, #name },
+#define FEAT_DEF(name, reg, bit) \
+	[RTE_CPUFLAG_##name] = {reg, bit, #name},
 
 #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)
+	FEAT_DEF(FP,		REG_HWCAP,    0)
+	FEAT_DEF(NEON,		REG_HWCAP,    1)
+	FEAT_DEF(EVTSTRM,	REG_HWCAP,    2)
+	FEAT_DEF(AES,		REG_HWCAP,    3)
+	FEAT_DEF(PMULL,		REG_HWCAP,    4)
+	FEAT_DEF(SHA1,		REG_HWCAP,    5)
+	FEAT_DEF(SHA2,		REG_HWCAP,    6)
+	FEAT_DEF(CRC32,		REG_HWCAP,    7)
+	FEAT_DEF(AARCH64,	REG_PLATFORM, 1)
 };
 #else
 const struct feature_entry rte_cpu_feature_table[] = {
-	FEAT_DEF(SWP,       0x00000001, 0, REG_HWCAP,  0)
-	FEAT_DEF(HALF,      0x00000001, 0, REG_HWCAP,  1)
-	FEAT_DEF(THUMB,     0x00000001, 0, REG_HWCAP,  2)
-	FEAT_DEF(A26BIT,    0x00000001, 0, REG_HWCAP,  3)
-	FEAT_DEF(FAST_MULT, 0x00000001, 0, REG_HWCAP,  4)
-	FEAT_DEF(FPA,       0x00000001, 0, REG_HWCAP,  5)
-	FEAT_DEF(VFP,       0x00000001, 0, REG_HWCAP,  6)
-	FEAT_DEF(EDSP,      0x00000001, 0, REG_HWCAP,  7)
-	FEAT_DEF(JAVA,      0x00000001, 0, REG_HWCAP,  8)
-	FEAT_DEF(IWMMXT,    0x00000001, 0, REG_HWCAP,  9)
-	FEAT_DEF(CRUNCH,    0x00000001, 0, REG_HWCAP,  10)
-	FEAT_DEF(THUMBEE,   0x00000001, 0, REG_HWCAP,  11)
-	FEAT_DEF(NEON,      0x00000001, 0, REG_HWCAP,  12)
-	FEAT_DEF(VFPv3,     0x00000001, 0, REG_HWCAP,  13)
-	FEAT_DEF(VFPv3D16,  0x00000001, 0, REG_HWCAP,  14)
-	FEAT_DEF(TLS,       0x00000001, 0, REG_HWCAP,  15)
-	FEAT_DEF(VFPv4,     0x00000001, 0, REG_HWCAP,  16)
-	FEAT_DEF(IDIVA,     0x00000001, 0, REG_HWCAP,  17)
-	FEAT_DEF(IDIVT,     0x00000001, 0, REG_HWCAP,  18)
-	FEAT_DEF(VFPD32,    0x00000001, 0, REG_HWCAP,  19)
-	FEAT_DEF(LPAE,      0x00000001, 0, REG_HWCAP,  20)
-	FEAT_DEF(EVTSTRM,   0x00000001, 0, REG_HWCAP,  21)
-	FEAT_DEF(AES,       0x00000001, 0, REG_HWCAP2,  0)
-	FEAT_DEF(PMULL,     0x00000001, 0, REG_HWCAP2,  1)
-	FEAT_DEF(SHA1,      0x00000001, 0, REG_HWCAP2,  2)
-	FEAT_DEF(SHA2,      0x00000001, 0, REG_HWCAP2,  3)
-	FEAT_DEF(CRC32,     0x00000001, 0, REG_HWCAP2,  4)
-	FEAT_DEF(V7L,       0x00000001, 0, REG_PLATFORM, 0)
+	FEAT_DEF(SWP,       REG_HWCAP,    0)
+	FEAT_DEF(HALF,      REG_HWCAP,    1)
+	FEAT_DEF(THUMB,     REG_HWCAP,    2)
+	FEAT_DEF(A26BIT,    REG_HWCAP,    3)
+	FEAT_DEF(FAST_MULT, REG_HWCAP,    4)
+	FEAT_DEF(FPA,       REG_HWCAP,    5)
+	FEAT_DEF(VFP,       REG_HWCAP,    6)
+	FEAT_DEF(EDSP,      REG_HWCAP,    7)
+	FEAT_DEF(JAVA,      REG_HWCAP,    8)
+	FEAT_DEF(IWMMXT,    REG_HWCAP,    9)
+	FEAT_DEF(CRUNCH,    REG_HWCAP,   10)
+	FEAT_DEF(THUMBEE,   REG_HWCAP,   11)
+	FEAT_DEF(NEON,      REG_HWCAP,   12)
+	FEAT_DEF(VFPv3,     REG_HWCAP,   13)
+	FEAT_DEF(VFPv3D16,  REG_HWCAP,   14)
+	FEAT_DEF(TLS,       REG_HWCAP,   15)
+	FEAT_DEF(VFPv4,     REG_HWCAP,   16)
+	FEAT_DEF(IDIVA,     REG_HWCAP,   17)
+	FEAT_DEF(IDIVT,     REG_HWCAP,   18)
+	FEAT_DEF(VFPD32,    REG_HWCAP,   19)
+	FEAT_DEF(LPAE,      REG_HWCAP,   20)
+	FEAT_DEF(EVTSTRM,   REG_HWCAP,   21)
+	FEAT_DEF(AES,       REG_HWCAP2,   0)
+	FEAT_DEF(PMULL,     REG_HWCAP2,   1)
+	FEAT_DEF(SHA1,      REG_HWCAP2,   2)
+	FEAT_DEF(SHA2,      REG_HWCAP2,   3)
+	FEAT_DEF(CRC32,     REG_HWCAP2,   4)
+	FEAT_DEF(V7L,       REG_PLATFORM, 0)
 };
 #endif
 
@@ -122,8 +119,7 @@ const struct feature_entry rte_cpu_feature_table[] = {
  * 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)
+rte_cpu_get_features(hwcap_registers_t out)
 {
 	int auxv_fd;
 #ifdef RTE_ARCH_64
@@ -157,22 +153,16 @@ int
 rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature)
 {
 	const struct feature_entry *feat;
-	cpuid_registers_t regs = {0};
+	hwcap_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! */
+	if (feat->reg == REG_NONE)
 		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 */
+	rte_cpu_get_features(regs);
 	return (regs[feat->reg] >> feat->bit) & 1;
 }
 
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v1 4/5] eal/ppc: adapt CPU flags check to the arch
  2016-02-02 22:59 [PATCH v1 0/5] clean-up cpuflags Thomas Monjalon
                   ` (2 preceding siblings ...)
  2016-02-02 23:10 ` [PATCH v1 3/5] eal/arm: adapt CPU flags check to the arch Thomas Monjalon
@ 2016-02-02 23:10 ` Thomas Monjalon
  2016-02-02 23:10 ` [PATCH v1 5/5] eal: remove compiler optimization workaround Thomas Monjalon
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 19+ messages in thread
From: Thomas Monjalon @ 2016-02-02 23:10 UTC (permalink / raw)
  To: david.marchand, ferruh.yigit; +Cc: dev, viktorin

The structure feature_entry does not need leaf/subleaf
which were copied from x86 CPUID implementation.

On x86, a valid flag is detected with the non-zero leaf value.
This check is replaced by a check with a dummy "none" register.

Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c | 104 ++++++++++-------------
 1 file changed, 47 insertions(+), 57 deletions(-)

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 b7e0b72..a8147c8 100644
--- a/lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c
+++ b/lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c
@@ -43,70 +43,66 @@
 
 /* software based registers */
 enum cpu_register_t {
-	REG_HWCAP = 0,
+	REG_NONE = 0,
+	REG_HWCAP,
 	REG_HWCAP2,
+	REG_MAX
 };
 
-typedef uint32_t cpuid_registers_t[4];
+typedef uint32_t hwcap_registers_t[REG_MAX];
 
-/**
- * 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 */
+	uint32_t reg;
+	uint32_t bit;
 #define CPU_FLAG_NAME_MAX_LEN 64
-	char name[CPU_FLAG_NAME_MAX_LEN];       /**< String for printing */
+	char name[CPU_FLAG_NAME_MAX_LEN];
 };
 
-#define FEAT_DEF(name, leaf, subleaf, reg, bit) \
-	[RTE_CPUFLAG_##name] = {leaf, subleaf, reg, bit, #name },
+#define FEAT_DEF(name, reg, bit) \
+	[RTE_CPUFLAG_##name] = {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)
-	FEAT_DEF(PSERIES_PERFMON_COMPAT, 0x00000001, 0, REG_HWCAP,  6)
-	FEAT_DEF(VSX, 0x00000001, 0, REG_HWCAP,  7)
-	FEAT_DEF(ARCH_2_06, 0x00000001, 0, REG_HWCAP,  8)
-	FEAT_DEF(POWER6_EXT, 0x00000001, 0, REG_HWCAP,  9)
-	FEAT_DEF(DFP, 0x00000001, 0, REG_HWCAP,  10)
-	FEAT_DEF(PA6T, 0x00000001, 0, REG_HWCAP,  11)
-	FEAT_DEF(ARCH_2_05, 0x00000001, 0, REG_HWCAP,  12)
-	FEAT_DEF(ICACHE_SNOOP, 0x00000001, 0, REG_HWCAP,  13)
-	FEAT_DEF(SMT, 0x00000001, 0, REG_HWCAP,  14)
-	FEAT_DEF(BOOKE, 0x00000001, 0, REG_HWCAP,  15)
-	FEAT_DEF(CELLBE, 0x00000001, 0, REG_HWCAP,  16)
-	FEAT_DEF(POWER5_PLUS, 0x00000001, 0, REG_HWCAP,  17)
-	FEAT_DEF(POWER5, 0x00000001, 0, REG_HWCAP,  18)
-	FEAT_DEF(POWER4, 0x00000001, 0, REG_HWCAP,  19)
-	FEAT_DEF(NOTB, 0x00000001, 0, REG_HWCAP,  20)
-	FEAT_DEF(EFP_DOUBLE, 0x00000001, 0, REG_HWCAP,  21)
-	FEAT_DEF(EFP_SINGLE, 0x00000001, 0, REG_HWCAP,  22)
-	FEAT_DEF(SPE, 0x00000001, 0, REG_HWCAP,  23)
-	FEAT_DEF(UNIFIED_CACHE, 0x00000001, 0, REG_HWCAP,  24)
-	FEAT_DEF(4xxMAC, 0x00000001, 0, REG_HWCAP,  25)
-	FEAT_DEF(MMU, 0x00000001, 0, REG_HWCAP,  26)
-	FEAT_DEF(FPU, 0x00000001, 0, REG_HWCAP,  27)
-	FEAT_DEF(ALTIVEC, 0x00000001, 0, REG_HWCAP,  28)
-	FEAT_DEF(PPC601, 0x00000001, 0, REG_HWCAP,  29)
-	FEAT_DEF(PPC64, 0x00000001, 0, REG_HWCAP,  30)
-	FEAT_DEF(PPC32, 0x00000001, 0, REG_HWCAP,  31)
-	FEAT_DEF(TAR, 0x00000001, 0, REG_HWCAP2,  26)
-	FEAT_DEF(LSEL, 0x00000001, 0, REG_HWCAP2,  27)
-	FEAT_DEF(EBB, 0x00000001, 0, REG_HWCAP2,  28)
-	FEAT_DEF(DSCR, 0x00000001, 0, REG_HWCAP2,  29)
-	FEAT_DEF(HTM, 0x00000001, 0, REG_HWCAP2,  30)
-	FEAT_DEF(ARCH_2_07, 0x00000001, 0, REG_HWCAP2,  31)
+	FEAT_DEF(PPC_LE,                 REG_HWCAP,   0)
+	FEAT_DEF(TRUE_LE,                REG_HWCAP,   1)
+	FEAT_DEF(PSERIES_PERFMON_COMPAT, REG_HWCAP,   6)
+	FEAT_DEF(VSX,                    REG_HWCAP,   7)
+	FEAT_DEF(ARCH_2_06,              REG_HWCAP,   8)
+	FEAT_DEF(POWER6_EXT,             REG_HWCAP,   9)
+	FEAT_DEF(DFP,                    REG_HWCAP,  10)
+	FEAT_DEF(PA6T,                   REG_HWCAP,  11)
+	FEAT_DEF(ARCH_2_05,              REG_HWCAP,  12)
+	FEAT_DEF(ICACHE_SNOOP,           REG_HWCAP,  13)
+	FEAT_DEF(SMT,                    REG_HWCAP,  14)
+	FEAT_DEF(BOOKE,                  REG_HWCAP,  15)
+	FEAT_DEF(CELLBE,                 REG_HWCAP,  16)
+	FEAT_DEF(POWER5_PLUS,            REG_HWCAP,  17)
+	FEAT_DEF(POWER5,                 REG_HWCAP,  18)
+	FEAT_DEF(POWER4,                 REG_HWCAP,  19)
+	FEAT_DEF(NOTB,                   REG_HWCAP,  20)
+	FEAT_DEF(EFP_DOUBLE,             REG_HWCAP,  21)
+	FEAT_DEF(EFP_SINGLE,             REG_HWCAP,  22)
+	FEAT_DEF(SPE,                    REG_HWCAP,  23)
+	FEAT_DEF(UNIFIED_CACHE,          REG_HWCAP,  24)
+	FEAT_DEF(4xxMAC,                 REG_HWCAP,  25)
+	FEAT_DEF(MMU,                    REG_HWCAP,  26)
+	FEAT_DEF(FPU,                    REG_HWCAP,  27)
+	FEAT_DEF(ALTIVEC,                REG_HWCAP,  28)
+	FEAT_DEF(PPC601,                 REG_HWCAP,  29)
+	FEAT_DEF(PPC64,                  REG_HWCAP,  30)
+	FEAT_DEF(PPC32,                  REG_HWCAP,  31)
+	FEAT_DEF(TAR,                    REG_HWCAP2, 26)
+	FEAT_DEF(LSEL,                   REG_HWCAP2, 27)
+	FEAT_DEF(EBB,                    REG_HWCAP2, 28)
+	FEAT_DEF(DSCR,                   REG_HWCAP2, 29)
+	FEAT_DEF(HTM,                    REG_HWCAP2, 30)
+	FEAT_DEF(ARCH_2_07,              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)
+rte_cpu_get_features(hwcap_registers_t out)
 {
 	int auxv_fd;
 	Elf64_auxv_t auxv;
@@ -129,22 +125,16 @@ int
 rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature)
 {
 	const struct feature_entry *feat;
-	cpuid_registers_t regs = {0};
+	hwcap_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! */
+	if (feat->reg == REG_NONE)
 		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 */
+	rte_cpu_get_features(regs);
 	return (regs[feat->reg] >> feat->bit) & 1;
 }
 
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v1 5/5] eal: remove compiler optimization workaround
  2016-02-02 22:59 [PATCH v1 0/5] clean-up cpuflags Thomas Monjalon
                   ` (3 preceding siblings ...)
  2016-02-02 23:10 ` [PATCH v1 4/5] eal/ppc: " Thomas Monjalon
@ 2016-02-02 23:10 ` Thomas Monjalon
  2016-02-02 23:51 ` [PATCH v1 0/5] clean-up cpuflags Jan Viktorin
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 19+ messages in thread
From: Thomas Monjalon @ 2016-02-02 23:10 UTC (permalink / raw)
  To: david.marchand, ferruh.yigit; +Cc: dev, viktorin

The compiler optimization was disabled a long time ago
without describing what was the exact issue.
Maybe it does not apply anymore.
As it looks unneeded, let's remove this strange pragma.

Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 lib/librte_eal/common/eal_common_cpuflags.c | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_cpuflags.c b/lib/librte_eal/common/eal_common_cpuflags.c
index a4c5a29..ecb1240 100644
--- a/lib/librte_eal/common/eal_common_cpuflags.c
+++ b/lib/librte_eal/common/eal_common_cpuflags.c
@@ -36,19 +36,6 @@
 #include <rte_common.h>
 #include <rte_cpuflags.h>
 
-/*
- * This should prevent use of advanced instruction sets in this file. Otherwise
- * the check function itself could cause a crash.
- */
-#ifdef __INTEL_COMPILER
-#pragma optimize ("", off)
-#else
-#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
-#if GCC_VERSION > 404000
-#pragma GCC optimize ("O0")
-#endif
-#endif
-
 /**
  * Checks if the machine is adequate for running the binary. If it is not, the
  * program exits with status 1.
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v1 0/5] clean-up cpuflags
  2016-02-02 22:59 [PATCH v1 0/5] clean-up cpuflags Thomas Monjalon
                   ` (4 preceding siblings ...)
  2016-02-02 23:10 ` [PATCH v1 5/5] eal: remove compiler optimization workaround Thomas Monjalon
@ 2016-02-02 23:51 ` Jan Viktorin
  2016-02-03 13:38 ` Jerin Jacob
  2016-02-06 22:17 ` [PATCH v2 " Thomas Monjalon
  7 siblings, 0 replies; 19+ messages in thread
From: Jan Viktorin @ 2016-02-02 23:51 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev

Hello Thomas,

the patch set fails when compiling for ARMv7 with the following (full
build.log is attached):

/var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/lib/librte_eal/common/arch/arm/rte_cpuflags.c:114:22: error: ‘REG_PLATFORM’ undeclared here (not in a function)
  FEAT_DEF(V7L,       REG_PLATFORM, 0)
                      ^
/var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/lib/librte_eal/common/arch/arm/rte_cpuflags.c:71:26: note: in definition of macro ‘FEAT_DEF’
  [RTE_CPUFLAG_##name] = {reg, bit, #name},
                          ^
/var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/lib/librte_eal/common/arch/arm/rte_cpuflags.c: In function ‘rte_cpu_get_features’:
/var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/lib/librte_eal/common/arch/arm/rte_cpuflags.c:144:8: error: array subscript is not an integer
     out[REG_PLATFORM] = 0x0001;
        ^
/var/lib/jenkins/jobs/dpdk-armv7-testing/workspace/lib/librte_eal/common/arch/arm/rte_cpuflags.c:144:5: error: statement with no effect [-Werror=unused-value]
     out[REG_PLATFORM] = 0x0001;
     ^   
cc1: all warnings being treated as errors

Regards
Jan

On Tue,  2 Feb 2016 23:59:48 +0100
Thomas Monjalon <thomas.monjalon@6wind.com> wrote:

> Following the work of Ferruh, I suggest this cleanup to remove as much
> as possible of the code from the cpuflags headers.
> The goal is to un-inline these functions (not performance sensitive)
> and remove the CPU flags table from the ABI (just added recently).
> The bonus is to stop mimic x86 in ARM and PPC implementations.
> 
> WARNING: it has not been tested nor compiled on Tilera, ARM and POWER8.
> Please help, thank you.
> 
> Thomas Monjalon (5):
>   eal: get CPU flag name
>   eal: move CPU flag functions out of headers
>   eal/arm: adapt CPU flags check to the arch
>   eal/ppc: adapt CPU flags check to the arch
>   eal: remove compiler optimization workaround
> 
>  app/test/test_hash_scaling.c                       |   2 +
>  lib/librte_eal/bsdapp/eal/rte_eal_version.map      |   2 +-
>  lib/librte_eal/common/arch/arm/rte_cpuflags.c      | 170 ++++++++++++++++-----
>  lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c   | 145 +++++++++++++-----
>  lib/librte_eal/common/arch/tile/rte_cpuflags.c     |  11 ++
>  lib/librte_eal/common/arch/x86/rte_cpuflags.c      |  91 +++++++++++
>  lib/librte_eal/common/eal_common_cpuflags.c        |  18 +--
>  .../common/include/arch/arm/rte_cpuflags_32.h      |  78 ----------
>  .../common/include/arch/arm/rte_cpuflags_64.h      |  79 ----------
>  .../common/include/arch/ppc_64/rte_cpuflags.h      |  64 --------
>  .../common/include/arch/tile/rte_cpuflags.h        |  29 ----
>  .../common/include/arch/x86/rte_cpuflags.h         |  66 --------
>  .../common/include/generic/rte_cpuflags.h          |  56 ++-----
>  lib/librte_eal/linuxapp/eal/rte_eal_version.map    |   3 +-
>  14 files changed, 364 insertions(+), 450 deletions(-)
> 



-- 
  Jan Viktorin                E-mail: Viktorin@RehiveTech.com
  System Architect            Web:    www.RehiveTech.com
  RehiveTech
  Brno, Czech Republic

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v1 0/5] clean-up cpuflags
  2016-02-02 22:59 [PATCH v1 0/5] clean-up cpuflags Thomas Monjalon
                   ` (5 preceding siblings ...)
  2016-02-02 23:51 ` [PATCH v1 0/5] clean-up cpuflags Jan Viktorin
@ 2016-02-03 13:38 ` Jerin Jacob
  2016-02-03 14:01   ` Thomas Monjalon
  2016-02-06 22:17 ` [PATCH v2 " Thomas Monjalon
  7 siblings, 1 reply; 19+ messages in thread
From: Jerin Jacob @ 2016-02-03 13:38 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, viktorin

On Tue, Feb 02, 2016 at 11:59:48PM +0100, Thomas Monjalon wrote:
> Following the work of Ferruh, I suggest this cleanup to remove as much
> as possible of the code from the cpuflags headers.
> The goal is to un-inline these functions (not performance sensitive)
> and remove the CPU flags table from the ABI (just added recently).
> The bonus is to stop mimic x86 in ARM and PPC implementations.
> 
> WARNING: it has not been tested nor compiled on Tilera, ARM and POWER8.
> Please help, thank you.

compilation errors on arm64 too.

arm64 toolchains are publicly available @
http://releases.linaro.org/14.11/components/toolchain/binaries/aarch64-linux-gnu/

➜ [master] thunderx  [dpdk-master] $ make
== Build lib
== Build lib/librte_compat
== Build lib/librte_eal
== Build lib/librte_eal/common
== Build lib/librte_eal/linuxapp
== Build lib/librte_eal/linuxapp/igb_uio
(cat /dev/null;   echo
kernel//home/jerin/dpdk-master/build/build/lib/librte_eal/linuxapp/igb_uio/igb_uio.ko;)
> /home/jerin/dpdk-master/build/build/lib/librte_eal/linuxapp/igb_uio/modules.order
  Building modules, stage 2.
  MODPOST 1 modules
== Build lib/librte_eal/linuxapp/eal
  CC rte_cpuflags.o
/home/jerin/dpdk-master/lib/librte_eal/common/arch/arm/rte_cpuflags.c:83:20:
error: ‘REG_PLATFORM’ undeclared here (not in a function)
  FEAT_DEF(AARCH64, REG_PLATFORM, 1)
                    ^
/home/jerin/dpdk-master/lib/librte_eal/common/arch/arm/rte_cpuflags.c:71:26:
note: in definition of macro ‘FEAT_DEF’
  [RTE_CPUFLAG_##name] = {reg, bit, #name},
                          ^
/home/jerin/dpdk-master/lib/librte_eal/common/arch/arm/rte_cpuflags.c:
In function ‘rte_cpu_get_features’:
/home/jerin/dpdk-master/lib/librte_eal/common/arch/arm/rte_cpuflags.c:144:8:
error: array subscript is not an integer
     out[REG_PLATFORM] = 0x0001;
        ^
/home/jerin/dpdk-master/lib/librte_eal/common/arch/arm/rte_cpuflags.c:144:5:
error: statement with no effect [-Werror=unused-value]
     out[REG_PLATFORM] = 0x0001;
     ^
cc1: all warnings being treated as errors
/home/jerin/dpdk-master/mk/internal/rte.compile-pre.mk:126: recipe for
target 'rte_cpuflags.o' failed
make[5]: *** [rte_cpuflags.o] Error 1
/home/jerin/dpdk-master/mk/rte.subdir.mk:61: recipe for target 'eal'
failed
make[4]: *** [eal] Error 2
/home/jerin/dpdk-master/mk/rte.subdir.mk:61: recipe for target
'linuxapp' failed
make[3]: *** [linuxapp] Error 2
/home/jerin/dpdk-master/mk/rte.subdir.mk:61: recipe for target
'librte_eal' failed
make[2]: *** [librte_eal] Error 2
/home/jerin/dpdk-master/mk/rte.sdkbuild.mk:77: recipe for target 'lib'
failed
make[1]: *** [lib] Error 2
/home/jerin/dpdk-master/mk/rte.sdkroot.mk:123: recipe for target 'all'
failed
make: *** [all] Error 2


> 
> Thomas Monjalon (5):
>   eal: get CPU flag name
>   eal: move CPU flag functions out of headers
>   eal/arm: adapt CPU flags check to the arch
>   eal/ppc: adapt CPU flags check to the arch
>   eal: remove compiler optimization workaround
> 
>  app/test/test_hash_scaling.c                       |   2 +
>  lib/librte_eal/bsdapp/eal/rte_eal_version.map      |   2 +-
>  lib/librte_eal/common/arch/arm/rte_cpuflags.c      | 170 ++++++++++++++++-----
>  lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c   | 145 +++++++++++++-----
>  lib/librte_eal/common/arch/tile/rte_cpuflags.c     |  11 ++
>  lib/librte_eal/common/arch/x86/rte_cpuflags.c      |  91 +++++++++++
>  lib/librte_eal/common/eal_common_cpuflags.c        |  18 +--
>  .../common/include/arch/arm/rte_cpuflags_32.h      |  78 ----------
>  .../common/include/arch/arm/rte_cpuflags_64.h      |  79 ----------
>  .../common/include/arch/ppc_64/rte_cpuflags.h      |  64 --------
>  .../common/include/arch/tile/rte_cpuflags.h        |  29 ----
>  .../common/include/arch/x86/rte_cpuflags.h         |  66 --------
>  .../common/include/generic/rte_cpuflags.h          |  56 ++-----
>  lib/librte_eal/linuxapp/eal/rte_eal_version.map    |   3 +-
>  14 files changed, 364 insertions(+), 450 deletions(-)
> 
> -- 
> 2.5.2
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v1 0/5] clean-up cpuflags
  2016-02-03 13:38 ` Jerin Jacob
@ 2016-02-03 14:01   ` Thomas Monjalon
  2016-02-03 15:36     ` Jerin Jacob
  0 siblings, 1 reply; 19+ messages in thread
From: Thomas Monjalon @ 2016-02-03 14:01 UTC (permalink / raw)
  To: Jerin Jacob; +Cc: dev, viktorin

2016-02-03 19:08, Jerin Jacob:
> On Tue, Feb 02, 2016 at 11:59:48PM +0100, Thomas Monjalon wrote:
> > Following the work of Ferruh, I suggest this cleanup to remove as much
> > as possible of the code from the cpuflags headers.
> > The goal is to un-inline these functions (not performance sensitive)
> > and remove the CPU flags table from the ABI (just added recently).
> > The bonus is to stop mimic x86 in ARM and PPC implementations.
> > 
> > WARNING: it has not been tested nor compiled on Tilera, ARM and POWER8.
> > Please help, thank you.
> 
> compilation errors on arm64 too.

Yes I forgot REG_PLATFORM.

> arm64 toolchains are publicly available @
> http://releases.linaro.org/14.11/components/toolchain/binaries/aarch64-linux-gnu/

Yes I know, thank you.
I will test and make a v2.

Do you have any comment on the changes?

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v1 0/5] clean-up cpuflags
  2016-02-03 14:01   ` Thomas Monjalon
@ 2016-02-03 15:36     ` Jerin Jacob
  0 siblings, 0 replies; 19+ messages in thread
From: Jerin Jacob @ 2016-02-03 15:36 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, viktorin

On Wed, Feb 03, 2016 at 03:01:26PM +0100, Thomas Monjalon wrote:
> 2016-02-03 19:08, Jerin Jacob:
> > On Tue, Feb 02, 2016 at 11:59:48PM +0100, Thomas Monjalon wrote:
> > compilation errors on arm64 too.
> 
> Yes I forgot REG_PLATFORM.
> 
> > arm64 toolchains are publicly available @
> > http://releases.linaro.org/14.11/components/toolchain/binaries/aarch64-linux-gnu/
> 
> Yes I know, thank you.
> I will test and make a v2.
> 
> Do you have any comment on the changes?

looks good, nice cleanup.

IMO, Something like below can be done to remove the #ifdef clutter in
rte_cpu_get_features for ARM introduced in this rework

[master] pass2  [dpdk-master] $ git diff
diff --git a/lib/librte_eal/common/arch/arm/rte_cpuflags.c
b/lib/librte_eal/common/arch/arm/rte_cpuflags.c
index fba0a61..861ac57 100644
--- a/lib/librte_eal/common/arch/arm/rte_cpuflags.c
+++ b/lib/librte_eal/common/arch/arm/rte_cpuflags.c
@@ -71,6 +71,9 @@ struct feature_entry {
        [RTE_CPUFLAG_##name] = {reg, bit, #name},
 
 #ifdef RTE_ARCH_64
+#define PLATFORM_STR "aarch64"
+typedef Elf64_auxv_t _Elfx_auxv_t
+
 const struct feature_entry rte_cpu_feature_table[] = {
        FEAT_DEF(FP,            REG_HWCAP,    0)
        FEAT_DEF(NEON,          REG_HWCAP,    1)
@@ -83,6 +86,9 @@ const struct feature_entry rte_cpu_feature_table[] = {
        FEAT_DEF(AARCH64,       REG_PLATFORM, 1)
 };
 #else
+#define PLATFORM_STR "v7l"
+typedef Elf32_auxv_t _Elfx_auxv_t
+
 const struct feature_entry rte_cpu_feature_table[] = {
        FEAT_DEF(SWP,       REG_HWCAP,    0)
        FEAT_DEF(HALF,      REG_HWCAP,    1)
@@ -115,6 +121,7 @@ const struct feature_entry rte_cpu_feature_table[] =
{
 };
 #endif
 
+
 /*
  * Read AUXV software register and get cpu features for ARM
  */
@@ -122,11 +129,8 @@ static void
 rte_cpu_get_features(hwcap_registers_t out)
 {
        int auxv_fd;
-#ifdef RTE_ARCH_64
-       Elf64_auxv_t auxv;
-#else
-       Elf32_auxv_t auxv;
-#endif
+
+       _Elfx_auxv_t auxv;
 
        auxv_fd = open("/proc/self/auxv", O_RDONLY);
        assert(auxv_fd);
@@ -136,11 +140,7 @@ rte_cpu_get_features(hwcap_registers_t out)
                } else if (auxv.a_type == AT_HWCAP2) {
                        out[REG_HWCAP2] = auxv.a_un.a_val;
                } else if (auxv.a_type == AT_PLATFORM) {
-#ifdef RTE_ARCH_64
-                       if (!strcmp((const char *)auxv.a_un.a_val, "aarch64"))
-#else
-                       if (!strcmp((const char *)auxv.a_un.a_val, "v7l"))
-#endif
+                       if (!strcmp((const char *)auxv.a_un.a_val, PLATFORM_STR))
                                out[REG_PLATFORM] = 0x0001;
                }
        }

Jerin

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 0/5] clean-up cpuflags
  2016-02-02 22:59 [PATCH v1 0/5] clean-up cpuflags Thomas Monjalon
                   ` (6 preceding siblings ...)
  2016-02-03 13:38 ` Jerin Jacob
@ 2016-02-06 22:17 ` Thomas Monjalon
  2016-02-06 22:17   ` [PATCH v2 1/5] eal: get CPU flag name Thomas Monjalon
                     ` (5 more replies)
  7 siblings, 6 replies; 19+ messages in thread
From: Thomas Monjalon @ 2016-02-06 22:17 UTC (permalink / raw)
  To: david.marchand, ferruh.yigit; +Cc: dev, viktorin

Following the work of Ferruh, I suggest this cleanup to remove as much
as possible of the code from the cpuflags headers.
The goal is to un-inline these functions (not performance sensitive)
and remove the CPU flags table from the ABI (just added recently).
The bonus is to stop mimic x86 in ARM and PPC implementations.

WARNING: it has not been tested nor compiled on Tilera and POWER8.

v2 changes:
- fix maintainers file
- fix include from C++ app
- fix missing REG_PLATFORM for ARM
- suggested ARM refactor from Jerin

Thomas Monjalon (5):
  eal: get CPU flag name
  eal: move CPU flag functions out of headers
  eal/arm: adapt CPU flags check to the arch
  eal/ppc: adapt CPU flags check to the arch
  eal: remove compiler optimization workaround

 MAINTAINERS                                        |   4 +
 app/test/test_hash_scaling.c                       |   2 +
 lib/librte_eal/bsdapp/eal/rte_eal_version.map      |   2 +-
 lib/librte_eal/common/arch/arm/rte_cpuflags.c      | 179 ++++++++++++++++-----
 lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c   | 145 +++++++++++++----
 lib/librte_eal/common/arch/tile/rte_cpuflags.c     |  11 ++
 lib/librte_eal/common/arch/x86/rte_cpuflags.c      |  91 +++++++++++
 lib/librte_eal/common/eal_common_cpuflags.c        |  18 +--
 .../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          |  56 ++-----
 lib/librte_eal/linuxapp/eal/rte_eal_version.map    |   2 +-
 15 files changed, 378 insertions(+), 458 deletions(-)

-- 
2.7.0

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v2 1/5] eal: get CPU flag name
  2016-02-06 22:17 ` [PATCH v2 " Thomas Monjalon
@ 2016-02-06 22:17   ` Thomas Monjalon
  2016-02-06 22:17   ` [PATCH v2 2/5] eal: move CPU flag functions out of headers Thomas Monjalon
                     ` (4 subsequent siblings)
  5 siblings, 0 replies; 19+ messages in thread
From: Thomas Monjalon @ 2016-02-06 22:17 UTC (permalink / raw)
  To: david.marchand, ferruh.yigit; +Cc: dev, viktorin

The new function rte_cpu_get_flag_name() is added to the EAL API.
It is implemented (duplicated) in each arch because the next patch
will remove the public exposure of the feature tables.

Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 lib/librte_eal/bsdapp/eal/rte_eal_version.map        |  1 +
 lib/librte_eal/common/arch/arm/rte_cpuflags.c        |  7 +++++++
 lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c     |  8 ++++++++
 lib/librte_eal/common/arch/x86/rte_cpuflags.c        |  8 ++++++++
 lib/librte_eal/common/eal_common_cpuflags.c          |  2 +-
 lib/librte_eal/common/include/generic/rte_cpuflags.h | 14 ++++++++++++--
 lib/librte_eal/linuxapp/eal/rte_eal_version.map      |  1 +
 7 files changed, 38 insertions(+), 3 deletions(-)

diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index d8ac7f7..9bea0e2 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -139,6 +139,7 @@ DPDK_2.2 {
 DPDK_2.3 {
 	global:
 
+	rte_cpu_get_flag_name;
 	rte_eal_pci_map_device;
 	rte_eal_pci_unmap_device;
 	rte_cpu_feature_table;
diff --git a/lib/librte_eal/common/arch/arm/rte_cpuflags.c b/lib/librte_eal/common/arch/arm/rte_cpuflags.c
index 4348574..62e0791 100644
--- a/lib/librte_eal/common/arch/arm/rte_cpuflags.c
+++ b/lib/librte_eal/common/arch/arm/rte_cpuflags.c
@@ -77,3 +77,10 @@ const struct feature_entry rte_cpu_feature_table[] = {
 };
 #endif
 
+const char *
+rte_cpu_get_flag_name(enum rte_cpu_flag_t feature)
+{
+	if (feature >= RTE_CPUFLAG_NUMFLAGS)
+		return NULL;
+	return rte_cpu_feature_table[feature].name;
+}
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 7f4e6dd..a270ccc 100644
--- a/lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c
+++ b/lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c
@@ -68,3 +68,11 @@ const struct feature_entry rte_cpu_feature_table[] = {
 	FEAT_DEF(HTM, 0x00000001, 0, REG_HWCAP2,  30)
 	FEAT_DEF(ARCH_2_07, 0x00000001, 0, REG_HWCAP2,  31)
 };
+
+const char *
+rte_cpu_get_flag_name(enum rte_cpu_flag_t feature)
+{
+	if (feature >= RTE_CPUFLAG_NUMFLAGS)
+		return NULL;
+	return rte_cpu_feature_table[feature].name;
+}
diff --git a/lib/librte_eal/common/arch/x86/rte_cpuflags.c b/lib/librte_eal/common/arch/x86/rte_cpuflags.c
index 22dc572..3346fde 100644
--- a/lib/librte_eal/common/arch/x86/rte_cpuflags.c
+++ b/lib/librte_eal/common/arch/x86/rte_cpuflags.c
@@ -127,3 +127,11 @@ const struct feature_entry rte_cpu_feature_table[] = {
 
 	FEAT_DEF(INVTSC, 0x80000007, 0, RTE_REG_EDX,  8)
 };
+
+const char *
+rte_cpu_get_flag_name(enum rte_cpu_flag_t feature)
+{
+	if (feature >= RTE_CPUFLAG_NUMFLAGS)
+		return NULL;
+	return rte_cpu_feature_table[feature].name;
+}
diff --git a/lib/librte_eal/common/eal_common_cpuflags.c b/lib/librte_eal/common/eal_common_cpuflags.c
index 9ba9b1e..8c0576d 100644
--- a/lib/librte_eal/common/eal_common_cpuflags.c
+++ b/lib/librte_eal/common/eal_common_cpuflags.c
@@ -79,7 +79,7 @@ rte_cpu_check_supported(void)
 			fprintf(stderr,
 			        "ERROR: This system does not support \"%s\".\n"
 			        "Please check that RTE_MACHINE is set correctly.\n",
-			        rte_cpu_feature_table[compile_time_flags[i]].name);
+			        rte_cpu_get_flag_name(compile_time_flags[i]));
 			exit(1);
 		}
 	}
diff --git a/lib/librte_eal/common/include/generic/rte_cpuflags.h b/lib/librte_eal/common/include/generic/rte_cpuflags.h
index 5738a2a..3ca2e36 100644
--- a/lib/librte_eal/common/include/generic/rte_cpuflags.h
+++ b/lib/librte_eal/common/include/generic/rte_cpuflags.h
@@ -47,9 +47,7 @@
 /**
  * Enumeration of all CPU features supported
  */
-#ifdef __DOXYGEN__
 enum rte_cpu_flag_t;
-#endif
 
 /**
  * Enumeration of CPU registers
@@ -95,6 +93,18 @@ static inline void
 rte_cpu_get_features(uint32_t leaf, uint32_t subleaf, cpuid_registers_t out);
 
 /**
+ * Get name of CPU flag
+ *
+ * @param feature
+ *     CPU flag ID
+ * @return
+ *     flag name
+ *     NULL if flag ID is invalid
+ */
+const char *
+rte_cpu_get_flag_name(enum rte_cpu_flag_t feature);
+
+/**
  * Function for checking a CPU flag availability
  *
  * @param feature
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 4c09c0b..48e8e4f 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -142,6 +142,7 @@ DPDK_2.2 {
 DPDK_2.3 {
 	global:
 
+	rte_cpu_get_flag_name;
 	rte_eal_pci_map_device;
 	rte_eal_pci_unmap_device;
 	rte_cpu_feature_table;
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 2/5] eal: move CPU flag functions out of headers
  2016-02-06 22:17 ` [PATCH v2 " Thomas Monjalon
  2016-02-06 22:17   ` [PATCH v2 1/5] eal: get CPU flag name Thomas Monjalon
@ 2016-02-06 22:17   ` Thomas Monjalon
  2016-02-08  8:59     ` Jerin Jacob
  2016-02-06 22:17   ` [PATCH v2 3/5] eal/arm: adapt CPU flags check to the arch Thomas Monjalon
                     ` (3 subsequent siblings)
  5 siblings, 1 reply; 19+ messages in thread
From: Thomas Monjalon @ 2016-02-06 22:17 UTC (permalink / raw)
  To: david.marchand, ferruh.yigit; +Cc: dev, viktorin

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 <thomas.monjalon@6wind.com>
---
 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 <viktorin@rehivetech.com>
 M: Jianbo Liu <jianbo.liu@linaro.org>
+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 <zlu@ezchip.com>
+F: lib/librte_eal/common/arch/tile/
 F: lib/librte_eal/common/include/arch/tile/
 F: drivers/net/mpipe/
 
 IBM POWER
 M: Chao Zhu <chaozhu@linux.vnet.ibm.com>
+F: lib/librte_eal/common/arch/ppc_64/
 F: lib/librte_eal/common/include/arch/ppc_64/
 
 Intel x86
 M: Bruce Richardson <bruce.richardson@intel.com>
 M: Konstantin Ananyev <konstantin.ananyev@intel.com>
+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 <stdio.h>
+
 #include <rte_cycles.h>
 #include <rte_hash.h>
 #include <rte_hash_crc.h>
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 <elf.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <unistd.h>
+#include <string.h>
+
+#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 <elf.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <unistd.h>
+
+/* 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 <errno.h>
+
 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 <stdio.h>
+#include <errno.h>
+#include <stdint.h>
+
+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 <stdio.h>
+
 #include <rte_common.h>
 #include <rte_cpuflags.h>
 
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 <elf.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <unistd.h>
-#include <string.h>
-
-#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 <elf.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <unistd.h>
-#include <string.h>
-
-#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 <elf.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <unistd.h>
-
-#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 <elf.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <unistd.h>
-
-#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 <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <stdint.h>
-
-#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 <stdlib.h>
-#include <stdio.h>
 #include <errno.h>
-#include <stdint.h>
 
 /**
  * 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;
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 3/5] eal/arm: adapt CPU flags check to the arch
  2016-02-06 22:17 ` [PATCH v2 " Thomas Monjalon
  2016-02-06 22:17   ` [PATCH v2 1/5] eal: get CPU flag name Thomas Monjalon
  2016-02-06 22:17   ` [PATCH v2 2/5] eal: move CPU flag functions out of headers Thomas Monjalon
@ 2016-02-06 22:17   ` Thomas Monjalon
  2016-02-08  9:00     ` Jerin Jacob
  2016-02-06 22:17   ` [PATCH v2 4/5] eal/ppc: " Thomas Monjalon
                     ` (2 subsequent siblings)
  5 siblings, 1 reply; 19+ messages in thread
From: Thomas Monjalon @ 2016-02-06 22:17 UTC (permalink / raw)
  To: david.marchand, ferruh.yigit; +Cc: dev, viktorin

The structure feature_entry does not need leaf/subleaf
which were copied from x86 CPUID implementation.

On x86, a valid flag is detected with the non-zero leaf value.
This check is replaced by a check with a dummy "none" register.

Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 lib/librte_eal/common/arch/arm/rte_cpuflags.c | 107 ++++++++++++--------------
 1 file changed, 50 insertions(+), 57 deletions(-)

diff --git a/lib/librte_eal/common/arch/arm/rte_cpuflags.c b/lib/librte_eal/common/arch/arm/rte_cpuflags.c
index cd7a7b1..f14c56a 100644
--- a/lib/librte_eal/common/arch/arm/rte_cpuflags.c
+++ b/lib/librte_eal/common/arch/arm/rte_cpuflags.c
@@ -52,61 +52,61 @@
 #endif
 
 enum cpu_register_t {
-	REG_HWCAP = 0,
+	REG_NONE = 0,
+	REG_HWCAP,
 	REG_HWCAP2,
 	REG_PLATFORM,
+	REG_MAX
 };
 
-typedef uint32_t cpuid_registers_t[4];
+typedef uint32_t hwcap_registers_t[REG_MAX];
 
 /**
  * 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 */
+	uint32_t reg;
+	uint32_t bit;
 #define CPU_FLAG_NAME_MAX_LEN 64
-	char name[CPU_FLAG_NAME_MAX_LEN];       /**< String for printing */
+	char name[CPU_FLAG_NAME_MAX_LEN];
 };
 
-#define FEAT_DEF(name, leaf, subleaf, reg, bit) \
-	[RTE_CPUFLAG_##name] = {leaf, subleaf, reg, bit, #name },
+#define FEAT_DEF(name, reg, bit) \
+	[RTE_CPUFLAG_##name] = {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)
-	FEAT_DEF(THUMB,     0x00000001, 0, REG_HWCAP,  2)
-	FEAT_DEF(A26BIT,    0x00000001, 0, REG_HWCAP,  3)
-	FEAT_DEF(FAST_MULT, 0x00000001, 0, REG_HWCAP,  4)
-	FEAT_DEF(FPA,       0x00000001, 0, REG_HWCAP,  5)
-	FEAT_DEF(VFP,       0x00000001, 0, REG_HWCAP,  6)
-	FEAT_DEF(EDSP,      0x00000001, 0, REG_HWCAP,  7)
-	FEAT_DEF(JAVA,      0x00000001, 0, REG_HWCAP,  8)
-	FEAT_DEF(IWMMXT,    0x00000001, 0, REG_HWCAP,  9)
-	FEAT_DEF(CRUNCH,    0x00000001, 0, REG_HWCAP,  10)
-	FEAT_DEF(THUMBEE,   0x00000001, 0, REG_HWCAP,  11)
-	FEAT_DEF(NEON,      0x00000001, 0, REG_HWCAP,  12)
-	FEAT_DEF(VFPv3,     0x00000001, 0, REG_HWCAP,  13)
-	FEAT_DEF(VFPv3D16,  0x00000001, 0, REG_HWCAP,  14)
-	FEAT_DEF(TLS,       0x00000001, 0, REG_HWCAP,  15)
-	FEAT_DEF(VFPv4,     0x00000001, 0, REG_HWCAP,  16)
-	FEAT_DEF(IDIVA,     0x00000001, 0, REG_HWCAP,  17)
-	FEAT_DEF(IDIVT,     0x00000001, 0, REG_HWCAP,  18)
-	FEAT_DEF(VFPD32,    0x00000001, 0, REG_HWCAP,  19)
-	FEAT_DEF(LPAE,      0x00000001, 0, REG_HWCAP,  20)
-	FEAT_DEF(EVTSTRM,   0x00000001, 0, REG_HWCAP,  21)
-	FEAT_DEF(AES,       0x00000001, 0, REG_HWCAP2,  0)
-	FEAT_DEF(PMULL,     0x00000001, 0, REG_HWCAP2,  1)
-	FEAT_DEF(SHA1,      0x00000001, 0, REG_HWCAP2,  2)
-	FEAT_DEF(SHA2,      0x00000001, 0, REG_HWCAP2,  3)
-	FEAT_DEF(CRC32,     0x00000001, 0, REG_HWCAP2,  4)
-	FEAT_DEF(V7L,       0x00000001, 0, REG_PLATFORM, 0)
+	FEAT_DEF(SWP,       REG_HWCAP,    0)
+	FEAT_DEF(HALF,      REG_HWCAP,    1)
+	FEAT_DEF(THUMB,     REG_HWCAP,    2)
+	FEAT_DEF(A26BIT,    REG_HWCAP,    3)
+	FEAT_DEF(FAST_MULT, REG_HWCAP,    4)
+	FEAT_DEF(FPA,       REG_HWCAP,    5)
+	FEAT_DEF(VFP,       REG_HWCAP,    6)
+	FEAT_DEF(EDSP,      REG_HWCAP,    7)
+	FEAT_DEF(JAVA,      REG_HWCAP,    8)
+	FEAT_DEF(IWMMXT,    REG_HWCAP,    9)
+	FEAT_DEF(CRUNCH,    REG_HWCAP,   10)
+	FEAT_DEF(THUMBEE,   REG_HWCAP,   11)
+	FEAT_DEF(NEON,      REG_HWCAP,   12)
+	FEAT_DEF(VFPv3,     REG_HWCAP,   13)
+	FEAT_DEF(VFPv3D16,  REG_HWCAP,   14)
+	FEAT_DEF(TLS,       REG_HWCAP,   15)
+	FEAT_DEF(VFPv4,     REG_HWCAP,   16)
+	FEAT_DEF(IDIVA,     REG_HWCAP,   17)
+	FEAT_DEF(IDIVT,     REG_HWCAP,   18)
+	FEAT_DEF(VFPD32,    REG_HWCAP,   19)
+	FEAT_DEF(LPAE,      REG_HWCAP,   20)
+	FEAT_DEF(EVTSTRM,   REG_HWCAP,   21)
+	FEAT_DEF(AES,       REG_HWCAP2,   0)
+	FEAT_DEF(PMULL,     REG_HWCAP2,   1)
+	FEAT_DEF(SHA1,      REG_HWCAP2,   2)
+	FEAT_DEF(SHA2,      REG_HWCAP2,   3)
+	FEAT_DEF(CRC32,     REG_HWCAP2,   4)
+	FEAT_DEF(V7L,       REG_PLATFORM, 0)
 };
 
 #elif defined RTE_ARCH_ARM64
@@ -114,15 +114,15 @@ const struct feature_entry rte_cpu_feature_table[] = {
 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)
+	FEAT_DEF(FP,		REG_HWCAP,    0)
+	FEAT_DEF(NEON,		REG_HWCAP,    1)
+	FEAT_DEF(EVTSTRM,	REG_HWCAP,    2)
+	FEAT_DEF(AES,		REG_HWCAP,    3)
+	FEAT_DEF(PMULL,		REG_HWCAP,    4)
+	FEAT_DEF(SHA1,		REG_HWCAP,    5)
+	FEAT_DEF(SHA2,		REG_HWCAP,    6)
+	FEAT_DEF(CRC32,		REG_HWCAP,    7)
+	FEAT_DEF(AARCH64,	REG_PLATFORM, 1)
 };
 #endif /* RTE_ARCH */
 
@@ -130,8 +130,7 @@ const struct feature_entry rte_cpu_feature_table[] = {
  * 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)
+rte_cpu_get_features(hwcap_registers_t out)
 {
 	int auxv_fd;
 	_Elfx_auxv_t auxv;
@@ -157,22 +156,16 @@ int
 rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature)
 {
 	const struct feature_entry *feat;
-	cpuid_registers_t regs = {0};
+	hwcap_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! */
+	if (feat->reg == REG_NONE)
 		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 */
+	rte_cpu_get_features(regs);
 	return (regs[feat->reg] >> feat->bit) & 1;
 }
 
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 4/5] eal/ppc: adapt CPU flags check to the arch
  2016-02-06 22:17 ` [PATCH v2 " Thomas Monjalon
                     ` (2 preceding siblings ...)
  2016-02-06 22:17   ` [PATCH v2 3/5] eal/arm: adapt CPU flags check to the arch Thomas Monjalon
@ 2016-02-06 22:17   ` Thomas Monjalon
  2016-02-06 22:17   ` [PATCH v2 5/5] eal: remove compiler optimization workaround Thomas Monjalon
  2016-02-16  7:30   ` [PATCH v2 0/5] clean-up cpuflags Thomas Monjalon
  5 siblings, 0 replies; 19+ messages in thread
From: Thomas Monjalon @ 2016-02-06 22:17 UTC (permalink / raw)
  To: david.marchand, ferruh.yigit; +Cc: dev, viktorin

The structure feature_entry does not need leaf/subleaf
which were copied from x86 CPUID implementation.

On x86, a valid flag is detected with the non-zero leaf value.
This check is replaced by a check with a dummy "none" register.

Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c | 104 ++++++++++-------------
 1 file changed, 47 insertions(+), 57 deletions(-)

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 b7e0b72..a8147c8 100644
--- a/lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c
+++ b/lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c
@@ -43,70 +43,66 @@
 
 /* software based registers */
 enum cpu_register_t {
-	REG_HWCAP = 0,
+	REG_NONE = 0,
+	REG_HWCAP,
 	REG_HWCAP2,
+	REG_MAX
 };
 
-typedef uint32_t cpuid_registers_t[4];
+typedef uint32_t hwcap_registers_t[REG_MAX];
 
-/**
- * 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 */
+	uint32_t reg;
+	uint32_t bit;
 #define CPU_FLAG_NAME_MAX_LEN 64
-	char name[CPU_FLAG_NAME_MAX_LEN];       /**< String for printing */
+	char name[CPU_FLAG_NAME_MAX_LEN];
 };
 
-#define FEAT_DEF(name, leaf, subleaf, reg, bit) \
-	[RTE_CPUFLAG_##name] = {leaf, subleaf, reg, bit, #name },
+#define FEAT_DEF(name, reg, bit) \
+	[RTE_CPUFLAG_##name] = {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)
-	FEAT_DEF(PSERIES_PERFMON_COMPAT, 0x00000001, 0, REG_HWCAP,  6)
-	FEAT_DEF(VSX, 0x00000001, 0, REG_HWCAP,  7)
-	FEAT_DEF(ARCH_2_06, 0x00000001, 0, REG_HWCAP,  8)
-	FEAT_DEF(POWER6_EXT, 0x00000001, 0, REG_HWCAP,  9)
-	FEAT_DEF(DFP, 0x00000001, 0, REG_HWCAP,  10)
-	FEAT_DEF(PA6T, 0x00000001, 0, REG_HWCAP,  11)
-	FEAT_DEF(ARCH_2_05, 0x00000001, 0, REG_HWCAP,  12)
-	FEAT_DEF(ICACHE_SNOOP, 0x00000001, 0, REG_HWCAP,  13)
-	FEAT_DEF(SMT, 0x00000001, 0, REG_HWCAP,  14)
-	FEAT_DEF(BOOKE, 0x00000001, 0, REG_HWCAP,  15)
-	FEAT_DEF(CELLBE, 0x00000001, 0, REG_HWCAP,  16)
-	FEAT_DEF(POWER5_PLUS, 0x00000001, 0, REG_HWCAP,  17)
-	FEAT_DEF(POWER5, 0x00000001, 0, REG_HWCAP,  18)
-	FEAT_DEF(POWER4, 0x00000001, 0, REG_HWCAP,  19)
-	FEAT_DEF(NOTB, 0x00000001, 0, REG_HWCAP,  20)
-	FEAT_DEF(EFP_DOUBLE, 0x00000001, 0, REG_HWCAP,  21)
-	FEAT_DEF(EFP_SINGLE, 0x00000001, 0, REG_HWCAP,  22)
-	FEAT_DEF(SPE, 0x00000001, 0, REG_HWCAP,  23)
-	FEAT_DEF(UNIFIED_CACHE, 0x00000001, 0, REG_HWCAP,  24)
-	FEAT_DEF(4xxMAC, 0x00000001, 0, REG_HWCAP,  25)
-	FEAT_DEF(MMU, 0x00000001, 0, REG_HWCAP,  26)
-	FEAT_DEF(FPU, 0x00000001, 0, REG_HWCAP,  27)
-	FEAT_DEF(ALTIVEC, 0x00000001, 0, REG_HWCAP,  28)
-	FEAT_DEF(PPC601, 0x00000001, 0, REG_HWCAP,  29)
-	FEAT_DEF(PPC64, 0x00000001, 0, REG_HWCAP,  30)
-	FEAT_DEF(PPC32, 0x00000001, 0, REG_HWCAP,  31)
-	FEAT_DEF(TAR, 0x00000001, 0, REG_HWCAP2,  26)
-	FEAT_DEF(LSEL, 0x00000001, 0, REG_HWCAP2,  27)
-	FEAT_DEF(EBB, 0x00000001, 0, REG_HWCAP2,  28)
-	FEAT_DEF(DSCR, 0x00000001, 0, REG_HWCAP2,  29)
-	FEAT_DEF(HTM, 0x00000001, 0, REG_HWCAP2,  30)
-	FEAT_DEF(ARCH_2_07, 0x00000001, 0, REG_HWCAP2,  31)
+	FEAT_DEF(PPC_LE,                 REG_HWCAP,   0)
+	FEAT_DEF(TRUE_LE,                REG_HWCAP,   1)
+	FEAT_DEF(PSERIES_PERFMON_COMPAT, REG_HWCAP,   6)
+	FEAT_DEF(VSX,                    REG_HWCAP,   7)
+	FEAT_DEF(ARCH_2_06,              REG_HWCAP,   8)
+	FEAT_DEF(POWER6_EXT,             REG_HWCAP,   9)
+	FEAT_DEF(DFP,                    REG_HWCAP,  10)
+	FEAT_DEF(PA6T,                   REG_HWCAP,  11)
+	FEAT_DEF(ARCH_2_05,              REG_HWCAP,  12)
+	FEAT_DEF(ICACHE_SNOOP,           REG_HWCAP,  13)
+	FEAT_DEF(SMT,                    REG_HWCAP,  14)
+	FEAT_DEF(BOOKE,                  REG_HWCAP,  15)
+	FEAT_DEF(CELLBE,                 REG_HWCAP,  16)
+	FEAT_DEF(POWER5_PLUS,            REG_HWCAP,  17)
+	FEAT_DEF(POWER5,                 REG_HWCAP,  18)
+	FEAT_DEF(POWER4,                 REG_HWCAP,  19)
+	FEAT_DEF(NOTB,                   REG_HWCAP,  20)
+	FEAT_DEF(EFP_DOUBLE,             REG_HWCAP,  21)
+	FEAT_DEF(EFP_SINGLE,             REG_HWCAP,  22)
+	FEAT_DEF(SPE,                    REG_HWCAP,  23)
+	FEAT_DEF(UNIFIED_CACHE,          REG_HWCAP,  24)
+	FEAT_DEF(4xxMAC,                 REG_HWCAP,  25)
+	FEAT_DEF(MMU,                    REG_HWCAP,  26)
+	FEAT_DEF(FPU,                    REG_HWCAP,  27)
+	FEAT_DEF(ALTIVEC,                REG_HWCAP,  28)
+	FEAT_DEF(PPC601,                 REG_HWCAP,  29)
+	FEAT_DEF(PPC64,                  REG_HWCAP,  30)
+	FEAT_DEF(PPC32,                  REG_HWCAP,  31)
+	FEAT_DEF(TAR,                    REG_HWCAP2, 26)
+	FEAT_DEF(LSEL,                   REG_HWCAP2, 27)
+	FEAT_DEF(EBB,                    REG_HWCAP2, 28)
+	FEAT_DEF(DSCR,                   REG_HWCAP2, 29)
+	FEAT_DEF(HTM,                    REG_HWCAP2, 30)
+	FEAT_DEF(ARCH_2_07,              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)
+rte_cpu_get_features(hwcap_registers_t out)
 {
 	int auxv_fd;
 	Elf64_auxv_t auxv;
@@ -129,22 +125,16 @@ int
 rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature)
 {
 	const struct feature_entry *feat;
-	cpuid_registers_t regs = {0};
+	hwcap_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! */
+	if (feat->reg == REG_NONE)
 		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 */
+	rte_cpu_get_features(regs);
 	return (regs[feat->reg] >> feat->bit) & 1;
 }
 
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 5/5] eal: remove compiler optimization workaround
  2016-02-06 22:17 ` [PATCH v2 " Thomas Monjalon
                     ` (3 preceding siblings ...)
  2016-02-06 22:17   ` [PATCH v2 4/5] eal/ppc: " Thomas Monjalon
@ 2016-02-06 22:17   ` Thomas Monjalon
  2016-02-16  7:30   ` [PATCH v2 0/5] clean-up cpuflags Thomas Monjalon
  5 siblings, 0 replies; 19+ messages in thread
From: Thomas Monjalon @ 2016-02-06 22:17 UTC (permalink / raw)
  To: david.marchand, ferruh.yigit; +Cc: dev, viktorin

The compiler optimization was disabled a long time ago
without describing what was the exact issue.
Maybe it does not apply anymore.
As it looks unneeded, let's remove this strange pragma.

Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>
---
 lib/librte_eal/common/eal_common_cpuflags.c | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_cpuflags.c b/lib/librte_eal/common/eal_common_cpuflags.c
index a4c5a29..ecb1240 100644
--- a/lib/librte_eal/common/eal_common_cpuflags.c
+++ b/lib/librte_eal/common/eal_common_cpuflags.c
@@ -36,19 +36,6 @@
 #include <rte_common.h>
 #include <rte_cpuflags.h>
 
-/*
- * This should prevent use of advanced instruction sets in this file. Otherwise
- * the check function itself could cause a crash.
- */
-#ifdef __INTEL_COMPILER
-#pragma optimize ("", off)
-#else
-#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
-#if GCC_VERSION > 404000
-#pragma GCC optimize ("O0")
-#endif
-#endif
-
 /**
  * Checks if the machine is adequate for running the binary. If it is not, the
  * program exits with status 1.
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 2/5] eal: move CPU flag functions out of headers
  2016-02-06 22:17   ` [PATCH v2 2/5] eal: move CPU flag functions out of headers Thomas Monjalon
@ 2016-02-08  8:59     ` Jerin Jacob
  0 siblings, 0 replies; 19+ messages in thread
From: Jerin Jacob @ 2016-02-08  8:59 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, viktorin

On Sat, Feb 06, 2016 at 11:17:10PM +0100, Thomas Monjalon wrote:
> 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 <thomas.monjalon@6wind.com>

arm64 specific changes looks good.

Acked-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>

> ---
>  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 <viktorin@rehivetech.com>
>  M: Jianbo Liu <jianbo.liu@linaro.org>
> +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 <zlu@ezchip.com>
> +F: lib/librte_eal/common/arch/tile/
>  F: lib/librte_eal/common/include/arch/tile/
>  F: drivers/net/mpipe/
>  
>  IBM POWER
>  M: Chao Zhu <chaozhu@linux.vnet.ibm.com>
> +F: lib/librte_eal/common/arch/ppc_64/
>  F: lib/librte_eal/common/include/arch/ppc_64/
>  
>  Intel x86
>  M: Bruce Richardson <bruce.richardson@intel.com>
>  M: Konstantin Ananyev <konstantin.ananyev@intel.com>
> +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 <stdio.h>
> +
>  #include <rte_cycles.h>
>  #include <rte_hash.h>
>  #include <rte_hash_crc.h>
> 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 <elf.h>
> +#include <fcntl.h>
> +#include <assert.h>
> +#include <unistd.h>
> +#include <string.h>
> +
> +#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 <elf.h>
> +#include <fcntl.h>
> +#include <assert.h>
> +#include <unistd.h>
> +
> +/* 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 <errno.h>
> +
>  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 <stdio.h>
> +#include <errno.h>
> +#include <stdint.h>
> +
> +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 <stdio.h>
> +
>  #include <rte_common.h>
>  #include <rte_cpuflags.h>
>  
> 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 <elf.h>
> -#include <fcntl.h>
> -#include <assert.h>
> -#include <unistd.h>
> -#include <string.h>
> -
> -#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 <elf.h>
> -#include <fcntl.h>
> -#include <assert.h>
> -#include <unistd.h>
> -#include <string.h>
> -
> -#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 <elf.h>
> -#include <fcntl.h>
> -#include <assert.h>
> -#include <unistd.h>
> -
> -#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 <elf.h>
> -#include <fcntl.h>
> -#include <assert.h>
> -#include <unistd.h>
> -
> -#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 <stdlib.h>
> -#include <stdio.h>
> -#include <errno.h>
> -#include <stdint.h>
> -
> -#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 <stdlib.h>
> -#include <stdio.h>
>  #include <errno.h>
> -#include <stdint.h>
>  
>  /**
>   * 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;
> -- 
> 2.7.0
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 3/5] eal/arm: adapt CPU flags check to the arch
  2016-02-06 22:17   ` [PATCH v2 3/5] eal/arm: adapt CPU flags check to the arch Thomas Monjalon
@ 2016-02-08  9:00     ` Jerin Jacob
  0 siblings, 0 replies; 19+ messages in thread
From: Jerin Jacob @ 2016-02-08  9:00 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, viktorin

On Sat, Feb 06, 2016 at 11:17:11PM +0100, Thomas Monjalon wrote:
> The structure feature_entry does not need leaf/subleaf
> which were copied from x86 CPUID implementation.
> 
> On x86, a valid flag is detected with the non-zero leaf value.
> This check is replaced by a check with a dummy "none" register.
> 
> Signed-off-by: Thomas Monjalon <thomas.monjalon@6wind.com>

Tested on a arm64 based platform.

Acked-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
Tested-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>

> ---
>  lib/librte_eal/common/arch/arm/rte_cpuflags.c | 107 ++++++++++++--------------
>  1 file changed, 50 insertions(+), 57 deletions(-)
> 
> diff --git a/lib/librte_eal/common/arch/arm/rte_cpuflags.c b/lib/librte_eal/common/arch/arm/rte_cpuflags.c
> index cd7a7b1..f14c56a 100644
> --- a/lib/librte_eal/common/arch/arm/rte_cpuflags.c
> +++ b/lib/librte_eal/common/arch/arm/rte_cpuflags.c
> @@ -52,61 +52,61 @@
>  #endif
>  
>  enum cpu_register_t {
> -	REG_HWCAP = 0,
> +	REG_NONE = 0,
> +	REG_HWCAP,
>  	REG_HWCAP2,
>  	REG_PLATFORM,
> +	REG_MAX
>  };
>  
> -typedef uint32_t cpuid_registers_t[4];
> +typedef uint32_t hwcap_registers_t[REG_MAX];
>  
>  /**
>   * 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 */
> +	uint32_t reg;
> +	uint32_t bit;
>  #define CPU_FLAG_NAME_MAX_LEN 64
> -	char name[CPU_FLAG_NAME_MAX_LEN];       /**< String for printing */
> +	char name[CPU_FLAG_NAME_MAX_LEN];
>  };
>  
> -#define FEAT_DEF(name, leaf, subleaf, reg, bit) \
> -	[RTE_CPUFLAG_##name] = {leaf, subleaf, reg, bit, #name },
> +#define FEAT_DEF(name, reg, bit) \
> +	[RTE_CPUFLAG_##name] = {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)
> -	FEAT_DEF(THUMB,     0x00000001, 0, REG_HWCAP,  2)
> -	FEAT_DEF(A26BIT,    0x00000001, 0, REG_HWCAP,  3)
> -	FEAT_DEF(FAST_MULT, 0x00000001, 0, REG_HWCAP,  4)
> -	FEAT_DEF(FPA,       0x00000001, 0, REG_HWCAP,  5)
> -	FEAT_DEF(VFP,       0x00000001, 0, REG_HWCAP,  6)
> -	FEAT_DEF(EDSP,      0x00000001, 0, REG_HWCAP,  7)
> -	FEAT_DEF(JAVA,      0x00000001, 0, REG_HWCAP,  8)
> -	FEAT_DEF(IWMMXT,    0x00000001, 0, REG_HWCAP,  9)
> -	FEAT_DEF(CRUNCH,    0x00000001, 0, REG_HWCAP,  10)
> -	FEAT_DEF(THUMBEE,   0x00000001, 0, REG_HWCAP,  11)
> -	FEAT_DEF(NEON,      0x00000001, 0, REG_HWCAP,  12)
> -	FEAT_DEF(VFPv3,     0x00000001, 0, REG_HWCAP,  13)
> -	FEAT_DEF(VFPv3D16,  0x00000001, 0, REG_HWCAP,  14)
> -	FEAT_DEF(TLS,       0x00000001, 0, REG_HWCAP,  15)
> -	FEAT_DEF(VFPv4,     0x00000001, 0, REG_HWCAP,  16)
> -	FEAT_DEF(IDIVA,     0x00000001, 0, REG_HWCAP,  17)
> -	FEAT_DEF(IDIVT,     0x00000001, 0, REG_HWCAP,  18)
> -	FEAT_DEF(VFPD32,    0x00000001, 0, REG_HWCAP,  19)
> -	FEAT_DEF(LPAE,      0x00000001, 0, REG_HWCAP,  20)
> -	FEAT_DEF(EVTSTRM,   0x00000001, 0, REG_HWCAP,  21)
> -	FEAT_DEF(AES,       0x00000001, 0, REG_HWCAP2,  0)
> -	FEAT_DEF(PMULL,     0x00000001, 0, REG_HWCAP2,  1)
> -	FEAT_DEF(SHA1,      0x00000001, 0, REG_HWCAP2,  2)
> -	FEAT_DEF(SHA2,      0x00000001, 0, REG_HWCAP2,  3)
> -	FEAT_DEF(CRC32,     0x00000001, 0, REG_HWCAP2,  4)
> -	FEAT_DEF(V7L,       0x00000001, 0, REG_PLATFORM, 0)
> +	FEAT_DEF(SWP,       REG_HWCAP,    0)
> +	FEAT_DEF(HALF,      REG_HWCAP,    1)
> +	FEAT_DEF(THUMB,     REG_HWCAP,    2)
> +	FEAT_DEF(A26BIT,    REG_HWCAP,    3)
> +	FEAT_DEF(FAST_MULT, REG_HWCAP,    4)
> +	FEAT_DEF(FPA,       REG_HWCAP,    5)
> +	FEAT_DEF(VFP,       REG_HWCAP,    6)
> +	FEAT_DEF(EDSP,      REG_HWCAP,    7)
> +	FEAT_DEF(JAVA,      REG_HWCAP,    8)
> +	FEAT_DEF(IWMMXT,    REG_HWCAP,    9)
> +	FEAT_DEF(CRUNCH,    REG_HWCAP,   10)
> +	FEAT_DEF(THUMBEE,   REG_HWCAP,   11)
> +	FEAT_DEF(NEON,      REG_HWCAP,   12)
> +	FEAT_DEF(VFPv3,     REG_HWCAP,   13)
> +	FEAT_DEF(VFPv3D16,  REG_HWCAP,   14)
> +	FEAT_DEF(TLS,       REG_HWCAP,   15)
> +	FEAT_DEF(VFPv4,     REG_HWCAP,   16)
> +	FEAT_DEF(IDIVA,     REG_HWCAP,   17)
> +	FEAT_DEF(IDIVT,     REG_HWCAP,   18)
> +	FEAT_DEF(VFPD32,    REG_HWCAP,   19)
> +	FEAT_DEF(LPAE,      REG_HWCAP,   20)
> +	FEAT_DEF(EVTSTRM,   REG_HWCAP,   21)
> +	FEAT_DEF(AES,       REG_HWCAP2,   0)
> +	FEAT_DEF(PMULL,     REG_HWCAP2,   1)
> +	FEAT_DEF(SHA1,      REG_HWCAP2,   2)
> +	FEAT_DEF(SHA2,      REG_HWCAP2,   3)
> +	FEAT_DEF(CRC32,     REG_HWCAP2,   4)
> +	FEAT_DEF(V7L,       REG_PLATFORM, 0)
>  };
>  
>  #elif defined RTE_ARCH_ARM64
> @@ -114,15 +114,15 @@ const struct feature_entry rte_cpu_feature_table[] = {
>  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)
> +	FEAT_DEF(FP,		REG_HWCAP,    0)
> +	FEAT_DEF(NEON,		REG_HWCAP,    1)
> +	FEAT_DEF(EVTSTRM,	REG_HWCAP,    2)
> +	FEAT_DEF(AES,		REG_HWCAP,    3)
> +	FEAT_DEF(PMULL,		REG_HWCAP,    4)
> +	FEAT_DEF(SHA1,		REG_HWCAP,    5)
> +	FEAT_DEF(SHA2,		REG_HWCAP,    6)
> +	FEAT_DEF(CRC32,		REG_HWCAP,    7)
> +	FEAT_DEF(AARCH64,	REG_PLATFORM, 1)
>  };
>  #endif /* RTE_ARCH */
>  
> @@ -130,8 +130,7 @@ const struct feature_entry rte_cpu_feature_table[] = {
>   * 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)
> +rte_cpu_get_features(hwcap_registers_t out)
>  {
>  	int auxv_fd;
>  	_Elfx_auxv_t auxv;
> @@ -157,22 +156,16 @@ int
>  rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature)
>  {
>  	const struct feature_entry *feat;
> -	cpuid_registers_t regs = {0};
> +	hwcap_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! */
> +	if (feat->reg == REG_NONE)
>  		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 */
> +	rte_cpu_get_features(regs);
>  	return (regs[feat->reg] >> feat->bit) & 1;
>  }
>  
> -- 
> 2.7.0
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 0/5] clean-up cpuflags
  2016-02-06 22:17 ` [PATCH v2 " Thomas Monjalon
                     ` (4 preceding siblings ...)
  2016-02-06 22:17   ` [PATCH v2 5/5] eal: remove compiler optimization workaround Thomas Monjalon
@ 2016-02-16  7:30   ` Thomas Monjalon
  5 siblings, 0 replies; 19+ messages in thread
From: Thomas Monjalon @ 2016-02-16  7:30 UTC (permalink / raw)
  To: david.marchand; +Cc: dev, viktorin

2016-02-06 23:17, Thomas Monjalon:
> Following the work of Ferruh, I suggest this cleanup to remove as much
> as possible of the code from the cpuflags headers.
> The goal is to un-inline these functions (not performance sensitive)
> and remove the CPU flags table from the ABI (just added recently).
> The bonus is to stop mimic x86 in ARM and PPC implementations.
> 
> WARNING: it has not been tested nor compiled on Tilera and POWER8.
> 
> v2 changes:
> - fix maintainers file
> - fix include from C++ app
> - fix missing REG_PLATFORM for ARM
> - suggested ARM refactor from Jerin

Applied

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2016-02-16  7:31 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-02-02 22:59 [PATCH v1 0/5] clean-up cpuflags Thomas Monjalon
2016-02-02 22:59 ` [PATCH v1 1/5] eal: get CPU flag name Thomas Monjalon
2016-02-02 23:10 ` [PATCH v1 2/5] eal: move CPU flag functions out of headers Thomas Monjalon
2016-02-02 23:10 ` [PATCH v1 3/5] eal/arm: adapt CPU flags check to the arch Thomas Monjalon
2016-02-02 23:10 ` [PATCH v1 4/5] eal/ppc: " Thomas Monjalon
2016-02-02 23:10 ` [PATCH v1 5/5] eal: remove compiler optimization workaround Thomas Monjalon
2016-02-02 23:51 ` [PATCH v1 0/5] clean-up cpuflags Jan Viktorin
2016-02-03 13:38 ` Jerin Jacob
2016-02-03 14:01   ` Thomas Monjalon
2016-02-03 15:36     ` Jerin Jacob
2016-02-06 22:17 ` [PATCH v2 " Thomas Monjalon
2016-02-06 22:17   ` [PATCH v2 1/5] eal: get CPU flag name Thomas Monjalon
2016-02-06 22:17   ` [PATCH v2 2/5] eal: move CPU flag functions out of headers Thomas Monjalon
2016-02-08  8:59     ` Jerin Jacob
2016-02-06 22:17   ` [PATCH v2 3/5] eal/arm: adapt CPU flags check to the arch Thomas Monjalon
2016-02-08  9:00     ` Jerin Jacob
2016-02-06 22:17   ` [PATCH v2 4/5] eal/ppc: " Thomas Monjalon
2016-02-06 22:17   ` [PATCH v2 5/5] eal: remove compiler optimization workaround Thomas Monjalon
2016-02-16  7:30   ` [PATCH v2 0/5] clean-up cpuflags Thomas Monjalon

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.