Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 18 May 2005 19:35:18 -0400
From:      Jung-uk Kim <jkim@niksun.com>
To:        freebsd-amd64@freebsd.org
Cc:        Pav Lucistnik <pav@freebsd.org>
Subject:   AMD64 multicore (Was: Re: FreeBSD on dual core Opterons - stupid buildworld test)
Message-ID:  <200505181935.18493.jkim@niksun.com>
In-Reply-To: <200505181453.49988.jkim@niksun.com>
References:  <428B6FC1.3000907@fsn.hu> <200505181441.39457.jkim@niksun.com> <200505181453.49988.jkim@niksun.com>

Next in thread | Previous in thread | Raw E-Mail | Index | Archive | Help

--Boundary-00=_2E9iC9mVuPyuPcQ
Content-Type: text/plain;
  charset="utf-8"
Content-Transfer-Encoding: 8bit
Content-Disposition: inline

On Wednesday 18 May 2005 02:53 pm, Jung-uk Kim wrote:
> On Wednesday 18 May 2005 02:41 pm, Jung-uk Kim wrote:
> > On Wednesday 18 May 2005 02:05 pm, Brooks Davis wrote:
> > > On Wed, May 18, 2005 at 07:29:00PM +0200, Pav Lucistnik wrote:
> > > > Attila Nagy pí?e v st 18. 05. 2005 v 18:39 +0200:
> > > > > Hello,
> > > > >
> > > > > I did some buildworld tests on an HP BL45p with 4 2,2 GHz
> > > > > Opterons.
> > > > >
> > > > > Sequential time make buildworld -jX times (if there is a
> > > > > missing iteration, then the build has failed):
> > > > >
> > > > > http://people.fsn.hu/~bra/bl45p/dmesg.boot
> > > > >
> > > > >  Hyperthreading: 2 logical CPUs
> > > >
> > > > So dual-core Opterons report into system as Hyperthreading?
> > > > Uncool.
> > >
> > > What the AMD reps said at a session I attended last year is
> > > that they report as supporting hyper threading, but set another
> > > bit to say that they are actually real cores.  We probably need
> > > to find out what that bit is.
> >
> > FYI, Linux says:
> >
> > http://lxr.linux.no/source/include/asm-x86_64/cpufeature.h#L78
> > http://lxr.linux.no/source/arch/x86_64/kernel/setup.c#L834
>
> Check 'Logical Processor Count' (Page 122):
>
> http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_
>docs/24594.pdf

The attachment (against -CURRENT) is my attempt to 'do the right 
thing' by the above manual.  I did very light testing because I don't 
have a dual-core proc.  Can you test, please?

Thanks,

Jung-uk Kim

> Jung-uk Kim
>
> > Jung-uk Kim
> >
> > > -- Brooks

--Boundary-00=_2E9iC9mVuPyuPcQ
Content-Type: text/x-diff;
  charset="utf-8";
  name="multicore.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename="multicore.diff"

Index: sys/amd64/amd64/identcpu.c
===================================================================
RCS file: /home/ncvs/src/sys/amd64/amd64/identcpu.c,v
retrieving revision 1.135
diff -u -r1.135 identcpu.c
--- sys/amd64/amd64/identcpu.c	21 Jan 2005 05:56:40 -0000	1.135
+++ sys/amd64/amd64/identcpu.c	18 May 2005 23:16:09 -0000
@@ -283,13 +283,53 @@
 				"\0403DNow"	/* AMD 3DNow! */
 				);
 			}
