--- /dev/null
+// Copyright 2017 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "cpuinfo_arm.h"
+#include "filesystem_for_testing.h"
+#include "hwcaps_for_testing.h"
+
+#include "gtest/gtest.h"
+
+namespace cpu_features {
+namespace {
+
+void DisableHardwareCapabilities() { SetHardwareCapabilities(0, 0); }
+
+TEST(CpuinfoArmTest, FromHardwareCap) {
+ SetHardwareCapabilities(ARM_HWCAP_NEON, ARM_HWCAP2_AES | ARM_HWCAP2_CRC32);
+ GetEmptyFilesystem(); // disabling /proc/cpuinfo
+ const auto info = GetArmInfo();
+ EXPECT_TRUE(info.features.vfp); // triggered by vfpv3
+ EXPECT_TRUE(info.features.vfpv3); // triggered by neon
+ EXPECT_TRUE(info.features.neon);
+ EXPECT_TRUE(info.features.aes);
+ EXPECT_TRUE(info.features.crc32);
+
+ EXPECT_FALSE(info.features.vfpv4);
+ EXPECT_FALSE(info.features.iwmmxt);
+ EXPECT_FALSE(info.features.vfpv3d16);
+ EXPECT_FALSE(info.features.idiva);
+ EXPECT_FALSE(info.features.idivt);
+ EXPECT_FALSE(info.features.pmull);
+ EXPECT_FALSE(info.features.sha1);
+ EXPECT_FALSE(info.features.sha2);
+}
+
+TEST(CpuinfoArmTest, ODroidFromCpuInfo) {
+ DisableHardwareCapabilities();
+ auto& fs = GetEmptyFilesystem();
+ fs.CreateFile("/proc/cpuinfo", R"(processor : 0
+model name : ARMv7 Processor rev 3 (v71)
+BogoMIPS : 120.00
+Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae
+CPU implementer : 0x41
+CPU architecture: 7
+CPU variant : 0x2
+CPU part : 0xc0f
+CPU revision : 3)");
+ const auto info = GetArmInfo();
+ EXPECT_EQ(info.implementer, 0x41);
+ EXPECT_EQ(info.variant, 0x2);
+ EXPECT_EQ(info.part, 0xc0f);
+ EXPECT_EQ(info.revision, 3);
+ EXPECT_EQ(info.architecture, 7);
+
+ EXPECT_TRUE(info.features.vfp);
+ EXPECT_FALSE(info.features.iwmmxt);
+ EXPECT_TRUE(info.features.neon);
+ EXPECT_TRUE(info.features.vfpv3);
+ EXPECT_FALSE(info.features.vfpv3d16);
+ EXPECT_TRUE(info.features.vfpv4);
+ EXPECT_TRUE(info.features.idiva);
+ EXPECT_TRUE(info.features.idivt);
+ EXPECT_FALSE(info.features.aes);
+ EXPECT_FALSE(info.features.pmull);
+ EXPECT_FALSE(info.features.sha1);
+ EXPECT_FALSE(info.features.sha2);
+ EXPECT_FALSE(info.features.crc32);
+}
+
+// http://code.google.com/p/android/issues/detail?id=10812
+TEST(CpuinfoArmTest, InvalidArmv7) {
+ DisableHardwareCapabilities();
+ auto& fs = GetEmptyFilesystem();
+ fs.CreateFile("/proc/cpuinfo",
+ R"(Processor : ARMv6-compatible processor rev 6 (v6l)
+BogoMIPS : 199.47
+Features : swp half thumb fastmult vfp edsp java
+CPU implementer : 0x41
+CPU architecture: 7
+CPU variant : 0x0
+CPU part : 0xb76
+CPU revision : 6
+
+Hardware : SPICA
+Revision : 0020
+Serial : 33323613546d00ec )");
+ const auto info = GetArmInfo();
+ EXPECT_EQ(info.architecture, 6);
+}
+
+// https://crbug.com/341598.
+TEST(CpuinfoArmTest, InvalidNeon) {
+ auto& fs = GetEmptyFilesystem();
+ fs.CreateFile("/proc/cpuinfo",
+ R"(Processor: ARMv7 Processory rev 0 (v71)
+processor: 0
+BogoMIPS: 13.50
+
+Processor: 1
+BogoMIPS: 13.50
+
+Features: swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt
+CPU implementer : 0x51
+CPU architecture: 7
+CPU variant: 0x1
+CPU part: 0x04d
+CPU revision: 0
+
+Hardware: SAMSUNG M2
+Revision: 0010
+Serial: 00001e030000354e)");
+ const auto info = GetArmInfo();
+ EXPECT_FALSE(info.features.neon);
+}
+
+// The Nexus 4 (Qualcomm Krait) kernel configuration forgets to report IDIV
+// support.
+TEST(CpuinfoArmTest, Nexus4_0x510006f2) {
+ DisableHardwareCapabilities();
+ auto& fs = GetEmptyFilesystem();
+ fs.CreateFile("/proc/cpuinfo",
+ R"(CPU implementer : 0x51
+CPU architecture: 7
+CPU variant : 0x0
+CPU part : 0x6f
+CPU revision : 2)");
+ const auto info = GetArmInfo();
+ EXPECT_TRUE(info.features.idiva);
+ EXPECT_TRUE(info.features.idivt);
+}
+
+// The Nexus 4 (Qualcomm Krait) kernel configuration forgets to report IDIV
+// support.
+TEST(CpuinfoArmTest, Nexus4_0x510006f3) {
+ DisableHardwareCapabilities();
+ auto& fs = GetEmptyFilesystem();
+ fs.CreateFile("/proc/cpuinfo",
+ R"(CPU implementer : 0x51
+CPU architecture: 7
+CPU variant : 0x0
+CPU part : 0x6f
+CPU revision : 3)");
+ const auto info = GetArmInfo();
+ EXPECT_TRUE(info.features.idiva);
+ EXPECT_TRUE(info.features.idivt);
+}
+
+// The emulator-specific Android 4.2 kernel fails to report support for the
+// 32-bit ARM IDIV instruction. Technically, this is a feature of the virtual
+// CPU implemented by the emulator.
+TEST(CpuinfoArmTest, EmulatorSpecificIdiv) {
+ DisableHardwareCapabilities();
+ auto& fs = GetEmptyFilesystem();
+ fs.CreateFile("/proc/cpuinfo",
+ R"(Processor : ARMv7 Processor rev 0 (v7l)
+BogoMIPS : 629.14
+Features : swp half thumb fastmult vfp edsp neon vfpv3
+CPU implementer : 0x41
+CPU architecture: 7
+CPU variant : 0x0
+CPU part : 0xc08
+CPU revision : 0
+
+Hardware : Goldfish
+Revision : 0000
+Serial : 0000000000000000)");
+ const auto info = GetArmInfo();
+ EXPECT_TRUE(info.features.idiva);
+}
+
+} // namespace
+} // namespace cpu_features