Module Name:    src
Committed By:   martin
Date:           Fri Jul 10 11:20:29 UTC 2020

Modified Files:
        src/usr.sbin/cpuctl [netbsd-9]: Makefile cpuctl.c cpuctl.h
        src/usr.sbin/cpuctl/arch [netbsd-9]: cpuctl_i386.h i386.c
Added Files:
        src/sys/arch/x86/x86 [netbsd-9]: identcpu_subr.c

Log Message:
Pull up the following revisions (all via patch) requested by msaitoh in
ticket #995:

        usr.sbin/cpuctl/Makefile                        1.9
        usr.sbin/cpuctl/arch/cpuctl_i386.h              1.5
        usr.sbin/cpuctl/arch/i386.c                     1.111-1.113
        usr.sbin/cpuctl/cpuctl.c                        1.31
        usr.sbin/cpuctl/cpuctl.h                        1.7
        sys/arch/x86/x86/identcpu_subr.c                1.1-1.7

- Get TSC frequency from CPUID 0x15 and/or x16 for newer Intel
  processors.
- Add 0xa5 and 0xa6 for Comet Lake.
- Rename ci_cpuid_level to ci_max_cpuid and ci_cpuid_extlevel to
  ci_max_ext_cpuid to match x86/include/cpu.h. No functional change.
- Sort some entries.
- Add comment.


To generate a diff of this commit:
cvs rdiff -u -r0 -r1.7.2.2 src/sys/arch/x86/x86/identcpu_subr.c
cvs rdiff -u -r1.8 -r1.8.18.1 src/usr.sbin/cpuctl/Makefile
cvs rdiff -u -r1.30 -r1.30.2.1 src/usr.sbin/cpuctl/cpuctl.c
cvs rdiff -u -r1.6 -r1.6.6.1 src/usr.sbin/cpuctl/cpuctl.h
cvs rdiff -u -r1.4 -r1.4.2.1 src/usr.sbin/cpuctl/arch/cpuctl_i386.h
cvs rdiff -u -r1.104.2.5 -r1.104.2.6 src/usr.sbin/cpuctl/arch/i386.c

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

Modified files:

Index: src/usr.sbin/cpuctl/Makefile
diff -u src/usr.sbin/cpuctl/Makefile:1.8 src/usr.sbin/cpuctl/Makefile:1.8.18.1
--- src/usr.sbin/cpuctl/Makefile:1.8	Sat Jan 23 21:22:50 2016
+++ src/usr.sbin/cpuctl/Makefile	Fri Jul 10 11:20:29 2020
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile,v 1.8 2016/01/23 21:22:50 christos Exp $
+#	$NetBSD: Makefile,v 1.8.18.1 2020/07/10 11:20:29 martin Exp $
 
 .include <bsd.own.mk>
 
@@ -19,6 +19,12 @@ SRCS+=	noarch.c
 SRCS+=	${MACHINE_ARCH}-asm.S
 .endif
 
+.if ${MACHINE_ARCH} == "x86_64" || ${MACHINE_ARCH} == "i386"
+CPPFLAGS+= -I${.CURDIR} -I${.CURDIR}/arch
+.PATH.c: ${NETBSDSRCDIR}/sys/arch/x86/x86
+SRCS+=	identcpu_subr.c
+.endif
+
 CPPFLAGS+=	-D_KERNTYPES
 LDADD+=-lutil
 DPADD+=${LIBUTIL}

