From 73cb0062e30ec09aa38bc98d91cbdfc86a8fb6c0 Mon Sep 17 00:00:00 2001 From: Gabriel Ganne Date: Tue, 5 Dec 2017 14:26:33 +0100 Subject: [PATCH] fill "show cpu" Flag list on aarch64 platforms (VPP-1065) use getauxval(AT_HWCAP) to get the processor capabilities. The result should be the same as calling cat /proc/cpuinfo | grep Feature | head -n1 All but one (aes) features have a different name. handle aes by adding it an arch prefix, which is skipped during print and a clib_cpu_supports_aes() custom function. Change-Id: If9830bd5a17bac1bd1b5337dacbb0ddbb8ed6b18 Signed-off-by: Gabriel Ganne --- src/vppinfra/cpu.c | 21 +++++++++++++++-- src/vppinfra/cpu.h | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 84 insertions(+), 6 deletions(-) diff --git a/src/vppinfra/cpu.c b/src/vppinfra/cpu.c index b13527a40b5..6bd19c8e7f3 100644 --- a/src/vppinfra/cpu.c +++ b/src/vppinfra/cpu.c @@ -126,16 +126,33 @@ format_cpu_model_name (u8 * s, va_list * args) #endif } + +static inline char const * +flag_skip_prefix (char const *flag) +{ + if (memcmp (flag, "x86_", sizeof ("x86_") - 1) == 0) + return flag + sizeof ("x86_") - 1; + if (memcmp (flag, "aarch64_", sizeof ("aarch64_") - 1) == 0) + return flag + sizeof ("aarch64_") - 1; + return flag; +} + u8 * format_cpu_flags (u8 * s, va_list * args) { #if defined(__x86_64__) #define _(flag, func, reg, bit) \ if (clib_cpu_supports_ ## flag()) \ - s = format (s, #flag " "); + s = format (s, "%s ", flag_skip_prefix(#flag)); foreach_x86_64_flags return s; #undef _ -#else /* ! __x86_64__ */ +#elif defined(__aarch64__) +#define _(flag, bit) \ + if (clib_cpu_supports_ ## flag()) \ + s = format (s, "%s ", flag_skip_prefix(#flag)); + foreach_aarch64_flags return s; +#undef _ +#else /* ! ! __x86_64__ && ! __aarch64__ */ return format (s, "unknown"); #endif } diff --git a/src/vppinfra/cpu.h b/src/vppinfra/cpu.h index 75b01e606f3..6504c7b4e3a 100644 --- a/src/vppinfra/cpu.h +++ b/src/vppinfra/cpu.h @@ -67,10 +67,36 @@ _ (sse42, 1, ecx, 20) \ _ (avx, 1, ecx, 28) \ _ (avx2, 7, ebx, 5) \ _ (avx512f, 7, ebx, 16) \ -_ (aes, 1, ecx, 25) \ +_ (x86_aes, 1, ecx, 25) \ _ (sha, 7, ebx, 29) \ _ (invariant_tsc, 0x80000007, edx, 8) + +#define foreach_aarch64_flags \ +_ (fp, 0) \ +_ (asimd, 1) \ +_ (evtstrm, 2) \ +_ (aarch64_aes, 3) \ +_ (pmull, 4) \ +_ (sha1, 5) \ +_ (sha2, 6) \ +_ (crc32, 7) \ +_ (atomics, 8) \ +_ (fphp, 9) \ +_ (asimdhp, 10) \ +_ (cpuid, 11) \ +_ (asimdrdm, 12) \ +_ (jscvt, 13) \ +_ (fcma, 14) \ +_ (lrcpc, 15) \ +_ (dcpop, 16) \ +_ (sha3, 17) \ +_ (sm3, 18) \ +_ (sm4, 19) \ +_ (asimddp, 20) \ +_ (sha512, 21) \ +_ (sve, 22) + #if defined(__x86_64__) #include "cpuid.h" @@ -98,15 +124,50 @@ clib_cpu_supports_ ## flag() \ } foreach_x86_64_flags #undef _ -#else +#else /* __x86_64__ */ #define _(flag, func, reg, bit) \ static inline int clib_cpu_supports_ ## flag() { return 0; } foreach_x86_64_flags #undef _ +#endif /* __x86_64__ */ +#if defined(__aarch64__) +#include +#define _(flag, bit) \ +static inline int \ +clib_cpu_supports_ ## flag() \ +{ \ + unsigned long hwcap = getauxval(AT_HWCAP); \ + return (hwcap & (1 << bit)); \ +} + foreach_aarch64_flags +#undef _ +#else /* ! __x86_64__ && !__aarch64__ */ +#define _(flag, bit) \ +static inline int clib_cpu_supports_ ## flag() { return 0; } + foreach_aarch64_flags +#undef _ +#endif /* __x86_64__, __aarch64__ */ +/* + * aes is the only feature with the same name in both flag lists + * handle this by prefixing it with the arch name, and handling it + * with the custom function below + */ + static inline int +clib_cpu_supports_aes () +{ +#if defined (__aarch64__) + return clib_cpu_supports_x86_aes (); +#elif defined (__aarch64__) + return clib_cpu_supports_aarch64_aes (); +#else + return 0; #endif -#endif - format_function_t format_cpu_uarch; +} + +#endif /* included_clib_cpu_h */ + +format_function_t format_cpu_uarch; format_function_t format_cpu_model_name; format_function_t format_cpu_flags; -- 2.16.6