[PATCH v2] fhandler_proc.cc(format_proc_cpuinfo): fix issues, add fields, flags

Brian Inglis Brian.Inglis@SystematicSW.ab.ca
Sat Oct 5 22:24:00 GMT 2019


fix cache size return code handling and make AMD/Intel code common;
fix cpuid level count as number of non-zero leafs excluding sub-leafs;
fix AMD physical cores count to be documented nc + 1;
round cpu MHz to correct Windows and match Linux cpuinfo;
add microcode from Windows registry Update Revision REG_BINARY;
add bogomips which has been cpu MHz*2 since Pentium MMX;
handle as common former Intel only feature flags also supported on AMD;
add 88 feature flags inc. AVX512 extensions, AES, SHA with 20 cpuid calls;
commented out flags are mostly not reported by Linux in cpuinfo but some
may not be used by Linux

---
 winsup/cygwin/fhandler_proc.cc | 747 +++++++++++++++++++--------------
 1 file changed, 442 insertions(+), 305 deletions(-)

diff --git a/winsup/cygwin/fhandler_proc.cc b/winsup/cygwin/fhandler_proc.cc
index 48476beb8..386bd20d5 100644
--- a/winsup/cygwin/fhandler_proc.cc
+++ b/winsup/cygwin/fhandler_proc.cc
@@ -609,6 +609,8 @@ format_proc_stat (void *, char *&destbuf)
 }
 
 #define print(x) { bufptr = stpcpy (bufptr, (x)); }
+/* feature test bit position (0-32) and conditional print */
+#define ftcprint(feat,bitno,msg) if ((feat) & (1 << (bitno))) { print (" " msg); }
 
 static inline uint32_t
 get_msb (uint32_t in)
@@ -686,15 +688,36 @@ format_proc_cpuinfo (void *, char *&destbuf)
 	 to be rescheduled */
       yield ();
 
-      DWORD cpu_mhz = 0;
-      RTL_QUERY_REGISTRY_TABLE tab[2] = {
-	{ NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOSTRING,
-	  L"~Mhz", &cpu_mhz, REG_NONE, NULL, 0 },
-	{ NULL, 0, NULL, NULL, 0, NULL, 0 }
-      };
+      DWORD cpu_mhz;
+      DWORD bogomips;
+      long long microcode;	/* at least 8 bytes for AMD */
+      union
+        {
+	  LONG uc_len;		/* -max size of buffer before call */
+	  char uc_microcode[16];
+        } uc;
+
+      cpu_mhz = 0;
+      bogomips = 0;
+      microcode = 0;
+      memset (&uc, 0, sizeof (uc.uc_microcode));
+      uc.uc_len = -16;	/* -max length of microcode buffer */
+
+      RTL_QUERY_REGISTRY_TABLE tab[3] =
+        {
+	  { NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOSTRING,
+	    L"~Mhz", &cpu_mhz, REG_NONE, NULL, 0 },
+	  { NULL, RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_NOSTRING,
+	    L"Update Revision", &uc, REG_NONE, NULL, 0 },
+	  { NULL, 0, NULL, NULL, 0, NULL, 0 }
+        };
 
       RtlQueryRegistryValues (RTL_REGISTRY_ABSOLUTE, cpu_key, tab,
 			      NULL, NULL);
+      cpu_mhz = ((cpu_mhz - 1) / 10 + 1) * 10;	/* round up to multiple of 10 */
+      bogomips = cpu_mhz * 2;	/* bogomips is double cpu MHz since MMX */
+      memcpy (&microcode, &uc, sizeof (microcode));
+
       bufptr += __small_sprintf (bufptr, "processor\t: %d\n", cpu_number);
       uint32_t maxf, vendor_id[4], unused;
 
@@ -720,9 +743,9 @@ format_proc_cpuinfo (void *, char *&destbuf)
 	       stepping		= cpuid_sig   & 0x0000000f,
 	       apic_id		= (extra_info & 0xff000000) >> 24;
       if (family == 15)
-	family += (cpuid_sig >> 20) & 0xff;
+	family += (cpuid_sig >> 20) & 0xff;	/* ext family + family */
       if (family >= 6)
-	model += ((cpuid_sig >> 16) & 0x0f) << 4;
+	model |= ((cpuid_sig >> 16) & 0x0f) << 4; /* ext model << 4 | model */
 
       uint32_t maxe = 0;
       cpuid (&maxe, &unused, &unused, &unused, 0x80000000);
@@ -744,6 +767,8 @@ format_proc_cpuinfo (void *, char *&destbuf)
       int cache_size = -1,
 	  clflush = 64,
 	  cache_alignment = 64;
+      long (*get_cpu_cache) (int, uint32_t) = NULL;
+      uint32_t max;
       if (features1 & (1 << 19)) /* CLFSH */
 	clflush = ((extra_info >> 8) & 0xff) << 3;
       if (is_intel && family == 15)
@@ -751,56 +776,47 @@ format_proc_cpuinfo (void *, char *&destbuf)
       if (is_intel)
 	{
 	  extern long get_cpu_cache_intel (int sysc, uint32_t maxf);
-	  long cs;
-
-	  cs = get_cpu_cache_intel (_SC_LEVEL3_CACHE_SIZE, maxf);
-	  if (cs == -1)
-	    cs = get_cpu_cache_intel (_SC_LEVEL2_CACHE_SIZE, maxf);
-	  if (cs == -1)
-	    {
-	      cs = get_cpu_cache_intel (_SC_LEVEL1_ICACHE_SIZE, maxf);
-	      if (cs != -1)
-		cache_size = cs;
-	      cs = get_cpu_cache_intel (_SC_LEVEL1_DCACHE_SIZE, maxf);
-	      if (cs != -1)
-		cache_size += cs;
-	    }
-	  else
-	    cache_size = cs;
-	  if (cache_size != -1)
-	    cache_size >>= 10;
+	  get_cpu_cache = get_cpu_cache_intel;
+	  max = maxf;	/* Intel uses normal cpuid levels */
 	}
       else if (is_amd)
