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