[newlib-cygwin] Fix /proc/cpuinfo topology info on newer AMD CPUs

Corinna Vinschen corinna@sourceware.org
Mon Aug 17 14:35:00 GMT 2015


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=37b6936f8b6860cda5881127b8ac272ed528ac34

commit 37b6936f8b6860cda5881127b8ac272ed528ac34
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Mon Aug 17 16:35:41 2015 +0200

    Fix /proc/cpuinfo topology info on newer AMD CPUs
    
            * fhandler_proc.cc (format_proc_cpuinfo): Handle AMDs providing
            extended topology info in CPUID leaf 0x8000001e.  Fix handling of
            AMD CPUs providing extended legacy core info in CPUID leaf 0x80000008.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/ChangeLog        |  6 ++++++
 winsup/cygwin/fhandler_proc.cc | 30 +++++++++++++++++++++++-------
 2 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 03a850a..b026b0e 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,9 @@
+2015-08-17  Corinna Vinschen  <corinna@vinschen.de>
+
+	* fhandler_proc.cc (format_proc_cpuinfo): Handle AMDs providing
+	extended topology info in CPUID leaf 0x8000001e.  Fix handling of
+	AMD CPUs providing extended legacy core info in CPUID leaf 0x80000008.
+
 2015-08-17  Orgad Shaneh  <orgads@gmail.com>
 
 	* mkglobals_h: Handle CRLF earlier.
diff --git a/winsup/cygwin/fhandler_proc.cc b/winsup/cygwin/fhandler_proc.cc
index 55e13cd..5d05757 100644
--- a/winsup/cygwin/fhandler_proc.cc
+++ b/winsup/cygwin/fhandler_proc.cc
@@ -896,21 +896,37 @@ format_proc_cpuinfo (void *, char *&destbuf)
 	    }
 	  else if (is_amd)
 	    {
-	      if (maxe >= 0x80000008)
+	      if (maxe >= 0x8000001e)
+		{
+		  uint32_t cus, core_info;
+
+		  cpuid (&unused, &unused, &core_info, &unused, 0x80000008);
+		  cpuid (&unused, &cus, &unused, &unused, 0x8000001e);
+		  siblings = (core_info & 0xff) + 1;
+		  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)
 		{
 		  uint32_t core_info;
 
 		  cpuid (&unused, &unused, &core_info, &unused, 0x80000008);
-		  cpu_cores = (core_info & 0xff) + 1;
-		  siblings = cpu_cores;
+		  siblings = (core_info & 0xff) + 1;
+		  cpu_cores = siblings;
+		  logical_bits = (core_info >> 12) & 0xf;
+		  if (!logical_bits)
+		    logical_bits = mask_bits (siblings);
+		  ht_bits = 0;
 		}
 	      else
 		{
-		  cpu_cores = (extra_info >> 16) & 0xff;
-		  siblings = cpu_cores;
+		  siblings = (extra_info >> 16) & 0xff;
+		  cpu_cores = siblings;
+		  logical_bits = mask_bits (siblings);
+		  ht_bits = 0;
 		}
-	      logical_bits = mask_bits (cpu_cores);
-	      ht_bits = 0;
 	    }
 	  phys_id = initial_apic_id >> logical_bits;
 	  core_id = (initial_apic_id & ((1 << logical_bits) - 1)) >> ht_bits;



More information about the Cygwin-cvs mailing list