+			if (amd_feature2 != 0) {
+				printf("\n  AMD Features2=0x%b", amd_feature2,
+				"\020"
+				"\001LAHF"	/* LAHF/SAHF in long mode */
+				"\002CMP"	/* CMP legacy */
+				"\003<b2>"
+				"\004<b3>"
+				"\005CR8"	/* CR8 in legacy mode */
+				"\006<b5>"
+				"\007<b6>"
+				"\010<b7>"
+				"\011<b8>"
+				"\012<b9>"
+				"\013<b10>"
+				"\014<b11>"
+				"\015<b12>"
+				"\016<b13>"
+				"\017<b14>"
+				"\020<b15>"
+				"\021<b16>"
+				"\022<b17>"
+				"\023<b18>"
+				"\024<b19>"
+				"\025<b20>"
+				"\026<b21>"
+				"\027<b22>"
+				"\030<b23>"
+				"\031<b24>"
+				"\032<b25>"
+				"\033<b26>"
+				"\034<b27>"
+				"\035<b28>"
+				"\036<b29>"
+				"\037<b30>"
+				"\040<b31>"
+				);
+			}
 
 			/*
 			 * If this CPU supports hyperthreading then mention
 			 * the number of logical CPU's it contains.
 			 */
 			if (cpu_feature & CPUID_HTT &&
-			    (cpu_procinfo & CPUID_HTT_CORES) >> 16 > 1)
+			    (cpu_procinfo & CPUID_HTT_CORES) >> 16 > 1 &&
+			    (strcmp(cpu_vendor, "GenuineIntel") == 0 ||
+			    (strcmp(cpu_vendor, "AuthenticAMD") == 0 &&
+			    !(amd_feature2 & AMDID2_CMP))))
 				printf("\n  Hyperthreading: %d logical CPUs",
 				    (cpu_procinfo & CPUID_HTT_CORES) >> 16);
 		}
@@ -357,6 +397,11 @@
 	if (cpu_exthigh >= 0x80000001) {
 		do_cpuid(0x80000001, regs);
 		amd_feature = regs[3] & ~(cpu_feature & 0x0183f3ff);
+		amd_feature2 = regs[2] & 0x00000013;
+	}
+	if (cpu_exthigh >= 0x80000008) {
+		do_cpuid(0x80000008, regs);
+		cpu_procinfo2 = regs[2];
 	}
 
 	/* XXX */
Index: sys/amd64/amd64/initcpu.c
===================================================================
RCS file: /home/ncvs/src/sys/amd64/amd64/initcpu.c,v
retrieving revision 1.48
diff -u -r1.48 initcpu.c
--- sys/amd64/amd64/initcpu.c	8 Jun 2004 01:02:51 -0000	1.48
+++ sys/amd64/amd64/initcpu.c	18 May 2005 23:16:09 -0000
@@ -51,11 +51,13 @@
 int	cpu;			/* Are we 386, 386sx, 486, etc? */
 u_int	cpu_feature;		/* Feature flags */
 u_int	cpu_feature2;		/* Feature flags */
-u_int	amd_feature;		/* Feature flags */
+u_int	amd_feature;		/* AMD Feature flags */
+u_int	amd_feature2;		/* AMD Feature flags */
 u_int	cpu_high;		/* Highest arg to CPUID */
 u_int	cpu_exthigh;		/* Highest arg to extended CPUID */
 u_int	cpu_id;			/* Stepping ID */
 u_int	cpu_procinfo;		/* HyperThreading Info / Brand Index / CLFUSH */
+u_int	cpu_procinfo2;		/* Multicore info */
 char	cpu_vendor[20];		/* CPU Origin code */
 u_int	cpu_fxsr;		/* SSE enabled */
 
Index: sys/amd64/amd64/mp_machdep.c
===================================================================
RCS file: /home/ncvs/src/sys/amd64/amd64/mp_machdep.c,v
retrieving revision 1.255
diff -u -r1.255 mp_machdep.c
--- sys/amd64/amd64/mp_machdep.c	13 May 2005 00:57:04 -0000	1.255
+++ sys/amd64/amd64/mp_machdep.c	18 May 2005 23:16:09 -0000
@@ -168,7 +168,13 @@
 	/* Nothing to do if there is no HTT support. */
 	if ((cpu_feature & CPUID_HTT) == 0)
 		return;
-	logical_cpus = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
+	if (strcmp(cpu_vendor, "AuthenticAMD") == 0) {
+		if (amd_feature2 & AMDID2_CMP)
+			logical_cpus = (cpu_procinfo2 & AMDID_CMP_CORES) + 1;
+		else
+			logical_cpus = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
+	} else
+		logical_cpus = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
 	if (logical_cpus <= 1)
 		return;
 	group = &mp_groups[0];
