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