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