@@ -353,37 +359,41 @@
 	 * At the time of writing (May 12, 2005) the only hyperthreaded
 	 * cpus are from Intel, and Intel's dual-core processors can be
 	 * identified via the "deterministic cache parameters" cpuid
-	 * calls.
+	 * calls. AMD's hyperthreaded cpus can be identified via the
+	 * "CMP legacy" cpuid call.
 	 */
-	/*
-	 * First determine if this is an Intel processor which claims
-	 * to have hyperthreading support.
-	 */
-	if ((cpu_feature & CPUID_HTT) &&
-	    (strcmp(cpu_vendor, "GenuineIntel") == 0)) {
-		/*
-		 * If the "deterministic cache parameters" cpuid calls
-		 * are available, use them.
-		 */
-		if (cpu_high >= 4) {
-			/* Ask the processor about up to 32 caches. */
-			for (i = 0; i < 32; i++) {
-				cpuid_count(4, i, p);
-				threads_per_cache = ((p[0] & 0x3ffc000) >> 14) + 1;
-				if (hyperthreading_cpus < threads_per_cache)
-					hyperthreading_cpus = threads_per_cache;
-				if ((p[0] & 0x1f) == 0)
-					break;
+	if (cpu_feature & CPUID_HTT) {
+		if (strcmp(cpu_vendor, "AuthenticAMD") == 0) {
+			if (!(amd_feature2 & AMDID2_CMP))
+				hyperthreading_cpus = logical_cpus;
+		} else if (strcmp(cpu_vendor, "GenuineIntel") == 0) {
+			/*
+			 * If the "deterministic cache parameters" cpuid
+			 * calls are available, use them.
+			 */
+			if (cpu_high >= 4) {
+				/* Ask the processor about up to 32 caches. */
+				for (i = 0; i < 32; i++) {
+					cpuid_count(4, i, p);
+					threads_per_cache =
+					    ((p[0] & 0x3ffc000) >> 14) + 1;
+					if (hyperthreading_cpus <
+					    threads_per_cache)
+						hyperthreading_cpus =
+						    threads_per_cache;
+					if ((p[0] & 0x1f) == 0)
+						break;
+				}
 			}
-		}
 
-		/*
-		 * If the deterministic cache parameters are not
-		 * available, or if no caches were reported to exist,
-		 * just accept what the HTT flag indicated.
-		 */
-		if (hyperthreading_cpus == 0)
-			hyperthreading_cpus = logical_cpus;
+			/*
+			 * If the deterministic cache parameters are not
+			 * available, or if no caches were reported to exist,
+			 * just accept what the HTT flag indicated.
+			 */
+			if (hyperthreading_cpus == 0)
+				hyperthreading_cpus = logical_cpus;
+		}
 	}
 
 	set_logical_apic_ids();
Index: sys/amd64/include/md_var.h
===================================================================
RCS file: /home/ncvs/src/sys/amd64/include/md_var.h,v
retrieving revision 1.75
diff -u -r1.75 md_var.h
--- sys/amd64/include/md_var.h	10 Jun 2004 20:30:55 -0000	1.75
+++ sys/amd64/include/md_var.h	18 May 2005 23:16:09 -0000
@@ -43,10 +43,12 @@
 extern	u_int	cpu_feature;
 extern	u_int	cpu_feature2;
 extern	u_int	amd_feature;
+extern	u_int	amd_feature2;
 extern	u_int	cpu_fxsr;
 extern	u_int	cpu_high;
 extern	u_int	cpu_id;
 extern	u_int	cpu_procinfo;
+extern	u_int	cpu_procinfo2;
 extern	char	cpu_vendor[];
 extern	char	kstack[];
 extern	char	sigcode[];
Index: sys/amd64/include/specialreg.h
===================================================================
RCS file: /home/ncvs/src/sys/amd64/include/specialreg.h,v
retrieving revision 1.30
diff -u -r1.30 specialreg.h
--- sys/amd64/include/specialreg.h	8 Jun 2004 01:02:52 -0000	1.30
+++ sys/amd64/include/specialreg.h	18 May 2005 23:16:09 -0000
@@ -128,6 +128,8 @@
 #define AMDID_NX	0x00100000
 #define AMDID_LM	0x20000000
 
+#define AMDID2_CMP	0x00000002
+
 /*
  * CPUID instruction 1 ebx info
  */
@@ -137,6 +139,11 @@
 #define	CPUID_LOCAL_APIC_ID	0xff000000
 
 /*
+ * AMD extended function 8000_0008h ecx info
+ */
+#define AMDID_CMP_CORES		0x000000ff
+
+/*
  * Model-specific registers for the i386 family
  */
 #define MSR_P5_MC_ADDR		0x000
Index: sys/i386/i386/identcpu.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/i386/identcpu.c,v
retrieving revision 1.143
diff -u -r1.143 identcpu.c
--- sys/i386/i386/identcpu.c	16 May 2005 09:47:53 -0000	1.143
+++ sys/i386/i386/identcpu.c	18 May 2005 23:16:10 -0000
@@ -309,6 +309,15 @@
 			}
 		}
 	} else if (strcmp(cpu_vendor, "AuthenticAMD") == 0) {
+		if (cpu_exthigh >= 0x80000001) {
+			do_cpuid(0x80000001, regs);
+			amd_feature = regs[3] & ~(cpu_feature & 0x0183f3ff);
+			amd_feature2 = regs[2] & 0x00000013;
+		}
+		if (cpu_exthigh >= 0x80000008) {
+			do_cpuid(0x80000008, regs);
+			cpu_procinfo2 = regs[2];
+		}
 		/*
 		 * Values taken from AMD Processor Recognition
 		 * http://www.amd.com/K6/k6docs/pdf/20734g.pdf
@@ -730,7 +739,10 @@
 			 * the number of logical CPU's it contains.
 			 */
 			if (cpu_feature & CPUID_HTT &&
-			    (cpu_procinfo & CPUID_HTT_CORES) >> 16 > 1)
+			    (cpu_procinfo & CPUID_HTT_CORES) >> 16 > 1 &&
+			    (strcmp(cpu_vendor, "GenuineIntel") == 0 ||
+			    (strcmp(cpu_vendor, "AuthenticAMD") == 0 &&
+			    !(amd_feature2 & AMDID2_CMP))))
 				printf("\n  Hyperthreading: %d logical CPUs",
 				    (cpu_procinfo & CPUID_HTT_CORES) >> 16);
 		}
