- 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)
This commit is contained in:
jkim 2005-10-14 22:52:01 +00:00
parent 10f007ca7d
commit 0dd10470ec
8 changed files with 196 additions and 23 deletions

View File

@ -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 */

View File

@ -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 */

View File

@ -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[];

View File

@ -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
@ -136,6 +145,11 @@
#define CPUID_HTT_CORES 0x00ff0000
#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
*/

View File

@ -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);

View File

@ -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

View File

@ -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[];

View File

@ -107,6 +107,23 @@
#define CPUID_IA64 0x40000000
#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
*/
@ -115,6 +132,11 @@
#define CPUID_HTT_CORES 0x00ff0000
#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
*/