diff options
Diffstat (limited to 'src/vppinfra/cpu.h')
-rw-r--r-- | src/vppinfra/cpu.h | 212 |
1 files changed, 142 insertions, 70 deletions
diff --git a/src/vppinfra/cpu.h b/src/vppinfra/cpu.h index c1f2e9e8248..7a1b75fcf7d 100644 --- a/src/vppinfra/cpu.h +++ b/src/vppinfra/cpu.h @@ -21,21 +21,31 @@ #if defined(__x86_64__) #define foreach_march_variant \ + _ (scalar, "Generic (SIMD disabled)") \ _ (hsw, "Intel Haswell") \ _ (trm, "Intel Tremont") \ _ (skx, "Intel Skylake (server) / Cascade Lake") \ - _ (icl, "Intel Ice Lake") + _ (icl, "Intel Ice Lake") \ + _ (adl, "Intel Alder Lake") \ + _ (spr, "Intel Sapphire Rapids") \ + _ (znver3, "AMD Milan") \ + _ (znver4, "AMD Genoa") #elif defined(__aarch64__) #define foreach_march_variant \ _ (octeontx2, "Marvell Octeon TX2") \ _ (thunderx2t99, "Marvell ThunderX2 T99") \ _ (qdf24xx, "Qualcomm CentriqTM 2400") \ _ (cortexa72, "ARM Cortex-A72") \ - _ (neoversen1, "ARM Neoverse N1") + _ (neoversen1, "ARM Neoverse N1") \ + _ (neoversen2, "ARM Neoverse N2") #else #define foreach_march_variant #endif +#define amd_vendor(t1, t2, t3) \ + ((t1 == 0x68747541) && /* htuA */ \ + (t2 == 0x444d4163) && /* DMAc */ \ + (t3 == 0x69746e65)) /* itne */ typedef enum { CLIB_MARCH_VARIANT_TYPE = 0, @@ -84,6 +94,9 @@ clib_march_select_fn_ptr (clib_march_fn_registration * r) #define CLIB_MARCH_FN_POINTER(fn) \ (__typeof__ (fn) *) clib_march_select_fn_ptr (fn##_march_fn_registrations); +#define CLIB_MARCH_FN_VOID_POINTER(fn) \ + clib_march_select_fn_ptr (fn##_march_fn_registrations); + #define _CLIB_MARCH_FN_REGISTRATION(fn) \ static clib_march_fn_registration \ CLIB_MARCH_SFX(fn##_march_fn_registration) = \ @@ -120,6 +133,7 @@ _CLIB_MARCH_FN_REGISTRATION(fn) _ (avx, 1, ecx, 28) \ _ (rdrand, 1, ecx, 30) \ _ (avx2, 7, ebx, 5) \ + _ (bmi2, 7, ebx, 8) \ _ (rtm, 7, ebx, 11) \ _ (pqm, 7, ebx, 12) \ _ (pqe, 7, ebx, 15) \ @@ -134,7 +148,10 @@ _CLIB_MARCH_FN_REGISTRATION(fn) _ (avx512_vpopcntdq, 7, ecx, 14) \ _ (movdiri, 7, ecx, 27) \ _ (movdir64b, 7, ecx, 28) \ - _ (invariant_tsc, 0x80000007, edx, 8) + _ (enqcmd, 7, ecx, 29) \ + _ (avx512_fp16, 7, edx, 23) \ + _ (invariant_tsc, 0x80000007, edx, 8) \ + _ (monitorx, 0x80000001, ecx, 29) #define foreach_aarch64_flags \ _ (fp, 0) \ @@ -161,8 +178,10 @@ _ (asimddp, 20) \ _ (sha512, 21) \ _ (sve, 22) -u32 clib_get_current_cpu_id (); -u32 clib_get_current_numa_node (); +u32 clib_get_current_cpu_id (void); +u32 clib_get_current_numa_node (void); + +typedef int (*clib_cpu_supports_func_t) (void); #if defined(__x86_64__) #include "cpuid.h" @@ -179,8 +198,6 @@ clib_get_cpuid (const u32 lev, u32 * eax, u32 * ebx, u32 * ecx, u32 * edx) return 1; } -typedef int (*clib_cpu_supports_func_t) (); - #define _(flag, func, reg, bit) \ static inline int \ clib_cpu_supports_ ## flag() \ @@ -234,6 +251,20 @@ clib_cpu_supports_aes () } static inline int +clib_cpu_march_priority_scalar () +{ + return 1; +} + +static inline int +clib_cpu_march_priority_spr () +{ + if (clib_cpu_supports_enqcmd ()) + return 300; + return -1; +} + +static inline int clib_cpu_march_priority_icl () { if (clib_cpu_supports_avx512_bitalg ()) @@ -242,6 +273,14 @@ clib_cpu_march_priority_icl () } static inline int +clib_cpu_march_priority_adl () +{ + if (clib_cpu_supports_movdiri () && clib_cpu_supports_avx2 ()) + return 150; + return -1; +} + +static inline int clib_cpu_march_priority_skx () { if (clib_cpu_supports_avx512f ()) @@ -253,7 +292,7 @@ static inline int clib_cpu_march_priority_trm () { if (clib_cpu_supports_movdiri ()) - return 60; + return 40; return -1; } @@ -265,116 +304,149 @@ clib_cpu_march_priority_hsw () return -1; } -static inline u32 -clib_cpu_implementer () +static inline int +clib_cpu_march_priority_znver4 () { - char buf[128]; - static u32 implementer = -1; - - if (-1 != implementer) - return implementer; - - FILE *fp = fopen ("/proc/cpuinfo", "r"); - if (!fp) - return implementer; - - while (!feof (fp)) - { - if (!fgets (buf, sizeof (buf), fp)) - break; - buf[127] = '\0'; - if (strstr (buf, "CPU implementer")) - implementer = (u32) strtol (memchr (buf, ':', 128) + 2, NULL, 0); - if (-1 != implementer) - break; - } - fclose (fp); - - return implementer; + if (clib_cpu_supports_avx512_bitalg () && clib_cpu_supports_monitorx ()) + return 250; + return -1; } -static inline u32 -clib_cpu_part () +static inline int +clib_cpu_march_priority_znver3 () { - char buf[128]; - static u32 part = -1; + if (clib_cpu_supports_avx2 () && clib_cpu_supports_monitorx ()) + return 70; + return -1; +} - if (-1 != part) - return part; +#define X86_CPU_ARCH_PERF_FUNC 0xA - FILE *fp = fopen ("/proc/cpuinfo", "r"); - if (!fp) - return part; +static inline int +clib_get_pmu_counter_count (u8 *fixed, u8 *general) +{ +#if defined(__x86_64__) + u32 __clib_unused eax = 0, ebx = 0, ecx = 0, edx = 0; + clib_get_cpuid (X86_CPU_ARCH_PERF_FUNC, &eax, &ebx, &ecx, &edx); - while (!feof (fp)) - { - if (!fgets (buf, sizeof (buf), fp)) - break; - buf[127] = '\0'; - if (strstr (buf, "CPU part")) - part = (u32) strtol (memchr (buf, ':', 128) + 2, NULL, 0); - if (-1 != part) - break; - } - fclose (fp); + *general = (eax & 0xFF00) >> 8; + *fixed = (edx & 0xF); - return part; + return 1; +#else + return 0; +#endif } +typedef struct +{ + struct + { + u8 implementer; + u16 part_num; + } aarch64; +} clib_cpu_info_t; + +const clib_cpu_info_t *clib_get_cpu_info (); + +/* ARM */ +#define AARCH64_CPU_IMPLEMENTER_ARM 0x41 +#define AARCH64_CPU_PART_CORTEXA72 0xd08 +#define AARCH64_CPU_PART_NEOVERSEN1 0xd0c +#define AARCH64_CPU_PART_NEOVERSEN2 0xd49 + +/*cavium */ #define AARCH64_CPU_IMPLEMENTER_CAVIUM 0x43 #define AARCH64_CPU_PART_THUNDERX2 0x0af #define AARCH64_CPU_PART_OCTEONTX2T96 0x0b2 #define AARCH64_CPU_PART_OCTEONTX2T98 0x0b1 -#define AARCH64_CPU_IMPLEMENTER_QDF24XX 0x51 + +/* Qualcomm */ +#define AARCH64_CPU_IMPLEMENTER_QUALCOMM 0x51 #define AARCH64_CPU_PART_QDF24XX 0xc00 -#define AARCH64_CPU_IMPLEMENTER_CORTEXA72 0x41 -#define AARCH64_CPU_PART_CORTEXA72 0xd08 -#define AARCH64_CPU_IMPLEMENTER_NEOVERSEN1 0x41 -#define AARCH64_CPU_PART_NEOVERSEN1 0xd0c static inline int clib_cpu_march_priority_octeontx2 () { - if ((AARCH64_CPU_IMPLEMENTER_CAVIUM == clib_cpu_implementer ()) && - ((AARCH64_CPU_PART_OCTEONTX2T96 == clib_cpu_part ()) - || AARCH64_CPU_PART_OCTEONTX2T98 == clib_cpu_part ())) + const clib_cpu_info_t *info = clib_get_cpu_info (); + + if (!info || info->aarch64.implementer != AARCH64_CPU_IMPLEMENTER_CAVIUM) + return -1; + + if (info->aarch64.part_num == AARCH64_CPU_PART_OCTEONTX2T96 || + info->aarch64.part_num == AARCH64_CPU_PART_OCTEONTX2T98) return 20; + return -1; } static inline int clib_cpu_march_priority_thunderx2t99 () { - if ((AARCH64_CPU_IMPLEMENTER_CAVIUM == clib_cpu_implementer ()) && - (AARCH64_CPU_PART_THUNDERX2 == clib_cpu_part ())) + const clib_cpu_info_t *info = clib_get_cpu_info (); + + if (!info || info->aarch64.implementer != AARCH64_CPU_IMPLEMENTER_CAVIUM) + return -1; + + if (info->aarch64.part_num == AARCH64_CPU_PART_THUNDERX2) return 20; + return -1; } static inline int clib_cpu_march_priority_qdf24xx () { - if ((AARCH64_CPU_IMPLEMENTER_QDF24XX == clib_cpu_implementer ()) && - (AARCH64_CPU_PART_QDF24XX == clib_cpu_part ())) + const clib_cpu_info_t *info = clib_get_cpu_info (); + + if (!info || info->aarch64.implementer != AARCH64_CPU_IMPLEMENTER_QUALCOMM) + return -1; + + if (info->aarch64.part_num == AARCH64_CPU_PART_QDF24XX) return 20; + return -1; } static inline int clib_cpu_march_priority_cortexa72 () { - if ((AARCH64_CPU_IMPLEMENTER_CORTEXA72 == clib_cpu_implementer ()) && - (AARCH64_CPU_PART_CORTEXA72 == clib_cpu_part ())) + const clib_cpu_info_t *info = clib_get_cpu_info (); + + if (!info || info->aarch64.implementer != AARCH64_CPU_IMPLEMENTER_ARM) + return -1; + + if (info->aarch64.part_num == AARCH64_CPU_PART_CORTEXA72) return 10; + return -1; } static inline int clib_cpu_march_priority_neoversen1 () { - if ((AARCH64_CPU_IMPLEMENTER_NEOVERSEN1 == clib_cpu_implementer ()) && - (AARCH64_CPU_PART_NEOVERSEN1 == clib_cpu_part ())) + const clib_cpu_info_t *info = clib_get_cpu_info (); + + if (!info || info->aarch64.implementer != AARCH64_CPU_IMPLEMENTER_ARM) + return -1; + + if (info->aarch64.part_num == AARCH64_CPU_PART_NEOVERSEN1) + return 10; + + return -1; +} + +static inline int +clib_cpu_march_priority_neoversen2 () +{ + const clib_cpu_info_t *info = clib_get_cpu_info (); + + if (!info || info->aarch64.implementer != AARCH64_CPU_IMPLEMENTER_ARM) + return -1; + + if (info->aarch64.part_num == AARCH64_CPU_PART_NEOVERSEN2) return 10; + return -1; } |