Determine and store processor family and model on x86-64.
authorH.J. Lu <hongjiu.lu@intel.com>
Tue, 30 Jun 2009 11:39:09 +0000 (04:39 -0700)
committerUlrich Drepper <drepper@redhat.com>
Tue, 30 Jun 2009 11:39:09 +0000 (04:39 -0700)
ChangeLog
sysdeps/x86_64/multiarch/ifunc-defines.sym
sysdeps/x86_64/multiarch/init-arch.c
sysdeps/x86_64/multiarch/init-arch.h

index ff4e26a..7a25874 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2009-06-26  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * sysdeps/x86_64/multiarch/ifunc-defines.sym (FAMILIY_OFFSET): Define.
+       (MODEL_OFFSET): Define.
+       * sysdeps/x86_64/multiarch/init-arch.h (cpu_features): Add
+       family and model.
+       * sysdeps/x86_64/multiarch/init-arch.c (__init_cpu_features): Break
+       out common code into new function get_common_indeces. Determine
+       extended family and model for Intel processors.
+
 2009-06-26  Ulrich Drepper  <drepper@redhat.com>
 
        * resolv/resolv.h: Define RES_SNGLKUPREOP.
index 48d1287..e2021cd 100644 (file)
@@ -11,5 +11,7 @@ CPUID_EAX_OFFSET      offsetof (struct cpuid_registers, eax)
 CPUID_EBX_OFFSET       offsetof (struct cpuid_registers, ebx)
 CPUID_ECX_OFFSET       offsetof (struct cpuid_registers, ecx)
 CPUID_EDX_OFFSET       offsetof (struct cpuid_registers, edx)
+FAMILY_OFFSET          offsetof (struct cpu_features, family)
+MODEL_OFFSET           offsetof (struct cpu_features, model)
 
 COMMON_CPUID_INDEX_1
index ec0eb29..d559331 100644 (file)
 struct cpu_features __cpu_features attribute_hidden;
 
 
+static void
+get_common_indeces (void)
+{
+  asm volatile ("cpuid"
+               : "=a" (__cpu_features.cpuid[COMMON_CPUID_INDEX_1].eax),
+                 "=b" (__cpu_features.cpuid[COMMON_CPUID_INDEX_1].ebx),
+                 "=c" (__cpu_features.cpuid[COMMON_CPUID_INDEX_1].ecx),
+                 "=d" (__cpu_features.cpuid[COMMON_CPUID_INDEX_1].edx)
+               : "0" (1));
+
+  unsigned int eax = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].eax;
+  __cpu_features.family = (eax >> 8) & 0x0f;
+  __cpu_features.model = (eax >> 4) & 0x0f;
+}
+
+
 void
 __init_cpu_features (void)
 {
@@ -41,20 +57,25 @@ __init_cpu_features (void)
     {
       __cpu_features.kind = arch_kind_intel;
 
-    get_common_cpuid:
-      asm volatile ("cpuid"
-                   : "=a" (__cpu_features.cpuid[COMMON_CPUID_INDEX_1].eax),
-                     "=b" (__cpu_features.cpuid[COMMON_CPUID_INDEX_1].ebx),
-                     "=c" (__cpu_features.cpuid[COMMON_CPUID_INDEX_1].ecx),
-                     "=d" (__cpu_features.cpuid[COMMON_CPUID_INDEX_1].edx)
-                   : "0" (1));
+      get_common_indeces ();
+
+      unsigned int eax = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].eax;
+      unsigned int extended_family = (eax >> 20) & 0xff;
+      unsigned int extended_model = (eax >> 12) & 0xf0;
+      if (family == 0x0f)
+       {
+         __cpu_features.family += extended_family;
+         __cpu_features.model += extended_model;
+       }
+      else if (family == 0x06)
+       __cpu_features.model += extended_model;
     }
   /* This spells out "AuthenticAMD".  */
   else if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65)
     {
       __cpu_features.kind = arch_kind_amd;
 
-      goto get_common_cpuid;
+      get_common_indeces ();
     }
   else
     __cpu_features.kind = arch_kind_other;
index 5c4892d..48a2127 100644 (file)
@@ -42,6 +42,8 @@ extern struct cpu_features
     unsigned int ecx;
     unsigned int edx;
   } cpuid[COMMON_CPUID_INDEX_MAX];
+  unsigned int family;
+  unsigned int model;
 } __cpu_features attribute_hidden;