Module Name:    src
Committed By:   mlelstv
Date:           Fri May 10 16:42:57 UTC 2019

Modified Files:
        src/usr.sbin/cpuctl/arch: cpuctl_i386.h i386-asm.S i386.c x86_64-asm.S

Log Message:
Get CPU topology data for AMD processors.


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/usr.sbin/cpuctl/arch/cpuctl_i386.h
cvs rdiff -u -r1.4 -r1.5 src/usr.sbin/cpuctl/arch/i386-asm.S
cvs rdiff -u -r1.95 -r1.96 src/usr.sbin/cpuctl/arch/i386.c
cvs rdiff -u -r1.5 -r1.6 src/usr.sbin/cpuctl/arch/x86_64-asm.S

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/arch/cpuctl_i386.h
diff -u src/usr.sbin/cpuctl/arch/cpuctl_i386.h:1.2 src/usr.sbin/cpuctl/arch/cpuctl_i386.h:1.3
--- src/usr.sbin/cpuctl/arch/cpuctl_i386.h:1.2	Mon Jan  7 23:20:42 2013
+++ src/usr.sbin/cpuctl/arch/cpuctl_i386.h	Fri May 10 16:42:57 2019
@@ -1,4 +1,4 @@
-/*      $NetBSD: cpuctl_i386.h,v 1.2 2013/01/07 23:20:42 dsl Exp $      */
+/*      $NetBSD: cpuctl_i386.h,v 1.3 2019/05/10 16:42:57 mlelstv Exp $      */
 
 /* Interfaces to code in i386-asm.S */
 
@@ -7,3 +7,4 @@
 void x86_cpuid2(uint32_t, uint32_t, uint32_t *);
 uint32_t x86_identify(void);
 uint32_t x86_xgetbv(void);
+uint64_t rdmsr(u_int);

Index: src/usr.sbin/cpuctl/arch/i386-asm.S
diff -u src/usr.sbin/cpuctl/arch/i386-asm.S:1.4 src/usr.sbin/cpuctl/arch/i386-asm.S:1.5
--- src/usr.sbin/cpuctl/arch/i386-asm.S:1.4	Sun Mar  1 18:02:42 2015
+++ src/usr.sbin/cpuctl/arch/i386-asm.S	Fri May 10 16:42:57 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: i386-asm.S,v 1.4 2015/03/01 18:02:42 tnn Exp $	*/
+/*	$NetBSD: i386-asm.S,v 1.5 2019/05/10 16:42:57 mlelstv Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2000, 2004, 2006, 2007 The NetBSD Foundation, Inc.
@@ -30,6 +30,9 @@
 #include <machine/cputypes.h>
 #include <machine/psl.h>
 
+/* From sys/arch/x86/include/cpufunc.h */
+#define	OPTERON_MSR_PASSCODE	0x9c5a203aU
+
 	.text
 
 ENTRY(x86_cpuid2)
@@ -160,3 +163,12 @@ trycyrix486:
 is486dlc:
 	movl	$CPU_486DLC,%eax
 	ret
+
+ENTRY(rdmsr_locked)
+	movl	4(%esp), %ecx
+	pushl	%edi
+	movl	$OPTERON_MSR_PASSCODE, %edi
+	rdmsr
+	popl	%edi
+	ret
+END(rdmsr_locked)

