From: Jerin Jacob Date: Fri, 6 Nov 2015 09:40:21 +0000 (+0530) Subject: eal/arm: add CPU flags for ARMv8 X-Git-Tag: spdx-start~8036 X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=97523f822ba9;p=dpdk.git eal/arm: add CPU flags for ARMv8 Signed-off-by: Jerin Jacob --- diff --git a/app/test/test_cpuflags.c b/app/test/test_cpuflags.c index 557458f53c..e8d0ce7ee3 100644 --- a/app/test/test_cpuflags.c +++ b/app/test/test_cpuflags.c @@ -120,6 +120,32 @@ test_cpuflags(void) CHECK_FOR_FLAG(RTE_CPUFLAG_NEON); #endif +#if defined(RTE_ARCH_ARM64) + printf("Check for FP:\t\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_FP); + + printf("Check for ASIMD:\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_NEON); + + printf("Check for EVTSTRM:\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_EVTSTRM); + + printf("Check for AES:\t\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_AES); + + printf("Check for PMULL:\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_PMULL); + + printf("Check for SHA1:\t\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_SHA1); + + printf("Check for SHA2:\t\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_SHA2); + + printf("Check for CRC32:\t"); + CHECK_FOR_FLAG(RTE_CPUFLAG_CRC32); +#endif + #if defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_I686) printf("Check for SSE:\t\t"); CHECK_FOR_FLAG(RTE_CPUFLAG_SSE); diff --git a/lib/librte_eal/common/include/arch/arm/rte_cpuflags.h b/lib/librte_eal/common/include/arch/arm/rte_cpuflags.h index 8de78d2367..b8f62889bb 100644 --- a/lib/librte_eal/common/include/arch/arm/rte_cpuflags.h +++ b/lib/librte_eal/common/include/arch/arm/rte_cpuflags.h @@ -33,6 +33,10 @@ #ifndef _RTE_CPUFLAGS_ARM_H_ #define _RTE_CPUFLAGS_ARM_H_ +#ifdef RTE_ARCH_64 +#include +#else #include +#endif #endif /* _RTE_CPUFLAGS_ARM_H_ */ 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 new file mode 100644 index 0000000000..7bcc12fd1c --- /dev/null +++ b/lib/librte_eal/common/include/arch/arm/rte_cpuflags_64.h @@ -0,0 +1,152 @@ +/* + * BSD LICENSE + * + * Copyright (C) Cavium networks Ltd. 2015. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Cavium networks nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _RTE_CPUFLAGS_ARM64_H_ +#define _RTE_CPUFLAGS_ARM64_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include + +#include "generic/rte_cpuflags.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 + +/* software based registers */ +enum cpu_register_t { + REG_HWCAP = 0, + REG_HWCAP2, + REG_PLATFORM, +}; + +/** + * Enumeration of all CPU features supported + */ +enum rte_cpu_flag_t { + RTE_CPUFLAG_FP = 0, + RTE_CPUFLAG_NEON, + RTE_CPUFLAG_EVTSTRM, + RTE_CPUFLAG_AES, + RTE_CPUFLAG_PMULL, + RTE_CPUFLAG_SHA1, + RTE_CPUFLAG_SHA2, + RTE_CPUFLAG_CRC32, + RTE_CPUFLAG_AARCH64, + /* The last item */ + RTE_CPUFLAG_NUMFLAGS,/**< This should always be the last! */ +}; + +static const struct feature_entry 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) +}; + +/* + * 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 = &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 + +#endif /* _RTE_CPUFLAGS_ARM64_H_ */