Index: sys/amd64/amd64/identcpu.c =================================================================== RCS file: /home/ncvs/src/sys/amd64/amd64/identcpu.c,v retrieving revision 1.136 diff -u -r1.136 identcpu.c --- sys/amd64/amd64/identcpu.c 29 May 2005 17:43:23 -0000 1.136 +++ sys/amd64/amd64/identcpu.c 14 Oct 2005 21:13:15 -0000 @@ -165,6 +165,8 @@ 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 @@ "\040" ); } + + /* + * 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 @@ "\027MMX+" /* AMD MMX Extensions */ "\030" /* Same */ "\031" /* Same */ - "\032" /* Undefined */ + "\032FFXSR" /* Fast FXSAVE/FXRSTOR */ "\033" /* Undefined */ - "\034" /* Undefined */ + "\034RDTSCP" /* RDTSCP */ "\035" /* Undefined */ "\036LM" /* 64 bit long mode */ "\0373DNow+" /* AMD 3DNow! Extensions */ @@ -284,14 +296,61 @@ ); } + if (amd_feature2 != 0) { + printf("\n AMD Features2=0x%b", amd_feature2, + "\020" + "\001LAHF" /* LAHF/SAHF in long mode */ + "\002CMP" /* CMP legacy */ + "\003" + "\004" + "\005CR8" /* CR8 in legacy mode */ + "\006" + "\007" + "\010" + "\011" + "\012" + "\013" + "\014" + "\015" + "\016" + "\017" + "\020" + "\021" + "\022" + "\023" + "\024" + "\025" + "\026" + "\027" + "\030" + "\031" + "\032" + "\033" + "\034" + "\035" + "\036" + "\037" + "\040" + ); + } + /* - * 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 @@ 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 */ 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 14 Oct 2005 21:13:15 -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/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 14 Oct 2005 21:13:15 -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 14 Oct 2005 21:13:15 -0000 @@ -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 Index: sys/i386/i386/identcpu.c =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/identcpu.c,v retrieving revision 1.145 diff -u -r1.145 identcpu.c --- sys/i386/i386/identcpu.c 30 Jun 2005 06:44:34 -0000 1.145 +++ sys/i386/i386/identcpu.c 14 Oct 2005 21:13:15 -0000 @@ -173,11 +173,17 @@ } /* 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 @@ 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 @@ "\040" ); } + + /* + * 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 @@ "\027MMX+" /* AMD MMX Extensions */ "\030" /* Same */ "\031" /* Same */ - "\032" /* Undefined */ + "\032FFXSR" /* Fast FXSAVE/FXRSTOR */ "\033" /* Undefined */ - "\034" /* Undefined */ + "\034RDTSCP" /* RDTSCP */ "\035" /* Undefined */ "\036LM" /* 64 bit long mode */ "\0373DNow+" /* AMD 3DNow! Extensions */ @@ -768,14 +786,61 @@ ); } + if (amd_feature2 != 0) { + printf("\n AMD Features2=0x%b", amd_feature2, + "\020" + "\001LAHF" /* LAHF/SAHF in long mode */ + "\002CMP" /* CMP legacy */ + "\003" + "\004" + "\005CR8" /* CR8 in legacy mode */ + "\006" + "\007" + "\010" + "\011" + "\012" + "\013" + "\014" + "\015" + "\016" + "\017" + "\020" + "\021" + "\022" + "\023" + "\024" + "\025" + "\026" + "\027" + "\030" + "\031" + "\032" + "\033" + "\034" + "\035" + "\036" + "\037" + "\040" + ); + } + /* - * 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); Index: sys/i386/i386/initcpu.c =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/initcpu.c,v retrieving revision 1.52 diff -u -r1.52 initcpu.c --- sys/i386/i386/initcpu.c 2 Jul 2005 20:06:43 -0000 1.52 +++ sys/i386/i386/initcpu.c 14 Oct 2005 21:13:16 -0000 @@ -77,10 +77,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; /* 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/include/md_var.h =================================================================== RCS file: /home/ncvs/src/sys/i386/include/md_var.h,v retrieving revision 1.72 diff -u -r1.72 md_var.h --- sys/i386/include/md_var.h 30 Jun 2005 06:44:34 -0000 1.72 +++ sys/i386/include/md_var.h 14 Oct 2005 21:13:16 -0000 @@ -48,10 +48,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 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 14 Oct 2005 21:13:16 -0000 @@ -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