Index: src/usr.sbin/cpuctl/cpuctl.c
diff -u src/usr.sbin/cpuctl/cpuctl.c:1.30 src/usr.sbin/cpuctl/cpuctl.c:1.30.2.1
--- src/usr.sbin/cpuctl/cpuctl.c:1.30	Sat May 11 11:59:21 2019
+++ src/usr.sbin/cpuctl/cpuctl.c	Fri Jul 10 11:20:29 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpuctl.c,v 1.30 2019/05/11 11:59:21 maxv Exp $	*/
+/*	$NetBSD: cpuctl.c,v 1.30.2.1 2020/07/10 11:20:29 martin Exp $	*/
 
 /*-
  * Copyright (c) 2007, 2008, 2009, 2012, 2015 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #ifndef lint
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: cpuctl.c,v 1.30 2019/05/11 11:59:21 maxv Exp $");
+__RCSID("$NetBSD: cpuctl.c,v 1.30.2.1 2020/07/10 11:20:29 martin Exp $");
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -382,3 +382,4 @@ aprint_normal_dev(const char *dev, const
 }
 __strong_alias(aprint_verbose_dev,aprint_normal_dev)
 __strong_alias(aprint_error_dev,aprint_normal_dev)
+__strong_alias(aprint_debug_dev,aprint_normal_dev)

Index: src/usr.sbin/cpuctl/cpuctl.h
diff -u src/usr.sbin/cpuctl/cpuctl.h:1.6 src/usr.sbin/cpuctl/cpuctl.h:1.6.6.1
--- src/usr.sbin/cpuctl/cpuctl.h:1.6	Tue Jan 16 08:23:18 2018
+++ src/usr.sbin/cpuctl/cpuctl.h	Fri Jul 10 11:20:29 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpuctl.h,v 1.6 2018/01/16 08:23:18 mrg Exp $	*/
+/*	$NetBSD: cpuctl.h,v 1.6.6.1 2020/07/10 11:20:29 martin Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -26,12 +26,15 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <sys/cpuio.h>
+
 int	aprint_normal(const char *, ...) __printflike(1, 2);
 int	aprint_verbose(const char *, ...) __printflike(1, 2);
 int	aprint_error(const char *, ...) __printflike(1, 2);
 int	aprint_normal_dev(const char *, const char *, ...) __printflike(2, 3);
 int	aprint_verbose_dev(const char *, const char *, ...) __printflike(2, 3);
 int	aprint_error_dev(const char *, const char *, ...) __printflike(2, 3);
+int	aprint_debug_dev(const char *, const char *, ...) __printflike(2, 3);
 
 void	identifycpu(int, const char *);
 bool	identifycpu_bind(void);

Index: src/usr.sbin/cpuctl/arch/cpuctl_i386.h
diff -u src/usr.sbin/cpuctl/arch/cpuctl_i386.h:1.4 src/usr.sbin/cpuctl/arch/cpuctl_i386.h:1.4.2.1
--- src/usr.sbin/cpuctl/arch/cpuctl_i386.h:1.4	Tue May 21 05:29:21 2019
+++ src/usr.sbin/cpuctl/arch/cpuctl_i386.h	Fri Jul 10 11:20:29 2020
@@ -1,4 +1,50 @@
-/*      $NetBSD: cpuctl_i386.h,v 1.4 2019/05/21 05:29:21 mlelstv Exp $      */
+/*      $NetBSD: cpuctl_i386.h,v 1.4.2.1 2020/07/10 11:20:29 martin Exp $      */
+
+#include <machine/specialreg.h>
+#include <x86/cputypes.h>
+#include <x86/cacheinfo.h>
+
+struct cpu_info {
+	const char	*ci_dev;
+	int32_t		ci_cpu_type;	 /* for cpu's without cpuid */
+	uint32_t	ci_signature;	 /* X86 cpuid type */
+	uint32_t	ci_vendor[4];	 /* vendor string */
+	int32_t		ci_max_cpuid;	 /* highest cpuid supported */
+	uint32_t	ci_max_ext_cpuid; /* highest cpuid extended func lv */
+	uint32_t	ci_family;	 /* from ci_signature */
+	uint32_t	ci_model;	 /* from ci_signature */
+	uint32_t	ci_feat_val[10]; /* 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] structure ext. feat. %ebx
+					  *	[6] structure ext. feat. %ecx
+					  *     [7] structure ext. feat. %edx
+					  *	[8] XCR0 bits (d:0 %eax)
+					  *	[9] xsave flags (d:1 %eax)
+					  */
+	uint32_t	ci_cpu_class;	 /* CPU class */
+	uint32_t	ci_brand_id;	 /* Intel brand id */
+	uint32_t	ci_cpu_serial[3]; /* PIII serial number */
+	uint64_t	ci_tsc_freq;	 /* cpu cycles/second */
+	uint8_t		ci_packageid;
+	uint8_t		ci_coreid;
+	uint8_t		ci_smtid;
+	uint32_t	ci_initapicid;	/* our initial APIC ID */
+
+	uint32_t	ci_cur_xsave;
+	uint32_t	ci_max_xsave;
+
+	struct x86_cache_info ci_cinfo[CAI_COUNT];
+	void		(*ci_info)(struct cpu_info *);
+};
+
+extern int cpu_vendor;
+
+/* For x86/x86/identcpu_subr.c */
+uint64_t cpu_tsc_freq_cpuid(struct cpu_info *);
 
 /* Interfaces to code in i386-asm.S */
 

