diff options
author | jkim <jkim@FreeBSD.org> | 2005-10-14 22:52:01 +0000 |
---|---|---|
committer | jkim <jkim@FreeBSD.org> | 2005-10-14 22:52:01 +0000 |
commit | 0dd10470eca4b50758f1f3fa559697f67bd0a188 (patch) | |
tree | a8764706a4db8c765f1763d02dbb2688b1955119 /sys | |
parent | 10f007ca7dcc58198c5b122a663950ba305936d2 (diff) | |
download | FreeBSD-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.c | 80 | ||||
-rw-r--r-- | sys/amd64/amd64/initcpu.c | 4 | ||||
-rw-r--r-- | sys/amd64/include/md_var.h | 2 | ||||
-rw-r--r-- | sys/amd64/include/specialreg.h | 14 | ||||
-rw-r--r-- | sys/i386/i386/identcpu.c | 91 | ||||
-rw-r--r-- | sys/i386/i386/initcpu.c | 4 | ||||
-rw-r--r-- | sys/i386/include/md_var.h | 2 | ||||
-rw-r--r-- | sys/i386/include/specialreg.h | 22 |
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 |