vppinfra: add AMD EPYC cpu family details

Type: feature

- Added support for AMD EPYC processor family

Change-Id: I60da87cca429117c209d240e5a5f3b4d9f4981d8
Signed-off-by: Sivaprasad Tummala <sivaprasad.tummala@amd.com>
diff --git a/src/vppinfra/cpu.c b/src/vppinfra/cpu.c
index 4f6b46f..735a183 100644
--- a/src/vppinfra/cpu.c
+++ b/src/vppinfra/cpu.c
@@ -93,13 +93,34 @@
 #if __x86_64__
   u32 __attribute__ ((unused)) eax, ebx, ecx, edx;
   u8 model, family, stepping;
+  u8 amd_vendor = 0;
+
+  if (__get_cpuid (0, &eax, &ebx, &ecx, &edx) == 0)
+    return format (s, "unknown (missing cpuid)");
+
+  if (amd_vendor (ebx, ecx, edx))
+    amd_vendor = 1;
 
   if (__get_cpuid (1, &eax, &ebx, &ecx, &edx) == 0)
     return format (s, "unknown (missing cpuid)");
 
-  model = ((eax >> 4) & 0x0f) | ((eax >> 12) & 0xf0);
-  family = (eax >> 8) & 0x0f;
   stepping = eax & 0x0f;
+  if (amd_vendor)
+    {
+      family = ((eax >> 8) & 0x0f);
+      model = ((eax >> 4) & 0x0f);
+      if (family >= 0xf)
+	{
+	  family = family + ((eax >> 20) & 0xf);
+	  model = (model | ((eax >> 12) & 0xf0));
+	}
+      return format (s, "Zen (family 0x%02x model 0x%02x)", family, model);
+    }
+  else
+    {
+      model = ((eax >> 4) & 0x0f) | ((eax >> 12) & 0xf0);
+      family = (eax >> 8) & 0x0f;
+    }
 
 #define _(f,m,a,c) if ((model == m) && (family == f)) return \
 format(s, "[0x%x] %s ([0x%02x] %s) stepping 0x%x", f, a, m, c, stepping);
diff --git a/src/vppinfra/cpu.h b/src/vppinfra/cpu.h
index 60439e0..29992bb 100644
--- a/src/vppinfra/cpu.h
+++ b/src/vppinfra/cpu.h
@@ -39,6 +39,10 @@
 #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,