16 #ifndef included_clib_cpu_h 17 #define included_clib_cpu_h 19 #include <sys/syscall.h> 29 #if __x86_64__ && CLIB_DEBUG == 0 30 #define foreach_march_variant(macro, x) \ 31 macro(avx2, x, "arch=core-avx2") 33 #define foreach_march_variant(macro, x) 37 #if __GNUC__ > 4 && !__clang__ && CLIB_DEBUG == 0 38 #define CLIB_CPU_OPTIMIZED __attribute__ ((optimize ("O3"))) 40 #define CLIB_CPU_OPTIMIZED 44 #define CLIB_MULTIARCH_ARCH_CHECK(arch, fn, tgt) \ 45 if (clib_cpu_supports_ ## arch()) \ 46 return & fn ## _ ##arch; 49 #define CLIB_MULTIARCH_SELECT_FN(fn,...) 51 #ifdef CLIB_MARCH_VARIANT 52 #define __CLIB_MULTIARCH_FN(a,b) a##_##b 53 #define _CLIB_MULTIARCH_FN(a,b) __CLIB_MULTIARCH_FN(a,b) 54 #define CLIB_MULTIARCH_FN(fn) _CLIB_MULTIARCH_FN(fn,CLIB_MARCH_VARIANT) 56 #define CLIB_MULTIARCH_FN(fn) fn 59 #define CLIB_MARCH_SFX CLIB_MULTIARCH_FN 61 typedef struct _clib_march_fn_registration
65 struct _clib_march_fn_registration *next;
79 last_prio = r->priority;
87 #define CLIB_MARCH_FN_POINTER(fn) \ 88 clib_march_select_fn_ptr (fn##_march_fn_registrations); 90 #define _CLIB_MARCH_FN_REGISTRATION(fn) \ 91 static clib_march_fn_registration \ 92 CLIB_MARCH_SFX(fn##_march_fn_registration) = \ 94 .name = CLIB_MARCH_VARIANT_STR \ 97 static void __clib_constructor \ 98 fn##_march_register () \ 100 clib_march_fn_registration *r; \ 101 r = & CLIB_MARCH_SFX (fn##_march_fn_registration); \ 102 r->priority = CLIB_MARCH_FN_PRIORITY(); \ 103 r->next = fn##_march_fn_registrations; \ 104 r->function = CLIB_MARCH_SFX (fn); \ 105 fn##_march_fn_registrations = r; \ 108 #ifdef CLIB_MARCH_VARIANT 109 #define CLIB_MARCH_FN_REGISTRATION(fn) \ 110 extern clib_march_fn_registration *fn##_march_fn_registrations; \ 111 _CLIB_MARCH_FN_REGISTRATION(fn) 113 #define CLIB_MARCH_FN_REGISTRATION(fn) \ 114 clib_march_fn_registration *fn##_march_fn_registrations = 0; \ 115 _CLIB_MARCH_FN_REGISTRATION(fn) 117 #define foreach_x86_64_flags \ 118 _ (sse3, 1, ecx, 0) \ 119 _ (ssse3, 1, ecx, 9) \ 120 _ (sse41, 1, ecx, 19) \ 121 _ (sse42, 1, ecx, 20) \ 122 _ (avx, 1, ecx, 28) \ 123 _ (rdrand, 1, ecx, 30) \ 124 _ (avx2, 7, ebx, 5) \ 125 _ (rtm, 7, ebx, 11) \ 126 _ (pqm, 7, ebx, 12) \ 127 _ (pqe, 7, ebx, 15) \ 128 _ (avx512f, 7, ebx, 16) \ 129 _ (rdseed, 7, ebx, 18) \ 130 _ (x86_aes, 1, ecx, 25) \ 131 _ (sha, 7, ebx, 29) \ 132 _ (vaes, 7, ecx, 9) \ 133 _ (vpclmulqdq, 7, ecx, 10) \ 134 _ (invariant_tsc, 0x80000007, edx, 8) 137 #define foreach_aarch64_flags \ 166 syscall (__NR_getcpu, &cpu, &node, 0);
174 syscall (__NR_getcpu, &cpu, &node, 0);
178 #if defined(__x86_64__) 184 if ((
u32) __get_cpuid_max (0x80000000 & lev, 0) < lev)
187 __cpuid_count (lev, 0, *eax, *ebx, *ecx, *edx);
189 __cpuid (lev, *eax, *ebx, *ecx, *edx);
194 #define _(flag, func, reg, bit) \ 196 clib_cpu_supports_ ## flag() \ 198 u32 __attribute__((unused)) eax, ebx = 0, ecx = 0, edx = 0; \ 199 clib_get_cpuid (func, &eax, &ebx, &ecx, &edx); \ 201 return ((reg & (1 << bit)) != 0); \ 207 #define _(flag, func, reg, bit) \ 208 static inline int clib_cpu_supports_ ## flag() { return 0; } 212 #if defined(__aarch64__) 213 #include <sys/auxv.h> 214 #define _(flag, bit) \ 216 clib_cpu_supports_ ## flag() \ 218 unsigned long hwcap = getauxval(AT_HWCAP); \ 219 return (hwcap & (1 << bit)); \ 224 #define _(flag, bit) \ 225 static inline int clib_cpu_supports_ ## flag() { return 0; } 237 #if defined (__aarch64__) 238 return clib_cpu_supports_x86_aes ();
239 #elif defined (__aarch64__) 240 return clib_cpu_supports_aarch64_aes ();
249 if (clib_cpu_supports_avx512f ())
257 if (clib_cpu_supports_avx2 ())
266 static u32 implementer = -1;
268 if (-1 != implementer)
271 FILE *fp = fopen (
"/proc/cpuinfo",
"r");
277 if (!fgets (buf,
sizeof (buf), fp))
280 if (strstr (buf,
"CPU implementer"))
281 implementer = (
u32) strtol (memchr (buf,
':', 128) + 2,
NULL, 0);
282 if (-1 != implementer)
294 static u32 part = -1;
299 FILE *fp = fopen (
"/proc/cpuinfo",
"r");
305 if (!fgets (buf,
sizeof (buf), fp))
308 if (strstr (buf,
"CPU part"))
309 part = (
u32) strtol (memchr (buf,
':', 128) + 2,
NULL, 0);
318 #define AARCH64_CPU_IMPLEMENTER_THUNERDERX2 0x43 319 #define AARCH64_CPU_PART_THUNERDERX2 0x0af 320 #define AARCH64_CPU_IMPLEMENTER_QDF24XX 0x51 321 #define AARCH64_CPU_PART_QDF24XX 0xc00 322 #define AARCH64_CPU_IMPLEMENTER_CORTEXA72 0x41 323 #define AARCH64_CPU_PART_CORTEXA72 0xd08 352 #ifdef CLIB_MARCH_VARIANT 353 #define CLIB_MARCH_FN_PRIORITY() CLIB_MARCH_SFX(clib_cpu_march_priority)() 355 #define CLIB_MARCH_FN_PRIORITY() 0 359 #define CLIB_MARCH_FN_CONSTRUCTOR(fn) \ 360 static void __clib_constructor \ 361 CLIB_MARCH_SFX(fn ## _march_constructor) (void) \ 363 if (CLIB_MARCH_FN_PRIORITY() > fn ## _selected_priority) \ 365 fn ## _selected = & CLIB_MARCH_SFX (fn ## _ma); \ 366 fn ## _selected_priority = CLIB_MARCH_FN_PRIORITY(); \ 370 #ifndef CLIB_MARCH_VARIANT 371 #define CLIB_MARCH_FN(fn, rtype, _args...) \ 372 static rtype CLIB_CPU_OPTIMIZED CLIB_MARCH_SFX (fn ## _ma)(_args); \ 373 rtype (*fn ## _selected) (_args) = & CLIB_MARCH_SFX (fn ## _ma); \ 374 int fn ## _selected_priority = 0; \ 375 static inline rtype CLIB_CPU_OPTIMIZED \ 376 CLIB_MARCH_SFX (fn ## _ma)(_args) 378 #define CLIB_MARCH_FN(fn, rtype, _args...) \ 379 static rtype CLIB_CPU_OPTIMIZED CLIB_MARCH_SFX (fn ## _ma)(_args); \ 380 extern rtype (*fn ## _selected) (_args); \ 381 extern int fn ## _selected_priority; \ 382 CLIB_MARCH_FN_CONSTRUCTOR (fn) \ 383 static rtype CLIB_CPU_OPTIMIZED CLIB_MARCH_SFX (fn ## _ma)(_args) 386 #define CLIB_MARCH_FN_SELECT(fn) (* fn ## _selected) static int clib_cpu_march_priority_cortexa72()
#define AARCH64_CPU_IMPLEMENTER_THUNERDERX2
static u32 clib_get_current_numa_node()
static u32 clib_get_current_cpu_id()
format_function_t format_cpu_flags
#define foreach_aarch64_flags
#define static_always_inline
static u32 clib_cpu_part()
static int clib_cpu_march_priority_avx512()
#define AARCH64_CPU_PART_QDF24XX
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()
static int clib_cpu_march_priority_avx2()
#define foreach_x86_64_flags
struct _clib_march_fn_registration clib_march_fn_registration
#define AARCH64_CPU_PART_THUNERDERX2
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
format_function_t format_cpu_model_name
#define AARCH64_CPU_PART_CORTEXA72
#define AARCH64_CPU_IMPLEMENTER_QDF24XX