-	{
+        {
 	  extern long get_cpu_cache_amd (int sysc, uint32_t maxe);
+	  get_cpu_cache = get_cpu_cache_amd;
+	  max = maxe;	/* AMD uses extended cpuid levels */
+	}
+      if (get_cpu_cache)
+	{
 	  long cs;
 
-	  cs = get_cpu_cache_amd (_SC_LEVEL3_CACHE_SIZE, maxe);
-	  if (cs == -1)
-	    cs = get_cpu_cache_amd (_SC_LEVEL2_CACHE_SIZE, maxe);
-	  if (cs == -1)
+	  cs = get_cpu_cache (_SC_LEVEL3_CACHE_SIZE, max);
+	  if (cs <= 0)
+	    cs = get_cpu_cache (_SC_LEVEL2_CACHE_SIZE, max);
+	  if (cs <= 0)
 	    {
-	      cs = get_cpu_cache_amd (_SC_LEVEL1_ICACHE_SIZE, maxe);
-	      if (cs != -1)
+	      cs = get_cpu_cache (_SC_LEVEL1_ICACHE_SIZE, max);
+	      if (cs > 0)
 		cache_size = cs;
-	      cs = get_cpu_cache_amd (_SC_LEVEL1_DCACHE_SIZE, maxe);
-	      if (cs != -1)
+	      cs = get_cpu_cache (_SC_LEVEL1_DCACHE_SIZE, max);
+	      if (cs > 0)
 		cache_size += cs;
 	    }
 	  else
 	    cache_size = cs;
-	  if (cache_size != -1)
+	  if (cache_size > 0)
 	    cache_size >>= 10;
 	}
       bufptr += __small_sprintf (bufptr, "cpu family\t: %d\n"
 					 "model\t\t: %d\n"
 					 "model name\t: %s\n"
 					 "stepping\t: %d\n"
+					 "microcode\t: 0x%x\n"
 					 "cpu MHz\t\t: %d.000\n",
 				 family,
 				 model,
 				 in_buf.s + strspn (in_buf.s, " 	"),
 				 stepping,
+				 microcode,
 				 cpu_mhz);
 
       if (cache_size >= 0)
@@ -894,11 +910,11 @@ format_proc_cpuinfo (void *, char *&destbuf)
 
 		  cpuid (&unused, &unused, &core_info, &unused, 0x80000008);
 		  cpuid (&unused, &cus, &unused, &unused, 0x8000001e);
-		  siblings = (core_info & 0xff) + 1;
+		  siblings = (core_info & 0xff) + 1;	/* physical cores */
+		  cpu_cores = siblings;			/* physical cores */
 		  logical_bits = (core_info >> 12) & 0xf;
 		  cus = ((cus >> 8) & 0x3) + 1;
 		  ht_bits = mask_bits (cus);
-		  cpu_cores = siblings >> ht_bits;
 		}
 	      else if (maxe >= 0x80000008)
 		{
@@ -936,291 +952,416 @@ format_proc_cpuinfo (void *, char *&destbuf)
 
 	}
 
+      /* level is number of non-zero leafs exc. sub-leafs */
+      int level = maxf + 1 + (maxe & 0x7fffffff) + 1;
+
+      for (uint32_t l = maxe; 0x80000001 < l; --l)
+        {
+	  uint32_t a, b, c, d;
+	  cpuid (&a, &b, &c, &d, l);
+	  if (!(a | b | c | d))	--level;
+        }
+
+      for (uint32_t l = maxf; 1 < l; --l)
+        {
+	  uint32_t a, b, c, d;
+	  cpuid (&a, &b, &c, &d, l);
+	  if (!(a | b | c | d))	--level;
+        }
+
       bufptr += __small_sprintf (bufptr, "fpu\t\t: %s\n"
 					 "fpu_exception\t: %s\n"
 					 "cpuid level\t: %d\n"
 					 "wp\t\t: yes\n",
 				 (features1 & (1 << 0)) ? "yes" : "no",
 				 (features1 & (1 << 0)) ? "yes" : "no",
-				 maxf);
+				 level);
       print ("flags\t\t:");
