diff options
-rw-r--r-- | android/android.make | 22 | ||||
-rw-r--r-- | android/cpufeatures/cpu-features.c | 385 | ||||
-rw-r--r-- | android/cpufeatures/cpu-features.h | 62 |
3 files changed, 460 insertions, 9 deletions
diff --git a/android/android.make b/android/android.make index 65463778dc..1a4c39ceb8 100644 --- a/android/android.make +++ b/android/android.make | |||
@@ -7,23 +7,26 @@ | |||
7 | # $Id$ | 7 | # $Id$ |
8 | # | 8 | # |
9 | 9 | ||
10 | PACKAGE=org.rockbox | ||
11 | PACKAGE_PATH=org/rockbox | ||
12 | BINLIB_DIR=$(BUILDDIR)/libs/armeabi | ||
13 | ANDROID_DIR=$(ROOTDIR)/android | ||
14 | |||
10 | # this is a glibc compatibility hack to provide a get_nprocs() replacement. | 15 | # this is a glibc compatibility hack to provide a get_nprocs() replacement. |
11 | # The NDK ships cpu-features.c which has a compatible function android_getCpuCount() | 16 | # The NDK ships cpu-features.c which has a compatible function android_getCpuCount() |
12 | CPUFEAT = $(ANDROID_NDK_PATH)/sources/android/cpufeatures | 17 | CPUFEAT = $(ANDROID_DIR)/cpufeatures |
18 | CPUFEAT_BUILD = $(subst $(ANDROID_DIR),$(BUILDDIR),$(CPUFEAT)) | ||
13 | INCLUDES += -I$(CPUFEAT) | 19 | INCLUDES += -I$(CPUFEAT) |
14 | OTHER_SRC += $(CPUFEAT)/cpu-features.c | 20 | OTHER_SRC += $(CPUFEAT)/cpu-features.c |
15 | $(BUILDDIR)/cpu-features.o: $(CPUFEAT)/cpu-features.c | 21 | CLEANOBJS += $(CPUFEAT_BUILD)/cpu-features.o |
16 | $(call PRINTS,CC $(subst $(ANDROID_NDK_PATH)/,,$<))$(CC) -o $@ -c $^ \ | 22 | $(CPUFEAT_BUILD)/cpu-features.o: $(CPUFEAT)/cpu-features.c |
17 | $(GCCOPTS) -Wno-unused | 23 | $(SILENT)mkdir -p $(dir $@) |
24 | $(call PRINTS,CC $(subst $(ROOTDIR)/,,$<))$(CC) -o $@ -c $^ $(GCCOPTS) -Wno-unused | ||
18 | 25 | ||
19 | .SECONDEXPANSION: # $$(JAVA_OBJ) is not populated until after this | 26 | .SECONDEXPANSION: # $$(JAVA_OBJ) is not populated until after this |
20 | .SECONDEXPANSION: # $$(OBJ) is not populated until after this | 27 | .SECONDEXPANSION: # $$(OBJ) is not populated until after this |
21 | .PHONY: apk classes clean dex dirs libs jar | 28 | .PHONY: apk classes clean dex dirs libs jar |
22 | 29 | ||
23 | PACKAGE=org.rockbox | ||
24 | PACKAGE_PATH=org/rockbox | ||
25 | ANDROID_DIR=$(ROOTDIR)/android | ||
26 | BINLIB_DIR=$(BUILDDIR)/libs/armeabi | ||
27 | 30 | ||
28 | java2class = $(addsuffix .class,$(basename $(subst $(ANDROID_DIR),$(BUILDDIR),$(1)))) | 31 | java2class = $(addsuffix .class,$(basename $(subst $(ANDROID_DIR),$(BUILDDIR),$(1)))) |
29 | 32 | ||
@@ -66,6 +69,7 @@ DIRS := $(subst ___,bin,$(_DIRS)) | |||
66 | DIRS += $(subst ___,gen,$(_DIRS)) | 69 | DIRS += $(subst ___,gen,$(_DIRS)) |
67 | DIRS += $(subst ___,data,$(_DIRS)) | 70 | DIRS += $(subst ___,data,$(_DIRS)) |
68 | DIRS += $(BUILDDIR)/libs/armeabi | 71 | DIRS += $(BUILDDIR)/libs/armeabi |
72 | DIRS += $(CPUFEAT_BUILD) | ||
69 | 73 | ||
70 | RES := $(wildcard $(ANDROID_DIR)/res/*/*) | 74 | RES := $(wildcard $(ANDROID_DIR)/res/*/*) |
71 | 75 | ||
@@ -110,7 +114,7 @@ dex: $(DEX) | |||
110 | classes: $(R_OBJ) $(JAVA_OBJ) | 114 | classes: $(R_OBJ) $(JAVA_OBJ) |
111 | 115 | ||
112 | 116 | ||
113 | $(BUILDDIR)/$(BINARY): $$(OBJ) $(VOICESPEEXLIB) $(FIRMLIB) $(SKINLIB) $(BUILDDIR)/cpu-features.o | 117 | $(BUILDDIR)/$(BINARY): $$(OBJ) $(VOICESPEEXLIB) $(FIRMLIB) $(SKINLIB) $(CPUFEAT_BUILD)/cpu-features.o |
114 | $(call PRINTS,LD $(BINARY))$(CC) -o $@ $^ $(LDOPTS) $(GLOBAL_LDOPTS) | 118 | $(call PRINTS,LD $(BINARY))$(CC) -o $@ $^ $(LDOPTS) $(GLOBAL_LDOPTS) |
115 | 119 | ||
116 | $(BINLIB_DIR)/$(BINARY): $(BUILDDIR)/$(BINARY) | 120 | $(BINLIB_DIR)/$(BINARY): $(BUILDDIR)/$(BINARY) |
diff --git a/android/cpufeatures/cpu-features.c b/android/cpufeatures/cpu-features.c new file mode 100644 index 0000000000..b027ea4b5c --- /dev/null +++ b/android/cpufeatures/cpu-features.c | |||
@@ -0,0 +1,385 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 The Android Open Source Project | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * * Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * * Redistributions in binary form must reproduce the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer in | ||
12 | * the documentation and/or other materials provided with the | ||
13 | * distribution. | ||
14 | * | ||
15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
19 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS | ||
22 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | ||
23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
25 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
26 | * SUCH DAMAGE. | ||
27 | */ | ||
28 | |||
29 | /* ChangeLog for this library: | ||
30 | * | ||
31 | * NDK r5: Handle buggy kernels which report a CPU Architecture number of 7 | ||
32 | * for an ARMv6 CPU (see below). | ||
33 | * | ||
34 | * Handle kernels that only report 'neon', and not 'vfpv3' | ||
35 | * (VFPv3 is mandated by the ARM architecture is Neon is implemented) | ||
36 | * | ||
37 | * Handle kernels that only report 'vfpv3d16', and not 'vfpv3' | ||
38 | * | ||
39 | * Fix x86 compilation. Report ANDROID_CPU_FAMILY_X86 in | ||
40 | * android_getCpuFamily(). | ||
41 | * | ||
42 | * NDK r4: Initial release | ||
43 | */ | ||
44 | #include <sys/system_properties.h> | ||
45 | #ifdef __arm__ | ||
46 | #include <machine/cpu-features.h> | ||
47 | #endif | ||
48 | #include <pthread.h> | ||
49 | #include "cpu-features.h" | ||
50 | #include <stdio.h> | ||
51 | #include <stdlib.h> | ||
52 | #include <fcntl.h> | ||
53 | #include <errno.h> | ||
54 | |||
55 | static pthread_once_t g_once; | ||
56 | static AndroidCpuFamily g_cpuFamily; | ||
57 | static uint64_t g_cpuFeatures; | ||
58 | static int g_cpuCount; | ||
59 | |||
60 | static const int android_cpufeatures_debug = 0; | ||
61 | |||
62 | #ifdef __arm__ | ||
63 | # define DEFAULT_CPU_FAMILY ANDROID_CPU_FAMILY_ARM | ||
64 | #elif defined __i386__ | ||
65 | # define DEFAULT_CPU_FAMILY ANDROID_CPU_FAMILY_X86 | ||
66 | #else | ||
67 | # define DEFAULT_CPU_FAMILY ANDROID_CPU_FAMILY_UNKNOWN | ||
68 | #endif | ||
69 | |||
70 | #define D(...) \ | ||
71 | do { \ | ||
72 | if (android_cpufeatures_debug) { \ | ||
73 | printf(__VA_ARGS__); fflush(stdout); \ | ||
74 | } \ | ||
75 | } while (0) | ||
76 | |||
77 | /* Read the content of /proc/cpuinfo into a user-provided buffer. | ||
78 | * Return the length of the data, or -1 on error. Does *not* | ||
79 | * zero-terminate the content. Will not read more | ||
80 | * than 'buffsize' bytes. | ||
81 | */ | ||
82 | static int | ||
83 | read_file(const char* pathname, char* buffer, size_t buffsize) | ||
84 | { | ||
85 | int fd, len; | ||
86 | |||
87 | fd = open(pathname, O_RDONLY); | ||
88 | if (fd < 0) | ||
89 | return -1; | ||
90 | |||
91 | do { | ||
92 | len = read(fd, buffer, buffsize); | ||
93 | } while (len < 0 && errno == EINTR); | ||
94 | |||
95 | close(fd); | ||
96 | |||
97 | return len; | ||
98 | } | ||
99 | |||
100 | /* Extract the content of a the first occurence of a given field in | ||
101 | * the content of /proc/cpuinfo and return it as a heap-allocated | ||
102 | * string that must be freed by the caller. | ||
103 | * | ||
104 | * Return NULL if not found | ||
105 | */ | ||
106 | static char* | ||
107 | extract_cpuinfo_field(char* buffer, int buflen, const char* field) | ||
108 | { | ||
109 | int fieldlen = strlen(field); | ||
110 | char* bufend = buffer + buflen; | ||
111 | char* result = NULL; | ||
112 | int len, ignore; | ||
113 | const char *p, *q; | ||
114 | |||
115 | /* Look for first field occurence, and ensures it starts the line. | ||
116 | */ | ||
117 | p = buffer; | ||
118 | bufend = buffer + buflen; | ||
119 | for (;;) { | ||
120 | p = memmem(p, bufend-p, field, fieldlen); | ||
121 | if (p == NULL) | ||
122 | goto EXIT; | ||
123 | |||
124 | if (p == buffer || p[-1] == '\n') | ||
125 | break; | ||
126 | |||
127 | p += fieldlen; | ||
128 | } | ||
129 | |||
130 | /* Skip to the first column followed by a space */ | ||
131 | p += fieldlen; | ||
132 | p = memchr(p, ':', bufend-p); | ||
133 | if (p == NULL || p[1] != ' ') | ||
134 | goto EXIT; | ||
135 | |||
136 | /* Find the end of the line */ | ||
137 | p += 2; | ||
138 | q = memchr(p, '\n', bufend-p); | ||
139 | if (q == NULL) | ||
140 | q = bufend; | ||
141 | |||
142 | /* Copy the line into a heap-allocated buffer */ | ||
143 | len = q-p; | ||
144 | result = malloc(len+1); | ||
145 | if (result == NULL) | ||
146 | goto EXIT; | ||
147 | |||
148 | memcpy(result, p, len); | ||
149 | result[len] = '\0'; | ||
150 | |||
151 | EXIT: | ||
152 | return result; | ||
153 | } | ||
154 | |||
155 | /* Count the number of occurences of a given field prefix in /proc/cpuinfo. | ||
156 | */ | ||
157 | static int | ||
158 | count_cpuinfo_field(char* buffer, int buflen, const char* field) | ||
159 | { | ||
160 | int fieldlen = strlen(field); | ||
161 | const char* p = buffer; | ||
162 | const char* bufend = buffer + buflen; | ||
163 | const char* q; | ||
164 | int count = 0; | ||
165 | |||
166 | for (;;) { | ||
167 | const char* q; | ||
168 | |||
169 | p = memmem(p, bufend-p, field, fieldlen); | ||
170 | if (p == NULL) | ||
171 | break; | ||
172 | |||
173 | /* Ensure that the field is at the start of a line */ | ||
174 | if (p > buffer && p[-1] != '\n') { | ||
175 | p += fieldlen; | ||
176 | continue; | ||
177 | } | ||
178 | |||
179 | |||
180 | /* skip any whitespace */ | ||
181 | q = p + fieldlen; | ||
182 | while (q < bufend && (*q == ' ' || *q == '\t')) | ||
183 | q++; | ||
184 | |||
185 | /* we must have a colon now */ | ||
186 | if (q < bufend && *q == ':') { | ||
187 | count += 1; | ||
188 | q ++; | ||
189 | } | ||
190 | p = q; | ||
191 | } | ||
192 | |||
193 | return count; | ||
194 | } | ||
195 | |||
196 | /* Like strlen(), but for constant string literals */ | ||
197 | #define STRLEN_CONST(x) ((sizeof(x)-1) | ||
198 | |||
199 | |||
200 | /* Checks that a space-separated list of items contains one given 'item'. | ||
201 | * Returns 1 if found, 0 otherwise. | ||
202 | */ | ||
203 | static int | ||
204 | has_list_item(const char* list, const char* item) | ||
205 | { | ||
206 | const char* p = list; | ||
207 | int itemlen = strlen(item); | ||
208 | |||
209 | if (list == NULL) | ||
210 | return 0; | ||
211 | |||
212 | while (*p) { | ||
213 | const char* q; | ||
214 | |||
215 | /* skip spaces */ | ||
216 | while (*p == ' ' || *p == '\t') | ||
217 | p++; | ||
218 | |||
219 | /* find end of current list item */ | ||
220 | q = p; | ||
221 | while (*q && *q != ' ' && *q != '\t') | ||
222 | q++; | ||
223 | |||
224 | if (itemlen == q-p && !memcmp(p, item, itemlen)) | ||
225 | return 1; | ||
226 | |||
227 | /* skip to next item */ | ||
228 | p = q; | ||
229 | } | ||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | |||
234 | static void | ||
235 | android_cpuInit(void) | ||
236 | { | ||
237 | char cpuinfo[4096]; | ||
238 | int cpuinfo_len; | ||
239 | |||
240 | g_cpuFamily = DEFAULT_CPU_FAMILY; | ||
241 | g_cpuFeatures = 0; | ||
242 | g_cpuCount = 1; | ||
243 | |||
244 | cpuinfo_len = read_file("/proc/cpuinfo", cpuinfo, sizeof cpuinfo); | ||
245 | D("cpuinfo_len is (%d):\n%.*s\n", cpuinfo_len, | ||
246 | cpuinfo_len >= 0 ? cpuinfo_len : 0, cpuinfo); | ||
247 | |||
248 | if (cpuinfo_len < 0) /* should not happen */ { | ||
249 | return; | ||
250 | } | ||
251 | |||
252 | /* Count the CPU cores, the value may be 0 for single-core CPUs */ | ||
253 | g_cpuCount = count_cpuinfo_field(cpuinfo, cpuinfo_len, "processor"); | ||
254 | if (g_cpuCount == 0) { | ||
255 | g_cpuCount = count_cpuinfo_field(cpuinfo, cpuinfo_len, "Processor"); | ||
256 | if (g_cpuCount == 0) { | ||
257 | g_cpuCount = 1; | ||
258 | } | ||
259 | } | ||
260 | |||
261 | D("found cpuCount = %d\n", g_cpuCount); | ||
262 | |||
263 | #ifdef __ARM_ARCH__ | ||
264 | { | ||
265 | char* features = NULL; | ||
266 | char* architecture = NULL; | ||
267 | |||
268 | /* Extract architecture from the "CPU Architecture" field. | ||
269 | * The list is well-known, unlike the the output of | ||
270 | * the 'Processor' field which can vary greatly. | ||
271 | * | ||
272 | * See the definition of the 'proc_arch' array in | ||
273 | * $KERNEL/arch/arm/kernel/setup.c and the 'c_show' function in | ||
274 | * same file. | ||
275 | */ | ||
276 | char* cpuArch = extract_cpuinfo_field(cpuinfo, cpuinfo_len, "CPU architecture"); | ||
277 | |||
278 | if (cpuArch != NULL) { | ||
279 | char* end; | ||
280 | long archNumber; | ||
281 | int hasARMv7 = 0; | ||
282 | |||
283 | D("found cpuArch = '%s'\n", cpuArch); | ||
284 | |||
285 | /* read the initial decimal number, ignore the rest */ | ||
286 | archNumber = strtol(cpuArch, &end, 10); | ||
287 | |||
288 | /* Here we assume that ARMv8 will be upwards compatible with v7 | ||
289 | * in the future. Unfortunately, there is no 'Features' field to | ||
290 | * indicate that Thumb-2 is supported. | ||
291 | */ | ||
292 | if (end > cpuArch && archNumber >= 7) { | ||
293 | hasARMv7 = 1; | ||
294 | } | ||
295 | |||
296 | /* Unfortunately, it seems that certain ARMv6-based CPUs | ||
297 | * report an incorrect architecture number of 7! | ||
298 | * | ||
299 | * See http://code.google.com/p/android/issues/detail?id=10812 | ||
300 | * | ||
301 | * We try to correct this by looking at the 'elf_format' | ||
302 | * field reported by the 'Processor' field, which is of the | ||
303 | * form of "(v7l)" for an ARMv7-based CPU, and "(v6l)" for | ||
304 | * an ARMv6-one. | ||
305 | */ | ||
306 | if (hasARMv7) { | ||
307 | char* cpuProc = extract_cpuinfo_field(cpuinfo, cpuinfo_len, | ||
308 | "Processor"); | ||
309 | if (cpuProc != NULL) { | ||
310 | D("found cpuProc = '%s'\n", cpuProc); | ||
311 | if (has_list_item(cpuProc, "(v6l)")) { | ||
312 | D("CPU processor and architecture mismatch!!\n"); | ||
313 | hasARMv7 = 0; | ||
314 | } | ||
315 | free(cpuProc); | ||
316 | } | ||
317 | } | ||
318 | |||
319 | if (hasARMv7) { | ||
320 | g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_ARMv7; | ||
321 | } | ||
322 | |||
323 | /* The LDREX / STREX instructions are available from ARMv6 */ | ||
324 | if (archNumber >= 6) { | ||
325 | g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_LDREX_STREX; | ||
326 | } | ||
327 | |||
328 | free(cpuArch); | ||
329 | } | ||
330 | |||
331 | /* Extract the list of CPU features from 'Features' field */ | ||
332 | char* cpuFeatures = extract_cpuinfo_field(cpuinfo, cpuinfo_len, "Features"); | ||
333 | |||
334 | if (cpuFeatures != NULL) { | ||
335 | |||
336 | D("found cpuFeatures = '%s'\n", cpuFeatures); | ||
337 | |||
338 | if (has_list_item(cpuFeatures, "vfpv3")) | ||
339 | g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFPv3; | ||
340 | |||
341 | else if (has_list_item(cpuFeatures, "vfpv3d16")) | ||
342 | g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_VFPv3; | ||
343 | |||
344 | if (has_list_item(cpuFeatures, "neon")) { | ||
345 | /* Note: Certain kernels only report neon but not vfpv3 | ||
346 | * in their features list. However, ARM mandates | ||
347 | * that if Neon is implemented, so must be VFPv3 | ||
348 | * so always set the flag. | ||
349 | */ | ||
350 | g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_NEON | | ||
351 | ANDROID_CPU_ARM_FEATURE_VFPv3; | ||
352 | } | ||
353 | free(cpuFeatures); | ||
354 | } | ||
355 | } | ||
356 | #endif /* __ARM_ARCH__ */ | ||
357 | |||
358 | #ifdef __i386__ | ||
359 | g_cpuFamily = ANDROID_CPU_FAMILY_X86; | ||
360 | #endif | ||
361 | } | ||
362 | |||
363 | |||
364 | AndroidCpuFamily | ||
365 | android_getCpuFamily(void) | ||
366 | { | ||
367 | pthread_once(&g_once, android_cpuInit); | ||
368 | return g_cpuFamily; | ||
369 | } | ||
370 | |||
371 | |||
372 | uint64_t | ||
373 | android_getCpuFeatures(void) | ||
374 | { | ||
375 | pthread_once(&g_once, android_cpuInit); | ||
376 | return g_cpuFeatures; | ||
377 | } | ||
378 | |||
379 | |||
380 | int | ||
381 | android_getCpuCount(void) | ||
382 | { | ||
383 | pthread_once(&g_once, android_cpuInit); | ||
384 | return g_cpuCount; | ||
385 | } | ||
diff --git a/android/cpufeatures/cpu-features.h b/android/cpufeatures/cpu-features.h new file mode 100644 index 0000000000..837c7c2278 --- /dev/null +++ b/android/cpufeatures/cpu-features.h | |||
@@ -0,0 +1,62 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 The Android Open Source Project | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions | ||
7 | * are met: | ||
8 | * * Redistributions of source code must retain the above copyright | ||
9 | * notice, this list of conditions and the following disclaimer. | ||
10 | * * Redistributions in binary form must reproduce the above copyright | ||
11 | * notice, this list of conditions and the following disclaimer in | ||
12 | * the documentation and/or other materials provided with the | ||
13 | * distribution. | ||
14 | * | ||
15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | ||
18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
19 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS | ||
22 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | ||
23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
25 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
26 | * SUCH DAMAGE. | ||
27 | */ | ||
28 | #ifndef CPU_FEATURES_H | ||
29 | #define CPU_FEATURES_H | ||
30 | |||
31 | #include <sys/cdefs.h> | ||
32 | #include <stdint.h> | ||
33 | |||
34 | __BEGIN_DECLS | ||
35 | |||
36 | typedef enum { | ||
37 | ANDROID_CPU_FAMILY_UNKNOWN = 0, | ||
38 | ANDROID_CPU_FAMILY_ARM, | ||
39 | ANDROID_CPU_FAMILY_X86, | ||
40 | |||
41 | ANDROID_CPU_FAMILY_MAX /* do not remove */ | ||
42 | |||
43 | } AndroidCpuFamily; | ||
44 | |||
45 | /* Return family of the device's CPU */ | ||
46 | extern AndroidCpuFamily android_getCpuFamily(void); | ||
47 | |||
48 | enum { | ||
49 | ANDROID_CPU_ARM_FEATURE_ARMv7 = (1 << 0), | ||
50 | ANDROID_CPU_ARM_FEATURE_VFPv3 = (1 << 1), | ||
51 | ANDROID_CPU_ARM_FEATURE_NEON = (1 << 2), | ||
52 | ANDROID_CPU_ARM_FEATURE_LDREX_STREX = (1 << 3), | ||
53 | }; | ||
54 | |||
55 | extern uint64_t android_getCpuFeatures(void); | ||
56 | |||
57 | /* Return the number of CPU cores detected on this device. */ | ||
58 | extern int android_getCpuCount(void); | ||
59 | |||
60 | __END_DECLS | ||
61 | |||
62 | #endif /* CPU_FEATURES_H */ | ||