• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #pragma once
2 #include <stdint.h>
3 
4 #define CPUINFO_ARM_MIDR_IMPLEMENTER_MASK UINT32_C(0xFF000000)
5 #define CPUINFO_ARM_MIDR_VARIANT_MASK UINT32_C(0x00F00000)
6 #define CPUINFO_ARM_MIDR_ARCHITECTURE_MASK UINT32_C(0x000F0000)
7 #define CPUINFO_ARM_MIDR_PART_MASK UINT32_C(0x0000FFF0)
8 #define CPUINFO_ARM_MIDR_REVISION_MASK UINT32_C(0x0000000F)
9 
10 #define CPUINFO_ARM_MIDR_IMPLEMENTER_OFFSET 24
11 #define CPUINFO_ARM_MIDR_VARIANT_OFFSET 20
12 #define CPUINFO_ARM_MIDR_ARCHITECTURE_OFFSET 16
13 #define CPUINFO_ARM_MIDR_PART_OFFSET 4
14 #define CPUINFO_ARM_MIDR_REVISION_OFFSET 0
15 
16 #define CPUINFO_ARM_MIDR_ARM1156 UINT32_C(0x410FB560)
17 #define CPUINFO_ARM_MIDR_CORTEX_A7 UINT32_C(0x410FC070)
18 #define CPUINFO_ARM_MIDR_CORTEX_A9 UINT32_C(0x410FC090)
19 #define CPUINFO_ARM_MIDR_CORTEX_A15 UINT32_C(0x410FC0F0)
20 #define CPUINFO_ARM_MIDR_CORTEX_A17 UINT32_C(0x410FC0E0)
21 #define CPUINFO_ARM_MIDR_CORTEX_A35 UINT32_C(0x410FD040)
22 #define CPUINFO_ARM_MIDR_CORTEX_A53 UINT32_C(0x410FD030)
23 #define CPUINFO_ARM_MIDR_CORTEX_A55 UINT32_C(0x410FD050)
24 #define CPUINFO_ARM_MIDR_CORTEX_A57 UINT32_C(0x410FD070)
25 #define CPUINFO_ARM_MIDR_CORTEX_A72 UINT32_C(0x410FD080)
26 #define CPUINFO_ARM_MIDR_CORTEX_A73 UINT32_C(0x410FD090)
27 #define CPUINFO_ARM_MIDR_CORTEX_A75 UINT32_C(0x410FD0A0)
28 #define CPUINFO_ARM_MIDR_KRYO280_GOLD UINT32_C(0x51AF8001)
29 #define CPUINFO_ARM_MIDR_KRYO280_SILVER UINT32_C(0x51AF8014)
30 #define CPUINFO_ARM_MIDR_KRYO385_GOLD UINT32_C(0x518F802D)
31 #define CPUINFO_ARM_MIDR_KRYO385_SILVER UINT32_C(0x518F803C)
32 #define CPUINFO_ARM_MIDR_KRYO_SILVER_821 UINT32_C(0x510F2010)
33 #define CPUINFO_ARM_MIDR_KRYO_GOLD UINT32_C(0x510F2050)
34 #define CPUINFO_ARM_MIDR_KRYO_SILVER_820 UINT32_C(0x510F2110)
35 #define CPUINFO_ARM_MIDR_EXYNOS_M1_M2 UINT32_C(0x530F0010)
36 #define CPUINFO_ARM_MIDR_DENVER2 UINT32_C(0x4E0F0030)
37 #define CPUINFO_ARM_MIDR_AMPERE_ALTRA UINT32_C(0x413fd0c1)
38 
midr_set_implementer(uint32_t midr,uint32_t implementer)39 inline static uint32_t midr_set_implementer(uint32_t midr, uint32_t implementer) {
40 	return (midr & ~CPUINFO_ARM_MIDR_IMPLEMENTER_MASK) |
41 		((implementer << CPUINFO_ARM_MIDR_IMPLEMENTER_OFFSET) & CPUINFO_ARM_MIDR_IMPLEMENTER_MASK);
42 }
43 
midr_set_variant(uint32_t midr,uint32_t variant)44 inline static uint32_t midr_set_variant(uint32_t midr, uint32_t variant) {
45 	return (midr & ~CPUINFO_ARM_MIDR_VARIANT_MASK) |
46 		((variant << CPUINFO_ARM_MIDR_VARIANT_OFFSET) & CPUINFO_ARM_MIDR_VARIANT_MASK);
47 }
48 
midr_set_architecture(uint32_t midr,uint32_t architecture)49 inline static uint32_t midr_set_architecture(uint32_t midr, uint32_t architecture) {
50 	return (midr & ~CPUINFO_ARM_MIDR_ARCHITECTURE_MASK) |
51 		((architecture << CPUINFO_ARM_MIDR_ARCHITECTURE_OFFSET) & CPUINFO_ARM_MIDR_ARCHITECTURE_MASK);
52 }
53 
midr_set_part(uint32_t midr,uint32_t part)54 inline static uint32_t midr_set_part(uint32_t midr, uint32_t part) {
55 	return (midr & ~CPUINFO_ARM_MIDR_PART_MASK) |
56 		((part << CPUINFO_ARM_MIDR_PART_OFFSET) & CPUINFO_ARM_MIDR_PART_MASK);
57 }
58 
midr_set_revision(uint32_t midr,uint32_t revision)59 inline static uint32_t midr_set_revision(uint32_t midr, uint32_t revision) {
60 	return (midr & ~CPUINFO_ARM_MIDR_REVISION_MASK) |
61 		((revision << CPUINFO_ARM_MIDR_REVISION_OFFSET) & CPUINFO_ARM_MIDR_REVISION_MASK);
62 }
63 
midr_get_variant(uint32_t midr)64 inline static uint32_t midr_get_variant(uint32_t midr) {
65 	return (midr & CPUINFO_ARM_MIDR_VARIANT_MASK) >> CPUINFO_ARM_MIDR_VARIANT_OFFSET;
66 }
67 
midr_get_implementer(uint32_t midr)68 inline static uint32_t midr_get_implementer(uint32_t midr) {
69 	return (midr & CPUINFO_ARM_MIDR_IMPLEMENTER_MASK) >> CPUINFO_ARM_MIDR_IMPLEMENTER_OFFSET;
70 }
71 
midr_get_part(uint32_t midr)72 inline static uint32_t midr_get_part(uint32_t midr) {
73 	return (midr & CPUINFO_ARM_MIDR_PART_MASK) >> CPUINFO_ARM_MIDR_PART_OFFSET;
74 }
75 
midr_get_revision(uint32_t midr)76 inline static uint32_t midr_get_revision(uint32_t midr) {
77 	return (midr & CPUINFO_ARM_MIDR_REVISION_MASK) >> CPUINFO_ARM_MIDR_REVISION_OFFSET;
78 }
79 
midr_copy_implementer(uint32_t midr,uint32_t other_midr)80 inline static uint32_t midr_copy_implementer(uint32_t midr, uint32_t other_midr) {
81 	return (midr & ~CPUINFO_ARM_MIDR_IMPLEMENTER_MASK) | (other_midr & CPUINFO_ARM_MIDR_IMPLEMENTER_MASK);
82 }
83 
midr_copy_variant(uint32_t midr,uint32_t other_midr)84 inline static uint32_t midr_copy_variant(uint32_t midr, uint32_t other_midr) {
85 	return (midr & ~CPUINFO_ARM_MIDR_VARIANT_MASK) | (other_midr & CPUINFO_ARM_MIDR_VARIANT_MASK);
86 }
87 
midr_copy_architecture(uint32_t midr,uint32_t other_midr)88 inline static uint32_t midr_copy_architecture(uint32_t midr, uint32_t other_midr) {
89 	return (midr & ~CPUINFO_ARM_MIDR_ARCHITECTURE_MASK) | (other_midr & CPUINFO_ARM_MIDR_ARCHITECTURE_MASK);
90 }
91 
midr_copy_part(uint32_t midr,uint32_t other_midr)92 inline static uint32_t midr_copy_part(uint32_t midr, uint32_t other_midr) {
93 	return (midr & ~CPUINFO_ARM_MIDR_PART_MASK) | (other_midr & CPUINFO_ARM_MIDR_PART_MASK);
94 }
95 
midr_copy_revision(uint32_t midr,uint32_t other_midr)96 inline static uint32_t midr_copy_revision(uint32_t midr, uint32_t other_midr) {
97 	return (midr & ~CPUINFO_ARM_MIDR_REVISION_MASK) | (other_midr & CPUINFO_ARM_MIDR_REVISION_MASK);
98 }
99 
midr_is_arm1156(uint32_t midr)100 inline static bool midr_is_arm1156(uint32_t midr) {
101 	const uint32_t uarch_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
102 	return (midr & uarch_mask) == (CPUINFO_ARM_MIDR_ARM1156 & uarch_mask);
103 }
104 
midr_is_arm11(uint32_t midr)105 inline static bool midr_is_arm11(uint32_t midr) {
106 	return (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | 0x0000F000)) == UINT32_C(0x4100B000);
107 }
108 
midr_is_cortex_a9(uint32_t midr)109 inline static bool midr_is_cortex_a9(uint32_t midr) {
110 	const uint32_t uarch_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
111 	return (midr & uarch_mask) == (CPUINFO_ARM_MIDR_CORTEX_A9 & uarch_mask);
112 }
113 
midr_is_scorpion(uint32_t midr)114 inline static bool midr_is_scorpion(uint32_t midr) {
115 	switch (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK)) {
116 		case UINT32_C(0x510000F0):
117 		case UINT32_C(0x510002D0):
118 			return true;
119 		default:
120 			return false;
121 	}
122 }
123 
midr_is_krait(uint32_t midr)124 inline static bool midr_is_krait(uint32_t midr) {
125 	switch (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK)) {
126 		case UINT32_C(0x510004D0):
127 		case UINT32_C(0x510006F0):
128 			return true;
129 		default:
130 			return false;
131 	}
132 }
133 
midr_is_cortex_a53(uint32_t midr)134 inline static bool midr_is_cortex_a53(uint32_t midr) {
135 	const uint32_t uarch_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
136 	return (midr & uarch_mask) == (CPUINFO_ARM_MIDR_CORTEX_A53 & uarch_mask);
137 }
138 
midr_is_qualcomm_cortex_a53_silver(uint32_t midr)139 inline static bool midr_is_qualcomm_cortex_a53_silver(uint32_t midr) {
140 	const uint32_t uarch_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
141 	return (midr & uarch_mask) == (CPUINFO_ARM_MIDR_KRYO280_SILVER & uarch_mask);
142 }
143 
midr_is_qualcomm_cortex_a55_silver(uint32_t midr)144 inline static bool midr_is_qualcomm_cortex_a55_silver(uint32_t midr) {
145 	const uint32_t uarch_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
146 	return (midr & uarch_mask) == (CPUINFO_ARM_MIDR_KRYO385_SILVER & uarch_mask);
147 }
148 
midr_is_kryo280_gold(uint32_t midr)149 inline static bool midr_is_kryo280_gold(uint32_t midr) {
150 	const uint32_t uarch_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
151 	return (midr & uarch_mask) == (CPUINFO_ARM_MIDR_KRYO280_GOLD & uarch_mask);
152 }
153 
midr_is_kryo_silver(uint32_t midr)154 inline static bool midr_is_kryo_silver(uint32_t midr) {
155 	const uint32_t uarch_mask =
156 		CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_ARCHITECTURE_MASK | CPUINFO_ARM_MIDR_PART_MASK;
157 	switch (midr & uarch_mask) {
158 		case CPUINFO_ARM_MIDR_KRYO_SILVER_820:
159 		case CPUINFO_ARM_MIDR_KRYO_SILVER_821:
160 			return true;
161 		default:
162 			return false;
163 	}
164 }
165 
midr_is_kryo_gold(uint32_t midr)166 inline static bool midr_is_kryo_gold(uint32_t midr) {
167 	const uint32_t uarch_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
168 	return (midr & uarch_mask) == (CPUINFO_ARM_MIDR_KRYO_GOLD & uarch_mask);
169 }
170 
midr_is_ampere_altra(uint32_t midr)171 inline static bool midr_is_ampere_altra(uint32_t midr) {
172 	const uint32_t uarch_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
173 	return (midr & uarch_mask) == (CPUINFO_ARM_MIDR_AMPERE_ALTRA & uarch_mask);
174 }
175 
midr_score_core(uint32_t midr)176 inline static uint32_t midr_score_core(uint32_t midr) {
177 	const uint32_t core_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
178 	switch (midr & core_mask) {
179 		case UINT32_C(0x53000030): /* Exynos M4 */
180 		case UINT32_C(0x53000040): /* Exynos M5 */
181 		case UINT32_C(0x4100D440): /* Cortex-X1 */
182 		case UINT32_C(0x4100D480): /* Cortex-X2 */
183 		case UINT32_C(0x4100D4E0): /* Cortex-X3 */
184 			/* These cores are in big role w.r.t
185 			 * Cortex-A75/-A76/-A77/-A78/-A710/-A715
186 			 */
187 			return 6;
188 		case UINT32_C(0x4100D080): /* Cortex-A72 */
189 		case UINT32_C(0x4100D090): /* Cortex-A73 */
190 		case UINT32_C(0x4100D0A0): /* Cortex-A75 */
191 		case UINT32_C(0x4100D0B0): /* Cortex-A76 */
192 		case UINT32_C(0x4100D0D0): /* Cortex-A77 */
193 		case UINT32_C(0x4100D0E0): /* Cortex-A76AE */
194 		case UINT32_C(0x4100D410): /* Cortex-A78 */
195 		case UINT32_C(0x4100D470): /* Cortex-A710 */
196 		case UINT32_C(0x4100D4D0): /* Cortex-A715 */
197 		case UINT32_C(0x4800D400): /* Cortex-A76 (HiSilicon) */
198 		case UINT32_C(0x4E000030): /* Denver 2 */
199 		case UINT32_C(0x51002050): /* Kryo Gold */
200 		case UINT32_C(0x51008000): /* Kryo 260 / 280 Gold */
201 		case UINT32_C(0x51008020): /* Kryo 385 Gold */
202 		case UINT32_C(0x51008040): /* Kryo 485 Gold / Gold Prime */
203 		case UINT32_C(0x53000010): /* Exynos M1 and Exynos M2 */
204 		case UINT32_C(0x53000020): /* Exynos M3 */
205 #if CPUINFO_ARCH_ARM
206 		case UINT32_C(0x4100C0F0): /* Cortex-A15 */
207 		case UINT32_C(0x4100C0E0): /* Cortex-A17 */
208 		case UINT32_C(0x4100C0D0): /* Rockchip RK3288 cores */
209 		case UINT32_C(0x4100C0C0): /* Cortex-A12 */
210 #endif /* CPUINFO_ARCH_ARM */
211 			/* These cores are always in big role */
212 			return 5;
213 		case UINT32_C(0x4100D070): /* Cortex-A57 */
214 			/* Cortex-A57 can be in LITTLE role w.r.t. Denver 2, or
215 			 * in big role w.r.t. Cortex-A53 */
216 			return 4;
217 #if CPUINFO_ARCH_ARM64
218 		case UINT32_C(0x4100D060): /* Cortex-A65 */
219 #endif /* CPUINFO_ARCH_ARM64 */
220 		case UINT32_C(0x4100D030): /* Cortex-A53 */
221 		case UINT32_C(0x4100D050): /* Cortex-A55 */
222 		case UINT32_C(0x4100D460): /* Cortex-A510 */
223 			/* Cortex-A53 is usually in LITTLE role, but can be in
224 			 * big role w.r.t. Cortex-A35 */
225 			return 2;
226 		case UINT32_C(0x4100D040): /* Cortex-A35 */
227 #if CPUINFO_ARCH_ARM
228 		case UINT32_C(0x4100C070): /* Cortex-A7 */
229 #endif /* CPUINFO_ARCH_ARM */
230 		case UINT32_C(0x51008050): /* Kryo 485 Silver */
231 		case UINT32_C(0x51008030): /* Kryo 385 Silver */
232 		case UINT32_C(0x51008010): /* Kryo 260 / 280 Silver */
233 		case UINT32_C(0x51002110): /* Kryo Silver (Snapdragon 820) */
234 		case UINT32_C(0x51002010): /* Kryo Silver (Snapdragon 821) */
235 			/* These cores are always in LITTLE core */
236 			return 1;
237 		default:
238 			/*
239 			 * Unknown cores, or cores which do not have big/LITTLE
240 			 * roles. To be future-proof w.r.t. cores not yet
241 			 * recognized in cpuinfo, assume position between
242 			 * Cortex-A57/A72/A73/A75 and Cortex-A53/A55. Then at
243 			 * least future cores paired with one of these known
244 			 * cores will be properly scored.
245 			 */
246 			return 3;
247 	}
248 }
249 
midr_little_core_for_big(uint32_t midr)250 inline static uint32_t midr_little_core_for_big(uint32_t midr) {
251 	const uint32_t core_mask =
252 		CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_ARCHITECTURE_MASK | CPUINFO_ARM_MIDR_PART_MASK;
253 	switch (midr & core_mask) {
254 		case CPUINFO_ARM_MIDR_CORTEX_A75:
255 			return CPUINFO_ARM_MIDR_CORTEX_A55;
256 		case CPUINFO_ARM_MIDR_CORTEX_A73:
257 		case CPUINFO_ARM_MIDR_CORTEX_A72:
258 		case CPUINFO_ARM_MIDR_CORTEX_A57:
259 		case CPUINFO_ARM_MIDR_EXYNOS_M1_M2:
260 			return CPUINFO_ARM_MIDR_CORTEX_A53;
261 		case CPUINFO_ARM_MIDR_CORTEX_A17:
262 		case CPUINFO_ARM_MIDR_CORTEX_A15:
263 			return CPUINFO_ARM_MIDR_CORTEX_A7;
264 		case CPUINFO_ARM_MIDR_KRYO280_GOLD:
265 			return CPUINFO_ARM_MIDR_KRYO280_SILVER;
266 		case CPUINFO_ARM_MIDR_KRYO_GOLD:
267 			return CPUINFO_ARM_MIDR_KRYO_SILVER_820;
268 		case CPUINFO_ARM_MIDR_DENVER2:
269 			return CPUINFO_ARM_MIDR_CORTEX_A57;
270 		default:
271 			return midr;
272 	}
273 }
274