-      if (features1 & (1 << 0))
-	print (" fpu");
-      if (features1 & (1 << 1))
-	print (" vme");
-      if (features1 & (1 << 2))
-	print (" de");
-      if (features1 & (1 << 3))
-	print (" pse");
-      if (features1 & (1 << 4))
-	print (" tsc");
-      if (features1 & (1 << 5))
-	print (" msr");
-      if (features1 & (1 << 6))
-	print (" pae");
-      if (features1 & (1 << 7))
-	print (" mce");
-      if (features1 & (1 << 8))
-	print (" cx8");
-      if (features1 & (1 << 9))
-	print (" apic");
-      if (features1 & (1 << 11))
-	print (" sep");
-      if (features1 & (1 << 12))
-	print (" mtrr");
-      if (features1 & (1 << 13))
-	print (" pge");
-      if (features1 & (1 << 14))
-	print (" mca");
-      if (features1 & (1 << 15))
-	print (" cmov");
-      if (features1 & (1 << 16))
-	print (" pat");
-      if (features1 & (1 << 17))
-	print (" pse36");
-      if (features1 & (1 << 18))
-	print (" pn");
-      if (features1 & (1 << 19))
-	print (" clflush");
-      if (is_intel && features1 & (1 << 21))
-	print (" dts");
-      if (is_intel && features1 & (1 << 22))
-	print (" acpi");
-      if (features1 & (1 << 23))
-	print (" mmx");
-      if (features1 & (1 << 24))
-	print (" fxsr");
-      if (features1 & (1 << 25))
-	print (" sse");
-      if (features1 & (1 << 26))
-	print (" sse2");
-      if (is_intel && (features1 & (1 << 27)))
-	print (" ss");
-      if (features1 & (1 << 28))
-	print (" ht");
-      if (is_intel)
-	{
-	  if (features1 & (1 << 29))
-	    print (" tm");
-	  if (features1 & (1 << 30))
-	    print (" ia64");
-	  if (features1 & (1 << 31))
-	    print (" pbe");
-	}
-
+      /* cpuid 0x00000001 edx */
+      ftcprint (features1,  0, "fpu");	/* x87 floating point */
+      ftcprint (features1,  1, "vme");  /* VM enhancements */
+      ftcprint (features1,  2, "de");   /* debugging extensions */
+      ftcprint (features1,  3, "pse");  /* page size extensions */
+      ftcprint (features1,  4, "tsc");  /* rdtsc/p */
+      ftcprint (features1,  5, "msr");  /* rd/wrmsr */
+      ftcprint (features1,  6, "pae");  /* phy addr extensions */
+      ftcprint (features1,  7, "mce");  /* Machine check exception */
+      ftcprint (features1,  8, "cx8");  /* cmpxchg8b */
+      ftcprint (features1,  9, "apic"); /* APIC enabled */
+      ftcprint (features1, 11, "sep");  /* sysenter/sysexit */
+      ftcprint (features1, 12, "mtrr"); /* memory type range registers */
+      ftcprint (features1, 13, "pge");  /* page global extension */
+      ftcprint (features1, 14, "mca");  /* machine check architecture */
+      ftcprint (features1, 15, "cmov"); /* conditional move */
+      ftcprint (features1, 16, "pat");  /* page attribute table */
+      ftcprint (features1, 17, "pse36");/* 36 bit page size extensions */
+      ftcprint (features1, 18, "pn");   /* processor serial number */
+      ftcprint (features1, 19, "clflush"); /* clflush instruction */
+      ftcprint (features1, 21, "dts");  /* debug store */
+      ftcprint (features1, 22, "acpi"); /* ACPI via MSR */
+      ftcprint (features1, 23, "mmx");  /* multimedia extensions */
+      ftcprint (features1, 24, "fxsr"); /* fxsave/fxrstor */
+      ftcprint (features1, 25, "sse");  /* xmm */
+      ftcprint (features1, 26, "sse2"); /* xmm2 */
+      ftcprint (features1, 27, "ss");   /* CPU self snoop */
+      ftcprint (features1, 28, "ht");   /* hyper threading */
+      ftcprint (features1, 29, "tm");   /* acc automatic clock control */
+      ftcprint (features1, 30, "ia64"); /* IA 64 processor */
+      ftcprint (features1, 31, "pbe");  /* pending break enable */
+
+      /* AMD cpuid 0x80000001 edx */
       if (is_amd && maxe >= 0x80000001)
 	{
 	  cpuid (&unused, &unused, &unused, &features1, 0x80000001);
 
-	  if (features1 & (1 << 11))
-	    print (" syscall");
-	  if (features1 & (1 << 19)) /* Huh?  Not in AMD64 specs. */
-	    print (" mp");
-	  if (features1 & (1 << 20))
-	    print (" nx");
-	  if (features1 & (1 << 22))
-	    print (" mmxext");
-	  if (features1 & (1 << 25))
-	    print (" fxsr_opt");
-	  if (features1 & (1 << 26))
-	    print (" pdpe1gb");
-	  if (features1 & (1 << 27))
-	    print (" rdtscp");
-	  if (features1 & (1 << 29))
-	    print (" lm");
-	  if (features1 & (1 << 30)) /* 31th bit is on. */
-	    print (" 3dnowext");
-	  if (features1 & (1 << 31)) /* 32th bit (highest) is on. */
-	    print (" 3dnow");
+	  ftcprint (features1, 11, "syscall");	/* syscall/sysret */
+	  ftcprint (features1, 19, "mp");       /* MP capable */
+	  ftcprint (features1, 20, "nx");       /* no-execute protection */
+	  ftcprint (features1, 22, "mmxext");   /* MMX extensions */
+	  ftcprint (features1, 25, "fxsr_opt"); /* fxsave/fxrstor optims */
+	  ftcprint (features1, 26, "pdpe1gb");  /* GB large pages */
+	  ftcprint (features1, 27, "rdtscp");   /* rdtscp */
+	  ftcprint (features1, 29, "lm");       /* long mode (x86 64) */
+	  ftcprint (features1, 30, "3dnowext"); /* 3DNow extensions */
+	  ftcprint (features1, 31, "3dnow");    /* 3DNow */
 	}
