summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjkim <jkim@FreeBSD.org>2005-10-14 22:52:01 +0000
committerjkim <jkim@FreeBSD.org>2005-10-14 22:52:01 +0000
commit0dd10470eca4b50758f1f3fa559697f67bd0a188 (patch)
treea8764706a4db8c765f1763d02dbb2688b1955119 /sys
parent10f007ca7dcc58198c5b122a663950ba305936d2 (diff)
downloadFreeBSD-src-0dd10470eca4b50758f1f3fa559697f67bd0a188.zip
FreeBSD-src-0dd10470eca4b50758f1f3fa559697f67bd0a188.tar.gz
- Print number of physical/logical cores and more CPUID info.
- Add newer CPUID definitions for future use. Many thanks to Mike Tancsa <mike at sentex dot net> for providing test cases for Intel Pentium D and AMD Athlon 64 X2. Approved by: anholt (mentor)
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/amd64/identcpu.c80
-rw-r--r--sys/amd64/amd64/initcpu.c4
-rw-r--r--sys/amd64/include/md_var.h2
-rw-r--r--sys/amd64/include/specialreg.h14
-rw-r--r--sys/i386/i386/identcpu.c91
-rw-r--r--sys/i386/i386/initcpu.c4
-rw-r--r--sys/i386/include/md_var.h2
-rw-r--r--sys/i386/include/specialreg.h22
8 files changed, 196 insertions, 23 deletions
diff --git a/sys/amd64/amd64/identcpu.c b/sys/amd64/amd64/identcpu.c
index 4000448..4e69a7d 100644
--- a/sys/amd64/amd64/identcpu.c
+++ b/sys/amd64/amd64/identcpu.c
@@ -165,6 +165,8 @@ printcpuinfo(void)
strcmp(cpu_vendor, "AuthenticAMD") == 0) {
printf(" Stepping = %u", cpu_id & 0xf);
if (cpu_high > 0) {
+ u_int cmp = 1, htt = 1;
+
/*
* Here we should probably set up flags indicating
* whether or not various features are available.
@@ -246,6 +248,16 @@ printcpuinfo(void)
"\040<b31>"
);
}
+
+ /*
+ * 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
+ *
+ * IA-32 Intel Architecture Software Developer's Manual,
+ * Volume 2A: Instruction Set Reference, A-M
+ * ftp://download.intel.com/design/Pentium4/manuals/25366617.pdf
+ */
if (amd_feature != 0) {
printf("\n AMD Features=0x%b", amd_feature,
"\020" /* in hex */
@@ -274,9 +286,9 @@ printcpuinfo(void)
"\027MMX+" /* AMD MMX Extensions */
"\030<s23>" /* Same */
"\031<s24>" /* Same */
- "\032<b25>" /* Undefined */
+ "\032FFXSR" /* Fast FXSAVE/FXRSTOR */
"\033<b26>" /* Undefined */
- "\034<b27>" /* Undefined */
+ "\034RDTSCP" /* RDTSCP */
"\035<b28>" /* Undefined */
"\036LM" /* 64 bit long mode */
"\0373DNow+" /* AMD 3DNow! Extensions */
@@ -284,14 +296,61 @@ printcpuinfo(void)
);
}
+ 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 this CPU supports HTT or CMP then mention the
+ * number of physical/logical cores it contains.
*/
- if (cpu_feature & CPUID_HTT &&
- (cpu_procinfo & CPUID_HTT_CORES) >> 16 > 1)
- printf("\n Hyperthreading: %d logical CPUs",
- (cpu_procinfo & CPUID_HTT_CORES) >> 16);
+ if (cpu_feature & CPUID_HTT)
+ htt = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
+ if (strcmp(cpu_vendor, "AuthenticAMD") == 0 &&
+ (amd_feature2 & AMDID2_CMP))
+ cmp = (cpu_procinfo2 & AMDID_CMP_CORES) + 1;
+ else if (strcmp(cpu_vendor, "GenuineIntel") == 0 &&
+ (cpu_high >= 4)) {
+ cpuid_count(4, 0, regs);
+ cmp = ((regs[0] & 0xfc000000) >> 26) + 1;
+ }
+ if (htt > 1)
+ printf("\n Physical/Logical cores: %d/%d",
+ cmp, htt);
}
}
/* Avoid ugly blank lines: only print newline when we have to. */
@@ -357,6 +416,11 @@ identify_cpu(void)
if (cpu_exthigh >= 0x80000001) {
do_cpuid(0x80000001, regs);
amd_feature = regs[3] & ~(cpu_feature & 0x0183f3ff);
+ amd_feature2 = regs[2];
+ }
+ if (cpu_exthigh >= 0x80000008) {
+ do_cpuid(0x80000008, regs);
+ cpu_procinfo2 = regs[2];
}
/* XXX */
diff --git a/sys/amd64/amd64/initcpu.c b/sys/amd64/amd64/initcpu.c
index 88b7dc0..0e3ccb6 100644
--- a/sys/amd64/amd64/initcpu.c
+++ b/sys/amd64/amd64/initcpu.c
@@ -51,11 +51,13 @@ SYSCTL_INT(_hw, OID_AUTO, instruction_sse, CTLFLAG_RD,
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 */
diff --git a/sys/amd64/include/md_var.h b/sys/amd64/include/md_var.h
index 2e36bd8..0c0407c 100644
--- a/sys/amd64/include/md_var.h
+++ b/sys/amd64/include/md_var.h
@@ -43,10 +43,12 @@ extern u_int cpu_exthigh;
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[];
diff --git a/sys/amd64/include/specialreg.h b/sys/amd64/include/specialreg.h
index 37f2328..b3f8209 100644
--- a/sys/amd64/include/specialreg.h
+++ b/sys/amd64/include/specialreg.h
@@ -126,7 +126,16 @@
#define AMDID_SYSCALL 0x00000800
#define AMDID_MP 0x00080000
#define AMDID_NX 0x00100000
+#define AMDID_EXT_MMX 0x00400000
+#define AMDID_FFXSR 0x01000000
+#define AMDID_RDTSCP 0x08000000
#define AMDID_LM 0x20000000
+#define AMDID_EXT_3DNOW 0x40000000
+#define AMDID_3DNOW 0x80000000
+
+#define AMDID2_LAHF 0x00000001
+#define AMDID2_CMP 0x00000002
+#define AMDID2_CR8 0x00000010
/*
* CPUID instruction 1 ebx info
@@ -137,6 +146,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
diff --git a/sys/i386/i386/identcpu.c b/sys/i386/i386/identcpu.c
index cf5e557..7d4ef86 100644
--- a/sys/i386/i386/identcpu.c
+++ b/sys/i386/i386/identcpu.c
@@ -173,11 +173,17 @@ printcpuinfo(void)
}
/* Detect AMD features (PTE no-execute bit, 3dnow, 64 bit mode etc) */
- if (cpu_exthigh >= 0x80000001 &&
- (strcmp(cpu_vendor, "GenuineIntel") == 0 ||
- strcmp(cpu_vendor, "AuthenticAMD") == 0)) {
- do_cpuid(0x80000001, regs);
- amd_feature = regs[3] & ~(cpu_feature & 0x0183f3ff);
+ if (strcmp(cpu_vendor, "GenuineIntel") == 0 ||
+ strcmp(cpu_vendor, "AuthenticAMD") == 0) {
+ if (cpu_exthigh >= 0x80000001) {
+ do_cpuid(0x80000001, regs);
+ amd_feature = regs[3] & ~(cpu_feature & 0x0183f3ff);
+ amd_feature2 = regs[2];
+ }
+ if (cpu_exthigh >= 0x80000008) {
+ do_cpuid(0x80000008, regs);
+ cpu_procinfo2 = regs[2];
+ }
}
if (strcmp(cpu_vendor, "GenuineIntel") == 0) {
@@ -649,6 +655,8 @@ printcpuinfo(void)
if (strcmp(cpu_vendor, "CyrixInstead") == 0)
printf(" DIR=0x%04x", cyrix_did);
if (cpu_high > 0) {
+ u_int cmp = 1, htt = 1;
+
/*
* Here we should probably set up flags indicating
* whether or not various features are available.
@@ -730,6 +738,16 @@ printcpuinfo(void)
"\040<b31>"
);
}
+
+ /*
+ * 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
+ *
+ * IA-32 Intel Architecture Software Developer's Manual,
+ * Volume 2A: Instruction Set Reference, A-M
+ * ftp://download.intel.com/design/Pentium4/manuals/25366617.pdf
+ */
if (amd_feature != 0) {
printf("\n AMD Features=0x%b", amd_feature,
"\020" /* in hex */
@@ -758,9 +776,9 @@ printcpuinfo(void)
"\027MMX+" /* AMD MMX Extensions */
"\030<s23>" /* Same */
"\031<s24>" /* Same */
- "\032<b25>" /* Undefined */
+ "\032FFXSR" /* Fast FXSAVE/FXRSTOR */
"\033<b26>" /* Undefined */
- "\034<b27>" /* Undefined */
+ "\034RDTSCP" /* RDTSCP */
"\035<b28>" /* Undefined */
"\036LM" /* 64 bit long mode */
"\0373DNow+" /* AMD 3DNow! Extensions */
@@ -768,14 +786,61 @@ printcpuinfo(void)
);
}
+ 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 this CPU supports HTT or CMP then mention the
+ * number of physical/logical cores it contains.
*/
- if (cpu_feature & CPUID_HTT &&
- (cpu_procinfo & CPUID_HTT_CORES) >> 16 > 1)
- printf("\n Hyperthreading: %d logical CPUs",
- (cpu_procinfo & CPUID_HTT_CORES) >> 16);
+ if (cpu_feature & CPUID_HTT)
+ htt = (cpu_procinfo & CPUID_HTT_CORES) >> 16;
+ if (strcmp(cpu_vendor, "AuthenticAMD") == 0 &&
+ (amd_feature2 & AMDID2_CMP))
+ cmp = (cpu_procinfo2 & AMDID_CMP_CORES) + 1;
+ else if (strcmp(cpu_vendor, "GenuineIntel") == 0 &&
+ (cpu_high >= 4)) {
+ cpuid_count(4, 0, regs);
+ cmp = ((regs[0] & 0xfc000000) >> 26) + 1;
+ }
+ if (htt > 1)
+ printf("\n Physical/Logical cores: %d/%d",
+ cmp, htt);
}
} else if (strcmp(cpu_vendor, "CyrixInstead") == 0) {
printf(" DIR=0x%04x", cyrix_did);
diff --git a/sys/i386/i386/initcpu.c b/sys/i386/i386/initcpu.c
index cec1fa5..9bb89d5 100644
--- a/sys/i386/i386/initcpu.c
+++ b/sys/i386/i386/initcpu.c
@@ -77,10 +77,12 @@ SYSCTL_INT(_hw, OID_AUTO, instruction_sse, CTLFLAG_RD,
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; /* 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
diff --git a/sys/i386/include/md_var.h b/sys/i386/include/md_var.h
index 047f75f..afccf1d 100644
--- a/sys/i386/include/md_var.h
+++ b/sys/i386/include/md_var.h
@@ -48,10 +48,12 @@ extern u_int cpu_exthigh;
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 u_int cyrix_did;
extern char kstack[];
diff --git a/sys/i386/include/specialreg.h b/sys/i386/include/specialreg.h
index 4b91cf9..8ae1115 100644
--- a/sys/i386/include/specialreg.h
+++ b/sys/i386/include/specialreg.h
@@ -108,6 +108,23 @@
#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_EXT_MMX 0x00400000
+#define AMDID_FFXSR 0x01000000
+#define AMDID_RDTSCP 0x08000000
+#define AMDID_LM 0x20000000
+#define AMDID_EXT_3DNOW 0x40000000
+#define AMDID_3DNOW 0x80000000
+
+#define AMDID2_LAHF 0x00000001
+#define AMDID2_CMP 0x00000002
+#define AMDID2_CR8 0x00000010
+
+/*
* CPUID instruction 1 ebx info
*/
#define CPUID_BRAND_INDEX 0x000000ff
@@ -116,6 +133,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
OpenPOWER on IntegriCloud