Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.sbin/cpuctl/arch Add support for the xsave related data ...



details:   https://anonhg.NetBSD.org/src/rev/aa08552fb56c
branches:  trunk
changeset: 783761:aa08552fb56c
user:      dsl <dsl%NetBSD.org@localhost>
date:      Mon Jan 07 23:20:42 2013 +0000

description:
Add support for the xsave related data from cpuid 8.n.
Reorder the output so that the 'brand' string - which actually identifies
  the cpu is output first.

diffstat:

 usr.sbin/cpuctl/arch/cpuctl_i386.h |    3 +-
 usr.sbin/cpuctl/arch/i386-asm.S    |    7 +-
 usr.sbin/cpuctl/arch/i386.c        |  156 ++++++++++++++++++++----------------
 usr.sbin/cpuctl/arch/x86_64-asm.S  |    6 +-
 4 files changed, 101 insertions(+), 71 deletions(-)

diffs (truncated from 314 to 300 lines):

diff -r edae50e53b80 -r aa08552fb56c usr.sbin/cpuctl/arch/cpuctl_i386.h
--- a/usr.sbin/cpuctl/arch/cpuctl_i386.h        Mon Jan 07 22:32:24 2013 +0000
+++ b/usr.sbin/cpuctl/arch/cpuctl_i386.h        Mon Jan 07 23:20:42 2013 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: cpuctl_i386.h,v 1.1 2013/01/05 15:27:45 dsl Exp $      */
+/*      $NetBSD: cpuctl_i386.h,v 1.2 2013/01/07 23:20:42 dsl Exp $      */
 
 /* Interfaces to code in i386-asm.S */
 
@@ -6,3 +6,4 @@
 
 void x86_cpuid2(uint32_t, uint32_t, uint32_t *);
 uint32_t x86_identify(void);
+uint32_t x86_xgetbv(void);
diff -r edae50e53b80 -r aa08552fb56c usr.sbin/cpuctl/arch/i386-asm.S
--- a/usr.sbin/cpuctl/arch/i386-asm.S   Mon Jan 07 22:32:24 2013 +0000
+++ b/usr.sbin/cpuctl/arch/i386-asm.S   Mon Jan 07 23:20:42 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: i386-asm.S,v 1.2 2013/01/05 15:27:45 dsl Exp $ */
+/*     $NetBSD: i386-asm.S,v 1.3 2013/01/07 23:20:42 dsl Exp $ */
 
 /*-
  * Copyright (c) 1998, 2000, 2004, 2006, 2007 The NetBSD Foundation, Inc.
@@ -48,6 +48,11 @@
        ret
 END(x86_cpuid2)
 
+ENTRY(x86_xgetbv)
+       xgetbv
+       ret
+END(x86_xgetbv)
+
 ENTRY(x86_identify)
        /* Try to toggle alignment check flag; does not exist on 386. */
        pushfl
diff -r edae50e53b80 -r aa08552fb56c usr.sbin/cpuctl/arch/i386.c
--- a/usr.sbin/cpuctl/arch/i386.c       Mon Jan 07 22:32:24 2013 +0000
+++ b/usr.sbin/cpuctl/arch/i386.c       Mon Jan 07 23:20:42 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: i386.c,v 1.37 2013/01/06 23:17:35 dsl Exp $    */
+/*     $NetBSD: i386.c,v 1.38 2013/01/07 23:20:42 dsl Exp $    */
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -57,7 +57,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: i386.c,v 1.37 2013/01/06 23:17:35 dsl Exp $");
+__RCSID("$NetBSD: i386.c,v 1.38 2013/01/07 23:20:42 dsl Exp $");
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -97,12 +97,14 @@
        uint32_t        ci_signature;    /* X86 cpuid type */
        uint32_t        ci_family;       /* from ci_signature */
        uint32_t        ci_model;        /* from ci_signature */
-       uint32_t        ci_feat_val[5];  /* X86 CPUID feature bits
+       uint32_t        ci_feat_val[8];  /* X86 CPUID feature bits
                                          *     [0] basic features %edx
                                          *     [1] basic features %ecx
                                          *     [2] extended features %edx
                                          *     [3] extended features %ecx
                                          *     [4] VIA padlock features
+                                         *     [5] XCR0 bits (d:0 %eax)
+                                         *     [6] xsave flags (d:1 %eax)
                                          */
        uint32_t        ci_cpu_class;    /* CPU class */
        uint32_t        ci_brand_id;     /* Intel brand id */
@@ -113,6 +115,10 @@
        uint8_t         ci_coreid;
        uint8_t         ci_smtid;
        uint32_t        ci_initapicid;
+
+       uint32_t        ci_cur_xsave;
+       uint32_t        ci_max_xsave;
+
        struct x86_cache_info ci_cinfo[CAI_COUNT];
        void            (*ci_info)(struct cpu_info *);
 };