-
-      if (features2 & (1 << 0))
-	print (" pni");
-      if (is_intel)
+      /* AMD cpuid 0x80000007 edx */
+      if (is_amd && maxe >= 0x80000007)
 	{
-	  if (features2 & (1 << 2))
-	    print (" dtes64");
-	  if (features2 & (1 << 3))
-	    print (" monitor");
-	  if (features2 & (1 << 4))
-	    print (" ds_cpl");
-	  if (features2 & (1 << 5))
-	    print (" vmx");
-	  if (features2 & (1 << 6))
-	    print (" smx");
-	  if (features2 & (1 << 7))
-	    print (" est");
-	  if (features2 & (1 << 8))
-	    print (" tm2");
-	  if (features2 & (1 << 9))
-	    print (" ssse3");
-	  if (features2 & (1 << 10))
-	    print (" cid");
-	  if (features2 & (1 << 12))
-	    print (" fma");
+	  cpuid (&unused, &unused, &unused, &features1, 0x80000007);
+
+	  ftcprint (features1,  8, "constant_tsc");	/* TSC constant rate */
+	  ftcprint (features1,  8, "nonstop_tsc");	/* nonstop C states */
 	}
-      if (features2 & (1 << 13))
-	print (" cx16");
-      if (is_intel)
+      /* cpuid 0x00000006 ecx */
+      if (maxf >= 0x06)
 	{
-	  if (features2 & (1 << 14))
-	    print (" xtpr");
-	  if (features2 & (1 << 15))
-	    print (" pdcm");
-	  if (features2 & (1 << 18))
-	    print (" dca");
-	  if (features2 & (1 << 19))
-	    print (" sse4_1");
-	  if (features2 & (1 << 20))
-	    print (" sse4_2");
-	  if (features2 & (1 << 21))
-	    print (" x2apic");
-	  if (features2 & (1 << 22))
-	    print (" movbe");
-	  if (features2 & (1 << 23))
-	    print (" popcnt");
-	  if (features2 & (1 << 25))
-	    print (" aes");
-	  if (features2 & (1 << 26))
-	    print (" xsave");
-	  if (features2 & (1 << 27))
-	    print (" osxsave");
-	  if (features2 & (1 << 28))
-	    print (" avx");
-	  if (features2 & (1 << 29))
-	    print (" f16c");
-	  if (features2 & (1 << 30))
-	    print (" rdrand");
-	  if (features2 & (1 << 31))
-	    print (" hypervisor");
+	  cpuid (&unused, &unused, &features1, &unused, 0x06);
+
+	  ftcprint (features1,  0, "aperfmperf");   /* P state hw coord fb */
 	}
 
+      /* cpuid 0x00000001 ecx */
+      ftcprint (features2,  0, "pni");	    /* xmm3 sse3 */
+      ftcprint (features2,  1, "pclmuldq"); /* pclmulqdq instruction */
+      ftcprint (features2,  2, "dtes64");   /* 64-bit debug store */
+      ftcprint (features2,  3, "monitor");  /* monitor/mwait support */
+      ftcprint (features2,  4, "ds_cpl");   /* CPL-qual debug store */
+      ftcprint (features2,  5, "vmx");      /* hardware virtualization */
+      ftcprint (features2,  6, "smx");      /* safer mode extensions */
+      ftcprint (features2,  7, "est");      /* enhanced speedstep */
+      ftcprint (features2,  8, "tm2");      /* thermal monitor 2 */
+      ftcprint (features2,  9, "ssse3");    /* supplemental sse3 */
+      ftcprint (features2, 10, "cid");      /* context id */
+      ftcprint (features2, 11, "sdbg");     /* silicon debug */
+      ftcprint (features2, 12, "fma");      /* fused multiply add */
+      ftcprint (features2, 13, "cx16");     /* cmpxchg16b instruction */
+      ftcprint (features2, 14, "xtpr");     /* send task priority messages */
+      ftcprint (features2, 15, "pdcm");     /* perf/debug capabilities MSR */
+      ftcprint (features2, 17, "pcid");     /* process context identifiers */
+      ftcprint (features2, 18, "dca");      /* direct cache access */
+      ftcprint (features2, 19, "sse4_1");   /* xmm 4_1 sse 4.1 */
+      ftcprint (features2, 20, "sse4_2");   /* xmm 4_2 sse 4.2 */
+      ftcprint (features2, 21, "x2apic");   /* x2 APIC */
+      ftcprint (features2, 22, "movbe");    /* movbe instruction */
+      ftcprint (features2, 23, "popcnt");   /* popcnt instruction */
+      ftcprint (features2, 24, "tsc_deadline_timer"); /* TSC deadline timer */
+      ftcprint (features2, 25, "aes");	    /* AES instructions */
+      ftcprint (features2, 26, "xsave");    /* xsave/xrstor/xsetbv/xgetbv */
+/*    ftcprint (features2, 27, "osxsave"); */ /* not output on Linux */
+      ftcprint (features2, 28, "avx");	    /* advanced vector extensions */
+      ftcprint (features2, 29, "f16c");     /* 16 bit FP conversions */
+      ftcprint (features2, 30, "rdrand");   /* RNG rdrand instruction */
+      ftcprint (features2, 31, "hypervisor"); /* hypervisor guest */
+
+      /* cpuid 0x80000001 ecx */
       if (maxe >= 0x80000001)
 	{
 	  cpuid (&unused, &unused, &features1, &unused, 0x80000001);
 
-	  if (features1 & (1 << 0))
-	    print (" lahf_lm");
-	  if (features1 & (1 << 1))
-	    print (" cmp_legacy");
+	  ftcprint (features1,  0, "lahf_lm");		/* l/sahf long mode */
+	  ftcprint (features1,  1, "cmp_legacy");       /* HT not valid */
 	  if (is_amd)
 	    {
-	      if (features1 & (1 << 2))
-		print (" svm");
-	      if (features1 & (1 << 3))
-		print (" extapic");
-	      if (features1 & (1 << 4))
-		print (" cr8_legacy");
-	      if (features1 & (1 << 5))
-		print (" abm");
-	      if (features1 & (1 << 6))
-		print (" sse4a");
-	      if (features1 & (1 << 7))
-		print (" misalignsse");
-	      if (features1 & (1 << 8))
-		print (" 3dnowprefetch");
-	      if (features1 & (1 << 9))
-		print (" osvw");
+	      ftcprint (features1,  2, "svm");          /* secure VM */
+	      ftcprint (features1,  3, "extapic");      /* ext APIC space */
+	      ftcprint (features1,  4, "cr8_legacy");   /* CR8 32 bit mode */
+	      ftcprint (features1,  5, "abm");          /* adv bit manip lzcnt */
+	      ftcprint (features1,  6, "sse4a");        /* sse 4a */
+	      ftcprint (features1,  7, "misalignsse");  /* misaligned SSE ok */
+	      ftcprint (features1,  8, "3dnowprefetch"); /* 3DNow prefetch */
+	      ftcprint (features1,  9, "osvw");         /* OS vis workaround */
 	    }
-	  if (features1 & (1 << 10))
-	    print (" ibs");
+	  ftcprint (features1, 10, "ibs");	/* instr based sampling */
 	  if (is_amd)
 	    {
-	      if (features1 & (1 << 11))
-		print (" sse5");
-	      if (features1 & (1 << 12))
-		print (" skinit");
-	      if (features1 & (1 << 13))
-		print (" wdt");
-	      if (features1 & (1 << 15))
-		print (" lwp");
-	      if (features1 & (1 << 16))
-		print (" fma4");
-	      if (features1 & (1 << 17))
-		print (" tce");
-	      if (features1 & (1 << 19))
-		print (" nodeid_msr");
-	      if (features1 & (1 << 21))
-		print (" tbm");
-	      if (features1 & (1 << 22))
-		print (" topoext");
-	      if (features1 & (1 << 23))
-		print (" perfctr_core");
-	      if (features1 & (1 << 24))
-		print (" perfctr_nb");
-	      if (features1 & (1 << 28))
-		print (" perfctr_l2");
+	      ftcprint (features1, 11, "xop");		/* sse 5 extended AVX */
+	      ftcprint (features1, 12, "skinit");       /* skinit/stgi */
+	      ftcprint (features1, 13, "wdt");          /* watchdog timer */
+	      ftcprint (features1, 15, "lwp");          /* light weight prof */
+	      ftcprint (features1, 16, "fma4");         /* 4 operand MAC */
+	      ftcprint (features1, 17, "tce");          /* translat cache ext */
+	      ftcprint (features1, 19, "nodeid_msr");   /* nodeid MSR */
+	      ftcprint (features1, 21, "tbm");          /* trailing bit manip */
+	      ftcprint (features1, 22, "topoext");      /* topology ext */
+	      ftcprint (features1, 23, "perfctr_core"); /* core perf ctr ext */
+	      ftcprint (features1, 24, "perfctr_nb");   /* NB perf ctr ext */
+	      ftcprint (features1, 26, "bpext");        /* data brkpt ext */
+	      ftcprint (features1, 27, "ptsc");         /* perf timestamp ctr */
+	      ftcprint (features1, 28, "perfctr_llc");  /* ll cache perf ctr */
+	      ftcprint (features1, 29, "mwaitx");       /* monitor/mwaitx ext */
 	    }
 	}
