16 #ifndef included_clib_cpu_h 17 #define included_clib_cpu_h 19 #include <sys/syscall.h> 22 #if defined(__x86_64__) 23 #define foreach_march_variant \ 24 _ (hsw, "Intel Haswell") \ 25 _ (trm, "Intel Tremont") \ 26 _ (skx, "Intel Skylake (server) / Cascade Lake") \ 27 _ (icl, "Intel Ice Lake") 28 #elif defined(__aarch64__) 29 #define foreach_march_variant \ 30 _ (octeontx2, "Marvell Octeon TX2") \ 31 _ (thunderx2t99, "Marvell ThunderX2 T99") \ 32 _ (qdf24xx, "Qualcomm CentriqTM 2400") \ 33 _ (cortexa72, "ARM Cortex-A72") \ 34 _ (neoversen1, "ARM Neoverse N1") 36 #define foreach_march_variant 42 #define _(s, n) CLIB_MARCH_VARIANT_TYPE_##s, 48 #ifdef CLIB_MARCH_VARIANT 49 #define __CLIB_MULTIARCH_FN(a,b) a##_##b 50 #define _CLIB_MULTIARCH_FN(a,b) __CLIB_MULTIARCH_FN(a,b) 51 #define CLIB_MULTIARCH_FN(fn) _CLIB_MULTIARCH_FN(fn,CLIB_MARCH_VARIANT) 53 #define CLIB_MULTIARCH_FN(fn) fn 56 #define CLIB_MARCH_SFX CLIB_MULTIARCH_FN 58 typedef struct _clib_march_fn_registration
62 struct _clib_march_fn_registration *
next;
76 last_prio = r->priority;
84 #define CLIB_MARCH_FN_POINTER(fn) \ 85 (__typeof__ (fn) *) clib_march_select_fn_ptr (fn##_march_fn_registrations); 87 #define _CLIB_MARCH_FN_REGISTRATION(fn) \ 88 static clib_march_fn_registration \ 89 CLIB_MARCH_SFX(fn##_march_fn_registration) = \ 91 .name = CLIB_MARCH_VARIANT_STR \ 94 static void __clib_constructor \ 95 fn##_march_register () \ 97 clib_march_fn_registration *r; \ 98 r = & CLIB_MARCH_SFX (fn##_march_fn_registration); \ 99 r->priority = CLIB_MARCH_FN_PRIORITY(); \ 100 r->next = fn##_march_fn_registrations; \ 101 r->function = CLIB_MARCH_SFX (fn); \ 102 fn##_march_fn_registrations = r; \ 105 #ifdef CLIB_MARCH_VARIANT 106 #define CLIB_MARCH_FN_REGISTRATION(fn) \ 107 extern clib_march_fn_registration *fn##_march_fn_registrations; \ 108 _CLIB_MARCH_FN_REGISTRATION(fn) 110 #define CLIB_MARCH_FN_REGISTRATION(fn) \ 111 clib_march_fn_registration *fn##_march_fn_registrations = 0; \ 112 _CLIB_MARCH_FN_REGISTRATION(fn) 114 #define foreach_x86_64_flags \ 115 _ (sse3, 1, ecx, 0) \ 116 _ (pclmulqdq, 1, ecx, 1) \ 117 _ (ssse3, 1, ecx, 9) \ 118 _ (sse41, 1, ecx, 19) \ 119 _ (sse42, 1, ecx, 20) \ 120 _ (avx, 1, ecx, 28) \ 121 _ (rdrand, 1, ecx, 30) \ 122 _ (avx2, 7, ebx, 5) \ 123 _ (rtm, 7, ebx, 11) \ 124 _ (pqm, 7, ebx, 12) \ 125 _ (pqe, 7, ebx, 15) \ 126 _ (avx512f, 7, ebx, 16) \ 127 _ (rdseed, 7, ebx, 18) \ 128 _ (x86_aes, 1, ecx, 25) \ 129 _ (sha, 7, ebx, 29) \ 130 _ (vaes, 7, ecx, 9) \ 131 _ (vpclmulqdq, 7, ecx, 10) \ 132 _ (avx512_vnni, 7, ecx, 11) \ 133 _ (avx512_bitalg, 7, ecx, 12) \ 134 _ (avx512_vpopcntdq, 7, ecx, 14) \ 135 _ (movdiri, 7, ecx, 27) \ 136 _ (movdir64b, 7, ecx, 28) \ 137 _ (invariant_tsc, 0x80000007, edx, 8) 139 #define foreach_aarch64_flags \ 167 #if defined(__x86_64__) 173 if ((
u32) __get_cpuid_max (0x80000000 & lev, 0) < lev)
176 __cpuid_count (lev, 0, *eax, *ebx, *ecx, *edx);
178 __cpuid (lev, *eax, *ebx, *ecx, *edx);
184 #define _(flag, func, reg, bit) \ 186 clib_cpu_supports_ ## flag() \ 188 u32 __attribute__((unused)) eax, ebx = 0, ecx = 0, edx = 0; \ 189 clib_get_cpuid (func, &eax, &ebx, &ecx, &edx); \ 191 return ((reg & (1 << bit)) != 0); \ 197 #define _(flag, func, reg, bit) \ 198 static inline int clib_cpu_supports_ ## flag() { return 0; } 202 #if defined(__aarch64__) 203 #include <sys/auxv.h> 204 #define _(flag, bit) \ 206 clib_cpu_supports_ ## flag() \ 208 unsigned long hwcap = getauxval(AT_HWCAP); \ 209 return (hwcap & (1 << bit)); \ 214 #define _(flag, bit) \ 215 static inline int clib_cpu_supports_ ## flag() { return 0; } 227 #if defined(__x86_64__) 228 return clib_cpu_supports_x86_aes ();
229 #elif defined (__aarch64__) 230 return clib_cpu_supports_aarch64_aes ();
239 if (clib_cpu_supports_avx512_bitalg ())
247 if (clib_cpu_supports_avx512f ())
255 if (clib_cpu_supports_movdiri ())
263 if (clib_cpu_supports_avx2 ())
272 static u32 implementer = -1;
274 if (-1 != implementer)
277 FILE *fp = fopen (
"/proc/cpuinfo",
"r");
283 if (!fgets (buf,
sizeof (buf), fp))
286 if (strstr (buf,
"CPU implementer"))
287 implementer = (
u32) strtol (memchr (buf,
':', 128) + 2, NULL, 0);
288 if (-1 != implementer)
300 static u32 part = -1;
305 FILE *fp = fopen (
"/proc/cpuinfo",
"r");
311 if (!fgets (buf,
sizeof (buf), fp))
314 if (strstr (buf,
"CPU part"))
315 part = (
u32) strtol (memchr (buf,
':', 128) + 2, NULL, 0);
324 #define AARCH64_CPU_IMPLEMENTER_CAVIUM 0x43 325 #define AARCH64_CPU_PART_THUNDERX2 0x0af 326 #define AARCH64_CPU_PART_OCTEONTX2T96 0x0b2 327 #define AARCH64_CPU_PART_OCTEONTX2T98 0x0b1 328 #define AARCH64_CPU_IMPLEMENTER_QDF24XX 0x51 329 #define AARCH64_CPU_PART_QDF24XX 0xc00 330 #define AARCH64_CPU_IMPLEMENTER_CORTEXA72 0x41 331 #define AARCH64_CPU_PART_CORTEXA72 0xd08 332 #define AARCH64_CPU_IMPLEMENTER_NEOVERSEN1 0x41 333 #define AARCH64_CPU_PART_NEOVERSEN1 0xd0c 381 #ifdef CLIB_MARCH_VARIANT 382 #define CLIB_MARCH_FN_PRIORITY() CLIB_MARCH_SFX(clib_cpu_march_priority)() 384 #define CLIB_MARCH_FN_PRIORITY() 0 388 #define CLIB_MARCH_FN_CONSTRUCTOR(fn) \ 389 static void __clib_constructor \ 390 CLIB_MARCH_SFX(fn ## _march_constructor) (void) \ 392 if (CLIB_MARCH_FN_PRIORITY() > fn ## _selected_priority) \ 394 fn ## _selected = & CLIB_MARCH_SFX (fn ## _ma); \ 395 fn ## _selected_priority = CLIB_MARCH_FN_PRIORITY(); \ 399 #ifndef CLIB_MARCH_VARIANT 400 #define CLIB_MARCH_FN(fn, rtype, _args...) \ 401 static rtype CLIB_MARCH_SFX (fn##_ma) (_args); \ 402 rtype (*fn##_selected) (_args) = &CLIB_MARCH_SFX (fn##_ma); \ 403 int fn##_selected_priority = 0; \ 404 static inline rtype CLIB_MARCH_SFX (fn##_ma) (_args) 406 #define CLIB_MARCH_FN(fn, rtype, _args...) \ 407 static rtype CLIB_MARCH_SFX (fn##_ma) (_args); \ 408 extern rtype (*fn##_selected) (_args); \ 409 extern int fn##_selected_priority; \ 410 CLIB_MARCH_FN_CONSTRUCTOR (fn) \ 411 static rtype CLIB_MARCH_SFX (fn##_ma) (_args) 414 #define CLIB_MARCH_FN_SELECT(fn) (* fn ## _selected) static int clib_cpu_march_priority_cortexa72()
clib_march_variant_type_t
#define AARCH64_CPU_IMPLEMENTER_NEOVERSEN1
static int clib_cpu_march_priority_trm()
static int clib_cpu_march_priority_octeontx2()
vnet_hw_if_output_node_runtime_t * r
static int clib_cpu_march_priority_neoversen1()
#define AARCH64_CPU_PART_OCTEONTX2T96
format_function_t format_cpu_flags
static int clib_cpu_march_priority_hsw()
#define foreach_aarch64_flags
format_function_t format_march_variant
static int clib_cpu_march_priority_skx()
#define static_always_inline
#define AARCH64_CPU_IMPLEMENTER_CAVIUM
static u32 clib_cpu_part()
#define AARCH64_CPU_PART_QDF24XX
#define AARCH64_CPU_PART_NEOVERSEN1
#define foreach_march_variant
static int clib_cpu_march_priority_thunderx2t99()
static int clib_get_cpuid(const u32 lev, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx)
static u32 clib_cpu_implementer()
#define AARCH64_CPU_PART_OCTEONTX2T98
#define foreach_x86_64_flags
struct _clib_march_fn_registration clib_march_fn_registration
static_always_inline void * clib_march_select_fn_ptr(clib_march_fn_registration *r)
static foreach_aarch64_flags int clib_cpu_supports_aes()
#define AARCH64_CPU_IMPLEMENTER_CORTEXA72
static int clib_cpu_march_priority_qdf24xx()
format_function_t format_cpu_uarch
#define AARCH64_CPU_PART_THUNDERX2
int(* clib_cpu_supports_func_t)()
u32 clib_get_current_cpu_id()
u32 clib_get_current_numa_node()
format_function_t format_cpu_model_name
#define AARCH64_CPU_PART_CORTEXA72
static int clib_cpu_march_priority_icl()
#define AARCH64_CPU_IMPLEMENTER_QDF24XX