1*2b54f0dbSXin Li #pragma once
2*2b54f0dbSXin Li
3*2b54f0dbSXin Li #include <stdbool.h>
4*2b54f0dbSXin Li #include <stdint.h>
5*2b54f0dbSXin Li
6*2b54f0dbSXin Li #include <cpuinfo.h>
7*2b54f0dbSXin Li #include <cpuinfo/common.h>
8*2b54f0dbSXin Li #include <arm/midr.h>
9*2b54f0dbSXin Li #include <arm/api.h>
10*2b54f0dbSXin Li #include <linux/api.h>
11*2b54f0dbSXin Li
12*2b54f0dbSXin Li /* No hard limit in the kernel, maximum length observed on non-rogue kernels is 64 */
13*2b54f0dbSXin Li #define CPUINFO_HARDWARE_VALUE_MAX 64
14*2b54f0dbSXin Li /* No hard limit in the kernel, maximum length on Raspberry Pi is 8. Add 1 symbol to detect overly large revision strings */
15*2b54f0dbSXin Li #define CPUINFO_REVISION_VALUE_MAX 9
16*2b54f0dbSXin Li
17*2b54f0dbSXin Li #ifdef __ANDROID__
18*2b54f0dbSXin Li /* As per include/sys/system_properties.h in Android NDK */
19*2b54f0dbSXin Li #define CPUINFO_BUILD_PROP_NAME_MAX 32
20*2b54f0dbSXin Li #define CPUINFO_BUILD_PROP_VALUE_MAX 92
21*2b54f0dbSXin Li
22*2b54f0dbSXin Li struct cpuinfo_android_properties {
23*2b54f0dbSXin Li char proc_cpuinfo_hardware[CPUINFO_HARDWARE_VALUE_MAX];
24*2b54f0dbSXin Li char ro_product_board[CPUINFO_BUILD_PROP_VALUE_MAX];
25*2b54f0dbSXin Li char ro_board_platform[CPUINFO_BUILD_PROP_VALUE_MAX];
26*2b54f0dbSXin Li char ro_mediatek_platform[CPUINFO_BUILD_PROP_VALUE_MAX];
27*2b54f0dbSXin Li char ro_arch[CPUINFO_BUILD_PROP_VALUE_MAX];
28*2b54f0dbSXin Li char ro_chipname[CPUINFO_BUILD_PROP_VALUE_MAX];
29*2b54f0dbSXin Li char ro_hardware_chipname[CPUINFO_BUILD_PROP_VALUE_MAX];
30*2b54f0dbSXin Li };
31*2b54f0dbSXin Li #endif
32*2b54f0dbSXin Li
33*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_ARCH_T UINT32_C(0x00000001)
34*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_ARCH_E UINT32_C(0x00000002)
35*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_ARCH_J UINT32_C(0x00000004)
36*2b54f0dbSXin Li
37*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_ARCH_TE UINT32_C(0x00000003)
38*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_ARCH_TEJ UINT32_C(0x00000007)
39*2b54f0dbSXin Li
40*2b54f0dbSXin Li struct cpuinfo_arm_linux_proc_cpuinfo_cache {
41*2b54f0dbSXin Li uint32_t i_size;
42*2b54f0dbSXin Li uint32_t i_assoc;
43*2b54f0dbSXin Li uint32_t i_line_length;
44*2b54f0dbSXin Li uint32_t i_sets;
45*2b54f0dbSXin Li uint32_t d_size;
46*2b54f0dbSXin Li uint32_t d_assoc;
47*2b54f0dbSXin Li uint32_t d_line_length;
48*2b54f0dbSXin Li uint32_t d_sets;
49*2b54f0dbSXin Li };
50*2b54f0dbSXin Li
51*2b54f0dbSXin Li #if CPUINFO_ARCH_ARM
52*2b54f0dbSXin Li /* arch/arm/include/uapi/asm/hwcap.h */
53*2b54f0dbSXin Li
54*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_SWP UINT32_C(0x00000001)
55*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_HALF UINT32_C(0x00000002)
56*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_THUMB UINT32_C(0x00000004)
57*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_26BIT UINT32_C(0x00000008)
58*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_FASTMULT UINT32_C(0x00000010)
59*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_FPA UINT32_C(0x00000020)
60*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_VFP UINT32_C(0x00000040)
61*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_EDSP UINT32_C(0x00000080)
62*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_JAVA UINT32_C(0x00000100)
63*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_IWMMXT UINT32_C(0x00000200)
64*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_CRUNCH UINT32_C(0x00000400)
65*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_THUMBEE UINT32_C(0x00000800)
66*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_NEON UINT32_C(0x00001000)
67*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_VFPV3 UINT32_C(0x00002000)
68*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_VFPV3D16 UINT32_C(0x00004000) /* Also set for VFPv4 with 16 double-precision registers */
69*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_TLS UINT32_C(0x00008000)
70*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_VFPV4 UINT32_C(0x00010000)
71*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_IDIVA UINT32_C(0x00020000)
72*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_IDIVT UINT32_C(0x00040000)
73*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_IDIV UINT32_C(0x00060000)
74*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_VFPD32 UINT32_C(0x00080000)
75*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_LPAE UINT32_C(0x00100000)
76*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_EVTSTRM UINT32_C(0x00200000)
77*2b54f0dbSXin Li
78*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE2_AES UINT32_C(0x00000001)
79*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE2_PMULL UINT32_C(0x00000002)
80*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE2_SHA1 UINT32_C(0x00000004)
81*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE2_SHA2 UINT32_C(0x00000008)
82*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE2_CRC32 UINT32_C(0x00000010)
83*2b54f0dbSXin Li #elif CPUINFO_ARCH_ARM64
84*2b54f0dbSXin Li /* arch/arm64/include/uapi/asm/hwcap.h */
85*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_FP UINT32_C(0x00000001)
86*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_ASIMD UINT32_C(0x00000002)
87*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_EVTSTRM UINT32_C(0x00000004)
88*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_AES UINT32_C(0x00000008)
89*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_PMULL UINT32_C(0x00000010)
90*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_SHA1 UINT32_C(0x00000020)
91*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_SHA2 UINT32_C(0x00000040)
92*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_CRC32 UINT32_C(0x00000080)
93*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_ATOMICS UINT32_C(0x00000100)
94*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_FPHP UINT32_C(0x00000200)
95*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_ASIMDHP UINT32_C(0x00000400)
96*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_CPUID UINT32_C(0x00000800)
97*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_ASIMDRDM UINT32_C(0x00001000)
98*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_JSCVT UINT32_C(0x00002000)
99*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_FCMA UINT32_C(0x00004000)
100*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_LRCPC UINT32_C(0x00008000)
101*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_DCPOP UINT32_C(0x00010000)
102*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_SHA3 UINT32_C(0x00020000)
103*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_SM3 UINT32_C(0x00040000)
104*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_SM4 UINT32_C(0x00080000)
105*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_ASIMDDP UINT32_C(0x00100000)
106*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_SHA512 UINT32_C(0x00200000)
107*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_SVE UINT32_C(0x00400000)
108*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_ASIMDFHM UINT32_C(0x00800000)
109*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_DIT UINT32_C(0x01000000)
110*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_USCAT UINT32_C(0x02000000)
111*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_ILRCPC UINT32_C(0x04000000)
112*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_FLAGM UINT32_C(0x08000000)
113*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_SSBS UINT32_C(0x10000000)
114*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_SB UINT32_C(0x20000000)
115*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_PACA UINT32_C(0x40000000)
116*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE_PACG UINT32_C(0x80000000)
117*2b54f0dbSXin Li
118*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE2_DCPODP UINT32_C(0x00000001)
119*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE2_SVE2 UINT32_C(0x00000002)
120*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE2_SVEAES UINT32_C(0x00000004)
121*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE2_SVEPMULL UINT32_C(0x00000008)
122*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE2_SVEBITPERM UINT32_C(0x00000010)
123*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE2_SVESHA3 UINT32_C(0x00000020)
124*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE2_SVESM4 UINT32_C(0x00000040)
125*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE2_FLAGM2 UINT32_C(0x00000080)
126*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE2_FRINT UINT32_C(0x00000100)
127*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE2_SVEI8MM UINT32_C(0x00000200)
128*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE2_SVEF32MM UINT32_C(0x00000400)
129*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE2_SVEF64MM UINT32_C(0x00000800)
130*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE2_SVEBF16 UINT32_C(0x00001000)
131*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE2_I8MM UINT32_C(0x00002000)
132*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE2_BF16 UINT32_C(0x00004000)
133*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE2_DGH UINT32_C(0x00008000)
134*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE2_RNG UINT32_C(0x00010000)
135*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_FEATURE2_BTI UINT32_C(0x00020000)
136*2b54f0dbSXin Li #endif
137*2b54f0dbSXin Li
138*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_VALID_ARCHITECTURE UINT32_C(0x00010000)
139*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_VALID_IMPLEMENTER UINT32_C(0x00020000)
140*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_VALID_VARIANT UINT32_C(0x00040000)
141*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_VALID_PART UINT32_C(0x00080000)
142*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_VALID_REVISION UINT32_C(0x00100000)
143*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_VALID_PROCESSOR UINT32_C(0x00200000)
144*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_VALID_FEATURES UINT32_C(0x00400000)
145*2b54f0dbSXin Li #if CPUINFO_ARCH_ARM
146*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_VALID_ICACHE_SIZE UINT32_C(0x01000000)
147*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_VALID_ICACHE_SETS UINT32_C(0x02000000)
148*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_VALID_ICACHE_WAYS UINT32_C(0x04000000)
149*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_VALID_ICACHE_LINE UINT32_C(0x08000000)
150*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_VALID_DCACHE_SIZE UINT32_C(0x10000000)
151*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_VALID_DCACHE_SETS UINT32_C(0x20000000)
152*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_VALID_DCACHE_WAYS UINT32_C(0x40000000)
153*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_VALID_DCACHE_LINE UINT32_C(0x80000000)
154*2b54f0dbSXin Li #endif
155*2b54f0dbSXin Li
156*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_VALID_INFO UINT32_C(0x007F0000)
157*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_VALID_MIDR UINT32_C(0x003F0000)
158*2b54f0dbSXin Li #if CPUINFO_ARCH_ARM
159*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_VALID_ICACHE UINT32_C(0x0F000000)
160*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_VALID_DCACHE UINT32_C(0xF0000000)
161*2b54f0dbSXin Li #define CPUINFO_ARM_LINUX_VALID_CACHE_LINE UINT32_C(0x88000000)
162*2b54f0dbSXin Li #endif
163*2b54f0dbSXin Li
164*2b54f0dbSXin Li struct cpuinfo_arm_linux_processor {
165*2b54f0dbSXin Li uint32_t architecture_version;
166*2b54f0dbSXin Li #if CPUINFO_ARCH_ARM
167*2b54f0dbSXin Li uint32_t architecture_flags;
168*2b54f0dbSXin Li struct cpuinfo_arm_linux_proc_cpuinfo_cache proc_cpuinfo_cache;
169*2b54f0dbSXin Li #endif
170*2b54f0dbSXin Li uint32_t features;
171*2b54f0dbSXin Li uint32_t features2;
172*2b54f0dbSXin Li /**
173*2b54f0dbSXin Li * Main ID Register value.
174*2b54f0dbSXin Li */
175*2b54f0dbSXin Li uint32_t midr;
176*2b54f0dbSXin Li enum cpuinfo_vendor vendor;
177*2b54f0dbSXin Li enum cpuinfo_uarch uarch;
178*2b54f0dbSXin Li uint32_t uarch_index;
179*2b54f0dbSXin Li /**
180*2b54f0dbSXin Li * ID of the physical package which includes this logical processor.
181*2b54f0dbSXin Li * The value is parsed from /sys/devices/system/cpu/cpu<N>/topology/physical_package_id
182*2b54f0dbSXin Li */
183*2b54f0dbSXin Li uint32_t package_id;
184*2b54f0dbSXin Li /**
185*2b54f0dbSXin Li * Minimum processor ID on the package which includes this logical processor.
186*2b54f0dbSXin Li * This value can serve as an ID for the cluster of logical processors: it is the
187*2b54f0dbSXin Li * same for all logical processors on the same package.
188*2b54f0dbSXin Li */
189*2b54f0dbSXin Li uint32_t package_leader_id;
190*2b54f0dbSXin Li /**
191*2b54f0dbSXin Li * Number of logical processors in the package.
192*2b54f0dbSXin Li */
193*2b54f0dbSXin Li uint32_t package_processor_count;
194*2b54f0dbSXin Li /**
195*2b54f0dbSXin Li * Maximum frequency, in kHZ.
196*2b54f0dbSXin Li * The value is parsed from /sys/devices/system/cpu/cpu<N>/cpufreq/cpuinfo_max_freq
197*2b54f0dbSXin Li * If failed to read or parse the file, the value is 0.
198*2b54f0dbSXin Li */
199*2b54f0dbSXin Li uint32_t max_frequency;
200*2b54f0dbSXin Li /**
201*2b54f0dbSXin Li * Minimum frequency, in kHZ.
202*2b54f0dbSXin Li * The value is parsed from /sys/devices/system/cpu/cpu<N>/cpufreq/cpuinfo_min_freq
203*2b54f0dbSXin Li * If failed to read or parse the file, the value is 0.
204*2b54f0dbSXin Li */
205*2b54f0dbSXin Li uint32_t min_frequency;
206*2b54f0dbSXin Li /** Linux processor ID */
207*2b54f0dbSXin Li uint32_t system_processor_id;
208*2b54f0dbSXin Li uint32_t flags;
209*2b54f0dbSXin Li };
210*2b54f0dbSXin Li
211*2b54f0dbSXin Li struct cpuinfo_arm_linux_cluster {
212*2b54f0dbSXin Li uint32_t processor_id_min;
213*2b54f0dbSXin Li uint32_t processor_id_max;
214*2b54f0dbSXin Li };
215*2b54f0dbSXin Li
216*2b54f0dbSXin Li /* Returns true if the two processors do belong to the same cluster */
cpuinfo_arm_linux_processor_equals(struct cpuinfo_arm_linux_processor processor_i[restrict static1],struct cpuinfo_arm_linux_processor processor_j[restrict static1])217*2b54f0dbSXin Li static inline bool cpuinfo_arm_linux_processor_equals(
218*2b54f0dbSXin Li struct cpuinfo_arm_linux_processor processor_i[restrict static 1],
219*2b54f0dbSXin Li struct cpuinfo_arm_linux_processor processor_j[restrict static 1])
220*2b54f0dbSXin Li {
221*2b54f0dbSXin Li const uint32_t joint_flags = processor_i->flags & processor_j->flags;
222*2b54f0dbSXin Li
223*2b54f0dbSXin Li bool same_max_frequency = false;
224*2b54f0dbSXin Li if (joint_flags & CPUINFO_LINUX_FLAG_MAX_FREQUENCY) {
225*2b54f0dbSXin Li if (processor_i->max_frequency != processor_j->max_frequency) {
226*2b54f0dbSXin Li return false;
227*2b54f0dbSXin Li } else {
228*2b54f0dbSXin Li same_max_frequency = true;
229*2b54f0dbSXin Li }
230*2b54f0dbSXin Li }
231*2b54f0dbSXin Li
232*2b54f0dbSXin Li bool same_min_frequency = false;
233*2b54f0dbSXin Li if (joint_flags & CPUINFO_LINUX_FLAG_MIN_FREQUENCY) {
234*2b54f0dbSXin Li if (processor_i->min_frequency != processor_j->min_frequency) {
235*2b54f0dbSXin Li return false;
236*2b54f0dbSXin Li } else {
237*2b54f0dbSXin Li same_min_frequency = true;
238*2b54f0dbSXin Li }
239*2b54f0dbSXin Li }
240*2b54f0dbSXin Li
241*2b54f0dbSXin Li if ((joint_flags & CPUINFO_ARM_LINUX_VALID_MIDR) == CPUINFO_ARM_LINUX_VALID_MIDR) {
242*2b54f0dbSXin Li if (processor_i->midr == processor_j->midr) {
243*2b54f0dbSXin Li if (midr_is_cortex_a53(processor_i->midr)) {
244*2b54f0dbSXin Li return same_min_frequency & same_max_frequency;
245*2b54f0dbSXin Li } else {
246*2b54f0dbSXin Li return true;
247*2b54f0dbSXin Li }
248*2b54f0dbSXin Li }
249*2b54f0dbSXin Li }
250*2b54f0dbSXin Li
251*2b54f0dbSXin Li return same_max_frequency && same_min_frequency;
252*2b54f0dbSXin Li }
253*2b54f0dbSXin Li
254*2b54f0dbSXin Li /* Returns true if the two processors certainly don't belong to the same cluster */
cpuinfo_arm_linux_processor_not_equals(struct cpuinfo_arm_linux_processor processor_i[restrict static1],struct cpuinfo_arm_linux_processor processor_j[restrict static1])255*2b54f0dbSXin Li static inline bool cpuinfo_arm_linux_processor_not_equals(
256*2b54f0dbSXin Li struct cpuinfo_arm_linux_processor processor_i[restrict static 1],
257*2b54f0dbSXin Li struct cpuinfo_arm_linux_processor processor_j[restrict static 1])
258*2b54f0dbSXin Li {
259*2b54f0dbSXin Li const uint32_t joint_flags = processor_i->flags & processor_j->flags;
260*2b54f0dbSXin Li
261*2b54f0dbSXin Li if (joint_flags & CPUINFO_LINUX_FLAG_MAX_FREQUENCY) {
262*2b54f0dbSXin Li if (processor_i->max_frequency != processor_j->max_frequency) {
263*2b54f0dbSXin Li return true;
264*2b54f0dbSXin Li }
265*2b54f0dbSXin Li }
266*2b54f0dbSXin Li
267*2b54f0dbSXin Li if (joint_flags & CPUINFO_LINUX_FLAG_MIN_FREQUENCY) {
268*2b54f0dbSXin Li if (processor_i->min_frequency != processor_j->min_frequency) {
269*2b54f0dbSXin Li return true;
270*2b54f0dbSXin Li }
271*2b54f0dbSXin Li }
272*2b54f0dbSXin Li
273*2b54f0dbSXin Li if ((joint_flags & CPUINFO_ARM_LINUX_VALID_MIDR) == CPUINFO_ARM_LINUX_VALID_MIDR) {
274*2b54f0dbSXin Li if (processor_i->midr != processor_j->midr) {
275*2b54f0dbSXin Li return true;
276*2b54f0dbSXin Li }
277*2b54f0dbSXin Li }
278*2b54f0dbSXin Li
279*2b54f0dbSXin Li return false;
280*2b54f0dbSXin Li }
281*2b54f0dbSXin Li
282*2b54f0dbSXin Li CPUINFO_INTERNAL bool cpuinfo_arm_linux_parse_proc_cpuinfo(
283*2b54f0dbSXin Li char hardware[restrict static CPUINFO_HARDWARE_VALUE_MAX],
284*2b54f0dbSXin Li char revision[restrict static CPUINFO_REVISION_VALUE_MAX],
285*2b54f0dbSXin Li uint32_t max_processors_count,
286*2b54f0dbSXin Li struct cpuinfo_arm_linux_processor processors[restrict static max_processors_count]);
287*2b54f0dbSXin Li
288*2b54f0dbSXin Li #if CPUINFO_ARCH_ARM
289*2b54f0dbSXin Li CPUINFO_INTERNAL bool cpuinfo_arm_linux_hwcap_from_getauxval(
290*2b54f0dbSXin Li uint32_t hwcap[restrict static 1],
291*2b54f0dbSXin Li uint32_t hwcap2[restrict static 1]);
292*2b54f0dbSXin Li CPUINFO_INTERNAL bool cpuinfo_arm_linux_hwcap_from_procfs(
293*2b54f0dbSXin Li uint32_t hwcap[restrict static 1],
294*2b54f0dbSXin Li uint32_t hwcap2[restrict static 1]);
295*2b54f0dbSXin Li
296*2b54f0dbSXin Li CPUINFO_INTERNAL void cpuinfo_arm_linux_decode_isa_from_proc_cpuinfo(
297*2b54f0dbSXin Li uint32_t features,
298*2b54f0dbSXin Li uint32_t features2,
299*2b54f0dbSXin Li uint32_t midr,
300*2b54f0dbSXin Li uint32_t architecture_version,
301*2b54f0dbSXin Li uint32_t architecture_flags,
302*2b54f0dbSXin Li const struct cpuinfo_arm_chipset chipset[restrict static 1],
303*2b54f0dbSXin Li struct cpuinfo_arm_isa isa[restrict static 1]);
304*2b54f0dbSXin Li #elif CPUINFO_ARCH_ARM64
305*2b54f0dbSXin Li CPUINFO_INTERNAL void cpuinfo_arm_linux_hwcap_from_getauxval(
306*2b54f0dbSXin Li uint32_t hwcap[restrict static 1],
307*2b54f0dbSXin Li uint32_t hwcap2[restrict static 1]);
308*2b54f0dbSXin Li
309*2b54f0dbSXin Li CPUINFO_INTERNAL void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo(
310*2b54f0dbSXin Li uint32_t features,
311*2b54f0dbSXin Li uint32_t features2,
312*2b54f0dbSXin Li uint32_t midr,
313*2b54f0dbSXin Li const struct cpuinfo_arm_chipset chipset[restrict static 1],
314*2b54f0dbSXin Li struct cpuinfo_arm_isa isa[restrict static 1]);
315*2b54f0dbSXin Li #endif
316*2b54f0dbSXin Li
317*2b54f0dbSXin Li #ifdef __ANDROID__
318*2b54f0dbSXin Li CPUINFO_INTERNAL struct cpuinfo_arm_chipset
319*2b54f0dbSXin Li cpuinfo_arm_android_decode_chipset(
320*2b54f0dbSXin Li const struct cpuinfo_android_properties properties[restrict static 1],
321*2b54f0dbSXin Li uint32_t cores,
322*2b54f0dbSXin Li uint32_t max_cpu_freq_max);
323*2b54f0dbSXin Li #else
324*2b54f0dbSXin Li CPUINFO_INTERNAL struct cpuinfo_arm_chipset
325*2b54f0dbSXin Li cpuinfo_arm_linux_decode_chipset(
326*2b54f0dbSXin Li const char hardware[restrict static CPUINFO_HARDWARE_VALUE_MAX],
327*2b54f0dbSXin Li const char revision[restrict static CPUINFO_REVISION_VALUE_MAX],
328*2b54f0dbSXin Li uint32_t cores,
329*2b54f0dbSXin Li uint32_t max_cpu_freq_max);
330*2b54f0dbSXin Li #endif
331*2b54f0dbSXin Li
332*2b54f0dbSXin Li CPUINFO_INTERNAL struct cpuinfo_arm_chipset
333*2b54f0dbSXin Li cpuinfo_arm_linux_decode_chipset_from_proc_cpuinfo_hardware(
334*2b54f0dbSXin Li const char proc_cpuinfo_hardware[restrict static CPUINFO_HARDWARE_VALUE_MAX],
335*2b54f0dbSXin Li uint32_t cores, uint32_t max_cpu_freq_max, bool is_tegra);
336*2b54f0dbSXin Li
337*2b54f0dbSXin Li #ifdef __ANDROID__
338*2b54f0dbSXin Li CPUINFO_INTERNAL struct cpuinfo_arm_chipset
339*2b54f0dbSXin Li cpuinfo_arm_android_decode_chipset_from_ro_product_board(
340*2b54f0dbSXin Li const char ro_product_board[restrict static CPUINFO_BUILD_PROP_VALUE_MAX],
341*2b54f0dbSXin Li uint32_t cores, uint32_t max_cpu_freq_max);
342*2b54f0dbSXin Li CPUINFO_INTERNAL struct cpuinfo_arm_chipset
343*2b54f0dbSXin Li cpuinfo_arm_android_decode_chipset_from_ro_board_platform(
344*2b54f0dbSXin Li const char ro_board_platform[restrict static CPUINFO_BUILD_PROP_VALUE_MAX],
345*2b54f0dbSXin Li uint32_t cores, uint32_t max_cpu_freq_max);
346*2b54f0dbSXin Li CPUINFO_INTERNAL struct cpuinfo_arm_chipset
347*2b54f0dbSXin Li cpuinfo_arm_android_decode_chipset_from_ro_mediatek_platform(
348*2b54f0dbSXin Li const char ro_mediatek_platform[restrict static CPUINFO_BUILD_PROP_VALUE_MAX]);
349*2b54f0dbSXin Li CPUINFO_INTERNAL struct cpuinfo_arm_chipset
350*2b54f0dbSXin Li cpuinfo_arm_android_decode_chipset_from_ro_arch(
351*2b54f0dbSXin Li const char ro_arch[restrict static CPUINFO_BUILD_PROP_VALUE_MAX]);
352*2b54f0dbSXin Li CPUINFO_INTERNAL struct cpuinfo_arm_chipset
353*2b54f0dbSXin Li cpuinfo_arm_android_decode_chipset_from_ro_chipname(
354*2b54f0dbSXin Li const char ro_chipname[restrict static CPUINFO_BUILD_PROP_VALUE_MAX]);
355*2b54f0dbSXin Li CPUINFO_INTERNAL struct cpuinfo_arm_chipset
356*2b54f0dbSXin Li cpuinfo_arm_android_decode_chipset_from_ro_hardware_chipname(
357*2b54f0dbSXin Li const char ro_hardware_chipname[restrict static CPUINFO_BUILD_PROP_VALUE_MAX]);
358*2b54f0dbSXin Li #else
359*2b54f0dbSXin Li CPUINFO_INTERNAL struct cpuinfo_arm_chipset
360*2b54f0dbSXin Li cpuinfo_arm_linux_decode_chipset_from_proc_cpuinfo_revision(
361*2b54f0dbSXin Li const char proc_cpuinfo_revision[restrict static CPUINFO_REVISION_VALUE_MAX]);
362*2b54f0dbSXin Li #endif
363*2b54f0dbSXin Li
364*2b54f0dbSXin Li CPUINFO_INTERNAL bool cpuinfo_arm_linux_detect_core_clusters_by_heuristic(
365*2b54f0dbSXin Li uint32_t usable_processors,
366*2b54f0dbSXin Li uint32_t max_processors,
367*2b54f0dbSXin Li struct cpuinfo_arm_linux_processor processors[restrict static max_processors]);
368*2b54f0dbSXin Li
369*2b54f0dbSXin Li CPUINFO_INTERNAL void cpuinfo_arm_linux_detect_core_clusters_by_sequential_scan(
370*2b54f0dbSXin Li uint32_t max_processors,
371*2b54f0dbSXin Li struct cpuinfo_arm_linux_processor processors[restrict static max_processors]);
372*2b54f0dbSXin Li
373*2b54f0dbSXin Li CPUINFO_INTERNAL void cpuinfo_arm_linux_count_cluster_processors(
374*2b54f0dbSXin Li uint32_t max_processors,
375*2b54f0dbSXin Li struct cpuinfo_arm_linux_processor processors[restrict static max_processors]);
376*2b54f0dbSXin Li
377*2b54f0dbSXin Li CPUINFO_INTERNAL uint32_t cpuinfo_arm_linux_detect_cluster_midr(
378*2b54f0dbSXin Li const struct cpuinfo_arm_chipset chipset[restrict static 1],
379*2b54f0dbSXin Li uint32_t max_processors,
380*2b54f0dbSXin Li uint32_t usable_processors,
381*2b54f0dbSXin Li struct cpuinfo_arm_linux_processor processors[restrict static max_processors]);
382*2b54f0dbSXin Li
383*2b54f0dbSXin Li extern CPUINFO_INTERNAL const uint32_t* cpuinfo_linux_cpu_to_uarch_index_map;
384*2b54f0dbSXin Li extern CPUINFO_INTERNAL uint32_t cpuinfo_linux_cpu_to_uarch_index_map_entries;
385