-      if (is_intel) /* features scattered in various CPUID levels. */
+
+      /* random feature flags */
+      /* cpuid 0x80000007 edx */
+      if (maxf >= 0x07)
 	{
-	  cpuid (&features1, &unused, &features2, &unused, 0x06);
+	  cpuid (&unused, &unused, &unused, &features1, 0x80000007);
+
+	  ftcprint (features1,  9, "cpb");	/* core performance boost */
+	}
+      /* cpuid 0x00000006 ecx */
+      if (maxf >= 0x06)
+	{
+	  cpuid (&unused, &unused, &features1, &unused, 0x06);
+
+	  ftcprint (features1,  3, "epb");	/* energy perf bias */
+	}
+      /* cpuid 0x00000010 ebx */
+      if (maxf >= 0x10)
+	{
+	  cpuid (&unused, &features1, &unused, &unused, 0x10);
+
+	  ftcprint (features1,  1, "cat_l3");	/* cache alloc tech l3 */
+	  ftcprint (features1,  2, "cat_l2");	/* cache alloc tech l2 */
+
+	  /* cpuid 0x00000010:1 ecx */
+	  cpuid (&unused, &unused, &features1, &unused, 0x10, 1);
 
-	  if (features1 & (1 << 1))
-	    print (" ida");
-	  if (features1 & (1 << 2))
-	    print (" arat");
-	  if (features2 & (1 << 3))
-	    print (" epb");
-
-	  cpuid (&features2, &unused, &unused, &unused, 0x0d, 1);
-	  if (features2 & (1 << 0))
-	    print (" xsaveopt");
-
-	  if (features1 & (1 << 4))
-	    print (" pln");
-	  if (features1 & (1 << 6))
-	    print (" pts");
-	  if (features1 & (1 << 0))
-	    print (" dtherm");
+	  ftcprint (features1,  2, "cdp_l3");	/* code data prior l3 */
 	}