Index: src/usr.sbin/cpuctl/arch/i386.c
diff -u src/usr.sbin/cpuctl/arch/i386.c:1.104.2.5 src/usr.sbin/cpuctl/arch/i386.c:1.104.2.6
--- src/usr.sbin/cpuctl/arch/i386.c:1.104.2.5	Tue Apr 14 17:15:02 2020
+++ src/usr.sbin/cpuctl/arch/i386.c	Fri Jul 10 11:20:29 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: i386.c,v 1.104.2.5 2020/04/14 17:15:02 martin Exp $	*/
+/*	$NetBSD: i386.c,v 1.104.2.6 2020/07/10 11:20:29 martin 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.104.2.5 2020/04/14 17:15:02 martin Exp $");
+__RCSID("$NetBSD: i386.c,v 1.104.2.6 2020/07/10 11:20:29 martin Exp $");
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -81,7 +81,6 @@ __RCSID("$NetBSD: i386.c,v 1.104.2.5 202
 
 #include <x86/cpuvar.h>
 #include <x86/cputypes.h>
-#include <x86/cacheinfo.h>
 #include <x86/cpu_ucode.h>
 
 #include "../cpuctl.h"
@@ -90,43 +89,6 @@ __RCSID("$NetBSD: i386.c,v 1.104.2.5 202
 /* Size of buffer for printing humanized numbers */
 #define HUMAN_BUFSIZE sizeof("999KB")
 
-struct cpu_info {
-	const char	*ci_dev;
-	int32_t		ci_cpu_type;	 /* for cpu's without cpuid */
-	int32_t		ci_cpuid_level;	 /* highest cpuid supported */
-	uint32_t	ci_cpuid_extlevel; /* highest cpuid extended func lv */
-	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[10]; /* 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] structure ext. feat. %ebx
-					  *	[6] structure ext. feat. %ecx
-					  *     [7] structure ext. feat. %edx
-					  *	[8] XCR0 bits (d:0 %eax)
-					  *	[9] xsave flags (d:1 %eax)
-					  */
-	uint32_t	ci_cpu_class;	 /* CPU class */
-	uint32_t	ci_brand_id;	 /* Intel brand id */
-	uint32_t	ci_vendor[4];	 /* vendor string */
-	uint32_t	ci_cpu_serial[3]; /* PIII serial number */
-	uint64_t	ci_tsc_freq;	 /* cpu cycles/second */
-	uint8_t		ci_packageid;
-	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 *);
-};
-
 struct cpu_nocpuid_nameclass {
 	int cpu_vendor;
 	const char *cpu_vendorname;
@@ -197,7 +159,7 @@ static const char * const amd_brand[] = 
 	"4"		/* AMD Athlon(tm) 4 */
 };
 
-static int cpu_vendor;
+int cpu_vendor;
 static char cpu_brand_string[49];
 static char amd_brand_name[48];
 static int use_pae, largepagesize;
@@ -391,6 +353,8 @@ const struct cpu_cpuid_nameclass i386_cp
 				[0x86] = "Atom (Tremont)",
 				[0x8e] = "7th or 8th gen Core (Kaby Lake, Coffee Lake) or Xeon E (Coffee Lake)",
 				[0x9e] = "7th or 8th gen Core (Kaby Lake, Coffee Lake) or Xeon E (Coffee Lake)",
+				[0xa5] = "10th gen Core (Comet Lake)",
+				[0xa6] = "10th gen Core (Comet Lake)",
 			},
 			"Pentium Pro, II or III",	/* Default */
 			NULL,
