https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=37b6936f8b6860cda5881127b8ac272ed528ac34
commit 37b6936f8b6860cda5881127b8ac272ed528ac34 Author: Corinna Vinschen <cori...@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 <cori...@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 <cori...@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 <org...@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;