-      if (is_intel) /* Extended feature flags */
+      /* cpuid 0x80000007 edx */
+      if (maxe >= 0x80000007)
+	{
+	  cpuid (&unused, &unused, &unused, &features1, 0x80000007);
+
+	  ftcprint (features1,  7, "hw_pstate");	/* hw P state */
+	  ftcprint (features1, 11, "proc_feedback"); /* proc feedback interf */
+	}
+      /* cpuid 0x8000001f eax */
+      if (maxe >= 0x8000001f)
+	{
+	  cpuid (&features1, &unused, &unused, &unused, 0x8000001f);
+
+	  ftcprint (features1,  0, "sme");	/* secure memory encryption */
+	}
+      /* cpuid 0x00000010:2 ecx */
+      if (maxf >= 0x10)
+	{
+	  cpuid (&unused, &unused, &features1, &unused, 0x10, 2);
+
+	  ftcprint (features1,  2, "cdp_l2");	/* code data prior l2 */
+
+	  /* cpuid 0x00000010 ebx */
+	  cpuid (&unused, &features1, &unused, &unused, 0x10);
+
+	  ftcprint (features1,  3, "mba");	/* memory bandwidth alloc */
+	}
+      /* cpuid 0x80000008 ebx */
+      if (maxe >= 0x80000008)
+	{
+	  cpuid (&unused, &features1, &unused, &unused, 0x80000008);
+
+	  ftcprint (features1,  6, "mba");	/* memory bandwidth alloc */
+	}
+      /* cpuid 0x8000001f eax */
+      if (maxe >= 0x8000001f)
+	{
+	  cpuid (&features1, &unused, &unused, &unused, 0x8000001f);
+
+	  ftcprint (features1,  1, "sev");	/* secure encrypted virt */
+	}
+
+      /* cpuid 0x00000007 ebx */
+      if (maxf >= 0x07)
 	{
 	  cpuid (&unused, &features1, &unused, &unused, 0x07, 0);
 
-	  if (features1 & (1 << 0))
-	    print (" fsgsbase");
-	  if (features1 & (1 << 1))
-	    print (" tsc_adjust");
-	  if (features1 & (1 << 3))
-	    print (" bmi1");
-	  if (features1 & (1 << 4))
-	    print (" hle");
-	  if (features1 & (1 << 5))
-	    print (" avx2");
-	  if (features1 & (1 << 7))
-	    print (" smep");
-	  if (features1 & (1 << 8))
-	    print (" bmi2");
-	  if (features1 & (1 << 9))
-	    print (" erms");
-	  if (features1 & (1 << 10))
-	    print (" invpcid");
-	  if (features1 & (1 << 11))
-	    print (" rtm");
-	  if (features1 & (1 << 14))
-	    print (" mpx");
-	  if (features1 & (1 << 16))
-	    print (" avx512f");
-	  if (features1 & (1 << 18))
-	    print (" rdseed");
-	  if (features1 & (1 << 19))
-	    print (" adx");
-	  if (features1 & (1 << 20))
-	    print (" smap");
-	  if (features1 & (1 << 23))
-	    print (" clflushopt");
-	  if (features1 & (1 << 26))
-	    print (" avx512pf");
-	  if (features1 & (1 << 27))
-	    print (" avx512er");
-	  if (features1 & (1 << 28))
-	    print (" avx512cd");
+	  ftcprint (features1,  0, "fsgsbase");	    /* rd/wr fs/gs base */
+	  ftcprint (features1,  1, "tsc_adjust");   /* TSC adjustment MSR 0x3B */
+	  ftcprint (features1,  3, "bmi1");         /* bit manip ext group 1 */
+	  ftcprint (features1,  4, "hle");          /* hardware lock elision */
+	  ftcprint (features1,  5, "avx2");         /* AVX ext instructions */
+/*	  ftcprint (features1,  6, "fpdx"); */      /* FP data ptr upd on exc */
+	  ftcprint (features1,  7, "smep");         /* super mode exec prot */
+	  ftcprint (features1,  8, "bmi2");         /* bit manip ext group 2 */
+	  ftcprint (features1,  9, "erms");         /* enh rep movsb/stosb */
+	  ftcprint (features1, 10, "invpcid");      /* inv proc context id */
+	  ftcprint (features1, 11, "rtm");          /* restricted txnal mem */
+	  ftcprint (features1, 12, "cqm");          /* cache QoS monitoring */
+/*	  ftcprint (features1, 13, "fpcsdsz"); */   /* zero FP cs/ds */
+	  ftcprint (features1, 14, "mpx");          /* mem prot ext */
+	  ftcprint (features1, 15, "rdt_a");        /* rsrc dir tech alloc */
+	  ftcprint (features1, 16, "avx512f");      /* vec foundation */
+	  ftcprint (features1, 17, "avx512dq");     /* vec dq granular */
+	  ftcprint (features1, 18, "rdseed");       /* RNG rdseed instruction */
+	  ftcprint (features1, 19, "adx");          /* adcx/adox */
+	  ftcprint (features1, 20, "smap");         /* sec mode access prev */
+	  ftcprint (features1, 21, "avx512ifma");   /* vec int FMA */
+	  ftcprint (features1, 23, "clflushopt");   /* cache line flush opt */
+	  ftcprint (features1, 24, "clwb");         /* cache line write back */
+	  ftcprint (features1, 25, "intel_pt");     /* intel processor trace */
+	  ftcprint (features1, 26, "avx512pf");     /* vec prefetch */
+	  ftcprint (features1, 27, "avx512er");     /* vec exp/recip aprx */
+	  ftcprint (features1, 28, "avx512cd");     /* vec conflict detect */
+	  ftcprint (features1, 29, "sha_ni");       /* SHA extensions */
+	  ftcprint (features1, 30, "avx512bw");     /* vec byte/word gran */
+	  ftcprint (features1, 31, "avx512vl");     /* vec vec len ext */
 	}
 
