Module Name:    src
Committed By:   martin
Date:           Sun Mar  6 17:58:22 UTC 2016

Modified Files:
        src/sys/arch/x86/x86 [netbsd-7]: procfs_machdep.c

Log Message:
Pull up the following revisions, requested by msaitoh in ticket #1119:

        sys/arch/x86/x86/procfs_machdep.c               1.7-1.11

x86's /proc/cpuinfo fixes:
- Always output 2 digits for the cpu frequency decimal part.
- Update x86's feature bits in /proc/cpuinfo (PR#49246).
- Fix a bug that /proc/cpuinfo's CPU model was incorrect on many newer
  CPUs and CPU family was incorrect on some AMD CPUs.
- Add comment. Fix comment.


To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.6.4.1 src/sys/arch/x86/x86/procfs_machdep.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/x86/x86/procfs_machdep.c
diff -u src/sys/arch/x86/x86/procfs_machdep.c:1.6 src/sys/arch/x86/x86/procfs_machdep.c:1.6.4.1
--- src/sys/arch/x86/x86/procfs_machdep.c:1.6	Sat Apr  5 18:43:09 2014
+++ src/sys/arch/x86/x86/procfs_machdep.c	Sun Mar  6 17:58:22 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: procfs_machdep.c,v 1.6 2014/04/05 18:43:09 christos Exp $ */
+/*	$NetBSD: procfs_machdep.c,v 1.6.4.1 2016/03/06 17:58:22 martin Exp $ */
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -42,7 +42,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_machdep.c,v 1.6 2014/04/05 18:43:09 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: procfs_machdep.c,v 1.6.4.1 2016/03/06 17:58:22 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -56,50 +56,97 @@ __KERNEL_RCSID(0, "$NetBSD: procfs_machd
 #include <machine/reg.h>
 #include <machine/specialreg.h>
 
-static const char * const x86_features[] = {
-	/* Intel-defined */
+/*
+ *  The feature table. The order is the same as Linux's
+ *  x86/include/asm/cpufeatures.h.
+ */
+static const char * const x86_features[][32] = {
+	{ /* (0) Common */
 	"fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
 	"cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
 	"pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx",
-	"fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", NULL,
-#ifdef __x86_64__
-	/* AMD-defined */
-	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
-	NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL, 
-	NULL, NULL, NULL, NULL, "nx", NULL, "mmxext", NULL, 
-	NULL, "fxsr_opt", "rdtscp", NULL, NULL, "lm", "3dnowext", "3dnow",
-
-	/* Transmeta-defined */
-	"recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL, 
-	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
-	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
-	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
-
-	/* Linux-defined */
-	"cxmmx", NULL, "cyrix_arr", "centaur_mcr", NULL, 
-	"constant_tsc", NULL, NULL, 
-	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
-	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
-	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
-
-	/* Intel-defined */
-	"pni", NULL, NULL, "monitor", "ds_cpi", "vmx", NULL, "est", 
-	"tm2", NULL, "cid", NULL, NULL, "cx16", "xtpr", NULL, 
-	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
-	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
-
-	/* VIA/Cyrix/Centaur-defined */
-	NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en", 
-	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
-	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
-	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
-
-	/* AMD defined */
-	"lahf_lm", "cmp_legacy", "svm", NULL, "cr8_legacy", NULL, NULL, NULL,
-	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
-	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
-	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
-#endif
+	"fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", "pbe"},
+
+	{ /* (1) AMD-defined: 80000001 edx */
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, "mp", "nx", NULL, "mmxext", NULL,
+	NULL, "fxsr_opt", "pdpe1gb", "rdtscp", NULL, "lm", "3dnowext","3dnow"},
+
+	{ /* (2) Transmeta-defined */
+	"recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+
+	{ /* (3) Linux mapping */
+	"cxmmx", NULL, "cyrix_arr", "centaur_mcr", NULL,
+	"constant_tsc", NULL, NULL,
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+
+	{ /* (4) Intel-defined: 80000001 ecx */
+	"pni", "pclmulqdq", "dtes64", "monitor", "ds_cpl", "vmx", "smx", "est",
+	"tm2", "ssse3", "cid", "sdbg", "fma", "cx16", "xtpr", "pdcm",
+	NULL, "pcid", "dca", "sse4_1", "sse4_2", "x2apic", "movbe", "popcnt",
+	"tsc_deadline_timer", "aes", "xsave", NULL,
+	"avx", "f16c", "rdrand", "hypervisor"},
+
+	{ /* (5) VIA/Cyrix/Centaur-defined */
+	NULL, NULL, "rng", "rng_en", NULL, NULL, "ace", "ace_en",
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+
+	{ /* (6) AMD defined 80000001 ecx */
+	"lahf_lm", "cmp_legacy", "svm", "extapic",
+	"cr8_legacy", "abm", "sse4a", "misalignsse",
+	"3dnowprefetch", "osvw", "ibs", "xop", "skinit", "wdt", NULL, "lwp",
+	"fma4", "tce", NULL, "nodeid_msr",
+	NULL, "tbm", "topoext", "perfctr_core",
+	"perfctr_nb", NULL, "bpext", NULL, "perfctr_l2", "mwaitx", NULL, NULL},
+
+	{ /* (7) Linux mapping */
+	"ida", "arat", "cpb", "ebp", NULL, "pln", "pts", "dtherm",
+	"hw_pstate", "proc_feedback", "hwp", "hwp_notify", "hwp_act_window",
+	"hwp_epp", "hwp_pkg_req", "intel_pt",
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+
+	{ /* (8) Linux mapping */
+	"tpr_shadow", "vnmi", "flexpriority", "ept",
+	"vpid", "npt", "lbrv", "svm_lock",
+	"nrip_save", "tsc_scale", "vmcb_clean", "flushbyasid",
+	"decodeassists", "pausefilter", "pfthreshold", "vmmcall",
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+
+	{ /* (9) Intel-defined: 00000007 ebx */
+	"fsgsbase", "tsc_adjust", NULL, "bmi1", "hle", "avx2", NULL, "smep",
+	"bmi2", "erms", "invpcid", "rtm", "cqm", NULL, "mpx", NULL,
+	"avx512f", NULL, "rdseed", "adx",
+	"smap", NULL, "pcommit", "clflushopt",
+	"clwb", NULL, "avx512pf", "avx512er",
+	"avx512cd", "sha_ni", NULL, NULL},
+
+	{ /* (10) 0000000d eax */
+	"xsaveopt", "xsavec", "xgetbv1", "xsaves", NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+
+	{ /* (11) 0x0000000f:0 edx */
+	NULL, "cqm_llc", NULL, NULL, NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+
+	{ /* (12) 0x0000000f:1 edx */
+	"cqm_occup_llc", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
 };
 
 static int	procfs_getonecpu(int, struct cpu_info *, char *, size_t *);
@@ -119,7 +166,7 @@ procfs_getcpuinfstr(char *bf, size_t *le
 
 	i = total = 0;
 	used = size = *len;
-	
+
 	for (CPU_INFO_FOREACH(cii, ci)) {
 		procfs_getonecpu(i++, ci, bf, &used);
 		total += used + 1;
@@ -137,25 +184,85 @@ procfs_getcpuinfstr(char *bf, size_t *le
 }
 
 static int
-procfs_getonecpu(int xcpu, struct cpu_info *ci, char *bf, size_t *len)
+procfs_getonefeatreg(uint32_t reg, const char * const *table, char *p,
+    size_t *left)
 {
-	size_t left, l, size;
-	char featurebuf[1024], *p;
+	size_t l;
 
-	p = featurebuf;
-	left = sizeof(featurebuf);
-	size = *len;
 	for (size_t i = 0; i < 32; i++) {
-		if ((ci->ci_feat_val[0] & (1 << i)) && x86_features[i]) {
-			l = snprintf(p, left, "%s ", x86_features[i]);
-			if (l < left) {
-				left -= l;
+		if ((reg & (1 << i)) && table[i]) {
+			l = snprintf(p, *left, "%s ", table[i]);
+			if (l < *left) {
+				*left -= l;
 				p += l;
 			} else
 				break;
 		}
 	}
 
+	return 0; /* XXX */
+}
+
+/*
+ * Print feature bits. The code assume that unused entry of x86_features[]
+ * is zero-cleared.
+ *
+ * XXX This function will be rewritten when all of linux entries are
+ * decoded.
+ */
+static int
+procfs_getonecpufeatures(struct cpu_info *ci, char *p, size_t *left)
+{
+	size_t last = *left;
+	size_t diff;
+
+	procfs_getonefeatreg(ci->ci_feat_val[0], x86_features[0], p, left);
+	diff = last - *left;
+
+	procfs_getonefeatreg(ci->ci_feat_val[2], x86_features[1], p + diff,
+	    left);
+	diff = last - *left;
+
+	/* x86_features[2] is for Transmeta */
+	/* x86_features[3] is Linux defined mapping */
+	
+	procfs_getonefeatreg(ci->ci_feat_val[1], x86_features[4], p + diff,
+	    left);
+	diff = last - *left;
+
+	procfs_getonefeatreg(ci->ci_feat_val[4], x86_features[5], p + diff,
+	    left);
+	diff = last - *left;
+
+	procfs_getonefeatreg(ci->ci_feat_val[3], x86_features[6], p + diff,
+	    left);
+	diff = last - *left;
+
+	/* x86_features[7] is Linux defined mapping */
+	/* x86_features[8] is Linux defined mapping */
+
+	procfs_getonefeatreg(ci->ci_feat_val[5], x86_features[9], p + diff,
+	    left);
+	diff = last - *left;
+
+	/* (10) 0000000d eax */
+	/* (11) 0x0000000f(ecx=0) edx */
+	/* (12) 0x0000000f(ecx=1) edx */
+
+	return 0; /* XXX */
+}
+
+static int
+procfs_getonecpu(int xcpu, struct cpu_info *ci, char *bf, size_t *len)
+{
+	size_t left, l, size;
+	char featurebuf[1024], *p;
+
+	p = featurebuf;
+	left = sizeof(featurebuf);
+	size = *len;
+	procfs_getonecpufeatures(ci, p, &left);
+
 	p = bf;
 	left = *len;
 	size = 0;
@@ -168,8 +275,8 @@ procfs_getonecpu(int xcpu, struct cpu_in
 	    "stepping\t: ",
 	    xcpu,
 	    (char *)ci->ci_vendor,
-	    cpuid_level >= 0 ? ((ci->ci_signature >> 8) & 15) : cpu_class + 3,
-	    cpuid_level >= 0 ? ((ci->ci_signature >> 4) & 15) : 0,
+	    CPUID_TO_FAMILY(ci->ci_signature),
+	    CPUID_TO_MODEL(ci->ci_signature),
 	    cpu_brand_string
 	);
 	size += l;
@@ -180,7 +287,8 @@ procfs_getonecpu(int xcpu, struct cpu_in
 		left = 0;
 
 	if (cpuid_level >= 0)
-		l = snprintf(p, left, "%d\n", ci->ci_signature & 15);
+		l = snprintf(p, left, "%d\n",
+		    CPUID_TO_STEPPING(ci->ci_signature));
 	else
 		l = snprintf(p, left, "unknown\n");
 
@@ -196,8 +304,8 @@ procfs_getonecpu(int xcpu, struct cpu_in
 
 		freq = (ci->ci_data.cpu_cc_freq + 4999) / 1000000;
 		fraq = ((ci->ci_data.cpu_cc_freq + 4999) / 10000) % 100;
-		l = snprintf(p, left, "cpu MHz\t\t: %" PRIu64 ".%" PRIu64 "\n",
-		    freq, fraq);
+		l = snprintf(p, left, "cpu MHz\t\t: %" PRIu64 ".%02" PRIu64
+		    "\n", freq, fraq);
 	} else
 		l = snprintf(p, left, "cpu MHz\t\t: unknown\n");
 

Reply via email to