1*2b54f0dbSXin Li #include <stdio.h>
2*2b54f0dbSXin Li #include <stdint.h>
3*2b54f0dbSXin Li #include <stdlib.h>
4*2b54f0dbSXin Li #include <inttypes.h>
5*2b54f0dbSXin Li
6*2b54f0dbSXin Li #include <cpuinfo.h>
7*2b54f0dbSXin Li
8*2b54f0dbSXin Li
vendor_to_string(enum cpuinfo_vendor vendor)9*2b54f0dbSXin Li static const char* vendor_to_string(enum cpuinfo_vendor vendor) {
10*2b54f0dbSXin Li switch (vendor) {
11*2b54f0dbSXin Li case cpuinfo_vendor_unknown:
12*2b54f0dbSXin Li return "unknown";
13*2b54f0dbSXin Li case cpuinfo_vendor_intel:
14*2b54f0dbSXin Li return "Intel";
15*2b54f0dbSXin Li case cpuinfo_vendor_amd:
16*2b54f0dbSXin Li return "AMD";
17*2b54f0dbSXin Li case cpuinfo_vendor_huawei:
18*2b54f0dbSXin Li return "Huawei";
19*2b54f0dbSXin Li case cpuinfo_vendor_hygon:
20*2b54f0dbSXin Li return "Hygon";
21*2b54f0dbSXin Li case cpuinfo_vendor_arm:
22*2b54f0dbSXin Li return "ARM";
23*2b54f0dbSXin Li case cpuinfo_vendor_qualcomm:
24*2b54f0dbSXin Li return "Qualcomm";
25*2b54f0dbSXin Li case cpuinfo_vendor_apple:
26*2b54f0dbSXin Li return "Apple";
27*2b54f0dbSXin Li case cpuinfo_vendor_samsung:
28*2b54f0dbSXin Li return "Samsung";
29*2b54f0dbSXin Li case cpuinfo_vendor_nvidia:
30*2b54f0dbSXin Li return "Nvidia";
31*2b54f0dbSXin Li case cpuinfo_vendor_mips:
32*2b54f0dbSXin Li return "MIPS";
33*2b54f0dbSXin Li case cpuinfo_vendor_ibm:
34*2b54f0dbSXin Li return "IBM";
35*2b54f0dbSXin Li case cpuinfo_vendor_ingenic:
36*2b54f0dbSXin Li return "Ingenic";
37*2b54f0dbSXin Li case cpuinfo_vendor_via:
38*2b54f0dbSXin Li return "VIA";
39*2b54f0dbSXin Li case cpuinfo_vendor_cavium:
40*2b54f0dbSXin Li return "Cavium";
41*2b54f0dbSXin Li case cpuinfo_vendor_broadcom:
42*2b54f0dbSXin Li return "Broadcom";
43*2b54f0dbSXin Li case cpuinfo_vendor_apm:
44*2b54f0dbSXin Li return "Applied Micro";
45*2b54f0dbSXin Li default:
46*2b54f0dbSXin Li return NULL;
47*2b54f0dbSXin Li }
48*2b54f0dbSXin Li }
49*2b54f0dbSXin Li
uarch_to_string(enum cpuinfo_uarch uarch)50*2b54f0dbSXin Li static const char* uarch_to_string(enum cpuinfo_uarch uarch) {
51*2b54f0dbSXin Li switch (uarch) {
52*2b54f0dbSXin Li case cpuinfo_uarch_unknown:
53*2b54f0dbSXin Li return "unknown";
54*2b54f0dbSXin Li case cpuinfo_uarch_p5:
55*2b54f0dbSXin Li return "P5";
56*2b54f0dbSXin Li case cpuinfo_uarch_quark:
57*2b54f0dbSXin Li return "Quark";
58*2b54f0dbSXin Li case cpuinfo_uarch_p6:
59*2b54f0dbSXin Li return "P6";
60*2b54f0dbSXin Li case cpuinfo_uarch_dothan:
61*2b54f0dbSXin Li return "Dothan";
62*2b54f0dbSXin Li case cpuinfo_uarch_yonah:
63*2b54f0dbSXin Li return "Yonah";
64*2b54f0dbSXin Li case cpuinfo_uarch_conroe:
65*2b54f0dbSXin Li return "Conroe";
66*2b54f0dbSXin Li case cpuinfo_uarch_penryn:
67*2b54f0dbSXin Li return "Penryn";
68*2b54f0dbSXin Li case cpuinfo_uarch_nehalem:
69*2b54f0dbSXin Li return "Nehalem";
70*2b54f0dbSXin Li case cpuinfo_uarch_sandy_bridge:
71*2b54f0dbSXin Li return "Sandy Bridge";
72*2b54f0dbSXin Li case cpuinfo_uarch_ivy_bridge:
73*2b54f0dbSXin Li return "Ivy Bridge";
74*2b54f0dbSXin Li case cpuinfo_uarch_haswell:
75*2b54f0dbSXin Li return "Haswell";
76*2b54f0dbSXin Li case cpuinfo_uarch_broadwell:
77*2b54f0dbSXin Li return "Broadwell";
78*2b54f0dbSXin Li case cpuinfo_uarch_sky_lake:
79*2b54f0dbSXin Li return "Sky Lake";
80*2b54f0dbSXin Li case cpuinfo_uarch_palm_cove:
81*2b54f0dbSXin Li return "Palm Cove";
82*2b54f0dbSXin Li case cpuinfo_uarch_sunny_cove:
83*2b54f0dbSXin Li return "Sunny Cove";
84*2b54f0dbSXin Li case cpuinfo_uarch_willamette:
85*2b54f0dbSXin Li return "Willamette";
86*2b54f0dbSXin Li case cpuinfo_uarch_prescott:
87*2b54f0dbSXin Li return "Prescott";
88*2b54f0dbSXin Li case cpuinfo_uarch_bonnell:
89*2b54f0dbSXin Li return "Bonnell";
90*2b54f0dbSXin Li case cpuinfo_uarch_saltwell:
91*2b54f0dbSXin Li return "Saltwell";
92*2b54f0dbSXin Li case cpuinfo_uarch_silvermont:
93*2b54f0dbSXin Li return "Silvermont";
94*2b54f0dbSXin Li case cpuinfo_uarch_airmont:
95*2b54f0dbSXin Li return "Airmont";
96*2b54f0dbSXin Li case cpuinfo_uarch_goldmont:
97*2b54f0dbSXin Li return "Goldmont";
98*2b54f0dbSXin Li case cpuinfo_uarch_goldmont_plus:
99*2b54f0dbSXin Li return "Goldmont Plus";
100*2b54f0dbSXin Li case cpuinfo_uarch_knights_ferry:
101*2b54f0dbSXin Li return "Knights Ferry";
102*2b54f0dbSXin Li case cpuinfo_uarch_knights_corner:
103*2b54f0dbSXin Li return "Knights Corner";
104*2b54f0dbSXin Li case cpuinfo_uarch_knights_landing:
105*2b54f0dbSXin Li return "Knights Landing";
106*2b54f0dbSXin Li case cpuinfo_uarch_knights_hill:
107*2b54f0dbSXin Li return "Knights Hill";
108*2b54f0dbSXin Li case cpuinfo_uarch_knights_mill:
109*2b54f0dbSXin Li return "Knights Mill";
110*2b54f0dbSXin Li case cpuinfo_uarch_k5:
111*2b54f0dbSXin Li return "K5";
112*2b54f0dbSXin Li case cpuinfo_uarch_k6:
113*2b54f0dbSXin Li return "K6";
114*2b54f0dbSXin Li case cpuinfo_uarch_k7:
115*2b54f0dbSXin Li return "K7";
116*2b54f0dbSXin Li case cpuinfo_uarch_k8:
117*2b54f0dbSXin Li return "K8";
118*2b54f0dbSXin Li case cpuinfo_uarch_k10:
119*2b54f0dbSXin Li return "K10";
120*2b54f0dbSXin Li case cpuinfo_uarch_bulldozer:
121*2b54f0dbSXin Li return "Bulldozer";
122*2b54f0dbSXin Li case cpuinfo_uarch_piledriver:
123*2b54f0dbSXin Li return "Piledriver";
124*2b54f0dbSXin Li case cpuinfo_uarch_steamroller:
125*2b54f0dbSXin Li return "Steamroller";
126*2b54f0dbSXin Li case cpuinfo_uarch_excavator:
127*2b54f0dbSXin Li return "Excavator";
128*2b54f0dbSXin Li case cpuinfo_uarch_zen:
129*2b54f0dbSXin Li return "Zen";
130*2b54f0dbSXin Li case cpuinfo_uarch_zen2:
131*2b54f0dbSXin Li return "Zen 2";
132*2b54f0dbSXin Li case cpuinfo_uarch_zen3:
133*2b54f0dbSXin Li return "Zen 3";
134*2b54f0dbSXin Li case cpuinfo_uarch_geode:
135*2b54f0dbSXin Li return "Geode";
136*2b54f0dbSXin Li case cpuinfo_uarch_bobcat:
137*2b54f0dbSXin Li return "Bobcat";
138*2b54f0dbSXin Li case cpuinfo_uarch_jaguar:
139*2b54f0dbSXin Li return "Jaguar";
140*2b54f0dbSXin Li case cpuinfo_uarch_puma:
141*2b54f0dbSXin Li return "Puma";
142*2b54f0dbSXin Li case cpuinfo_uarch_xscale:
143*2b54f0dbSXin Li return "XScale";
144*2b54f0dbSXin Li case cpuinfo_uarch_arm7:
145*2b54f0dbSXin Li return "ARM7";
146*2b54f0dbSXin Li case cpuinfo_uarch_arm9:
147*2b54f0dbSXin Li return "ARM9";
148*2b54f0dbSXin Li case cpuinfo_uarch_arm11:
149*2b54f0dbSXin Li return "ARM11";
150*2b54f0dbSXin Li case cpuinfo_uarch_cortex_a5:
151*2b54f0dbSXin Li return "Cortex-A5";
152*2b54f0dbSXin Li case cpuinfo_uarch_cortex_a7:
153*2b54f0dbSXin Li return "Cortex-A7";
154*2b54f0dbSXin Li case cpuinfo_uarch_cortex_a8:
155*2b54f0dbSXin Li return "Cortex-A8";
156*2b54f0dbSXin Li case cpuinfo_uarch_cortex_a9:
157*2b54f0dbSXin Li return "Cortex-A9";
158*2b54f0dbSXin Li case cpuinfo_uarch_cortex_a12:
159*2b54f0dbSXin Li return "Cortex-A12";
160*2b54f0dbSXin Li case cpuinfo_uarch_cortex_a15:
161*2b54f0dbSXin Li return "Cortex-A15";
162*2b54f0dbSXin Li case cpuinfo_uarch_cortex_a17:
163*2b54f0dbSXin Li return "Cortex-A17";
164*2b54f0dbSXin Li case cpuinfo_uarch_cortex_a32:
165*2b54f0dbSXin Li return "Cortex-A32";
166*2b54f0dbSXin Li case cpuinfo_uarch_cortex_a35:
167*2b54f0dbSXin Li return "Cortex-A35";
168*2b54f0dbSXin Li case cpuinfo_uarch_cortex_a53:
169*2b54f0dbSXin Li return "Cortex-A53";
170*2b54f0dbSXin Li case cpuinfo_uarch_cortex_a55r0:
171*2b54f0dbSXin Li return "Cortex-A55r0";
172*2b54f0dbSXin Li case cpuinfo_uarch_cortex_a55:
173*2b54f0dbSXin Li return "Cortex-A55";
174*2b54f0dbSXin Li case cpuinfo_uarch_cortex_a57:
175*2b54f0dbSXin Li return "Cortex-A57";
176*2b54f0dbSXin Li case cpuinfo_uarch_cortex_a65:
177*2b54f0dbSXin Li return "Cortex-A65";
178*2b54f0dbSXin Li case cpuinfo_uarch_cortex_a72:
179*2b54f0dbSXin Li return "Cortex-A72";
180*2b54f0dbSXin Li case cpuinfo_uarch_cortex_a73:
181*2b54f0dbSXin Li return "Cortex-A73";
182*2b54f0dbSXin Li case cpuinfo_uarch_cortex_a75:
183*2b54f0dbSXin Li return "Cortex-A75";
184*2b54f0dbSXin Li case cpuinfo_uarch_cortex_a76:
185*2b54f0dbSXin Li return "Cortex-A76";
186*2b54f0dbSXin Li case cpuinfo_uarch_cortex_a77:
187*2b54f0dbSXin Li return "Cortex-A77";
188*2b54f0dbSXin Li case cpuinfo_uarch_cortex_a78:
189*2b54f0dbSXin Li return "Cortex-A78";
190*2b54f0dbSXin Li case cpuinfo_uarch_cortex_a510:
191*2b54f0dbSXin Li return "Cortex-A510";
192*2b54f0dbSXin Li case cpuinfo_uarch_cortex_a710:
193*2b54f0dbSXin Li return "Cortex-A710";
194*2b54f0dbSXin Li case cpuinfo_uarch_cortex_x1:
195*2b54f0dbSXin Li return "Cortex-X1";
196*2b54f0dbSXin Li case cpuinfo_uarch_cortex_x2:
197*2b54f0dbSXin Li return "Cortex-X2";
198*2b54f0dbSXin Li case cpuinfo_uarch_neoverse_n1:
199*2b54f0dbSXin Li return "Neoverse-N1";
200*2b54f0dbSXin Li case cpuinfo_uarch_neoverse_v1:
201*2b54f0dbSXin Li return "Neoverse-V1";
202*2b54f0dbSXin Li case cpuinfo_uarch_neoverse_n2:
203*2b54f0dbSXin Li return "Neoverse-N2";
204*2b54f0dbSXin Li case cpuinfo_uarch_scorpion:
205*2b54f0dbSXin Li return "Scorpion";
206*2b54f0dbSXin Li case cpuinfo_uarch_krait:
207*2b54f0dbSXin Li return "Krait";
208*2b54f0dbSXin Li case cpuinfo_uarch_kryo:
209*2b54f0dbSXin Li return "Kryo";
210*2b54f0dbSXin Li case cpuinfo_uarch_falkor:
211*2b54f0dbSXin Li return "Falkor";
212*2b54f0dbSXin Li case cpuinfo_uarch_saphira:
213*2b54f0dbSXin Li return "Saphira";
214*2b54f0dbSXin Li case cpuinfo_uarch_denver:
215*2b54f0dbSXin Li return "Denver";
216*2b54f0dbSXin Li case cpuinfo_uarch_denver2:
217*2b54f0dbSXin Li return "Denver 2";
218*2b54f0dbSXin Li case cpuinfo_uarch_carmel:
219*2b54f0dbSXin Li return "Carmel";
220*2b54f0dbSXin Li case cpuinfo_uarch_exynos_m1:
221*2b54f0dbSXin Li return "Exynos M1";
222*2b54f0dbSXin Li case cpuinfo_uarch_exynos_m2:
223*2b54f0dbSXin Li return "Exynos M2";
224*2b54f0dbSXin Li case cpuinfo_uarch_exynos_m3:
225*2b54f0dbSXin Li return "Exynos M3";
226*2b54f0dbSXin Li case cpuinfo_uarch_exynos_m4:
227*2b54f0dbSXin Li return "Exynos M4";
228*2b54f0dbSXin Li case cpuinfo_uarch_exynos_m5:
229*2b54f0dbSXin Li return "Exynos M5";
230*2b54f0dbSXin Li case cpuinfo_uarch_swift:
231*2b54f0dbSXin Li return "Swift";
232*2b54f0dbSXin Li case cpuinfo_uarch_cyclone:
233*2b54f0dbSXin Li return "Cyclone";
234*2b54f0dbSXin Li case cpuinfo_uarch_typhoon:
235*2b54f0dbSXin Li return "Typhoon";
236*2b54f0dbSXin Li case cpuinfo_uarch_twister:
237*2b54f0dbSXin Li return "Twister";
238*2b54f0dbSXin Li case cpuinfo_uarch_hurricane:
239*2b54f0dbSXin Li return "Hurricane";
240*2b54f0dbSXin Li case cpuinfo_uarch_monsoon:
241*2b54f0dbSXin Li return "Monsoon";
242*2b54f0dbSXin Li case cpuinfo_uarch_mistral:
243*2b54f0dbSXin Li return "Mistral";
244*2b54f0dbSXin Li case cpuinfo_uarch_vortex:
245*2b54f0dbSXin Li return "Vortex";
246*2b54f0dbSXin Li case cpuinfo_uarch_tempest:
247*2b54f0dbSXin Li return "Tempest";
248*2b54f0dbSXin Li case cpuinfo_uarch_lightning:
249*2b54f0dbSXin Li return "Lightning";
250*2b54f0dbSXin Li case cpuinfo_uarch_thunder:
251*2b54f0dbSXin Li return "Thunder";
252*2b54f0dbSXin Li case cpuinfo_uarch_firestorm:
253*2b54f0dbSXin Li return "Firestorm";
254*2b54f0dbSXin Li case cpuinfo_uarch_icestorm:
255*2b54f0dbSXin Li return "Icestorm";
256*2b54f0dbSXin Li case cpuinfo_uarch_avalanche:
257*2b54f0dbSXin Li return "Avalanche";
258*2b54f0dbSXin Li case cpuinfo_uarch_blizzard:
259*2b54f0dbSXin Li return "Blizzard";
260*2b54f0dbSXin Li case cpuinfo_uarch_thunderx:
261*2b54f0dbSXin Li return "ThunderX";
262*2b54f0dbSXin Li case cpuinfo_uarch_thunderx2:
263*2b54f0dbSXin Li return "ThunderX2";
264*2b54f0dbSXin Li case cpuinfo_uarch_pj4:
265*2b54f0dbSXin Li return "PJ4";
266*2b54f0dbSXin Li case cpuinfo_uarch_brahma_b15:
267*2b54f0dbSXin Li return "Brahma B15";
268*2b54f0dbSXin Li case cpuinfo_uarch_brahma_b53:
269*2b54f0dbSXin Li return "Brahma B53";
270*2b54f0dbSXin Li case cpuinfo_uarch_xgene:
271*2b54f0dbSXin Li return "X-Gene";
272*2b54f0dbSXin Li case cpuinfo_uarch_dhyana:
273*2b54f0dbSXin Li return "Dhyana";
274*2b54f0dbSXin Li case cpuinfo_uarch_taishan_v110:
275*2b54f0dbSXin Li return "TaiShan v110";
276*2b54f0dbSXin Li default:
277*2b54f0dbSXin Li return NULL;
278*2b54f0dbSXin Li }
279*2b54f0dbSXin Li }
280*2b54f0dbSXin Li
main(int argc,char ** argv)281*2b54f0dbSXin Li int main(int argc, char** argv) {
282*2b54f0dbSXin Li if (!cpuinfo_initialize()) {
283*2b54f0dbSXin Li fprintf(stderr, "failed to initialize CPU information\n");
284*2b54f0dbSXin Li exit(EXIT_FAILURE);
285*2b54f0dbSXin Li }
286*2b54f0dbSXin Li #ifdef __ANDROID__
287*2b54f0dbSXin Li printf("SoC name: %s\n", cpuinfo_get_package(0)->name);
288*2b54f0dbSXin Li #else
289*2b54f0dbSXin Li printf("Packages:\n");
290*2b54f0dbSXin Li for (uint32_t i = 0; i < cpuinfo_get_packages_count(); i++) {
291*2b54f0dbSXin Li printf("\t%"PRIu32": %s\n", i, cpuinfo_get_package(i)->name);
292*2b54f0dbSXin Li }
293*2b54f0dbSXin Li #endif
294*2b54f0dbSXin Li printf("Microarchitectures:\n");
295*2b54f0dbSXin Li for (uint32_t i = 0; i < cpuinfo_get_uarchs_count(); i++) {
296*2b54f0dbSXin Li const struct cpuinfo_uarch_info* uarch_info = cpuinfo_get_uarch(i);
297*2b54f0dbSXin Li const char* uarch_string = uarch_to_string(uarch_info->uarch);
298*2b54f0dbSXin Li if (uarch_string == NULL) {
299*2b54f0dbSXin Li printf("\t%"PRIu32"x Unknown (0x%08"PRIx32"\n",
300*2b54f0dbSXin Li uarch_info->core_count, (uint32_t) uarch_info->uarch);
301*2b54f0dbSXin Li } else {
302*2b54f0dbSXin Li printf("\t%"PRIu32"x %s\n", uarch_info->core_count, uarch_string);
303*2b54f0dbSXin Li }
304*2b54f0dbSXin Li }
305*2b54f0dbSXin Li printf("Cores:\n");
306*2b54f0dbSXin Li for (uint32_t i = 0; i < cpuinfo_get_cores_count(); i++) {
307*2b54f0dbSXin Li const struct cpuinfo_core* core = cpuinfo_get_core(i);
308*2b54f0dbSXin Li if (core->processor_count == 1) {
309*2b54f0dbSXin Li printf("\t%"PRIu32": 1 processor (%"PRIu32")", i, core->processor_start);
310*2b54f0dbSXin Li } else {
311*2b54f0dbSXin Li printf("\t%"PRIu32": %"PRIu32" processors (%"PRIu32"-%"PRIu32")",
312*2b54f0dbSXin Li i, core->processor_count, core->processor_start, core->processor_start + core->processor_count - 1);
313*2b54f0dbSXin Li }
314*2b54f0dbSXin Li const char* vendor_string = vendor_to_string(core->vendor);
315*2b54f0dbSXin Li const char* uarch_string = uarch_to_string(core->uarch);
316*2b54f0dbSXin Li if (vendor_string == NULL) {
317*2b54f0dbSXin Li printf(", vendor 0x%08"PRIx32" uarch 0x%08"PRIx32"\n",
318*2b54f0dbSXin Li (uint32_t) core->vendor, (uint32_t) core->uarch);
319*2b54f0dbSXin Li }
320*2b54f0dbSXin Li else if (uarch_string == NULL) {
321*2b54f0dbSXin Li printf(", %s uarch 0x%08"PRIx32"\n",
322*2b54f0dbSXin Li vendor_string, (uint32_t) core->uarch);
323*2b54f0dbSXin Li }
324*2b54f0dbSXin Li else {
325*2b54f0dbSXin Li printf(", %s %s\n", vendor_string, uarch_string);
326*2b54f0dbSXin Li }
327*2b54f0dbSXin Li }
328*2b54f0dbSXin Li printf("Logical processors");
329*2b54f0dbSXin Li #if defined(__linux__)
330*2b54f0dbSXin Li printf(" (System ID)");
331*2b54f0dbSXin Li #endif
332*2b54f0dbSXin Li printf(":\n");
333*2b54f0dbSXin Li for (uint32_t i = 0; i < cpuinfo_get_processors_count(); i++) {
334*2b54f0dbSXin Li const struct cpuinfo_processor* processor = cpuinfo_get_processor(i);
335*2b54f0dbSXin Li printf("\t%"PRIu32"", i);
336*2b54f0dbSXin Li
337*2b54f0dbSXin Li #if defined(__linux__)
338*2b54f0dbSXin Li printf(" (%"PRId32")", processor->linux_id);
339*2b54f0dbSXin Li #endif
340*2b54f0dbSXin Li
341*2b54f0dbSXin Li #if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
342*2b54f0dbSXin Li printf(": APIC ID 0x%08"PRIx32"\n", processor->apic_id);
343*2b54f0dbSXin Li #else
344*2b54f0dbSXin Li printf("\n");
345*2b54f0dbSXin Li #endif
346*2b54f0dbSXin Li }
347*2b54f0dbSXin Li }
348