1 /*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <jni.h>
18 #include <sys/auxv.h>
19 #include <sys/syscall.h>
20 #include <sys/system_properties.h>
21 #include <sys/utsname.h>
22 #include <sys/hwprobe.h>
23
24 #include "android-base/macros.h"
25
android_cts_CpuFeatures_isArmCpu(JNIEnv * env,jobject thiz)26 jboolean android_cts_CpuFeatures_isArmCpu(JNIEnv* env, jobject thiz)
27 {
28 #if defined(__arm__)
29 return JNI_TRUE;
30 #else
31 return JNI_FALSE;
32 #endif
33 }
34
android_cts_CpuFeatures_isX86Cpu(JNIEnv * env,jobject thiz)35 jboolean android_cts_CpuFeatures_isX86Cpu(JNIEnv* env, jobject thiz)
36 {
37 #if defined(__i386__)
38 return JNI_TRUE;
39 #else
40 return JNI_FALSE;
41 #endif
42 }
43
android_cts_CpuFeatures_isArm64Cpu(JNIEnv * env,jobject thiz)44 jboolean android_cts_CpuFeatures_isArm64Cpu(JNIEnv* env, jobject thiz)
45 {
46 #if defined(__aarch64__)
47 return JNI_TRUE;
48 #else
49 return JNI_FALSE;
50 #endif
51 }
52
android_cts_CpuFeatures_isRiscv64Cpu(JNIEnv * env,jobject thiz)53 jboolean android_cts_CpuFeatures_isRiscv64Cpu(JNIEnv* env, jobject thiz)
54 {
55 #if defined(__riscv)
56 return JNI_TRUE;
57 #else
58 return JNI_FALSE;
59 #endif
60 }
61
android_cts_CpuFeatures_isX86_64Cpu(JNIEnv * env,jobject thiz)62 jboolean android_cts_CpuFeatures_isX86_64Cpu(JNIEnv* env, jobject thiz)
63 {
64 #if defined(__x86_64__)
65 return JNI_TRUE;
66 #else
67 return JNI_FALSE;
68 #endif
69 }
70
android_cts_CpuFeatures_getHwCaps(JNIEnv *,jobject)71 jint android_cts_CpuFeatures_getHwCaps(JNIEnv*, jobject)
72 {
73 return (jint)getauxval(AT_HWCAP);
74 }
75
android_cts_CpuFeatures_isNativeBridgedCpu(JNIEnv * env,jobject thiz)76 jboolean android_cts_CpuFeatures_isNativeBridgedCpu(JNIEnv* env, jobject thiz)
77 {
78 #if defined(__BIONIC__)
79 return __system_property_find("ro.dalvik.vm.isa." ABI_STRING) != nullptr;
80 #else
81
82 return false;
83
84 #endif
85 }
86
android_cts_CpuFeatures_isRiscv64MisalignedFast(JNIEnv * env,jobject thiz)87 jboolean android_cts_CpuFeatures_isRiscv64MisalignedFast(JNIEnv* env, jobject thiz) {
88 #if defined(__riscv)
89 // https://github.com/torvalds/linux/blob/master/arch/riscv/include/uapi/asm/hwprobe.h
90 riscv_hwprobe probes[] = {{.key = RISCV_HWPROBE_KEY_CPUPERF_0}};
91 __riscv_hwprobe(probes, 1, 0, nullptr, 0);
92 if ((probes[0].value & RISCV_HWPROBE_MISALIGNED_MASK) == RISCV_HWPROBE_MISALIGNED_FAST) {
93 return true;
94 }
95 #endif
96 return false;
97 }
98
99 static JNINativeMethod gMethods[] = {
100 { "isArmCpu", "()Z",
101 (void *) android_cts_CpuFeatures_isArmCpu },
102 { "isX86Cpu", "()Z",
103 (void *) android_cts_CpuFeatures_isX86Cpu },
104 { "isArm64Cpu", "()Z",
105 (void *) android_cts_CpuFeatures_isArm64Cpu },
106 { "isRiscv64Cpu", "()Z",
107 (void *) android_cts_CpuFeatures_isRiscv64Cpu },
108 { "isX86_64Cpu", "()Z",
109 (void *) android_cts_CpuFeatures_isX86_64Cpu },
110 { "getHwCaps", "()I",
111 (void *) android_cts_CpuFeatures_getHwCaps },
112 { "isRiscv64MisalignedFast", "()Z",
113 (void *) android_cts_CpuFeatures_isRiscv64MisalignedFast },
114 { "isNativeBridgedCpu", "()Z",
115 (void *) android_cts_CpuFeatures_isNativeBridgedCpu },
116 };
117
register_android_cts_CpuFeatures(JNIEnv * env)118 int register_android_cts_CpuFeatures(JNIEnv* env)
119 {
120 jclass clazz = env->FindClass("com/android/compatibility/common/util/CpuFeatures");
121
122 return env->RegisterNatives(clazz, gMethods,
123 sizeof(gMethods) / sizeof(JNINativeMethod));
124 }
125