--- cpuid.c.orig 2002-01-02 06:14:51.000000000 +0000 +++ cpuid.c @@ -3,38 +3,62 @@ * Updated 24 Apr 2001 to latest Intel CPUID spec * Updated 22 Dec 2001 to decode Intel flag 28, hyper threading * Updated 1 Jan 2002 to cover AMD Duron, Athlon + * Updated 24 Aug 2009 to decode additional Intel flags + * Updated 23 May 2010 to decode additional Intel flags * May be used under the terms of the GNU Public License (GPL) * Reference documents: - * ftp://download.intel.com/design/pro/applnots/24161809.pdf (AP-485) + * http://www.intel.com/Assets/PDF/appnote/241618.pdf (AN-485 August 2009) * http://developer.intel.com/design/Pentium4/manuals/24547103.pdf * http://developer.intel.com/design/pentiumiii/applnots/24512501.pdf (AP-909) * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/20734.pdf - * + * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/24594.pdf + * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25481.pdf + * */ #include +#include void decode_intel_tlb(int); void decode_cyrix_tlb(int); void dointel(int),doamd(int),docyrix(int); void printregs(int eax,int ebx,int ecx,int edx); -#define MAXBRANDS 9 +#define MAXBRANDS 24 char *Brands[MAXBRANDS] = { - "brand 0", + NULL, "Celeron processor", "Pentium III processor", "Intel Pentium III Xeon processor", - "brand 4", - "brand 5", - "brand 6", - "brand 7", + "Intel Pentium III processor", + NULL, + "Mobile Intel Pentium III processor-M", + "Mobile Intel Celeron processor", + /* 8 */ "Intel Pentium 4 processor", + "Intel Pentium 4 processor", + "Intel Celeron processor", + "Intel Xeon processor", + "Intel Xeon processor MP", + NULL, + "Mobile Intel Pentium 4 processor-M", + "Mobile Intel Celeron processor", + /* 16 */ + NULL, + "Mobile Genuine Intel processor", + "Intel Celeron M processor", + "Mobile Intel Celeron processor", + "Intel Celeron processor", + "Mobile Genuine Intel processor", + "Intel Pentium M processor", + "Mobile Intel Celeron processor", }; #define cpuid(in,a,b,c,d)\ asm("cpuid": "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (in)); +#define cpuidx(in,in2,a,b,c,d)\ + asm("cpuid": "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (in), "c" (in2)); int main(){ int i; @@ -48,8 +72,9 @@ int main(){ printf(" eax in eax ebx ecx edx\n"); for(i=0;i<=maxi;i++){ unsigned long eax,ebx,ecx,edx; + ecx = 0; /* basic query for leaves that dependent on it */ - cpuid(i,eax,ebx,ecx,edx); + cpuidx(i,ecx,eax,ebx,ecx,edx); printf("%08x %08lx %08lx %08lx %08lx\n",i,eax,ebx,ecx,edx); } cpuid(0x80000000,maxei,unused,unused,unused); @@ -89,7 +114,7 @@ int main(){ exit(0); } -char *Intel_feature_flags[] = { +char *Intel_feature_flags1[32] = { "FPU Floating Point Unit", "VME Virtual 8086 Mode Enhancements", "DE Debugging Extensions", @@ -108,7 +133,7 @@ char *Intel_feature_flags[] = { "CMOV Conditional Move and Compare Instructions", "FGPAT Page Attribute Table", "PSE-36 36-bit Page Size Extension", - "PN Processor Serial Number present and enabled", + "PSN Processor Serial Number present and enabled", "CLFSH CFLUSH instruction", "20 reserved", "DS Debug store", @@ -121,7 +146,76 @@ char *Intel_feature_flags[] = { "HT Hyper Threading", "TM Thermal monitor", "30 reserved", - "31 reserved", + "31 Pending Break Enable" +}; + +char *Intel_feature_flags2[32] = { + "SSE3 SSE3 extensions", + "PCLMULDQ PCLMULDQ instruction", + "DTES64 64-bit debug store", + "MONITOR MONITOR/MWAIT instructions", + "DS-CPL CPL Qualified Debug Store", + "VMX Virtual Machine Extensions", + "SMX Safer Mode Extension", + "EST Enhanced Intel SpeedStep Technology", + "TM2 Thermal Monitor 2", + "SSSE3 Supplemental Streaming SIMD Extension 3", + "CNXT-ID L1 Context ID", + NULL, + "FMA Fused Multiply-Add", + "CX16 CMPXCHG16B", + "xTPR Send Task Priority messages", + "PDCM Perfmon and debug capability", + NULL, + "PCID Process-Context Identifiers", + "DCA Direct Cache Access", + "SSE4.1 Streaming SIMD Extension 4.1", + "SSE4.2 Streaming SIMD Extension 4.2", + "x2APIC Extended xAPIC support", + "MOVBE MOVBE instruction", + "POPCNT POPCNT instruction", + "TSC-Deadline", + "AESNI AES Instruction set", + "XSAVE XSAVE/XSTOR states", + "OSXSAVE OS-enabled extended state managerment", + "AVX AVX extensions", + "F16C Half-precision conversions", + "RDRAND RDRAND Instruction", + NULL +}; + +char *Intel_ext_feature_flags1[32] = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, + "SYSCALL SYSCALL/SYSRET instructions", + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + "XD-bit Execution Disable bit", + NULL, NULL, NULL, + NULL, NULL, + "1GBP 1 GByte pages are available", + "RDTSCP RDTSCP and IA32_TSC_AUX are available", + NULL, + "EM64T Intel Extended Memory 64 Technology", + NULL, NULL +}; + +char *Intel_ext_feature_flags2[32] = { + "LAHF LAHF/SAHF available in IA-32e mode", + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +}; + +char *Intel_struct_ext_feature_flags_7_0_b[32] = { + "FSGSBASE", "IA32_TSC_ADJUST MSR", + NULL, "BMI1", "HLE", "AVX2", NULL, "SMEP", + "BMI2", "Enhanced REP MOVSB/STOSB", + "INVPCID", "RTM", "Quality of Service Monitoring capability", + "Deprecates FPU CS and FPU DS", NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; /* Intel-specific information */ @@ -131,22 +225,31 @@ void dointel(int maxi){ if(maxi >= 1){ /* Family/model/type etc */ int clf,apic_id,feature_flags; - int extended_model = -1,extended_family = -1; - unsigned long eax,ebx,edx,unused; - int stepping,model,family,type,reserved,brand,siblings; + int feature_flags2 = 0; + int ext_feature_flags = 0; + int ext_feature_flags2 = 0; + int basic_family, extended_family, basic_model, extended_model; + int family, model; + unsigned long eax,ebx,ecx,edx; + int stepping,type,reserved,brand,siblings; int i; - cpuid(1,eax,ebx,unused,edx); + cpuid(1,eax,ebx,ecx,edx); printf("Version %08lx:\n",eax); stepping = eax & 0xf; - model = (eax >> 4) & 0xf; - family = (eax >> 8) & 0xf; + basic_family = (eax >> 8) & 0xf; + extended_family = (eax >> 20) & 0xff; + family = basic_family + extended_family; + basic_model = (eax >> 4) & 0xf; + extended_model = (eax >> 16) & 0xf; + model = (extended_model << 4) | basic_model; type = (eax >> 12) & 0x3; - reserved = eax >> 14; + reserved = eax & 0xf000c000l; clf = (ebx >> 8) & 0xff; apic_id = (ebx >> 24) & 0xff; siblings = (ebx >> 16) & 0xff; feature_flags = edx; + feature_flags2 = ecx; printf("Type %d - ",type); switch(type){ @@ -183,10 +286,6 @@ void dointel(int maxi){ printf("Pentium 4"); } printf("\n"); - if(family == 15){ - extended_family = (eax >> 20) & 0xff; - printf("Extended family %d\n",extended_family); - } printf("Model %d - ",model); switch(family){ case 3: @@ -253,33 +352,72 @@ void dointel(int maxi){ case 8: printf("Pentium III/Pentium III Xeon - internal L2 cache"); break; + case 9: + printf("Intel Pentium M processor model 9"); + break; + case 10: + printf("Pentium III Xeon processor model A"); + break; + case 11: + printf("Intel Pentium III processor model B"); + break; + case 13: + printf("Intel Pentium M processor model D"); + break; + case 14: + printf("Intel Core family processor, 65nm"); + break; + case 15: + printf("Intel Core2 family processor, 65nm"); + break; + case 21: + printf("Intel EP80579 integrated processor"); + break; + case 22: + printf("Intel Celeron processor model 16h, 65nm"); + break; + case 23: + printf("Intel Core2 Extreme or Xeon processor, 45nm"); + break; + case 28: + printf("Intel Atom processor, 45nm"); + break; + case 30: + printf("Intel Corei7 or Xeon processor, 45nm"); + break; + case 31: + printf("Intel Xeon processor MP, 45nm"); + break; } break; case 15: + printf("Intel Pentium 4 processor (generic) or newer"); break; } printf("\n"); - if(model == 15){ - extended_model = (eax >> 16) & 0xf; - printf("Extended model %d\n",extended_model); - } printf("Stepping %d\n",stepping); - printf("Reserved %d\n\n",reserved); + printf("Reserved %x\n\n",reserved); brand = ebx & 0xff; if(brand > 0){ printf("Brand index: %d [",brand); - if(brand < MAXBRANDS){ + if(brand < MAXBRANDS && Brands[brand] != NULL){ printf("%s]\n",Brands[brand]); } else { printf("not in table]\n"); } } - cpuid(0x80000000,eax,ebx,unused,edx); + cpuid(0x80000000,eax,ebx,ecx,edx); if(eax & 0x80000000){ /* Extended feature/signature bits supported */ int maxe = eax; + if (maxe >= 0x80000001) { + unsigned long eax,ebx,ecx,edx; + cpuid(0x80000001,eax,ebx,ecx,edx); + ext_feature_flags = edx; + ext_feature_flags2 = ecx; + } if(maxe >= 0x80000004){ int i; @@ -303,10 +441,50 @@ void dointel(int maxi){ printf("Hyper threading siblings: %d\n",siblings); } - printf("\nFeature flags %08x:\n",feature_flags); + printf("\nFeature flags set 1 (CPUID.01H:EDX): %08x:\n", + feature_flags); for(i=0;i<32;i++){ if(feature_flags & (1<> 16); printf("-%04lX",signature & 0xffff); printf("-%04lX",edx >> 16); @@ -360,6 +538,72 @@ void dointel(int maxi){ printf("-%04lX",ecx >> 16); printf("-%04lX\n",ecx & 0xffff); } + if (maxi >= 4) { + unsigned long index, eax, ebx, ecx, edx, ctype; + unsigned long linesize, partitions, ways, sets, t; + for (index = 0; ; ++index) { + cpuidx(4,index,eax,ebx,ecx,edx); + ctype = eax&31; + if (ctype == 0) + break; + if (index==0) + printf("\nDeterministic Cache Parameters:\n"); + printf("index=%lu: eax=%08lx ebx=%08lx ecx=%08lx edx=%08lx\n> ", + index, eax, ebx, ecx, edx); + switch (ctype) { + case 1: + printf("Data cache"); + break; + case 2: + printf("Instruction cache"); + break; + case 3: + printf("Unified cache"); + break; + default: + printf("Unknown cache type (%lu)", ctype); + } + printf(", level %lu", (eax>>5)&7); + if (eax&0x100u) + printf(", self initializing"); + if (eax&0x200u) + printf(", fully associative"); + printf("\n"); + sets = ecx+1; + ways = ((ebx>>22)&0x3ffu)+1; + partitions = ((ebx>>12)&0x3ffu)+1; + linesize = (ebx&0xfffu)+1; + printf("> %lu sets", sets); + printf(", %lu ways", ways); + printf(", %lu partitions", partitions); + printf(", line size %lu", linesize); + printf("\n> full size %lu bytes\n", sets*ways*partitions*linesize); + t = (eax>>14)&0xfffu; + if (t>0) + printf("> shared between up to %lu threads\n", t+1); + t = (eax>>26)&0x3fu; + if (index==0 && t>0) + printf("> NB this package has up to %lx threads\n", t+1); + } + } + if (maxi >= 7) { + unsigned i; + unsigned long eax, ebx, ecx, edx; + cpuidx(7, 0, eax, ebx, ecx, edx); + if (ebx != 0) { + printf("\nStructured feature flags CPUID.07H.00H:EBX: %08lx:\n", + ebx); + for(i=0;i<32;i++){ + if(ebx & (1<= 0x80000002){