+      /* more random feature flags */
+      /* cpuid 0x0000000d:1 eax */
+      if (maxf >= 0x0d)
+	{
+	  cpuid (&features1, &unused, &unused, &unused, 0x0d, 1);
+
+	  ftcprint (features1,  0, "xsaveopt");	/* xsaveopt instruction */
+	  ftcprint (features1,  1, "xsavec");   /* xsavec instruction */
+	  ftcprint (features1,  2, "xgetbv1");  /* xgetbv ecx 1 */
+	  ftcprint (features1,  3, "xsaves");   /* xsaves/xrstors */
+	}
+      /* cpuid 0x0000000f edx */
+      if (maxf >= 0x0f)
+	{
+	  cpuid (&unused, &unused, &unused, &features1, 0x0f);
+
+	  ftcprint (features1,  1, "cqm_llc");		/* llc QoS */
+
+	  /* cpuid 0x0000000f:1 edx */
+	  cpuid (&unused, &unused, &unused, &features1, 0x0f, 1);
+
+	  ftcprint (features1,  0, "cqm_occup_llc");	/* llc occup monitor */
+	  ftcprint (features1,  1, "cqm_mbm_total");	/* llc total MBM mon */
+	  ftcprint (features1,  2, "cqm_mbm_local");	/* llc local MBM mon */
+	}
+      /* cpuid 0x00000007:1 eax */
+      if (maxf >= 0x07)
+	{
+	  cpuid (&features1, &unused, &unused, &unused, 0x07, 1);
+
+	  ftcprint (features1,  5, "avx512_bf16");  /* vec bfloat16 short */
+	}
+
+      /* AMD cpuid 0x80000008 ebx */
+      if (is_amd && maxe >= 0x80000008)
+        {
+	  cpuid (&unused, &features1, &unused, &unused, 0x80000008, 0);
+
+	  ftcprint (features1,  0, "clzero");	    /* clzero instruction */
+	  ftcprint (features1,  1, "irperf");       /* instr retired count */
+	  ftcprint (features1,  2, "xsaveerptr");   /* save/rest FP err ptrs */
+/*	  ftcprint (features1,  6,  "mba" }, */	    /* memory BW alloc */
+	  ftcprint (features1,  9, "wbnoinvd");     /* wbnoinvd instruction */
+/*	  ftcprint (features1, 12, "ibpb" ); */	    /* ind br pred barrier */
+/*	  ftcprint (features1, 14, "ibrs" ); */	    /* ind br restricted spec */
+/*	  ftcprint (features1, 15, "stibp"); */	    /* 1 thread ind br pred */
+/*	  ftcprint (features1, 17, "stibp_always_on"); */ /* stibp always on */
+/*	  ftcprint (features1, 24, "ssbd"); */	    /* spec store byp dis */
+	  ftcprint (features1, 25, "virt_ssbd");    /* vir spec store byp dis */
+/*	  ftcprint (features1, 26, "ssb_no"); */    /* ssb fixed in hardware */
+        }
+
+      /* thermal & power cpuid 0x00000006 eax */
+      if (maxf >= 0x06)
+	{
+	  cpuid (&features1, &unused, &features2, &unused, 0x06);
+
+	  ftcprint (features1,  0, "dtherm");	/* digital thermal sensor */
+	  ftcprint (features1,  1, "ida");      /* Intel dynamic acceleration */
+	  ftcprint (features1,  2, "arat");     /* always running APIC timer */
+	  ftcprint (features1,  4, "pln");      /* power limit notification */
+	  ftcprint (features1,  6, "pts");      /* package thermal status */
+	  ftcprint (features1,  7, "hwp");      /* hardware P states */
+	  ftcprint (features1,  8, "hwp_notify"); /* HWP notification */
+	  ftcprint (features1,  9, "hwp_act_window"); /* HWP activity window */
+	  ftcprint (features1, 10, "hwp_epp");  /* HWP energy perf pref */
+	  ftcprint (features1, 11, "hwp_pkg_req"); /* HWP package level req */
+	}
+
+      /* AMD SVM cpuid 0x8000000a edx */
+      if (is_amd && maxe >= 0x8000000a)
+        {
+	  cpuid (&unused, &unused, &unused, &features1, 0x8000000a, 0);
+
+	  ftcprint (features1,  0, "npt");		/* nested paging */
+	  ftcprint (features1,  1, "lbrv");             /* lbr virtualization */
+	  ftcprint (features1,  2, "svm_lock");         /* SVM locking MSR */
+	  ftcprint (features1,  3, "nrip_save");        /* SVM next rip save */
+	  ftcprint (features1,  4, "tsc_scale");        /* TSC rate control */
+	  ftcprint (features1,  5, "vmcb_clean");       /* VMCB clean bits */
+	  ftcprint (features1,  6, "flushbyasid");      /* flush by ASID */
+	  ftcprint (features1,  7, "decode_assists");   /* decode assists */
+	  ftcprint (features1, 10, "pausefilter");      /* filt pause intrcpt */
+	  ftcprint (features1, 12, "pfthreshold");      /* pause filt thresh */
+	  ftcprint (features1, 13, "avic");             /* virt int control */
+	  ftcprint (features1, 15, "v_vmsave_vmload");  /* virt vmsave vmload */
+	  ftcprint (features1, 16, "vgif");             /* virt glb int flag */
+        }
+
+      /* Intel cpuid 0x00000007 ecx */
+      if (is_intel && maxf >= 0x07)
+        {
+	  cpuid (&unused, &unused, &features1, &unused, 0x07, 0);
+
+	  ftcprint (features1,  1, "avx512vbmi");	/* vec bit manip */
+	  ftcprint (features1,  2, "umip");             /* user mode ins prot */
+	  ftcprint (features1,  3, "pku");              /* prot key userspace */
+	  ftcprint (features1,  4, "ospke");            /* OS prot keys en */
+	  ftcprint (features1,  5, "waitpkg");          /* umon/umwait/tpause */
+	  ftcprint (features1,  6, "avx512_vbmi2");     /* vec bit manip 2 */
+	  ftcprint (features1,  8, "gfni");             /* Galois field instr */
+	  ftcprint (features1,  9, "vaes");             /* vector AES */
+	  ftcprint (features1, 10, "vpclmulqdq");       /* nc mul dbl quad */
+	  ftcprint (features1, 11, "avx512_vnni");      /* vec neural net */
+	  ftcprint (features1, 12, "avx512_bitalg");    /* vpopcnt/b/w vpshuf */
+	  ftcprint (features1, 13, "tme");              /* total mem encrypt */
+	  ftcprint (features1, 14, "avx512_vpopcntdq"); /* vec popcnt dw/qw */
+	  ftcprint (features1, 16, "la57");             /* 5 level paging */
+	  ftcprint (features1, 22, "rdpid");            /* rdpid instruction */
+	  ftcprint (features1, 25, "cldemote");         /* cldemote instr */
+	  ftcprint (features1, 27, "movdiri");          /* movdiri instr */
+	  ftcprint (features1, 28, "movdir64b");        /* movdir64b instr */
+        }
+
+      /* AMD MCA cpuid 0x80000007 ebx */
+      if (is_amd && maxe >= 0x80000007)
+        {
+          cpuid (&unused, &features1, &unused, &unused, 0x80000007, 0);
+
+          ftcprint (features1,  0, "overflow_recov");	/* MCA oflow recovery */
+          ftcprint (features1,  1, "succor");           /* uncor err recovery */
+          ftcprint (features1,  3, "smca");             /* scalable MCA */
+        }
+
+      /* Intel cpuid 0x00000007 edx */
+      if (is_intel && maxf >= 0x07)
+        {
+          cpuid (&unused, &unused, &unused, &features1, 0x07, 0);
+
+          ftcprint (features1,  2, "avx512_4vnniw");	   /* vec dot prod dw */
+          ftcprint (features1,  3, "avx512_4fmaps");       /* vec 4 FMA single */
+          ftcprint (features1,  8, "avx512_vp2intersect"); /* vec intcpt d/q */
+          ftcprint (features1, 10, "md_clear");            /* verw clear buf */
+          ftcprint (features1, 18, "pconfig");		   /* platform config */
+          ftcprint (features1, 28, "flush_l1d");	   /* flush l1d cache */
+          ftcprint (features1, 29, "arch_capabilities");   /* arch cap MSR */
+        }
+
       print ("\n");
 