@@ -943,7 +955,17 @@
 	u_char	ccr3;
 	u_int	regs[4];
 
-	if (strcmp(cpu_vendor, "CyrixInstead") == 0) {
+	if (strcmp(cpu_vendor, "AuthenticAMD") == 0) {
+		if (cpu_exthigh >= 0x80000001) {
+			do_cpuid(0x80000001, regs);
+			amd_feature = regs[3] & ~(cpu_feature & 0x0183f3ff);
+			amd_feature2 = regs[2] & 0x00000013;
+		}
+		if (cpu_exthigh >= 0x80000008) {
+			do_cpuid(0x80000008, regs);
+			cpu_procinfo2 = regs[2];
+		}
+	} else if (strcmp(cpu_vendor, "CyrixInstead") == 0) {
 		if (cpu == CPU_486) {
 			/*
 			 * These conditions are equivalent to:
@@ -1105,48 +1127,87 @@
 static void
 print_AMD_features(void)
 {
-	u_int regs[4];
-
 	/*
 	 * Values taken from AMD Processor Recognition
 	 * http://www.amd.com/products/cpg/athlon/techdocs/pdf/20734.pdf
 	 */
-	do_cpuid(0x80000001, regs);
-	printf("\n  AMD Features=0x%b", regs[3] &~ cpu_feature,
-		"\020"		/* in hex */
-		"\001FPU"	/* Integral FPU */
-		"\002VME"	/* Extended VM86 mode support */
-		"\003DE"	/* Debug extensions */
-		"\004PSE"	/* 4MByte page tables */
-		"\005TSC"	/* Timestamp counter */
-		"\006MSR"	/* Machine specific registers */
-		"\007PAE"	/* Physical address extension */
-		"\010MCE"	/* Machine Check support */
-		"\011CX8"	/* CMPEXCH8 instruction */
-		"\012APIC"	/* SMP local APIC */
-		"\013<b10>"
-		"\014SYSCALL"	/* SYSENTER/SYSEXIT instructions */
-		"\015MTRR"	/* Memory Type Range Registers */
-		"\016PGE"	/* PG_G (global bit) support */
-		"\017MCA"	/* Machine Check Architecture */
-		"\020ICMOV"	/* CMOV instruction */
-		"\021PAT"	/* Page attributes table */
-		"\022PGE36"	/* 36 bit address space support */
-		"\023RSVD"	/* Reserved, unknown */
-		"\024MP"	/* Multiprocessor Capable */
-		"\025NX"	/* Has EFER.NXE, NX (no execute pte bit) */
-		"\026<b21>"
-		"\027AMIE"	/* AMD MMX Instruction Extensions */
-		"\030MMX"
-		"\031FXSAVE"	/* FXSAVE/FXRSTOR */
-		"\032<b25>"
-		"\033<b26>"
-		"\034<b27>"
-		"\035<b28>"
-		"\036LM"	/* Long mode */
-		"\037DSP"	/* AMD 3DNow! Instruction Extensions */
-		"\0403DNow!"	/* AMD 3DNow! Instructions */
-		);
+	if (amd_feature != 0)
+		printf("\n  AMD Features=0x%b", amd_feature,
+			"\020"		/* in hex */
+			"\001FPU"	/* Integral FPU */
+			"\002VME"	/* Extended VM86 mode support */
+			"\003DE"	/* Debug extensions */
+			"\004PSE"	/* 4MByte page tables */
+			"\005TSC"	/* Timestamp counter */
+			"\006MSR"	/* Machine specific registers */
+			"\007PAE"	/* Physical address extension */
+			"\010MCE"	/* Machine Check support */
+			"\011CX8"	/* CMPEXCH8 instruction */
+			"\012APIC"	/* SMP local APIC */
+			"\013<b10>"
+			"\014SYSCALL"	/* SYSENTER/SYSEXIT instructions */
+			"\015MTRR"	/* Memory Type Range Registers */
+			"\016PGE"	/* PG_G (global bit) support */
+			"\017MCA"	/* Machine Check Architecture */
+			"\020ICMOV"	/* CMOV instruction */
+			"\021PAT"	/* Page attributes table */
+			"\022PGE36"	/* 36 bit address space support */
+			"\023RSVD"	/* Reserved, unknown */
+			"\024MP"	/* Multiprocessor Capable */
+			"\025NX"	/* Has EFER.NXE, NX (no execute pte bit) */
+			"\026<b21>"
+			"\027AMIE"	/* AMD MMX Instruction Extensions */
+			"\030MMX"
+			"\031FXSAVE"	/* FXSAVE/FXRSTOR */
+			"\032<b25>"
+			"\033<b26>"
+			"\034<b27>"
+			"\035<b28>"
+			"\036LM"	/* Long mode */
+			"\037DSP"	/* AMD 3DNow! Instruction Extensions */
+			"\0403DNow!"	/* AMD 3DNow! Instructions */
+			);
+	/*
+	 * AMD64 Architecture Programmer's Manual Volume 3:
+	 * 	General-Purpose and System Instructions
+	 * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/24594.pdf
+	 */
+	if (amd_feature2 != 0)
+		printf("\n  AMD Features2=0x%b", amd_feature2,
+			"\020"
+			"\001LAHF"	/* LAHF/SAHF in long mode */
+			"\002CMP"	/* CMP legacy */
+			"\003<b2>"
+			"\004<b3>"
+			"\005CR8"	/* CR8 in legacy mode */
+			"\006<b5>"
+			"\007<b6>"
+			"\010<b7>"
+			"\011<b8>"
+			"\012<b9>"
+			"\013<b10>"
+			"\014<b11>"
+			"\015<b12>"
+			"\016<b13>"
+			"\017<b14>"
+			"\020<b15>"
+			"\021<b16>"
+			"\022<b17>"
+			"\023<b18>"
+			"\024<b19>"
+			"\025<b20>"
+			"\026<b21>"
+			"\027<b22>"
+			"\030<b23>"
+			"\031<b24>"
+			"\032<b25>"
+			"\033<b26>"
+			"\034<b27>"
+			"\035<b28>"
+			"\036<b29>"
+			"\037<b30>"
+			"\040<b31>"
+			);
 }
 #endif
 
Index: sys/i386/i386/initcpu.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/i386/initcpu.c,v
retrieving revision 1.50
diff -u -r1.50 initcpu.c
--- sys/i386/i386/initcpu.c	16 May 2005 09:47:53 -0000	1.50
+++ sys/i386/i386/initcpu.c	18 May 2005 23:16:10 -0000
@@ -80,9 +80,12 @@
 int	cpu = 0;		/* Are we 386, 386sx, 486, etc? */
 u_int	cpu_feature = 0;	/* Feature flags */
 u_int	cpu_feature2 = 0;	/* Feature flags */
+u_int	amd_feature = 0;	/* AMD Feature flags */
+u_int	amd_feature2 = 0;	/* AMD Feature flags */
 u_int	cpu_high = 0;		/* Highest arg to CPUID */
 u_int	cpu_id = 0;		/* Stepping ID */
 u_int	cpu_procinfo = 0;	/* HyperThreading Info / Brand Index / CLFUSH */
+u_int	cpu_procinfo2 = 0;	/* Multicore info */
 char	cpu_vendor[20] = "";	/* CPU Origin code */
 
 #ifdef CPU_ENABLE_SSE
Index: sys/i386/i386/mp_machdep.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/i386/mp_machdep.c,v
retrieving revision 1.249
diff -u -r1.249 mp_machdep.c
--- sys/i386/i386/mp_machdep.c	13 May 2005 00:57:04 -0000	1.249
+++ sys/i386/i386/mp_machdep.c	18 May 2005 23:16:10 -0000
@@ -239,7 +239,13 @@
 	/* Nothing to do if there is no HTT support. */
 	if ((cpu_feature & CPUID_HTT) == 0)
 		return;
-	logical_cpus = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
+	if (strcmp(cpu_vendor, "AuthenticAMD") == 0) {
+		if (amd_feature2 & AMDID2_CMP)
+			logical_cpus = (cpu_procinfo2 & AMDID_CMP_CORES) + 1;
+		else
+			logical_cpus = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
+	} else
+		logical_cpus = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
 	if (logical_cpus <= 1)
 		return;
 	group = &mp_groups[0];
@@ -414,37 +420,41 @@
 	 * At the time of writing (May 12, 2005) the only hyperthreaded
 	 * cpus are from Intel, and Intel's dual-core processors can be
 	 * identified via the "deterministic cache parameters" cpuid
-	 * calls.
+	 * calls. AMD's hyperthreaded cpus can be identified via the
+	 * "CMP legacy" cpuid call.
 	 */
-	/*
-	 * First determine if this is an Intel processor which claims
-	 * to have hyperthreading support.
-	 */
-	if ((cpu_feature & CPUID_HTT) &&
-	    (strcmp(cpu_vendor, "GenuineIntel") == 0)) {
-		/*
-		 * If the "deterministic cache parameters" cpuid calls
-		 * are available, use them.
-		 */
-		if (cpu_high >= 4) {
-			/* Ask the processor about up to 32 caches. */
-			for (i = 0; i < 32; i++) {
-				cpuid_count(4, i, p);
-				threads_per_cache = ((p[0] & 0x3ffc000) >> 14) + 1;
-				if (hyperthreading_cpus < threads_per_cache)
-					hyperthreading_cpus = threads_per_cache;
-				if ((p[0] & 0x1f) == 0)
-					break;
+	if (cpu_feature & CPUID_HTT) {
+		if (strcmp(cpu_vendor, "AuthenticAMD") == 0) {
+			if (!(amd_feature2 & AMDID2_CMP))
+				hyperthreading_cpus = logical_cpus;
+		} else if (strcmp(cpu_vendor, "GenuineIntel") == 0) {
+			/*
+			 * If the "deterministic cache parameters" cpuid
+			 * calls are available, use them.
+			 */
+			if (cpu_high >= 4) {
+				/* Ask the processor about up to 32 caches. */
+				for (i = 0; i < 32; i++) {
+					cpuid_count(4, i, p);
+					threads_per_cache =
+					    ((p[0] & 0x3ffc000) >> 14) + 1;
+					if (hyperthreading_cpus <
+					    threads_per_cache)
+						hyperthreading_cpus =
+						    threads_per_cache;
+					if ((p[0] & 0x1f) == 0)
+						break;
+				}
 			}
-		}
 
-		/*
-		 * If the deterministic cache parameters are not
-		 * available, or if no caches were reported to exist,
-		 * just accept what the HTT flag indicated.
-		 */
-		if (hyperthreading_cpus == 0)
-			hyperthreading_cpus = logical_cpus;
+			/*
+			 * If the deterministic cache parameters are not
+			 * available, or if no caches were reported to exist,
+			 * just accept what the HTT flag indicated.
+			 */
+			if (hyperthreading_cpus == 0)
+				hyperthreading_cpus = logical_cpus;
+		}
 	}
 
 	set_logical_apic_ids();
Index: sys/i386/include/md_var.h
===================================================================
RCS file: /home/ncvs/src/sys/i386/include/md_var.h,v
retrieving revision 1.71
diff -u -r1.71 md_var.h
--- sys/i386/include/md_var.h	16 May 2005 09:47:53 -0000	1.71
+++ sys/i386/include/md_var.h	18 May 2005 23:16:10 -0000
@@ -46,10 +46,11 @@
 extern	int	busdma_swi_pending;
 extern	u_int	cpu_exthigh;
 extern	u_int	cpu_feature, cpu_feature2;
+extern	u_int	amd_feature, amd_feature2;
 extern	u_int	cpu_fxsr;
 extern	u_int	cpu_high;
 extern	u_int	cpu_id;
-extern	u_int	cpu_procinfo;
+extern	u_int	cpu_procinfo, cpu_procinfo2;
 extern	char	cpu_vendor[];
 extern	u_int	cyrix_did;
 extern	char	kstack[];
Index: sys/i386/include/specialreg.h
===================================================================
RCS file: /home/ncvs/src/sys/i386/include/specialreg.h,v
retrieving revision 1.27
diff -u -r1.27 specialreg.h
--- sys/i386/include/specialreg.h	7 Apr 2004 20:46:05 -0000	1.27
+++ sys/i386/include/specialreg.h	18 May 2005 23:16:10 -0000
@@ -108,6 +108,16 @@
 #define	CPUID_PBE	0x80000000
 
 /*
+ * Important bits in the AMD extended cpuid flags
+ */
+#define AMDID_SYSCALL	0x00000800
+#define AMDID_MP	0x00080000
+#define AMDID_NX	0x00100000
+#define AMDID_LM	0x20000000
+
+#define AMDID2_CMP	0x00000002
+
+/*
  * CPUID instruction 1 ebx info
  */
 #define	CPUID_BRAND_INDEX	0x000000ff
@@ -116,6 +126,11 @@
 #define	CPUID_LOCAL_APIC_ID	0xff000000
 
 /*
+ * AMD extended function 8000_0008h ecx info
+ */
+#define AMDID_CMP_CORES		0x000000ff
+
+/*
  * Model-specific registers for the i386 family
  */
 #define MSR_P5_MC_ADDR		0x000

--Boundary-00=_2E9iC9mVuPyuPcQ--



Want to link to this message? Use this URL: <http://docs.FreeBSD.org/cgi/mid.cgi?200505181935.18493.jkim>