xref: /aosp_15_r20/external/cpuinfo/src/api.c (revision 2b54f0db79fd8303838913b20ff3780cddaa909f)
1*2b54f0dbSXin Li #include <stdbool.h>
2*2b54f0dbSXin Li #include <stddef.h>
3*2b54f0dbSXin Li 
4*2b54f0dbSXin Li #include <cpuinfo.h>
5*2b54f0dbSXin Li #include <cpuinfo/internal-api.h>
6*2b54f0dbSXin Li #include <cpuinfo/log.h>
7*2b54f0dbSXin Li 
8*2b54f0dbSXin Li #ifdef __linux__
9*2b54f0dbSXin Li 	#include <linux/api.h>
10*2b54f0dbSXin Li 
11*2b54f0dbSXin Li 	#include <unistd.h>
12*2b54f0dbSXin Li 	#include <sys/syscall.h>
13*2b54f0dbSXin Li 	#if !defined(__NR_getcpu)
14*2b54f0dbSXin Li 		#include <asm-generic/unistd.h>
15*2b54f0dbSXin Li 	#endif
16*2b54f0dbSXin Li #endif
17*2b54f0dbSXin Li 
18*2b54f0dbSXin Li bool cpuinfo_is_initialized = false;
19*2b54f0dbSXin Li 
20*2b54f0dbSXin Li struct cpuinfo_processor* cpuinfo_processors = NULL;
21*2b54f0dbSXin Li struct cpuinfo_core* cpuinfo_cores = NULL;
22*2b54f0dbSXin Li struct cpuinfo_cluster* cpuinfo_clusters = NULL;
23*2b54f0dbSXin Li struct cpuinfo_package* cpuinfo_packages = NULL;
24*2b54f0dbSXin Li struct cpuinfo_cache* cpuinfo_cache[cpuinfo_cache_level_max] = { NULL };
25*2b54f0dbSXin Li 
26*2b54f0dbSXin Li uint32_t cpuinfo_processors_count = 0;
27*2b54f0dbSXin Li uint32_t cpuinfo_cores_count = 0;
28*2b54f0dbSXin Li uint32_t cpuinfo_clusters_count = 0;
29*2b54f0dbSXin Li uint32_t cpuinfo_packages_count = 0;
30*2b54f0dbSXin Li uint32_t cpuinfo_cache_count[cpuinfo_cache_level_max] = { 0 };
31*2b54f0dbSXin Li uint32_t cpuinfo_max_cache_size = 0;
32*2b54f0dbSXin Li 
33*2b54f0dbSXin Li #if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
34*2b54f0dbSXin Li 	struct cpuinfo_uarch_info* cpuinfo_uarchs = NULL;
35*2b54f0dbSXin Li 	uint32_t cpuinfo_uarchs_count = 0;
36*2b54f0dbSXin Li #else
37*2b54f0dbSXin Li 	struct cpuinfo_uarch_info cpuinfo_global_uarch = { cpuinfo_uarch_unknown };
38*2b54f0dbSXin Li #endif
39*2b54f0dbSXin Li 
40*2b54f0dbSXin Li #ifdef __linux__
41*2b54f0dbSXin Li 	uint32_t cpuinfo_linux_cpu_max = 0;
42*2b54f0dbSXin Li 	const struct cpuinfo_processor** cpuinfo_linux_cpu_to_processor_map = NULL;
43*2b54f0dbSXin Li 	const struct cpuinfo_core** cpuinfo_linux_cpu_to_core_map = NULL;
44*2b54f0dbSXin Li 	#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
45*2b54f0dbSXin Li 		const uint32_t* cpuinfo_linux_cpu_to_uarch_index_map = NULL;
46*2b54f0dbSXin Li 	#endif
47*2b54f0dbSXin Li #endif
48*2b54f0dbSXin Li 
49*2b54f0dbSXin Li 
cpuinfo_get_processors(void)50*2b54f0dbSXin Li const struct cpuinfo_processor* cpuinfo_get_processors(void) {
51*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
52*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "processors");
53*2b54f0dbSXin Li 	}
54*2b54f0dbSXin Li 	return cpuinfo_processors;
55*2b54f0dbSXin Li }
56*2b54f0dbSXin Li 
cpuinfo_get_cores(void)57*2b54f0dbSXin Li const struct cpuinfo_core* cpuinfo_get_cores(void) {
58*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
59*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "core");
60*2b54f0dbSXin Li 	}
61*2b54f0dbSXin Li 	return cpuinfo_cores;
62*2b54f0dbSXin Li }
63*2b54f0dbSXin Li 
cpuinfo_get_clusters(void)64*2b54f0dbSXin Li const struct cpuinfo_cluster* cpuinfo_get_clusters(void) {
65*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
66*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "clusters");
67*2b54f0dbSXin Li 	}
68*2b54f0dbSXin Li 	return cpuinfo_clusters;
69*2b54f0dbSXin Li }
70*2b54f0dbSXin Li 
cpuinfo_get_packages(void)71*2b54f0dbSXin Li const struct cpuinfo_package* cpuinfo_get_packages(void) {
72*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
73*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "packages");
74*2b54f0dbSXin Li 	}
75*2b54f0dbSXin Li 	return cpuinfo_packages;
76*2b54f0dbSXin Li }
77*2b54f0dbSXin Li 
cpuinfo_get_uarchs()78*2b54f0dbSXin Li const struct cpuinfo_uarch_info* cpuinfo_get_uarchs() {
79*2b54f0dbSXin Li 	if (!cpuinfo_is_initialized) {
80*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "uarchs");
81*2b54f0dbSXin Li 	}
82*2b54f0dbSXin Li 	#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
83*2b54f0dbSXin Li 		return cpuinfo_uarchs;
84*2b54f0dbSXin Li 	#else
85*2b54f0dbSXin Li 		return &cpuinfo_global_uarch;
86*2b54f0dbSXin Li 	#endif
87*2b54f0dbSXin Li }
88*2b54f0dbSXin Li 
cpuinfo_get_processor(uint32_t index)89*2b54f0dbSXin Li const struct cpuinfo_processor* cpuinfo_get_processor(uint32_t index) {
90*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
91*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "processor");
92*2b54f0dbSXin Li 	}
93*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(index >= cpuinfo_processors_count) {
94*2b54f0dbSXin Li 		return NULL;
95*2b54f0dbSXin Li 	}
96*2b54f0dbSXin Li 	return &cpuinfo_processors[index];
97*2b54f0dbSXin Li }
98*2b54f0dbSXin Li 
cpuinfo_get_core(uint32_t index)99*2b54f0dbSXin Li const struct cpuinfo_core* cpuinfo_get_core(uint32_t index) {
100*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
101*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "core");
102*2b54f0dbSXin Li 	}
103*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(index >= cpuinfo_cores_count) {
104*2b54f0dbSXin Li 		return NULL;
105*2b54f0dbSXin Li 	}
106*2b54f0dbSXin Li 	return &cpuinfo_cores[index];
107*2b54f0dbSXin Li }
108*2b54f0dbSXin Li 
cpuinfo_get_cluster(uint32_t index)109*2b54f0dbSXin Li const struct cpuinfo_cluster* cpuinfo_get_cluster(uint32_t index) {
110*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
111*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "cluster");
112*2b54f0dbSXin Li 	}
113*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(index >= cpuinfo_clusters_count) {
114*2b54f0dbSXin Li 		return NULL;
115*2b54f0dbSXin Li 	}
116*2b54f0dbSXin Li 	return &cpuinfo_clusters[index];
117*2b54f0dbSXin Li }
118*2b54f0dbSXin Li 
cpuinfo_get_package(uint32_t index)119*2b54f0dbSXin Li const struct cpuinfo_package* cpuinfo_get_package(uint32_t index) {
120*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
121*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "package");
122*2b54f0dbSXin Li 	}
123*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(index >= cpuinfo_packages_count) {
124*2b54f0dbSXin Li 		return NULL;
125*2b54f0dbSXin Li 	}
126*2b54f0dbSXin Li 	return &cpuinfo_packages[index];
127*2b54f0dbSXin Li }
128*2b54f0dbSXin Li 
cpuinfo_get_uarch(uint32_t index)129*2b54f0dbSXin Li const struct cpuinfo_uarch_info* cpuinfo_get_uarch(uint32_t index) {
130*2b54f0dbSXin Li 	if (!cpuinfo_is_initialized) {
131*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "uarch");
132*2b54f0dbSXin Li 	}
133*2b54f0dbSXin Li 	#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
134*2b54f0dbSXin Li 		if CPUINFO_UNLIKELY(index >= cpuinfo_uarchs_count) {
135*2b54f0dbSXin Li 			return NULL;
136*2b54f0dbSXin Li 		}
137*2b54f0dbSXin Li 		return &cpuinfo_uarchs[index];
138*2b54f0dbSXin Li 	#else
139*2b54f0dbSXin Li 		if CPUINFO_UNLIKELY(index != 0) {
140*2b54f0dbSXin Li 			return NULL;
141*2b54f0dbSXin Li 		}
142*2b54f0dbSXin Li 		return &cpuinfo_global_uarch;
143*2b54f0dbSXin Li 	#endif
144*2b54f0dbSXin Li }
145*2b54f0dbSXin Li 
cpuinfo_get_processors_count(void)146*2b54f0dbSXin Li uint32_t cpuinfo_get_processors_count(void) {
147*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
148*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "processors_count");
149*2b54f0dbSXin Li 	}
150*2b54f0dbSXin Li 	return cpuinfo_processors_count;
151*2b54f0dbSXin Li }
152*2b54f0dbSXin Li 
cpuinfo_get_cores_count(void)153*2b54f0dbSXin Li uint32_t cpuinfo_get_cores_count(void) {
154*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
155*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "cores_count");
156*2b54f0dbSXin Li 	}
157*2b54f0dbSXin Li 	return cpuinfo_cores_count;
158*2b54f0dbSXin Li }
159*2b54f0dbSXin Li 
cpuinfo_get_clusters_count(void)160*2b54f0dbSXin Li uint32_t cpuinfo_get_clusters_count(void) {
161*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
162*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "clusters_count");
163*2b54f0dbSXin Li 	}
164*2b54f0dbSXin Li 	return cpuinfo_clusters_count;
165*2b54f0dbSXin Li }
166*2b54f0dbSXin Li 
cpuinfo_get_packages_count(void)167*2b54f0dbSXin Li uint32_t cpuinfo_get_packages_count(void) {
168*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
169*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "packages_count");
170*2b54f0dbSXin Li 	}
171*2b54f0dbSXin Li 	return cpuinfo_packages_count;
172*2b54f0dbSXin Li }
173*2b54f0dbSXin Li 
cpuinfo_get_uarchs_count(void)174*2b54f0dbSXin Li uint32_t cpuinfo_get_uarchs_count(void) {
175*2b54f0dbSXin Li 	if (!cpuinfo_is_initialized) {
176*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "uarchs_count");
177*2b54f0dbSXin Li 	}
178*2b54f0dbSXin Li 	#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
179*2b54f0dbSXin Li 		return cpuinfo_uarchs_count;
180*2b54f0dbSXin Li 	#else
181*2b54f0dbSXin Li 		return 1;
182*2b54f0dbSXin Li 	#endif
183*2b54f0dbSXin Li }
184*2b54f0dbSXin Li 
cpuinfo_get_l1i_caches(void)185*2b54f0dbSXin Li const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l1i_caches(void) {
186*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
187*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l1i_caches");
188*2b54f0dbSXin Li 	}
189*2b54f0dbSXin Li 	return cpuinfo_cache[cpuinfo_cache_level_1i];
190*2b54f0dbSXin Li }
191*2b54f0dbSXin Li 
cpuinfo_get_l1d_caches(void)192*2b54f0dbSXin Li const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l1d_caches(void) {
193*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
194*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l1d_caches");
195*2b54f0dbSXin Li 	}
196*2b54f0dbSXin Li 	return cpuinfo_cache[cpuinfo_cache_level_1d];
197*2b54f0dbSXin Li }
198*2b54f0dbSXin Li 
cpuinfo_get_l2_caches(void)199*2b54f0dbSXin Li const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l2_caches(void) {
200*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
201*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l2_caches");
202*2b54f0dbSXin Li 	}
203*2b54f0dbSXin Li 	return cpuinfo_cache[cpuinfo_cache_level_2];
204*2b54f0dbSXin Li }
205*2b54f0dbSXin Li 
cpuinfo_get_l3_caches(void)206*2b54f0dbSXin Li const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l3_caches(void) {
207*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
208*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l3_caches");
209*2b54f0dbSXin Li 	}
210*2b54f0dbSXin Li 	return cpuinfo_cache[cpuinfo_cache_level_3];
211*2b54f0dbSXin Li }
212*2b54f0dbSXin Li 
cpuinfo_get_l4_caches(void)213*2b54f0dbSXin Li const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l4_caches(void) {
214*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
215*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l4_caches");
216*2b54f0dbSXin Li 	}
217*2b54f0dbSXin Li 	return cpuinfo_cache[cpuinfo_cache_level_4];
218*2b54f0dbSXin Li }
219*2b54f0dbSXin Li 
cpuinfo_get_l1i_cache(uint32_t index)220*2b54f0dbSXin Li const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l1i_cache(uint32_t index) {
221*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
222*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l1i_cache");
223*2b54f0dbSXin Li 	}
224*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(index >= cpuinfo_cache_count[cpuinfo_cache_level_1i]) {
225*2b54f0dbSXin Li 		return NULL;
226*2b54f0dbSXin Li 	}
227*2b54f0dbSXin Li 	return &cpuinfo_cache[cpuinfo_cache_level_1i][index];
228*2b54f0dbSXin Li }
229*2b54f0dbSXin Li 
cpuinfo_get_l1d_cache(uint32_t index)230*2b54f0dbSXin Li const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l1d_cache(uint32_t index) {
231*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
232*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l1d_cache");
233*2b54f0dbSXin Li 	}
234*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(index >= cpuinfo_cache_count[cpuinfo_cache_level_1d]) {
235*2b54f0dbSXin Li 		return NULL;
236*2b54f0dbSXin Li 	}
237*2b54f0dbSXin Li 	return &cpuinfo_cache[cpuinfo_cache_level_1d][index];
238*2b54f0dbSXin Li }
239*2b54f0dbSXin Li 
cpuinfo_get_l2_cache(uint32_t index)240*2b54f0dbSXin Li const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l2_cache(uint32_t index) {
241*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
242*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l2_cache");
243*2b54f0dbSXin Li 	}
244*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(index >= cpuinfo_cache_count[cpuinfo_cache_level_2]) {
245*2b54f0dbSXin Li 		return NULL;
246*2b54f0dbSXin Li 	}
247*2b54f0dbSXin Li 	return &cpuinfo_cache[cpuinfo_cache_level_2][index];
248*2b54f0dbSXin Li }
249*2b54f0dbSXin Li 
cpuinfo_get_l3_cache(uint32_t index)250*2b54f0dbSXin Li const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l3_cache(uint32_t index) {
251*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
252*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l3_cache");
253*2b54f0dbSXin Li 	}
254*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(index >= cpuinfo_cache_count[cpuinfo_cache_level_3]) {
255*2b54f0dbSXin Li 		return NULL;
256*2b54f0dbSXin Li 	}
257*2b54f0dbSXin Li 	return &cpuinfo_cache[cpuinfo_cache_level_3][index];
258*2b54f0dbSXin Li }
259*2b54f0dbSXin Li 
cpuinfo_get_l4_cache(uint32_t index)260*2b54f0dbSXin Li const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l4_cache(uint32_t index) {
261*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
262*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l4_cache");
263*2b54f0dbSXin Li 	}
264*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(index >= cpuinfo_cache_count[cpuinfo_cache_level_4]) {
265*2b54f0dbSXin Li 		return NULL;
266*2b54f0dbSXin Li 	}
267*2b54f0dbSXin Li 	return &cpuinfo_cache[cpuinfo_cache_level_4][index];
268*2b54f0dbSXin Li }
269*2b54f0dbSXin Li 
cpuinfo_get_l1i_caches_count(void)270*2b54f0dbSXin Li uint32_t CPUINFO_ABI cpuinfo_get_l1i_caches_count(void) {
271*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
272*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l1i_caches_count");
273*2b54f0dbSXin Li 	}
274*2b54f0dbSXin Li 	return cpuinfo_cache_count[cpuinfo_cache_level_1i];
275*2b54f0dbSXin Li }
276*2b54f0dbSXin Li 
cpuinfo_get_l1d_caches_count(void)277*2b54f0dbSXin Li uint32_t CPUINFO_ABI cpuinfo_get_l1d_caches_count(void) {
278*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
279*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l1d_caches_count");
280*2b54f0dbSXin Li 	}
281*2b54f0dbSXin Li 	return cpuinfo_cache_count[cpuinfo_cache_level_1d];
282*2b54f0dbSXin Li }
283*2b54f0dbSXin Li 
cpuinfo_get_l2_caches_count(void)284*2b54f0dbSXin Li uint32_t CPUINFO_ABI cpuinfo_get_l2_caches_count(void) {
285*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
286*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l2_caches_count");
287*2b54f0dbSXin Li 	}
288*2b54f0dbSXin Li 	return cpuinfo_cache_count[cpuinfo_cache_level_2];
289*2b54f0dbSXin Li }
290*2b54f0dbSXin Li 
cpuinfo_get_l3_caches_count(void)291*2b54f0dbSXin Li uint32_t CPUINFO_ABI cpuinfo_get_l3_caches_count(void) {
292*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
293*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l3_caches_count");
294*2b54f0dbSXin Li 	}
295*2b54f0dbSXin Li 	return cpuinfo_cache_count[cpuinfo_cache_level_3];
296*2b54f0dbSXin Li }
297*2b54f0dbSXin Li 
cpuinfo_get_l4_caches_count(void)298*2b54f0dbSXin Li uint32_t CPUINFO_ABI cpuinfo_get_l4_caches_count(void) {
299*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
300*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l4_caches_count");
301*2b54f0dbSXin Li 	}
302*2b54f0dbSXin Li 	return cpuinfo_cache_count[cpuinfo_cache_level_4];
303*2b54f0dbSXin Li }
304*2b54f0dbSXin Li 
cpuinfo_get_max_cache_size(void)305*2b54f0dbSXin Li uint32_t CPUINFO_ABI cpuinfo_get_max_cache_size(void) {
306*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
307*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "max_cache_size");
308*2b54f0dbSXin Li 	}
309*2b54f0dbSXin Li 	return cpuinfo_max_cache_size;
310*2b54f0dbSXin Li }
311*2b54f0dbSXin Li 
cpuinfo_get_current_processor(void)312*2b54f0dbSXin Li const struct cpuinfo_processor* CPUINFO_ABI cpuinfo_get_current_processor(void) {
313*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
314*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "current_processor");
315*2b54f0dbSXin Li 	}
316*2b54f0dbSXin Li 	#ifdef __linux__
317*2b54f0dbSXin Li 		/* Initializing this variable silences a MemorySanitizer error. */
318*2b54f0dbSXin Li 		unsigned cpu = 0;
319*2b54f0dbSXin Li 		if CPUINFO_UNLIKELY(syscall(__NR_getcpu, &cpu, NULL, NULL) != 0) {
320*2b54f0dbSXin Li 			return 0;
321*2b54f0dbSXin Li 		}
322*2b54f0dbSXin Li 		if CPUINFO_UNLIKELY((uint32_t) cpu >= cpuinfo_linux_cpu_max) {
323*2b54f0dbSXin Li 			return 0;
324*2b54f0dbSXin Li 		}
325*2b54f0dbSXin Li 		return cpuinfo_linux_cpu_to_processor_map[cpu];
326*2b54f0dbSXin Li 	#else
327*2b54f0dbSXin Li 		return NULL;
328*2b54f0dbSXin Li 	#endif
329*2b54f0dbSXin Li }
330*2b54f0dbSXin Li 
cpuinfo_get_current_core(void)331*2b54f0dbSXin Li const struct cpuinfo_core* CPUINFO_ABI cpuinfo_get_current_core(void) {
332*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
333*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "current_core");
334*2b54f0dbSXin Li 	}
335*2b54f0dbSXin Li 	#ifdef __linux__
336*2b54f0dbSXin Li 		/* Initializing this variable silences a MemorySanitizer error. */
337*2b54f0dbSXin Li 		unsigned cpu = 0;
338*2b54f0dbSXin Li 		if CPUINFO_UNLIKELY(syscall(__NR_getcpu, &cpu, NULL, NULL) != 0) {
339*2b54f0dbSXin Li 			return 0;
340*2b54f0dbSXin Li 		}
341*2b54f0dbSXin Li 		if CPUINFO_UNLIKELY((uint32_t) cpu >= cpuinfo_linux_cpu_max) {
342*2b54f0dbSXin Li 			return 0;
343*2b54f0dbSXin Li 		}
344*2b54f0dbSXin Li 		return cpuinfo_linux_cpu_to_core_map[cpu];
345*2b54f0dbSXin Li 	#else
346*2b54f0dbSXin Li 		return NULL;
347*2b54f0dbSXin Li 	#endif
348*2b54f0dbSXin Li }
349*2b54f0dbSXin Li 
cpuinfo_get_current_uarch_index(void)350*2b54f0dbSXin Li uint32_t CPUINFO_ABI cpuinfo_get_current_uarch_index(void) {
351*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
352*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "current_uarch_index");
353*2b54f0dbSXin Li 	}
354*2b54f0dbSXin Li 	#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
355*2b54f0dbSXin Li 		#ifdef __linux__
356*2b54f0dbSXin Li 			if (cpuinfo_linux_cpu_to_uarch_index_map == NULL) {
357*2b54f0dbSXin Li 				/* Special case: avoid syscall on systems with only a single type of cores */
358*2b54f0dbSXin Li 				return 0;
359*2b54f0dbSXin Li 			}
360*2b54f0dbSXin Li 
361*2b54f0dbSXin Li 			/* General case */
362*2b54f0dbSXin Li 			/* Initializing this variable silences a MemorySanitizer error. */
363*2b54f0dbSXin Li 			unsigned cpu = 0;
364*2b54f0dbSXin Li 			if CPUINFO_UNLIKELY(syscall(__NR_getcpu, &cpu, NULL, NULL) != 0) {
365*2b54f0dbSXin Li 				return 0;
366*2b54f0dbSXin Li 			}
367*2b54f0dbSXin Li 			if CPUINFO_UNLIKELY((uint32_t) cpu >= cpuinfo_linux_cpu_max) {
368*2b54f0dbSXin Li 				return 0;
369*2b54f0dbSXin Li 			}
370*2b54f0dbSXin Li 			return cpuinfo_linux_cpu_to_uarch_index_map[cpu];
371*2b54f0dbSXin Li 		#else
372*2b54f0dbSXin Li 			/* Fallback: pretend to be on the big core. */
373*2b54f0dbSXin Li 			return 0;
374*2b54f0dbSXin Li 		#endif
375*2b54f0dbSXin Li 	#else
376*2b54f0dbSXin Li 		/* Only ARM/ARM64 processors may include cores of different types in the same package. */
377*2b54f0dbSXin Li 		return 0;
378*2b54f0dbSXin Li 	#endif
379*2b54f0dbSXin Li }
380*2b54f0dbSXin Li 
cpuinfo_get_current_uarch_index_with_default(uint32_t default_uarch_index)381*2b54f0dbSXin Li uint32_t CPUINFO_ABI cpuinfo_get_current_uarch_index_with_default(uint32_t default_uarch_index) {
382*2b54f0dbSXin Li 	if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
383*2b54f0dbSXin Li 		cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "current_uarch_index_with_default");
384*2b54f0dbSXin Li 	}
385*2b54f0dbSXin Li 	#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
386*2b54f0dbSXin Li 		#ifdef __linux__
387*2b54f0dbSXin Li 			if (cpuinfo_linux_cpu_to_uarch_index_map == NULL) {
388*2b54f0dbSXin Li 				/* Special case: avoid syscall on systems with only a single type of cores */
389*2b54f0dbSXin Li 				return 0;
390*2b54f0dbSXin Li 			}
391*2b54f0dbSXin Li 
392*2b54f0dbSXin Li 			/* General case */
393*2b54f0dbSXin Li 			/* Initializing this variable silences a MemorySanitizer error. */
394*2b54f0dbSXin Li 			unsigned cpu = 0;
395*2b54f0dbSXin Li 			if CPUINFO_UNLIKELY(syscall(__NR_getcpu, &cpu, NULL, NULL) != 0) {
396*2b54f0dbSXin Li 				return default_uarch_index;
397*2b54f0dbSXin Li 			}
398*2b54f0dbSXin Li 			if CPUINFO_UNLIKELY((uint32_t) cpu >= cpuinfo_linux_cpu_max) {
399*2b54f0dbSXin Li 				return default_uarch_index;
400*2b54f0dbSXin Li 			}
401*2b54f0dbSXin Li 			return cpuinfo_linux_cpu_to_uarch_index_map[cpu];
402*2b54f0dbSXin Li 		#else
403*2b54f0dbSXin Li 			/* Fallback: no API to query current core, use default uarch index. */
404*2b54f0dbSXin Li 			return default_uarch_index;
405*2b54f0dbSXin Li 		#endif
406*2b54f0dbSXin Li 	#else
407*2b54f0dbSXin Li 		/* Only ARM/ARM64 processors may include cores of different types in the same package. */
408*2b54f0dbSXin Li 		return 0;
409*2b54f0dbSXin Li 	#endif
410*2b54f0dbSXin Li }
411