Index: src/usr.sbin/cpuctl/arch/i386.c
diff -u src/usr.sbin/cpuctl/arch/i386.c:1.95 src/usr.sbin/cpuctl/arch/i386.c:1.96
--- src/usr.sbin/cpuctl/arch/i386.c:1.95	Sun Mar 24 04:43:54 2019
+++ src/usr.sbin/cpuctl/arch/i386.c	Fri May 10 16:42:57 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: i386.c,v 1.95 2019/03/24 04:43:54 msaitoh Exp $	*/
+/*	$NetBSD: i386.c,v 1.96 2019/05/10 16:42:57 mlelstv 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.95 2019/03/24 04:43:54 msaitoh Exp $");
+__RCSID("$NetBSD: i386.c,v 1.96 2019/05/10 16:42:57 mlelstv Exp $");
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -119,6 +119,7 @@ struct cpu_info {
 	uint8_t		ci_coreid;
 	uint8_t		ci_smtid;
 	uint32_t	ci_initapicid;
+	uint32_t	ci_max_ext_cpuid;
 
 	uint32_t	ci_cur_xsave;
 	uint32_t	ci_max_xsave;
@@ -1925,6 +1926,76 @@ identifycpu_cpuids_intel(struct cpu_info
 }
 
 static void
+identifycpu_cpuids_amd(struct cpu_info *ci)
+{
+	const char *cpuname = ci->ci_dev;
+	u_int lp_max, core_max;
+	int n, cpu_family, apic_id, smt_bits, core_bits = 0;
+	uint32_t descs[4];
+
+	apic_id = ci->ci_initapicid;
+	cpu_family = CPUID_TO_FAMILY(ci->ci_signature);
+
+	if (cpu_family < 0xf)
+		return;
+
+	if ((ci->ci_feat_val[0] & CPUID_HTT) != 0) {
+		x86_cpuid(1, descs);
+		lp_max = __SHIFTOUT(descs[1], CPUID_HTT_CORES);
+
+		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;
+			if (n != 0)
+				core_bits = n;
+		}
+	} else {
+		lp_max = 1;
+	}
+	core_max = lp_max;
+
+	smt_bits = ilog2((lp_max / core_max) - 1) + 1;
+	if (core_bits == 0)
+		core_bits = ilog2(core_max - 1) + 1;
+
+	if (cpu_family < 0x11) {
+		const uint64_t reg = rdmsr(MSR_NB_CFG);
+		if ((reg & NB_CFG_INITAPICCPUIDLO) == 0) {
+			const u_int node_id = apic_id & __BITS(0, 2);
+			apic_id = (cpu_family == 0xf) ?
+				(apic_id >> core_bits) | (node_id << core_bits) :
+				(apic_id >> 5) | (node_id << 2);
+		}
+	}
+
+	if (cpu_family == 0x17) {
+		x86_cpuid(0x8000001e, descs);
+		const u_int threads = ((descs[1] >> 8) & 0xff) + 1;
+		smt_bits = ilog2(threads);
+		core_bits -= smt_bits;
+	}
+
+	if (smt_bits + core_bits) {
+		if (smt_bits + core_bits < 32)
+			ci->ci_packageid = 0;
+	}
+	if (core_bits) {
+		u_int core_mask = __BITS(smt_bits, smt_bits + core_bits - 1);
+		ci->ci_coreid = __SHIFTOUT(apic_id, core_mask);
+	}
+	if (smt_bits) {
+		u_int smt_mask = __BITS(0, smt_bits - 1);
+		ci->ci_smtid = __SHIFTOUT(apic_id, smt_mask);
+	}
+
+	aprint_verbose("%s: Cluster/Package ID %u\n", cpuname,
+	    ci->ci_packageid);
+	aprint_verbose("%s: Core ID %u\n", cpuname, ci->ci_coreid);
+	aprint_verbose("%s: SMT ID %u\n", cpuname, ci->ci_smtid);
+}
+
+static void
 identifycpu_cpuids(struct cpu_info *ci)
 {
 	const char *cpuname = ci->ci_dev;
@@ -1936,6 +2007,8 @@ identifycpu_cpuids(struct cpu_info *ci)
 
 	if (cpu_vendor == CPUVENDOR_INTEL)
 		identifycpu_cpuids_intel(ci);
+	else if (cpu_vendor == CPUVENDOR_AMD)
+		identifycpu_cpuids_amd(ci);
 }
 
 void
@@ -2213,6 +2286,10 @@ identifycpu(int fd, const char *cpuname)
 
 	if (cpu_vendor == CPUVENDOR_AMD) {
 		x86_cpuid(0x80000000, descs);
+		if (descs[0] >= 0x80000000)
+			ci->ci_max_ext_cpuid = descs[0];
+		else
+			ci->ci_max_ext_cpuid = 0;
 		if (descs[0] >= 0x80000007)
 			powernow_probe(ci);
 

Index: src/usr.sbin/cpuctl/arch/x86_64-asm.S
diff -u src/usr.sbin/cpuctl/arch/x86_64-asm.S:1.5 src/usr.sbin/cpuctl/arch/x86_64-asm.S:1.6
--- src/usr.sbin/cpuctl/arch/x86_64-asm.S:1.5	Sun Mar  1 18:02:42 2015
+++ src/usr.sbin/cpuctl/arch/x86_64-asm.S	Fri May 10 16:42:57 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: x86_64-asm.S,v 1.5 2015/03/01 18:02:42 tnn Exp $	*/
+/*	$NetBSD: x86_64-asm.S,v 1.6 2019/05/10 16:42:57 mlelstv Exp $	*/
 
 /*-
  * Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -28,6 +28,9 @@
 
 #include <machine/asm.h>
 
+/* From sys/arch/x86/include/cpufunc.h */
+#define	OPTERON_MSR_PASSCODE	0x9c5a203aU
+
 	.text
 
 ENTRY(x86_cpuid2)
@@ -51,3 +54,12 @@ ENTRY(x86_xgetbv)
 ENTRY(x86_identify)
 	movl	$-1,%eax
 	ret
+
+ENTRY(rdmsr)
+	movq	%rdi, %rcx
+	xorq	%rax, %rax
+	movl	$OPTERON_MSR_PASSCODE, %edi
+	rdmsr
+	shlq	$32, %rdx
+	orq	%rdx, %rax
+	ret

Reply via email to