• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <stdint.h>
2 
3 #include <arm/api.h>
4 #include <arm/midr.h>
5 #include <cpuinfo/log.h>
6 
cpuinfo_arm_decode_vendor_uarch(uint32_t midr,bool has_vfpv4,enum cpuinfo_vendor vendor[restrict static1],enum cpuinfo_uarch uarch[restrict static1])7 void cpuinfo_arm_decode_vendor_uarch(
8 	uint32_t midr,
9 #if CPUINFO_ARCH_ARM
10 	bool has_vfpv4,
11 #endif /* CPUINFO_ARCH_ARM */
12 	enum cpuinfo_vendor vendor[restrict static 1],
13 	enum cpuinfo_uarch uarch[restrict static 1]) {
14 	switch (midr_get_implementer(midr)) {
15 		case 'A':
16 			*vendor = cpuinfo_vendor_arm;
17 			switch (midr_get_part(midr)) {
18 #if CPUINFO_ARCH_ARM
19 				case 0xC05:
20 					*uarch = cpuinfo_uarch_cortex_a5;
21 					break;
22 				case 0xC07:
23 					*uarch = cpuinfo_uarch_cortex_a7;
24 					break;
25 				case 0xC08:
26 					*uarch = cpuinfo_uarch_cortex_a8;
27 					break;
28 				case 0xC09:
29 					*uarch = cpuinfo_uarch_cortex_a9;
30 					break;
31 				case 0xC0C:
32 					*uarch = cpuinfo_uarch_cortex_a12;
33 					break;
34 				case 0xC0E:
35 					*uarch = cpuinfo_uarch_cortex_a17;
36 					break;
37 				case 0xC0D:
38 					/*
39 					 * Rockchip RK3288 only.
40 					 * Core information is ambiguous: some
41 					 * sources specify Cortex-A12, others -
42 					 * Cortex-A17. Assume it is Cortex-A12.
43 					 */
44 					*uarch = cpuinfo_uarch_cortex_a12;
45 					break;
46 				case 0xC0F:
47 					*uarch = cpuinfo_uarch_cortex_a15;
48 					break;
49 #endif /* CPUINFO_ARCH_ARM */
50 				case 0xD01:
51 					*uarch = cpuinfo_uarch_cortex_a32;
52 					break;
53 				case 0xD03:
54 					*uarch = cpuinfo_uarch_cortex_a53;
55 					break;
56 				case 0xD04:
57 					*uarch = cpuinfo_uarch_cortex_a35;
58 					break;
59 				case 0xD05:
60 					// Note: use Variant, not Revision,
61 					// field
62 					*uarch = (midr & CPUINFO_ARM_MIDR_VARIANT_MASK) == 0
63 						? cpuinfo_uarch_cortex_a55r0
64 						: cpuinfo_uarch_cortex_a55;
65 					break;
66 				case 0xD06:
67 					*uarch = cpuinfo_uarch_cortex_a65;
68 					break;
69 				case 0xD07:
70 					*uarch = cpuinfo_uarch_cortex_a57;
71 					break;
72 				case 0xD08:
73 					*uarch = cpuinfo_uarch_cortex_a72;
74 					break;
75 				case 0xD09:
76 					*uarch = cpuinfo_uarch_cortex_a73;
77 					break;
78 				case 0xD0A:
79 					*uarch = cpuinfo_uarch_cortex_a75;
80 					break;
81 				case 0xD0B:
82 					*uarch = cpuinfo_uarch_cortex_a76;
83 					break;
84 				case 0xD0C:
85 					*uarch = cpuinfo_uarch_neoverse_n1;
86 					break;
87 				case 0xD0D:
88 					*uarch = cpuinfo_uarch_cortex_a77;
89 					break;
90 				case 0xD0E: /* Cortex-A76AE */
91 					*uarch = cpuinfo_uarch_cortex_a76;
92 					break;
93 				case 0xD40: /* Neoverse V1 */
94 					*uarch = cpuinfo_uarch_neoverse_v1;
95 					break;
96 				case 0xD41: /* Cortex-A78 */
97 					*uarch = cpuinfo_uarch_cortex_a78;
98 					break;
99 				case 0xD44: /* Cortex-X1 */
100 					*uarch = cpuinfo_uarch_cortex_x1;
101 					break;
102 				case 0xD46: /* Cortex-A510 */
103 					*uarch = cpuinfo_uarch_cortex_a510;
104 					break;
105 				case 0xD47: /* Cortex-A710 */
106 					*uarch = cpuinfo_uarch_cortex_a710;
107 					break;
108 				case 0xD48: /* Cortex-X2 */
109 					*uarch = cpuinfo_uarch_cortex_x2;
110 					break;
111 				case 0xD49: /* Neoverse N2 */
112 					*uarch = cpuinfo_uarch_neoverse_n2;
113 					break;
114 #if CPUINFO_ARCH_ARM64
115 				case 0xD4A:
116 					*uarch = cpuinfo_uarch_neoverse_e1;
117 					break;
118 #endif /* CPUINFO_ARCH_ARM64 */
119 				case 0xD4D: /* Cortex-A715 */
120 					*uarch = cpuinfo_uarch_cortex_a715;
121 					break;
122 				case 0xD4E: /* Cortex-X3 */
123 					*uarch = cpuinfo_uarch_cortex_x3;
124 					break;
125 				case 0xD4F: /* Neoverse V2 */
126 					*uarch = cpuinfo_uarch_neoverse_v2;
127 					break;
128 				default:
129 					switch (midr_get_part(midr) >> 8) {
130 #if CPUINFO_ARCH_ARM
131 						case 7:
132 							*uarch = cpuinfo_uarch_arm7;
133 							break;
134 						case 9:
135 							*uarch = cpuinfo_uarch_arm9;
136 							break;
137 						case 11:
138 							*uarch = cpuinfo_uarch_arm11;
139 							break;
140 #endif /* CPUINFO_ARCH_ARM */
141 						default:
142 							cpuinfo_log_warning(
143 								"unknown ARM CPU part 0x%03" PRIx32 " ignored",
144 								midr_get_part(midr));
145 					}
146 			}
147 			break;
148 		case 'B':
149 			*vendor = cpuinfo_vendor_broadcom;
150 			switch (midr_get_part(midr)) {
151 				case 0x00F:
152 					*uarch = cpuinfo_uarch_brahma_b15;
153 					break;
154 				case 0x100:
155 					*uarch = cpuinfo_uarch_brahma_b53;
156 					break;
157 #if CPUINFO_ARCH_ARM64
158 				case 0x516:
159 					/* Broadcom Vulkan was sold to Cavium
160 					 * before it reached the market, so we
161 					 * identify it as Cavium ThunderX2 */
162 					*vendor = cpuinfo_vendor_cavium;
163 					*uarch = cpuinfo_uarch_thunderx2;
164 					break;
165 #endif /* CPUINFO_ARCH_ARM64 */
166 				default:
167 					cpuinfo_log_warning(
168 						"unknown Broadcom CPU part 0x%03" PRIx32 " ignored",
169 						midr_get_part(midr));
170 			}
171 			break;
172 #if CPUINFO_ARCH_ARM64
173 		case 'C':
174 			*vendor = cpuinfo_vendor_cavium;
175 			switch (midr_get_part(midr)) {
176 				case 0x0A0: /* ThunderX */
177 				case 0x0A1: /* ThunderX 88XX */
178 				case 0x0A2: /* ThunderX 81XX */
179 				case 0x0A3: /* ThunderX 83XX */
180 					*uarch = cpuinfo_uarch_thunderx;
181 					break;
182 				case 0x0AF: /* ThunderX2 99XX */
183 					*uarch = cpuinfo_uarch_thunderx2;
184 					break;
185 				default:
186 					cpuinfo_log_warning(
187 						"unknown Cavium CPU part 0x%03" PRIx32 " ignored", midr_get_part(midr));
188 			}
189 			break;
190 #endif /* CPUINFO_ARCH_ARM64 */
191 		case 'H':
192 			*vendor = cpuinfo_vendor_huawei;
193 			switch (midr_get_part(midr)) {
194 #if CPUINFO_ARCH_ARM64
195 				case 0xD01: /* Kunpeng 920 series */
196 					*uarch = cpuinfo_uarch_taishan_v110;
197 					break;
198 #endif /* CPUINFO_ARCH_ARM64 */
199 				case 0xD40: /* Kirin 980 Big/Medium cores ->
200 					       Cortex-A76 */
201 					*vendor = cpuinfo_vendor_arm;
202 					*uarch = cpuinfo_uarch_cortex_a76;
203 					break;
204 				default:
205 					cpuinfo_log_warning(
206 						"unknown Huawei CPU part 0x%03" PRIx32 " ignored", midr_get_part(midr));
207 			}
208 			break;
209 #if CPUINFO_ARCH_ARM
210 		case 'i':
211 			*vendor = cpuinfo_vendor_intel;
212 			switch (midr_get_part(midr) >> 8) {
213 				case 2: /* PXA 210/25X/26X */
214 				case 4: /* PXA 27X */
215 				case 6: /* PXA 3XX */
216 					*uarch = cpuinfo_uarch_xscale;
217 					break;
218 				default:
219 					cpuinfo_log_warning(
220 						"unknown Intel CPU part 0x%03" PRIx32 " ignored", midr_get_part(midr));
221 			}
222 			break;
223 #endif /* CPUINFO_ARCH_ARM */
224 		case 'N':
225 			*vendor = cpuinfo_vendor_nvidia;
226 			switch (midr_get_part(midr)) {
227 				case 0x000:
228 					*uarch = cpuinfo_uarch_denver;
229 					break;
230 				case 0x003:
231 					*uarch = cpuinfo_uarch_denver2;
232 					break;
233 				case 0x004:
234 					*uarch = cpuinfo_uarch_carmel;
235 					break;
236 				default:
237 					cpuinfo_log_warning(
238 						"unknown Nvidia CPU part 0x%03" PRIx32 " ignored", midr_get_part(midr));
239 			}
240 			break;
241 		case 'P':
242 			*vendor = cpuinfo_vendor_apm;
243 			switch (midr_get_part(midr)) {
244 				case 0x000:
245 					*uarch = cpuinfo_uarch_xgene;
246 					break;
247 				default:
248 					cpuinfo_log_warning(
249 						"unknown Applied Micro CPU part 0x%03" PRIx32 " ignored",
250 						midr_get_part(midr));
251 			}
252 			break;
253 		case 'Q':
254 			*vendor = cpuinfo_vendor_qualcomm;
255 			switch (midr_get_part(midr)) {
256 #if CPUINFO_ARCH_ARM
257 				case 0x00F:
258 					/* Mostly Scorpions, but some Cortex A5
259 					 * may report this value as well
260 					 */
261 					if (has_vfpv4) {
262 						/* Unlike Scorpion, Cortex-A5
263 						 * comes with VFPv4 */
264 						*vendor = cpuinfo_vendor_arm;
265 						*uarch = cpuinfo_uarch_cortex_a5;
266 					} else {
267 						*uarch = cpuinfo_uarch_scorpion;
268 					}
269 					break;
270 				case 0x02D: /* Dual-core Scorpions */
271 					*uarch = cpuinfo_uarch_scorpion;
272 					break;
273 				case 0x04D:
274 					/*
275 					 * Dual-core Krait:
276 					 * - r1p0 -> Krait 200
277 					 * - r1p4 -> Krait 200
278 					 * - r2p0 -> Krait 300
279 					 */
280 				case 0x06F:
281 					/*
282 					 * Quad-core Krait:
283 					 * - r0p1 -> Krait 200
284 					 * - r0p2 -> Krait 200
285 					 * - r1p0 -> Krait 300
286 					 * - r2p0 -> Krait 400 (Snapdragon 800
287 					 * MSMxxxx)
288 					 * - r2p1 -> Krait 400 (Snapdragon 801
289 					 * MSMxxxxPRO)
290 					 * - r3p1 -> Krait 450
291 					 */
292 					*uarch = cpuinfo_uarch_krait;
293 					break;
294 #endif /* CPUINFO_ARCH_ARM */
295 				case 0x201: /* Qualcomm Snapdragon 821:
296 					       Low-power Kryo "Silver" */
297 				case 0x205: /* Qualcomm Snapdragon 820 & 821:
298 					       High-performance Kryo "Gold" */
299 				case 0x211: /* Qualcomm Snapdragon 820:
300 					       Low-power Kryo "Silver" */
301 					*uarch = cpuinfo_uarch_kryo;
302 					break;
303 				case 0x800: /* High-performance Kryo 260 (r10p2)
304 					       / Kryo 280 (r10p1) "Gold" ->
305 					       Cortex-A73 */
306 					*vendor = cpuinfo_vendor_arm;
307 					*uarch = cpuinfo_uarch_cortex_a73;
308 					break;
309 				case 0x801: /* Low-power Kryo 260 / 280 "Silver"
310 					       -> Cortex-A53 */
311 					*vendor = cpuinfo_vendor_arm;
312 					*uarch = cpuinfo_uarch_cortex_a53;
313 					break;
314 				case 0x802: /* High-performance Kryo 385 "Gold"
315 					       -> Cortex-A75 */
316 					*vendor = cpuinfo_vendor_arm;
317 					*uarch = cpuinfo_uarch_cortex_a75;
318 					break;
319 				case 0x803: /* Low-power Kryo 385 "Silver" ->
320 					       Cortex-A55r0 */
321 					*vendor = cpuinfo_vendor_arm;
322 					*uarch = cpuinfo_uarch_cortex_a55r0;
323 					break;
324 				case 0x804: /* High-performance Kryo 485 "Gold"
325 					       / "Gold Prime" -> Cortex-A76 */
326 					*vendor = cpuinfo_vendor_arm;
327 					*uarch = cpuinfo_uarch_cortex_a76;
328 					break;
329 				case 0x805: /* Low-performance Kryo 485 "Silver"
330 					       -> Cortex-A55 */
331 					*vendor = cpuinfo_vendor_arm;
332 					*uarch = cpuinfo_uarch_cortex_a55;
333 					break;
334 #if CPUINFO_ARCH_ARM64
335 				case 0xC00:
336 					*uarch = cpuinfo_uarch_falkor;
337 					break;
338 				case 0xC01:
339 					*uarch = cpuinfo_uarch_saphira;
340 					break;
341 #endif /* CPUINFO_ARCH_ARM64 */
342 				default:
343 					cpuinfo_log_warning(
344 						"unknown Qualcomm CPU part 0x%03" PRIx32 " ignored",
345 						midr_get_part(midr));
346 			}
347 			break;
348 		case 'S':
349 			*vendor = cpuinfo_vendor_samsung;
350 			switch (midr & (CPUINFO_ARM_MIDR_VARIANT_MASK | CPUINFO_ARM_MIDR_PART_MASK)) {
351 				case 0x00100010:
352 					/*
353 					 * Exynos 8890 MIDR = 0x531F0011, assume
354 					 * Exynos M1 has:
355 					 * - CPU variant 0x1
356 					 * - CPU part 0x001
357 					 */
358 					*uarch = cpuinfo_uarch_exynos_m1;
359 					break;
360 				case 0x00400010:
361 					/*
362 					 * Exynos 8895 MIDR = 0x534F0010, assume
363 					 * Exynos M2 has:
364 					 * - CPU variant 0x4
365 					 * - CPU part 0x001
366 					 */
367 					*uarch = cpuinfo_uarch_exynos_m2;
368 					break;
369 				case 0x00100020:
370 					/*
371 					 * Exynos 9810 MIDR = 0x531F0020, assume
372 					 * Exynos M3 has:
373 					 * - CPU variant 0x1
374 					 * - CPU part 0x002
375 					 */
376 					*uarch = cpuinfo_uarch_exynos_m3;
377 					break;
378 				case 0x00100030:
379 					/*
380 					 * Exynos 9820 MIDR = 0x531F0030, assume
381 					 * Exynos M4 has:
382 					 * - CPU variant 0x1
383 					 * - CPU part 0x003
384 					 */
385 					*uarch = cpuinfo_uarch_exynos_m4;
386 					break;
387 				case 0x00100040:
388 					/*
389 					 * Exynos 9820 MIDR = 0x531F0040, assume
390 					 * Exynos M5 has:
391 					 * - CPU variant 0x1
392 					 * - CPU part 0x004
393 					 */
394 					*uarch = cpuinfo_uarch_exynos_m5;
395 					break;
396 				default:
397 					cpuinfo_log_warning(
398 						"unknown Samsung CPU variant 0x%01" PRIx32 " part 0x%03" PRIx32
399 						" ignored",
400 						midr_get_variant(midr),
401 						midr_get_part(midr));
402 			}
403 			break;
404 #if CPUINFO_ARCH_ARM
405 		case 'V':
406 			*vendor = cpuinfo_vendor_marvell;
407 			switch (midr_get_part(midr)) {
408 				case 0x581: /* PJ4 / PJ4B */
409 				case 0x584: /* PJ4B-MP / PJ4C */
410 					*uarch = cpuinfo_uarch_pj4;
411 					break;
412 				default:
413 					cpuinfo_log_warning(
414 						"unknown Marvell CPU part 0x%03" PRIx32 " ignored",
415 						midr_get_part(midr));
416 			}
417 			break;
418 #endif /* CPUINFO_ARCH_ARM */
419 		default:
420 			cpuinfo_log_warning(
421 				"unknown CPU implementer '%c' (0x%02" PRIx32 ") with CPU part 0x%03" PRIx32 " ignored",
422 				(char)midr_get_implementer(midr),
423 				midr_get_implementer(midr),
424 				midr_get_part(midr));
425 	}
426 }
427