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