@@ -204,11 +210,6 @@
 static void powernow_probe(struct cpu_info *);
 
 /*
- * Info for CTL_HW
- */
-static char    cpu_model[120];
-
-/*
  * Note: these are just the ones that may not have a cpuid instruction.
  * We deal with the rest in a different way.
  */
@@ -999,6 +1000,19 @@
                ci->ci_cpu_serial[2] = descs[2];
                ci->ci_cpu_serial[1] = descs[3];
        }
+
+       if (ci->ci_cpuid_level < 0xd)
+               return;
+
+       /* Get support XRC0 bits */
+       x86_cpuid2(0xd, 0, descs);
+       ci->ci_feat_val[5] = descs[0];  /* Actually 64 bits */
+       ci->ci_cur_xsave = descs[1];
+       ci->ci_max_xsave = descs[2];
+
+       /* Additional flags (eg xsaveopt support) */
+       x86_cpuid2(0xd, 1, descs);
+       ci->ci_feat_val[6] = descs[0];   /* Actually 64 bits */
 }
 
 static void
@@ -1159,6 +1173,26 @@
        }
 }
 
+static void
+print_bits(const char *cpuname, const char *hdr, const char *fmt, uint32_t val)
+{
+       char buf[32 * 16];
+       char *bp;
+
+#define        MAX_LINE_LEN    79      /* get from command arg or 'stty cols' ? */
+
+       if (val == 0 || fmt == NULL)
+               return;
+
+       snprintb_m(buf, sizeof(buf), fmt, val,
+           MAX_LINE_LEN - strlen(cpuname) - 2 - strlen(hdr) - 1);
+       bp = buf;
+       while (*bp != '\0') {
+               aprint_verbose("%s: %s %s\n", cpuname, hdr, bp);
+               bp += strlen(bp) + 1;
+       }
+}
+
 void
 identifycpu(int fd, const char *cpuname)
 {
@@ -1168,11 +1202,8 @@
        int modif, family;
        const struct cpu_cpuid_nameclass *cpup = NULL;
        const struct cpu_cpuid_family *cpufam;
-       const char *feature_str[5];
        struct cpu_info *ci, cistore;
        size_t sz;
-       char buf[512];
-       char *bp;
        struct cpu_ucode_version ucode;
        union {
                struct cpu_ucode_version_amd amd;
@@ -1279,20 +1310,31 @@
        (void)sysctlbyname("machdep.pae", &use_pae, &sz, NULL, 0);
        largepagesize = (use_pae ? 2 * 1024 * 1024 : 4 * 1024 * 1024);
 
-       snprintf(cpu_model, sizeof(cpu_model), "%s%s%s%s%s%s%s (%s-class)",
-           vendorname,
-           *modifier ? " " : "", modifier,
-           *name ? " " : "", name,
-           *brand ? " " : "", brand,
-           classnames[class]);
-       aprint_normal("%s: %s", cpuname, cpu_model);
+       /*
+        * The 'cpu_brand_string' is much more useful than the 'cpu_model'
+        * we try to determine from the family/model values.
+        */
+       if (*cpu_brand_string != '\0')
+               aprint_normal("%s: \"%s\"\n", cpuname, cpu_brand_string);
+
+       aprint_normal("%s: %s", cpuname, vendorname);
+       if (*modifier)
+               aprint_normal(" %s", modifier);
+       if (*name)
+               aprint_normal(" %s", name);
+       if (*brand)
+               aprint_normal(" %s", brand);
+       aprint_normal(" (%s-class)", classnames[class]);
 
        if (ci->ci_tsc_freq != 0)
-               aprint_normal(", %ju.%02ju MHz",
+               aprint_normal(", %ju.%02ju MHz\n",
                    ((uintmax_t)ci->ci_tsc_freq + 4999) / 1000000,
                    (((uintmax_t)ci->ci_tsc_freq + 4999) / 10000) % 100);
+
+       aprint_normal_dev(ci->ci_dev, "family %#x model %#x stepping %#x",
+           ci->ci_family, ci->ci_model, CPUID2STEPPING(ci->ci_signature));
        if (ci->ci_signature != 0)
-               aprint_normal(", id 0x%x", ci->ci_signature);
+               aprint_normal(" (id %#x)", ci->ci_signature);
        aprint_normal("\n");
 
        if (ci->ci_info)
@@ -1302,45 +1344,33 @@
         * display CPU feature flags
         */
 
-#define        MAX_FEATURE_LEN 60      /* XXX Need to find a better way to set this */
+       print_bits(cpuname, "features", CPUID_FLAGS1, ci->ci_feat_val[0]);
+       print_bits(cpuname, "features1", CPUID2_FLAGS1, ci->ci_feat_val[1]);
 
-       feature_str[0] = CPUID_FLAGS1;
-       feature_str[1] = CPUID2_FLAGS1;
-       feature_str[2] = CPUID_EXT_FLAGS;
-       feature_str[3] = NULL;
-       feature_str[4] = NULL;
+       /* These next two are actually common definitions! */
+       print_bits(cpuname, "features2",
+           cpu_vendor == CPUVENDOR_INTEL ? CPUID_INTEL_EXT_FLAGS
+               : CPUID_EXT_FLAGS, ci->ci_feat_val[2]);
+       print_bits(cpuname, "features3",
+           cpu_vendor == CPUVENDOR_INTEL ? CPUID_INTEL_FLAGS4
+               : CPUID_AMD_FLAGS4, ci->ci_feat_val[3]);
+
+       print_bits(cpuname, "padloack features", CPUID_FLAGS_PADLOCK,
+           ci->ci_feat_val[4]);
 
-       switch (cpu_vendor) {
-       case CPUVENDOR_AMD:
-               feature_str[3] = CPUID_AMD_FLAGS4;
-               break;
-       case CPUVENDOR_INTEL:
-               feature_str[2] = CPUID_INTEL_EXT_FLAGS;
-               feature_str[3] = CPUID_INTEL_FLAGS4;
-               break;
-       case CPUVENDOR_IDT:
-               feature_str[4] = CPUID_FLAGS_PADLOCK;
-               break;
-       default:
-               break;
+       print_bits(cpuname, "xsave features", XCR0_FLAGS1, ci->ci_feat_val[5]);
+       print_bits(cpuname, "xsave instructions", CPUID_PES1_FLAGS,
+           ci->ci_feat_val[6]);
+
+       if (ci->ci_max_xsave != 0) {
+               aprint_normal("%s: xsave area size: current %d, maximum %d",
+                       cpuname, ci->ci_cur_xsave, ci->ci_max_xsave);
+               aprint_normal(", xgetbv %sabled\n",
+                   ci->ci_feat_val[1] & CPUID2_OSXSAVE ? "en" : "dis");
+               if (ci->ci_feat_val[1] & CPUID2_OSXSAVE)
+                       print_bits(cpuname, "enabled xsave", XCR0_FLAGS1,
+                           x86_xgetbv());
        }
-       
-       for (i = 0; i <= 4; i++) {
-               if (ci->ci_feat_val[i] && feature_str[i] != NULL) {
-                       snprintb_m(buf, sizeof(buf), feature_str[i],
-                                  ci->ci_feat_val[i], MAX_FEATURE_LEN);
-                       bp = buf;
-                       while (*bp != '\0') {
-                               aprint_verbose("%s: %sfeatures%c %s\n",
-                                   cpuname, (i == 4)?"padlock ":"", 
-                                   (i == 4 || i == 0)?' ':'1' + i, bp);
-                               bp += strlen(bp) + 1;
-                       }
-               }
-       }
-
-       if (*cpu_brand_string != '\0')
-               aprint_normal("%s: \"%s\"\n", cpuname, cpu_brand_string);
 
        x86_print_cacheinfo(ci);
 
@@ -1390,19 +1420,12 @@
 
                if ((data[0] >= 0x8000000a)
                   && (ci->ci_feat_val[3] & CPUID_SVM) != 0) {
-
                        x86_cpuid(0x8000000a, data);
                        aprint_verbose("%s: SVM Rev. %d\n", cpuname,
                            data[0] & 0xf);
                        aprint_verbose("%s: SVM NASID %d\n", cpuname, data[1]);
-                       snprintb_m(buf, sizeof(buf), CPUID_AMD_SVM_FLAGS,
-                                  data[3], MAX_FEATURE_LEN);
-                       bp = buf;
-                       while (*bp != '\0') {
-                               aprint_verbose("%s: SVM features %s\n",
-                                   cpuname, bp);
-                               bp += strlen(bp) + 1;
-                       }
+                       print_bits(cpuname, "SVM features", CPUID_AMD_SVM_FLAGS,
+                                  data[3]);
                }
        }
 
@@ -1410,9 +1433,6 @@
        clockmod_init();
 #endif
 
-       aprint_normal_dev(ci->ci_dev, "family %02x model %02x stepping %02x\n",
-           ci->ci_family, ci->ci_model, CPUID2STEPPING(ci->ci_signature));
-
        if (cpu_vendor == CPUVENDOR_AMD)
                ucode.loader_version = CPU_UCODE_LOADER_AMD;
        else if (cpu_vendor == CPUVENDOR_INTEL)
diff -r edae50e53b80 -r aa08552fb56c usr.sbin/cpuctl/arch/x86_64-asm.S
--- a/usr.sbin/cpuctl/arch/x86_64-asm.S Mon Jan 07 22:32:24 2013 +0000
+++ b/usr.sbin/cpuctl/arch/x86_64-asm.S Mon Jan 07 23:20:42 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: x86_64-asm.S,v 1.3 2013/01/05 15:33:00 dsl Exp $       */
+/*     $NetBSD: x86_64-asm.S,v 1.4 2013/01/07 23:20:42 dsl Exp $       */



Home | Main Index | Thread Index | Old Index