aboutsummaryrefslogtreecommitdiffstats
path: root/src/vppinfra/cpu.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/vppinfra/cpu.h')
-rw-r--r--src/vppinfra/cpu.h212
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;
}