@@ -1065,7 +1029,7 @@ intel_cpu_cacheinfo(struct cpu_info *ci)
 	if (ci->ci_cpu_type >= 0)
 		return;
 
-	if (ci->ci_cpuid_level < 2)
+	if (ci->ci_max_cpuid < 2)
 		return;
 
 	/*
@@ -1103,13 +1067,13 @@ intel_cpu_cacheinfo(struct cpu_info *ci)
 		x86_cpuid(2, descs);
 	}
 
-	if (ci->ci_cpuid_level < 4)
+	if (ci->ci_max_cpuid < 4)
 		return;
 
 	/* Parse the cache info from `cpuid leaf 4', if we have it. */
 	cpu_dcp_cacheinfo(ci, 4);
 
-	if (ci->ci_cpuid_level < 0x18)
+	if (ci->ci_max_cpuid < 0x18)
 		return;
 	/* Parse the TLB info from `cpuid leaf 18H', if we have it. */
 	x86_cpuid(0x18, descs);
@@ -1583,7 +1547,7 @@ cpu_probe_base_features(struct cpu_info 
 	ci->ci_cpu_type = x86_identify();
 	if (ci->ci_cpu_type >= 0) {
 		/* Old pre-cpuid instruction cpu */
-		ci->ci_cpuid_level = -1;
+		ci->ci_max_cpuid = -1;
 		return;
 	}
 
@@ -1598,7 +1562,7 @@ cpu_probe_base_features(struct cpu_info 
 	 * - Save vendor string.
 	 */
 	x86_cpuid(0, descs);
-	ci->ci_cpuid_level = descs[0];
+	ci->ci_max_cpuid = descs[0];
 	/* Save vendor string */
 	ci->ci_vendor[0] = descs[1];
 	ci->ci_vendor[2] = descs[2];
@@ -1611,17 +1575,17 @@ cpu_probe_base_features(struct cpu_info 
 	 */
 	x86_cpuid(0x80000000, descs);
 	if (descs[0] >= 0x80000000)
-		ci->ci_cpuid_extlevel = descs[0];
+		ci->ci_max_ext_cpuid = descs[0];
 	else {
 		/* Set lower value than 0x80000000 */
-		ci->ci_cpuid_extlevel = 0;
+		ci->ci_max_ext_cpuid = 0;
 	}
 
 	/*
 	 * Fn8000_000[2-4]:
 	 * - Save brand string.
 	 */
-	if (ci->ci_cpuid_extlevel >= 0x80000004) {
+	if (ci->ci_max_ext_cpuid >= 0x80000004) {
 		x86_cpuid(0x80000002, brand);
 		x86_cpuid(0x80000003, brand + 4);
 		x86_cpuid(0x80000004, brand + 8);
@@ -1631,7 +1595,7 @@ cpu_probe_base_features(struct cpu_info 
 		memcpy(cpu_brand_string, ((char *) brand) + i, 48 - i);
 	}
 
-	if (ci->ci_cpuid_level < 1)
+	if (ci->ci_max_cpuid < 1)
 		return;
 
 	/*
@@ -1656,7 +1620,7 @@ cpu_probe_base_features(struct cpu_info 
 	ci->ci_feat_val[1] = descs[2];
 	ci->ci_feat_val[0] = descs[3];
 
-	if (ci->ci_cpuid_level < 3)
+	if (ci->ci_max_cpuid < 3)
 		return;
 
 	/*
@@ -1670,7 +1634,7 @@ cpu_probe_base_features(struct cpu_info 
 		ci->ci_cpu_serial[1] = descs[3];
 	}
 
-	if (ci->ci_cpuid_level < 0x7)
+	if (ci->ci_max_cpuid < 0x7)
 		return;
 
 	x86_cpuid(7, descs);
@@ -1678,7 +1642,7 @@ cpu_probe_base_features(struct cpu_info 
 	ci->ci_feat_val[6] = descs[2];
 	ci->ci_feat_val[7] = descs[3];
 
-	if (ci->ci_cpuid_level < 0xd)
+	if (ci->ci_max_cpuid < 0xd)
 		return;
 
 	/* Get support XCR0 bits */
@@ -1752,7 +1716,7 @@ cpu_probe_features(struct cpu_info *ci)
 	const struct cpu_cpuid_nameclass *cpup = NULL;
 	unsigned int i;
 
-	if (ci->ci_cpuid_level < 1)
+	if (ci->ci_max_cpuid < 1)
 		return;
 
 	for (i = 0; i < __arraycount(i386_cpuid_cpus); i++) {
@@ -1914,9 +1878,9 @@ identifycpu_cpuids_intel(struct cpu_info
 {
 	const char *cpuname = ci->ci_dev;
 
-	if (ci->ci_cpuid_level >= 0x0b)
+	if (ci->ci_max_cpuid >= 0x0b)
 		identifycpu_cpuids_intel_0x0b(ci);
-	else if (ci->ci_cpuid_level >= 4)
+	else if (ci->ci_max_cpuid >= 4)
 		identifycpu_cpuids_intel_0x04(ci);
 
 	aprint_verbose("%s: Cluster/Package ID %u\n", cpuname,
@@ -1943,7 +1907,7 @@ identifycpu_cpuids_amd(struct cpu_info *
 		x86_cpuid(1, descs);
 		lp_max = __SHIFTOUT(descs[1], CPUID_HTT_CORES);
 
-		if (cpu_family >= 0x10 && ci->ci_cpuid_extlevel >= 0x8000008) {
+		if (cpu_family >= 0x10 && ci->ci_max_ext_cpuid >= 0x8000008) {
 			x86_cpuid(0x8000008, descs);
 			core_max = (descs[2] & 0xff) + 1;
 			n = (descs[2] >> 12) & 0x0f;
@@ -2033,12 +1997,12 @@ identifycpu(int fd, const char *cpuname)
 
 	ci = &cistore;
 	cpu_probe_base_features(ci, cpuname);
-	dump_descs(0x00000000, ci->ci_cpuid_level, cpuname, "basic");
+	dump_descs(0x00000000, ci->ci_max_cpuid, cpuname, "basic");
 	if ((ci->ci_feat_val[1] & CPUID2_RAZ) != 0) {
 		x86_cpuid(0x40000000, descs);
 		dump_descs(0x40000000, descs[0], cpuname, "hypervisor");
 	}
-	dump_descs(0x80000000, ci->ci_cpuid_extlevel, cpuname, "extended");
+	dump_descs(0x80000000, ci->ci_max_ext_cpuid, cpuname, "extended");
 
 	cpu_probe_hv_features(ci, cpuname);
 	cpu_probe_features(ci);
@@ -2164,6 +2128,8 @@ identifycpu(int fd, const char *cpuname)
 		    (((uintmax_t)ci->ci_tsc_freq + 4999) / 10000) % 100);
 	aprint_normal("\n");
 
+	(void)cpu_tsc_freq_cpuid(ci);
+	
 	aprint_normal_dev(ci->ci_dev, "family %#x model %#x stepping %#x",
 	    ci->ci_family, ci->ci_model, CPUID_TO_STEPPING(ci->ci_signature));
 	if (ci->ci_signature != 0)
@@ -2217,7 +2183,7 @@ identifycpu(int fd, const char *cpuname)
 
 	x86_print_cache_and_tlb_info(ci);
 
-	if (ci->ci_cpuid_level >= 3 && (ci->ci_feat_val[0] & CPUID_PN)) {
+	if (ci->ci_max_cpuid >= 3 && (ci->ci_feat_val[0] & CPUID_PN)) {
 		aprint_verbose("%s: serial number %04X-%04X-%04X-%04X-%04X-%04X\n",
 		    cpuname,
 		    ci->ci_cpu_serial[0] / 65536, ci->ci_cpu_serial[0] % 65536,
@@ -2243,12 +2209,12 @@ identifycpu(int fd, const char *cpuname)
 	/*
 	 * Everything past this point requires a Pentium or later.
 	 */
-	if (ci->ci_cpuid_level < 0)
+	if (ci->ci_max_cpuid < 0)
 		return;
 
 	identifycpu_cpuids(ci);
 
-	if ((ci->ci_cpuid_level >= 5)
+	if ((ci->ci_max_cpuid >= 5)
 	    && ((cpu_vendor == CPUVENDOR_INTEL)
 		|| (cpu_vendor == CPUVENDOR_AMD))) {
 		uint16_t lmin, lmax;
@@ -2271,14 +2237,14 @@ identifycpu(int fd, const char *cpuname)
 				    cpuname, i, num);
 		}
 	}
-	if ((ci->ci_cpuid_level >= 6)
+	if ((ci->ci_max_cpuid >= 6)
 	    && ((cpu_vendor == CPUVENDOR_INTEL)
 		|| (cpu_vendor == CPUVENDOR_AMD))) {
 		x86_cpuid(6, descs);
 		print_bits(cpuname, "DSPM-eax", CPUID_DSPM_FLAGS, descs[0]);
 		print_bits(cpuname, "DSPM-ecx", CPUID_DSPM_FLAGS1, descs[2]);
 	}
-	if ((ci->ci_cpuid_level >= 7)
+	if ((ci->ci_max_cpuid >= 7)
 	    && ((cpu_vendor == CPUVENDOR_INTEL)
 		|| (cpu_vendor == CPUVENDOR_AMD))) {
 		x86_cpuid(7, descs);
@@ -2287,17 +2253,17 @@ identifycpu(int fd, const char *cpuname)
 	}
 
 	if ((cpu_vendor == CPUVENDOR_INTEL) || (cpu_vendor == CPUVENDOR_AMD))
-		if (ci->ci_cpuid_extlevel >= 0x80000007)
+		if (ci->ci_max_ext_cpuid >= 0x80000007)
 			powernow_probe(ci);
 
 	if (cpu_vendor == CPUVENDOR_AMD) {
-		if (ci->ci_cpuid_extlevel >= 0x80000008) {
+		if (ci->ci_max_ext_cpuid >= 0x80000008) {
 			x86_cpuid(0x80000008, descs);
 			print_bits(cpuname, "AMD Extended features",
 			    CPUID_CAPEX_FLAGS, descs[1]);
 		}
 
-		if ((ci->ci_cpuid_extlevel >= 0x8000000a)
+		if ((ci->ci_max_ext_cpuid >= 0x8000000a)
 		    && (ci->ci_feat_val[3] & CPUID_SVM) != 0) {
 			x86_cpuid(0x8000000a, descs);
 			aprint_verbose("%s: SVM Rev. %d\n", cpuname,
@@ -2307,7 +2273,7 @@ identifycpu(int fd, const char *cpuname)
 			print_bits(cpuname, "SVM features",
 			    CPUID_AMD_SVM_FLAGS, descs[3]);
 		}
-		if (ci->ci_cpuid_extlevel >= 0x8000001f) {
+		if (ci->ci_max_ext_cpuid >= 0x8000001f) {
 			x86_cpuid(0x8000001f, descs);
 			print_bits(cpuname, "Encrypted Memory features",
 			    CPUID_AMD_ENCMEM_FLAGS, descs[0]);
@@ -2315,7 +2281,7 @@ identifycpu(int fd, const char *cpuname)
 	} else if (cpu_vendor == CPUVENDOR_INTEL) {
 		int32_t bi_index;
 
-		for (bi_index = 1; bi_index <= ci->ci_cpuid_level; bi_index++) {
+		for (bi_index = 1; bi_index <= ci->ci_max_cpuid; bi_index++) {
 			x86_cpuid(bi_index, descs);
 			switch (bi_index) {
 			case 0x0a:

Added files:

Index: src/sys/arch/x86/x86/identcpu_subr.c
diff -u /dev/null src/sys/arch/x86/x86/identcpu_subr.c:1.7.2.2
--- /dev/null	Fri Jul 10 11:20:29 2020
+++ src/sys/arch/x86/x86/identcpu_subr.c	Fri Jul 10 11:20:29 2020
@@ -0,0 +1,145 @@
+/* $NetBSD: identcpu_subr.c,v 1.7.2.2 2020/07/10 11:20:29 martin Exp $ */
+
+/*-
+ * Copyright (c) 2020 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Masanobu SAITOH.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Subroutines for CPU.
+ * This file is shared between kernel and userland.
+ * See src/usr.sbin/cpuctl/{Makefile, arch/i386.c}).
+ */
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: identcpu_subr.c,v 1.7.2.2 2020/07/10 11:20:29 martin Exp $");
+
+#ifdef _KERNEL_OPT
+#include "lapic.h"
+#endif
+
+#include <sys/param.h>
+
+#ifdef _KERNEL
+#include <sys/systm.h>
+#include <x86/cpuvar.h>
+#include <x86/apicvar.h>
+#include <machine/cpufunc.h>
+#include <machine/cputypes.h>
+#include <machine/specialreg.h>
+#else
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "cpuctl.h"
+#include "cpuctl_i386.h"
+#endif
+
+uint64_t
+cpu_tsc_freq_cpuid(struct cpu_info *ci)
+{
+	uint64_t freq = 0, khz;
+	uint32_t descs[4];
+	uint32_t denominator, numerator;
+
+	if (!((ci->ci_max_cpuid >= 0x15) && (cpu_vendor == CPUVENDOR_INTEL)))
+		return 0;
+		
+	x86_cpuid(0x15, descs);
+	denominator = descs[0];
+	numerator = descs[1];
+	if ((denominator != 0) && (numerator != 0)) {
+		khz = 0;
+		if (descs[2] != 0)
+			khz = descs[2] / 1000;
+		else if (CPUID_TO_FAMILY(ci->ci_signature) == 6) {
+			/*
+			 * Table 18-85 Nominal Core Crystal Clock Frequency,
+			 * 18.7.3 Determining the Processor Base Frequency,
+			 * Intel SDM.
+			 */
+			switch (CPUID_TO_MODEL(ci->ci_signature)) {
+			case 0x55: /* Xeon Scalable */
+			case 0x5f: /*
+				    * Atom Goldmont (Denverton). Right?
+				    * XXX Not documented!
+				    */
+				khz = 25000; /* 25.0 MHz */
+				break;
+			case 0x4e: /* 7th gen Core (Skylake) */
+			case 0x5e: /* 7th gen Core (Skylake) */
+			case 0x8e: /* 8th gen Core (Kaby Lake) */
+			case 0x9e: /* 8th gen Core (Kaby Lake) */
+				khz = 24000; /* 24.0 MHz */
+				break;
+			case 0x5c: /* Atom Goldmont */
+				khz = 19200; /* 19.2 MHz */
+				break;
+			default: /* Unknown */
+				break;
+			}
+		}
+		freq = khz * 1000 * numerator / denominator;
+		if (ci->ci_max_cpuid >= 0x16) {
+			x86_cpuid(0x16, descs);
+			if (descs[0] != 0) {
+				aprint_verbose_dev(ci->ci_dev,
+				    "CPU base freq %" PRIu64 " Hz\n",
+				    (uint64_t)descs[0] * 1000000);
+
+				/*
+				 * If we couldn't get frequency from
+				 * CPUID 0x15, use CPUID 0x16 EAX.
+				 */
+				if (freq == 0) {
+					khz = (uint64_t)descs[0] * 1000
+					    * denominator / numerator;
+					freq = (uint64_t)descs[0] * 1000000;
+				}
+			}
+			if (descs[1] != 0) {
+				aprint_verbose_dev(ci->ci_dev,
+				    "CPU max freq %" PRIu64 " Hz\n",
+				    (uint64_t)descs[1] * 1000000);
+			}
+		}
+#if defined(_KERNEL) &&  NLAPIC > 0
+		if ((khz != 0) && (lapic_per_second == 0)) {
+			lapic_per_second = khz * 1000;
+			aprint_debug_dev(ci->ci_dev,
+			    "lapic_per_second set to %" PRIu32 "\n",
+			    lapic_per_second);
+		}
+#endif
+	}
+	if (freq != 0)
+		aprint_verbose_dev(ci->ci_dev, "TSC freq CPUID %" PRIu64
+		    " Hz\n", freq);
+
+	return freq;
+}

Reply via email to