misc/cpuid: Add support for RDRAND/F16C and newer intel features

There is no maintainer for this port, so submitted patches are just
assumed to be correct.

PR:		179065
Submitted by:	Arthurmech (gmail.com)
Adds:		RDRAND/F16 support

PR:		185277
Submitted by:	netch (netch.kiev.ua)
Adds:		Additional intel features
This commit is contained in:
John Marino 2014-06-15 12:17:46 +00:00
parent 9e2206d60f
commit dadb814d14
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=357871
2 changed files with 169 additions and 31 deletions

View file

@ -3,7 +3,7 @@
PORTNAME= cpuid
PORTVERSION= 3.3
PORTREVISION= 6
PORTREVISION= 7
CATEGORIES= misc
MASTER_SITES= http://www.ka9q.net/code/cpuid/

View file

@ -1,6 +1,6 @@
--- cpuid.c
--- cpuid.c.orig 2002-01-02 06:14:51.000000000 +0000
+++ cpuid.c
@@ -3,34 +3,56 @@
@@ -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
@ -65,16 +65,42 @@
};
#define cpuid(in,a,b,c,d)\
@@ -89,7 +110,7 @@
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_flags[32] = {
+char *Intel_feature_flags1[32] = {
"FPU Floating Point Unit",
"VME Virtual 8086 Mode Enhancements",
"DE Debugging Extensions",
@@ -121,7 +142,64 @@
@@ -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",
@ -95,27 +121,29 @@
+ "SSSE3 Supplemental Streaming SIMD Extension 3",
+ "CNXT-ID L1 Context ID",
+ NULL,
+ NULL,
+ "FMA Fused Multiply-Add",
+ "CX16 CMPXCHG16B",
+ "xTPR Send Task Priority messages",
+ "PDCM Perfmon and debug capability",
+ NULL,
+ 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",
+ NULL,
+ "TSC-Deadline",
+ "AESNI AES Instruction set",
+ "XSAVE XSAVE/XSTOR states",
+ "OSXSAVE OS-enabled extended state managerment",
+ "AVX AVX extensions",
+ NULL, NULL, NULL
+ "F16C Half-precision conversions",
+ "RDRAND RDRAND Instruction",
+ NULL
+};
+
+char *Intel_ext_feature_flags[32] = {
+char *Intel_ext_feature_flags1[32] = {
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ "SYSCALL SYSCALL/SYSRET instructions",
@ -136,11 +164,21 @@
+ 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 +209,31 @@
@@ -131,22 +225,31 @@ void dointel(int maxi){
if(maxi >= 1){
/* Family/model/type etc */
int clf,apic_id,feature_flags;
@ -179,7 +217,7 @@
printf("Type %d - ",type);
switch(type){
@@ -183,10 +270,6 @@
@@ -183,10 +286,6 @@ void dointel(int maxi){
printf("Pentium 4");
}
printf("\n");
@ -190,7 +228,7 @@
printf("Model %d - ",model);
switch(family){
case 3:
@@ -253,33 +336,72 @@
@@ -253,33 +352,72 @@ void dointel(int maxi){
case 8:
printf("Pentium III/Pentium III Xeon - internal L2 cache");
break;
@ -270,19 +308,22 @@
if(maxe >= 0x80000004){
int i;
@@ -303,12 +425,48 @@
@@ -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: %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<<i)){
printf("%s\n",Intel_feature_flags[i]);
}
}
- printf("%s\n",Intel_feature_flags[i]);
+ printf("%s\n",Intel_feature_flags1[i]);
+ }
+ }
+ if(feature_flags2) {
+ printf("\nFeature flags set 2: %08x:\n",feature_flags2);
+ printf("\nFeature flags set 2 (CPUID.01H:ECX): %08x:\n",
+ feature_flags2);
+ for (i = 0; i < 32; ++i) {
+ if (feature_flags2 & (1 << i)) {
+ const char* fn = Intel_feature_flags2[i];
@ -294,10 +335,11 @@
+ }
+ }
+ if(ext_feature_flags) {
+ printf("\nExtended feature flags: %08x:\n",ext_feature_flags);
+ printf("\nExtended feature flags set 1 (CPUID.80000001H:EDX): %08x\n",
+ ext_feature_flags);
+ for (i = 0; i < 32; ++i) {
+ if (ext_feature_flags & (1 << i)) {
+ const char* fn = Intel_ext_feature_flags[i];
+ const char* fn = Intel_ext_feature_flags1[i];
+ if (fn != NULL)
+ printf("%s\n", fn);
+ else
@ -306,7 +348,8 @@
+ }
+ }
+ if(ext_feature_flags2) {
+ printf("\nExtended feature flags set 2: %08x:\n",ext_feature_flags2);
+ printf("\nExtended feature flags set 2 (CPUID.80000001H:ECX): %08x\n",
+ ext_feature_flags2);
+ for (i = 0; i < 32; ++i) {
+ if (ext_feature_flags2 & (1 << i)) {
+ const char* fn = Intel_ext_feature_flags2[i];
@ -315,12 +358,101 @@
+ else
+ printf("%d - unknown feature\n", i);
+ }
}
}
printf("\n");
@@ -316,7 +494,7 @@ void dointel(int maxi){
int ntlb,i;
ntlb = 255;
- printf("TLB and cache info:\n");
+ printf("Old-styled TLB and cache info:\n");
for(i=0;i<ntlb;i++){
unsigned long eax,ebx,ecx,edx;
@@ -352,7 +530,7 @@ void dointel(int maxi){
cpuid(1,signature,unused,unused,unused);
cpuid(3,unused,unused,ecx,edx);
- printf("Processor serial: ");
+ printf("\nProcessor serial: ");
printf("%04lX",signature >> 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<<i)){
+ const char* fn = Intel_struct_ext_feature_flags_7_0_b[i];
+ if (fn != NULL)
+ printf("%s\n", fn);
+ else
+ printf("%d - unknown feature\n", i);
+ }
+ }
+ }
printf("\n");
}
if(maxi >= 2){
@@ -396,18 +554,66 @@
+ }
}
void printregs(int eax,int ebx,int ecx,int edx){
int j;
@@ -396,18 +640,66 @@ void decode_intel_tlb(int x){
case 0x4:
printf("Data TLB: 4MB pages, 4-way set assoc, 8 entries\n");
break;
@ -387,7 +519,7 @@
case 0x40:
printf("No 2nd-level cache, or if 2nd-level cache exists, no 3rd-level cache\n");
break;
@@ -426,23 +632,67 @@
@@ -426,23 +718,67 @@ void decode_intel_tlb(int x){
case 0x45:
printf("2nd-level cache: 2MB, 4-way set assoc, 32 byte line size\n");
break;
@ -461,7 +593,7 @@
break;
case 0x66:
printf("1st-level data cache: 8KB, 4-way set assoc, 64 byte line size\n");
@@ -454,25 +704,37 @@
@@ -454,25 +790,40 @@ void decode_intel_tlb(int x){
printf("1st-level data cache: 32KB, 4-way set assoc, 64 byte line size\n");
break;
case 0x70:
@ -479,6 +611,9 @@
+ case 0x73:
+ printf("Trace cache: 64K-micro-op, 8-way set assoc\n");
+ break;
+ case 0x76:
+ printf("Instruction TLB: 2M/4M pages, fully associative, 8 entries\n");
+ break;
+ case 0x78:
+ printf("2nd-level cache: 1MB, 4-way set assoc, 64 byte line size\n");
break;
@ -504,7 +639,7 @@
break;
case 0x82:
printf("2nd-level cache: 256KB, 8-way set assoc, 32 byte line size\n");
@@ -486,44 +748,189 @@
@@ -486,44 +837,192 @@ void decode_intel_tlb(int x){
case 0x85:
printf("2nd-level cache: 2MB, 8-way set assoc, 32 byte line size\n");
break;
@ -582,6 +717,9 @@
+ break;
+ case 0xF1:
+ printf("128-byte prefetching\n");
+ break;
+ case 0xFF:
+ printf("CPUID leaf 2 does not report full information, query leaf 4\n");
+ break;
default:
printf("unknown TLB/cache descriptor\n");
@ -726,7 +864,7 @@
};
char *Assoc[] = {
@@ -657,10 +1064,16 @@
@@ -657,10 +1156,16 @@ void doamd(int maxi){
printf("Global Paging Extensions\n");
} else {
if(edx & (1<<i)){