-      /* TODO: bogomips */
+      bufptr += __small_sprintf (bufptr, "bogomips\t: %d.00\n",
+						bogomips);
 
       bufptr += __small_sprintf (bufptr, "clflush size\t: %d\n"
 					 "cache_alignment\t: %d\n",
@@ -1243,31 +1384,27 @@ format_proc_cpuinfo (void *, char *&destbuf)
 				     phys, virt);
 	}
 
+      /* cpuid 0x80000007 edx */
       if (maxe >= 0x80000007) /* Advanced power management. */
 	{
 	  cpuid (&unused, &unused, &unused, &features1, 0x80000007);
 
 	  print ("power management:");
-	  if (features1 & (1 << 0))
-	    print (" ts");
-	  if (features1 & (1 << 1))
-	    print (" fid");
-	  if (features1 & (1 << 2))
-	    print (" vid");
-	  if (features1 & (1 << 3))
-	    print (" ttp");
-	  if (features1 & (1 << 4))
-	    print (" tm");
-	  if (features1 & (1 << 5))
-	    print (" stc");
-	  if (features1 & (1 << 6))
-	    print (" 100mhzsteps");
-	  if (features1 & (1 << 7))
-	    print (" hwpstate");
-	  if (features1 & (1 << 9))
-	    print (" cpb");
-	  if (features1 & (1 << 10))
-	    print (" eff_freq_ro");
+	  ftcprint (features1,  0, "ts");	    /* temperature sensor */
+	  ftcprint (features1,  1, "fid");          /* frequency id control */
+	  ftcprint (features1,  2, "vid");          /* voltage id control */
+	  ftcprint (features1,  3, "ttp");          /* thermal trip */
+	  ftcprint (features1,  4, "tm");           /* hw thermal control */
+	  ftcprint (features1,  5, "stc");          /* sw thermal control */
+	  ftcprint (features1,  6, "100mhzsteps");  /* 100 MHz mult control */
+	  ftcprint (features1,  7, "hwpstate");     /* hw P state control */
+/*	  ftcprint (features1,  8, "invariant_tsc");*/ /* TSC invariant */
+	  ftcprint (features1,  9, "cpb");          /* core performance boost */
+	  ftcprint (features1, 10, "eff_freq_ro");  /* ro eff freq interface */
+/*	  ftcprint (features1, 11, "proc_feedback");*/ /* proc feedback if */
+/*	  ftcprint (features1, 12, "acc_power");    */ /* core power reporting */
+/*	  ftcprint (features1, 13, "connstby");	    */ /* connected standby */
+/*	  ftcprint (features1, 14, "rapl");	    */ /* running average power limit */
 	}
 
       if (orig_affinity_mask != 0)
-- 
2.21.0



More information about the Cygwin-patches mailing list