• 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 				case 0xD41: /* Cortex-A78 */
95 					*uarch = cpuinfo_uarch_cortex_a78;
96 					break;
97 				case 0xD44: /* Cortex-X1 */
98 					*uarch = cpuinfo_uarch_cortex_x1;
99 					break;
100 #if CPUINFO_ARCH_ARM64 && !defined(__ANDROID__)
101 				case 0xD4A:
102 					*uarch = cpuinfo_uarch_neoverse_e1;
103 					break;
104 #endif /* CPUINFO_ARCH_ARM64 && !defined(__ANDROID__) */
105 				default:
106 					switch (midr_get_part(midr) >> 8) {
107 #if CPUINFO_ARCH_ARM
108 						case 7:
109 							*uarch = cpuinfo_uarch_arm7;
110 							break;
111 						case 9:
112 							*uarch = cpuinfo_uarch_arm9;
113 							break;
114 						case 11:
115 							*uarch = cpuinfo_uarch_arm11;
116 							break;
117 #endif /* CPUINFO_ARCH_ARM */
118 						default:
119 							cpuinfo_log_warning("unknown ARM CPU part 0x%03"PRIx32" ignored", midr_get_part(midr));
120 					}
121 			}
122 			break;
123 		case 'B':
124 			*vendor = cpuinfo_vendor_broadcom;
125 			switch (midr_get_part(midr)) {
126 				case 0x00F:
127 					*uarch = cpuinfo_uarch_brahma_b15;
128 					break;
129 				case 0x100:
130 					*uarch = cpuinfo_uarch_brahma_b53;
131 					break;
132 #if CPUINFO_ARCH_ARM64 && !defined(__ANDROID__)
133 				case 0x516:
134 					/* Broadcom Vulkan was sold to Cavium before it reached the market, so we identify it as Cavium ThunderX2 */
135 					*vendor = cpuinfo_vendor_cavium;
136 					*uarch = cpuinfo_uarch_thunderx2;
137 					break;
138 #endif
139 				default:
140 					cpuinfo_log_warning("unknown Broadcom CPU part 0x%03"PRIx32" ignored", midr_get_part(midr));
141 			}
142 			break;
143 #if CPUINFO_ARCH_ARM64 && !defined(__ANDROID__)
144 		case 'C':
145 			*vendor = cpuinfo_vendor_cavium;
146 			switch (midr_get_part(midr)) {
147 				case 0x0A0: /* ThunderX */
148 				case 0x0A1: /* ThunderX 88XX */
149 				case 0x0A2: /* ThunderX 81XX */
150 				case 0x0A3: /* ThunderX 83XX */
151 					*uarch = cpuinfo_uarch_thunderx;
152 					break;
153 				case 0x0AF: /* ThunderX2 99XX */
154 					*uarch = cpuinfo_uarch_thunderx2;
155 					break;
156 				default:
157 					cpuinfo_log_warning("unknown Cavium CPU part 0x%03"PRIx32" ignored", midr_get_part(midr));
158 			}
159 			break;
160 #endif
161 		case 'H':
162 			*vendor = cpuinfo_vendor_huawei;
163 			switch (midr_get_part(midr)) {
164 #if CPUINFO_ARCH_ARM64 && !defined(__ANDROID__)
165 				case 0xD01: /* Kunpeng 920 series */
166 					*uarch = cpuinfo_uarch_taishan_v110;
167 					break;
168 #endif
169 				case 0xD40: /* Kirin 980 Big/Medium cores -> Cortex-A76 */
170 					*vendor = cpuinfo_vendor_arm;
171 					*uarch = cpuinfo_uarch_cortex_a76;
172 					break;
173 				default:
174 					cpuinfo_log_warning("unknown Huawei CPU part 0x%03"PRIx32" ignored", midr_get_part(midr));
175 			}
176 			break;
177 #if CPUINFO_ARCH_ARM
178 		case 'i':
179 			*vendor = cpuinfo_vendor_intel;
180 			switch (midr_get_part(midr) >> 8) {
181 				case 2: /* PXA 210/25X/26X */
182 				case 4: /* PXA 27X */
183 				case 6: /* PXA 3XX */
184 					*uarch = cpuinfo_uarch_xscale;
185 					break;
186 				default:
187 					cpuinfo_log_warning("unknown Intel CPU part 0x%03"PRIx32" ignored", midr_get_part(midr));
188 			}
189 			break;
190 #endif /* CPUINFO_ARCH_ARM */
191 		case 'N':
192 			*vendor = cpuinfo_vendor_nvidia;
193 			switch (midr_get_part(midr)) {
194 				case 0x000:
195 					*uarch = cpuinfo_uarch_denver;
196 					break;
197 				case 0x003:
198 					*uarch = cpuinfo_uarch_denver2;
199 					break;
200 				case 0x004:
201 					*uarch = cpuinfo_uarch_carmel;
202 					break;
203 				default:
204 					cpuinfo_log_warning("unknown Nvidia CPU part 0x%03"PRIx32" ignored", midr_get_part(midr));
205 			}
206 			break;
207 #if !defined(__ANDROID__)
208 		case 'P':
209 			*vendor = cpuinfo_vendor_apm;
210 			switch (midr_get_part(midr)) {
211 				case 0x000:
212 					*uarch = cpuinfo_uarch_xgene;
213 					break;
214 				default:
215 					cpuinfo_log_warning("unknown Applied Micro CPU part 0x%03"PRIx32" ignored", midr_get_part(midr));
216 			}
217 			break;
218 #endif
219 		case 'Q':
220 			*vendor = cpuinfo_vendor_qualcomm;
221 			switch (midr_get_part(midr)) {
222 #if CPUINFO_ARCH_ARM
223 				case 0x00F:
224 					/* Mostly Scorpions, but some Cortex A5 may report this value as well */
225 					if (has_vfpv4) {
226 						/* Unlike Scorpion, Cortex-A5 comes with VFPv4 */
227 						*vendor = cpuinfo_vendor_arm;
228 						*uarch = cpuinfo_uarch_cortex_a5;
229 					} else {
230 						*uarch = cpuinfo_uarch_scorpion;
231 					}
232 					break;
233 				case 0x02D: /* Dual-core Scorpions */
234 					*uarch = cpuinfo_uarch_scorpion;
235 					break;
236 				case 0x04D:
237 					/*
238 					 * Dual-core Krait:
239 					 * - r1p0 -> Krait 200
240 					 * - r1p4 -> Krait 200
241 					 * - r2p0 -> Krait 300
242 					 */
243 				case 0x06F:
244 					/*
245 					 * Quad-core Krait:
246 					 * - r0p1 -> Krait 200
247 					 * - r0p2 -> Krait 200
248 					 * - r1p0 -> Krait 300
249 					 * - r2p0 -> Krait 400 (Snapdragon 800 MSMxxxx)
250 					 * - r2p1 -> Krait 400 (Snapdragon 801 MSMxxxxPRO)
251 					 * - r3p1 -> Krait 450
252 					 */
253 					*uarch = cpuinfo_uarch_krait;
254 					break;
255 #endif /* CPUINFO_ARCH_ARM */
256 				case 0x201: /* Qualcomm Snapdragon 821: Low-power Kryo "Silver" */
257 				case 0x205: /* Qualcomm Snapdragon 820 & 821: High-performance Kryo "Gold" */
258 				case 0x211: /* Qualcomm Snapdragon 820: Low-power Kryo "Silver" */
259 					*uarch = cpuinfo_uarch_kryo;
260 					break;
261 				case 0x800: /* High-performance Kryo 260 (r10p2) / Kryo 280 (r10p1) "Gold" -> Cortex-A73 */
262 					*vendor = cpuinfo_vendor_arm;
263 					*uarch = cpuinfo_uarch_cortex_a73;
264 					break;
265 				case 0x801: /* Low-power Kryo 260 / 280 "Silver" -> Cortex-A53 */
266 					*vendor = cpuinfo_vendor_arm;
267 					*uarch = cpuinfo_uarch_cortex_a53;
268 					break;
269 				case 0x802: /* High-performance Kryo 385 "Gold" -> Cortex-A75 */
270 					*vendor = cpuinfo_vendor_arm;
271 					*uarch = cpuinfo_uarch_cortex_a75;
272 					break;
273 				case 0x803: /* Low-power Kryo 385 "Silver" -> Cortex-A55r0 */
274 					*vendor = cpuinfo_vendor_arm;
275 					*uarch = cpuinfo_uarch_cortex_a55r0;
276 					break;
277 				case 0x804: /* High-performance Kryo 485 "Gold" / "Gold Prime" -> Cortex-A76 */
278 					*vendor = cpuinfo_vendor_arm;
279 					*uarch = cpuinfo_uarch_cortex_a76;
280 					break;
281 				case 0x805: /* Low-performance Kryo 485 "Silver" -> Cortex-A55 */
282 					*vendor = cpuinfo_vendor_arm;
283 					*uarch = cpuinfo_uarch_cortex_a55;
284 					break;
285 #if CPUINFO_ARCH_ARM64 && !defined(__ANDROID__)
286 				case 0xC00:
287 					*uarch = cpuinfo_uarch_falkor;
288 					break;
289 				case 0xC01:
290 					*uarch = cpuinfo_uarch_saphira;
291 					break;
292 #endif /* CPUINFO_ARCH_ARM64 && !defined(__ANDROID__) */
293 				default:
294 					cpuinfo_log_warning("unknown Qualcomm CPU part 0x%03"PRIx32" ignored", midr_get_part(midr));
295 			}
296 			break;
297 		case 'S':
298 			*vendor = cpuinfo_vendor_samsung;
299 			switch (midr & (CPUINFO_ARM_MIDR_VARIANT_MASK | CPUINFO_ARM_MIDR_PART_MASK)) {
300 				case 0x00100010:
301 					/*
302 					 * Exynos 8890 MIDR = 0x531F0011, assume Exynos M1 has:
303 					 * - CPU variant 0x1
304 					 * - CPU part 0x001
305 					 */
306 					*uarch = cpuinfo_uarch_exynos_m1;
307 					break;
308 				case 0x00400010:
309 					/*
310 					 * Exynos 8895 MIDR = 0x534F0010, assume Exynos M2 has:
311 					 * - CPU variant 0x4
312 					 * - CPU part 0x001
313 					 */
314 					*uarch = cpuinfo_uarch_exynos_m2;
315 					break;
316 				case 0x00100020:
317 					/*
318 					 * Exynos 9810 MIDR = 0x531F0020, assume Exynos M3 has:
319 					 * - CPU variant 0x1
320 					 * - CPU part 0x002
321 					 */
322 					*uarch = cpuinfo_uarch_exynos_m3;
323 					break;
324 				case 0x00100030:
325 					/*
326 					 * Exynos 9820 MIDR = 0x531F0030, assume Exynos M4 has:
327 					 * - CPU variant 0x1
328 					 * - CPU part 0x003
329 					 */
330 					*uarch = cpuinfo_uarch_exynos_m4;
331 					break;
332 				case 0x00100040:
333 					/*
334 					 * Exynos 9820 MIDR = 0x531F0040, assume Exynos M5 has:
335 					 * - CPU variant 0x1
336 					 * - CPU part 0x004
337 					 */
338 					*uarch = cpuinfo_uarch_exynos_m5;
339 					break;
340 				default:
341 					cpuinfo_log_warning("unknown Samsung CPU variant 0x%01"PRIx32" part 0x%03"PRIx32" ignored",
342 						midr_get_variant(midr), midr_get_part(midr));
343 			}
344 			break;
345 #if CPUINFO_ARCH_ARM
346 		case 'V':
347 			*vendor = cpuinfo_vendor_marvell;
348 			switch (midr_get_part(midr)) {
349 				case 0x581: /* PJ4 / PJ4B */
350 				case 0x584: /* PJ4B-MP / PJ4C */
351 					*uarch = cpuinfo_uarch_pj4;
352 					break;
353 				default:
354 					cpuinfo_log_warning("unknown Marvell CPU part 0x%03"PRIx32" ignored", midr_get_part(midr));
355 			}
356 			break;
357 #endif /* CPUINFO_ARCH_ARM */
358 		default:
359 			cpuinfo_log_warning("unknown CPU implementer '%c' (0x%02"PRIx32") with CPU part 0x%03"PRIx32" ignored",
360 				(char) midr_get_implementer(midr), midr_get_implementer(midr), midr_get_part(midr));
361 	}
362 }
363