blob: 58eb1b78e75f18e7a43e9575b43c09709245a8a8 [file] [log] [blame]
Marat Dukhan0de277f2017-09-22 14:25:10 -07001#include <stdio.h>
2#include <stdint.h>
3#include <inttypes.h>
4#include <string.h>
5
6#include <x86/cpuid.h>
7
8static void print_cpuid(struct cpuid_regs regs, uint32_t eax) {
9 printf("CPUID %08"PRIX32": %08"PRIX32"-%08"PRIX32"-%08"PRIX32"-%08"PRIX32"\n",
10 eax, regs.eax, regs.ebx, regs.ecx, regs.edx);
11}
12
13static void print_cpuidex(struct cpuid_regs regs, uint32_t eax, uint32_t ecx) {
14 printf("CPUID %08"PRIX32": %08"PRIX32"-%08"PRIX32"-%08"PRIX32"-%08"PRIX32" [SL %02"PRIX32"]\n",
15 eax, regs.eax, regs.ebx, regs.ecx, regs.edx, ecx);
16}
17
18static void print_cpuid_vendor(struct cpuid_regs regs, uint32_t eax) {
19 if (regs.ebx | regs.ecx | regs.edx) {
20 char vendor_id[12];
21 memcpy(&vendor_id[0], &regs.ebx, sizeof(regs.ebx));
22 memcpy(&vendor_id[4], &regs.edx, sizeof(regs.edx));
23 memcpy(&vendor_id[8], &regs.ecx, sizeof(regs.ecx));
24 printf("CPUID %08"PRIX32": %08"PRIX32"-%08"PRIX32"-%08"PRIX32"-%08"PRIX32" [%.12s]\n",
25 eax, regs.eax, regs.ebx, regs.ecx, regs.edx, vendor_id);
26 } else {
27 print_cpuid(regs, eax);
28 }
29}
30
31static void print_cpuid_brand_string(struct cpuid_regs regs, uint32_t eax) {
32 char brand_string[16];
33 memcpy(&brand_string[0], &regs.eax, sizeof(regs.eax));
34 memcpy(&brand_string[4], &regs.ebx, sizeof(regs.ebx));
35 memcpy(&brand_string[8], &regs.ecx, sizeof(regs.ecx));
36 memcpy(&brand_string[12], &regs.edx, sizeof(regs.edx));
37 printf("CPUID %08"PRIX32": %08"PRIX32"-%08"PRIX32"-%08"PRIX32"-%08"PRIX32" [%.16s]\n",
38 eax, regs.eax, regs.ebx, regs.ecx, regs.edx, brand_string);
39}
40
41int main(int argc, char** argv) {
42 const uint32_t max_base_index = cpuid(0).eax;
43 uint32_t max_structured_index = 0, max_trace_index = 0, max_socid_index = 0;
44 bool has_sgx = false;
45 for (uint32_t eax = 0; eax <= max_base_index; eax++) {
46 switch (eax) {
47 case UINT32_C(0x00000000):
48 print_cpuid_vendor(cpuid(eax), eax);
49 break;
50 case UINT32_C(0x00000004):
51 for (uint32_t ecx = 0; ; ecx++) {
52 const struct cpuid_regs regs = cpuidex(eax, ecx);
53 if ((regs.eax & UINT32_C(0x1F)) == 0) {
54 break;
55 }
56 print_cpuidex(regs, eax, ecx);
57 }
58 break;
59 case UINT32_C(0x00000007):
60 for (uint32_t ecx = 0; ecx <= max_structured_index; ecx++) {
61 const struct cpuid_regs regs = cpuidex(eax, ecx);
62 if (ecx == 0) {
63 max_structured_index = regs.eax;
64 has_sgx = !!(regs.ebx & UINT32_C(0x00000004));
65 }
66 print_cpuidex(regs, eax, ecx);
67 }
68 break;
69 case UINT32_C(0x0000000B):
70 for (uint32_t ecx = 0; ; ecx++) {
71 const struct cpuid_regs regs = cpuidex(eax, ecx);
72 if ((regs.ecx & UINT32_C(0x0000FF00)) == 0) {
73 break;
74 }
75 print_cpuidex(regs, eax, ecx);
76 }
77 break;
78 case UINT32_C(0x00000012):
79 if (has_sgx) {
80 for (uint32_t ecx = 0; ; ecx++) {
81 const struct cpuid_regs regs = cpuidex(eax, ecx);
82 if (ecx >= 2 && (regs.eax & UINT32_C(0x0000000F)) == 0) {
83 break;
84 }
85 print_cpuidex(regs, eax, ecx);
86 }
87 }
88 break;
89 case UINT32_C(0x00000014):
90 for (uint32_t ecx = 0; ecx <= max_trace_index; ecx++) {
91 const struct cpuid_regs regs = cpuidex(eax, ecx);
92 if (ecx == 0) {
93 max_trace_index = regs.eax;
94 }
95 print_cpuidex(regs, eax, ecx);
96 }
97 break;
98 case UINT32_C(0x00000017):
99 for (uint32_t ecx = 0; ecx <= max_socid_index; ecx++) {
100 const struct cpuid_regs regs = cpuidex(eax, ecx);
101 if (ecx == 0) {
102 max_socid_index = regs.eax;
103 }
104 print_cpuidex(regs, eax, ecx);
105 }
106 break;
107 default:
Marat Dukhanafa11ca2017-09-25 10:53:51 -0700108 print_cpuid(cpuidex(eax, 0), eax);
Marat Dukhan0de277f2017-09-22 14:25:10 -0700109 break;
110 }
111 }
112
113 const uint32_t max_extended_index = cpuid(UINT32_C(0x80000000)).eax;
114 for (uint32_t eax = UINT32_C(0x80000000); eax <= max_extended_index; eax++) {
115 switch (eax) {
116 case UINT32_C(0x80000000):
117 print_cpuid_vendor(cpuid(eax), eax);
118 break;
119 case UINT32_C(0x80000002):
120 case UINT32_C(0x80000003):
121 case UINT32_C(0x80000004):
122 print_cpuid_brand_string(cpuid(eax), eax);
123 break;
124 default:
Marat Dukhanafa11ca2017-09-25 10:53:51 -0700125 print_cpuid(cpuidex(eax, 0), eax);
Marat Dukhan0de277f2017-09-22 14:25:10 -0700126 }
127 }
128}