diff options
| -rw-r--r-- | runtime/arch/arm64/instruction_set_features_arm64.cc | 30 | ||||
| -rw-r--r-- | runtime/arch/arm64/instruction_set_features_arm64.h | 4 | ||||
| -rw-r--r-- | runtime/arch/instruction_set_features_test.cc | 57 |
3 files changed, 58 insertions, 33 deletions
diff --git a/runtime/arch/arm64/instruction_set_features_arm64.cc b/runtime/arch/arm64/instruction_set_features_arm64.cc index 696dd94e58..5bc943c93f 100644 --- a/runtime/arch/arm64/instruction_set_features_arm64.cc +++ b/runtime/arch/arm64/instruction_set_features_arm64.cc @@ -26,15 +26,29 @@ namespace art { const Arm64InstructionSetFeatures* Arm64InstructionSetFeatures::FromVariant( const std::string& variant ATTRIBUTE_UNUSED, std::string* error_msg ATTRIBUTE_UNUSED) { - if (variant != "default" && variant != "generic") { - std::ostringstream os; - os << "Unexpected CPU variant for Arm64: " << variant; - *error_msg = os.str(); - return nullptr; - } const bool smp = true; // Conservative default. - const bool is_a53 = true; // Pessimistically assume all ARM64s are A53s. - return new Arm64InstructionSetFeatures(smp, is_a53); + + // Look for variants that need a fix for a53 erratum 835769. + static const char* arm64_variants_with_a53_835769_bug[] = { + "default", "generic" // Pessimistically assume all generic ARM64s are A53s. + }; + bool needs_a53_835769_fix = FindVariantInArray(arm64_variants_with_a53_835769_bug, + arraysize(arm64_variants_with_a53_835769_bug), + variant); + + if (!needs_a53_835769_fix) { + // Check to see if this is an expected variant. + static const char* arm64_known_variants[] = { + "denver64" + }; + if (!FindVariantInArray(arm64_known_variants, arraysize(arm64_known_variants), variant)) { + std::ostringstream os; + os << "Unexpected CPU variant for Arm64: " << variant; + *error_msg = os.str(); + return nullptr; + } + } + return new Arm64InstructionSetFeatures(smp, needs_a53_835769_fix); } const Arm64InstructionSetFeatures* Arm64InstructionSetFeatures::FromBitmap(uint32_t bitmap) { diff --git a/runtime/arch/arm64/instruction_set_features_arm64.h b/runtime/arch/arm64/instruction_set_features_arm64.h index ee41536449..b0c66b3272 100644 --- a/runtime/arch/arm64/instruction_set_features_arm64.h +++ b/runtime/arch/arm64/instruction_set_features_arm64.h @@ -70,8 +70,8 @@ class Arm64InstructionSetFeatures FINAL : public InstructionSetFeatures { std::string* error_msg) const OVERRIDE; private: - explicit Arm64InstructionSetFeatures(bool smp, bool is_a53) - : InstructionSetFeatures(smp), fix_cortex_a53_835769_(is_a53) { + explicit Arm64InstructionSetFeatures(bool smp, bool needs_a53_835769_fix) + : InstructionSetFeatures(smp), fix_cortex_a53_835769_(needs_a53_835769_fix) { } // Bitmap positions for encoding features as a bitmap. diff --git a/runtime/arch/instruction_set_features_test.cc b/runtime/arch/instruction_set_features_test.cc index 83571cf2b1..e6f4e7ab01 100644 --- a/runtime/arch/instruction_set_features_test.cc +++ b/runtime/arch/instruction_set_features_test.cc @@ -27,12 +27,17 @@ namespace art { #ifdef HAVE_ANDROID_OS +#if defined(__aarch64__) +TEST(InstructionSetFeaturesTest, DISABLED_FeaturesFromSystemPropertyVariant) { + LOG(WARNING) << "Test disabled due to no CPP define for A53 erratum 835769"; +#else TEST(InstructionSetFeaturesTest, FeaturesFromSystemPropertyVariant) { +#endif // Take the default set of instruction features from the build. std::unique_ptr<const InstructionSetFeatures> instruction_set_features( InstructionSetFeatures::FromCppDefines()); - // Read the features property. + // Read the variant property. std::string key = StringPrintf("dalvik.vm.isa.%s.variant", GetInstructionSetString(kRuntimeISA)); char dex2oat_isa_variant[PROPERTY_VALUE_MAX]; if (property_get(key.c_str(), dex2oat_isa_variant, nullptr) > 0) { @@ -49,29 +54,41 @@ TEST(InstructionSetFeaturesTest, FeaturesFromSystemPropertyVariant) { } } +#if defined(__aarch64__) +TEST(InstructionSetFeaturesTest, DISABLED_FeaturesFromSystemPropertyString) { + LOG(WARNING) << "Test disabled due to no CPP define for A53 erratum 835769"; +#else TEST(InstructionSetFeaturesTest, FeaturesFromSystemPropertyString) { +#endif // Take the default set of instruction features from the build. std::unique_ptr<const InstructionSetFeatures> instruction_set_features( InstructionSetFeatures::FromCppDefines()); - // Read the features property. - std::string key = StringPrintf("dalvik.vm.isa.%s.features", GetInstructionSetString(kRuntimeISA)); - char dex2oat_isa_features[PROPERTY_VALUE_MAX]; - if (property_get(key.c_str(), dex2oat_isa_features, nullptr) > 0) { - // Use features from property to build InstructionSetFeatures and check against build's - // features. - std::string error_msg; - std::unique_ptr<const InstructionSetFeatures> base_features( - InstructionSetFeatures::FromVariant(kRuntimeISA, "default", &error_msg)); - ASSERT_TRUE(base_features.get() != nullptr) << error_msg; - - std::unique_ptr<const InstructionSetFeatures> property_features( - base_features->AddFeaturesFromString(dex2oat_isa_features, &error_msg)); - ASSERT_TRUE(property_features.get() != nullptr) << error_msg; - - EXPECT_TRUE(property_features->Equals(instruction_set_features.get())) + // Read the variant property. + std::string variant_key = StringPrintf("dalvik.vm.isa.%s.variant", + GetInstructionSetString(kRuntimeISA)); + char dex2oat_isa_variant[PROPERTY_VALUE_MAX]; + if (property_get(variant_key.c_str(), dex2oat_isa_variant, nullptr) > 0) { + // Read the features property. + std::string features_key = StringPrintf("dalvik.vm.isa.%s.features", + GetInstructionSetString(kRuntimeISA)); + char dex2oat_isa_features[PROPERTY_VALUE_MAX]; + if (property_get(features_key.c_str(), dex2oat_isa_features, nullptr) > 0) { + // Use features from property to build InstructionSetFeatures and check against build's + // features. + std::string error_msg; + std::unique_ptr<const InstructionSetFeatures> base_features( + InstructionSetFeatures::FromVariant(kRuntimeISA, dex2oat_isa_variant, &error_msg)); + ASSERT_TRUE(base_features.get() != nullptr) << error_msg; + + std::unique_ptr<const InstructionSetFeatures> property_features( + base_features->AddFeaturesFromString(dex2oat_isa_features, &error_msg)); + ASSERT_TRUE(property_features.get() != nullptr) << error_msg; + + EXPECT_TRUE(property_features->Equals(instruction_set_features.get())) << "System property features: " << *property_features.get() << "\nFeatures from build: " << *instruction_set_features.get(); + } } } @@ -127,13 +144,7 @@ TEST(InstructionSetFeaturesTest, FeaturesFromHwcap) { << "\nFeatures from build: " << *instruction_set_features.get(); } - -#if defined(__arm__) -TEST(InstructionSetFeaturesTest, DISABLED_FeaturesFromAssembly) { - LOG(WARNING) << "Test disabled due to buggy ARM kernels"; -#else TEST(InstructionSetFeaturesTest, FeaturesFromAssembly) { -#endif // Take the default set of instruction features from the build. std::unique_ptr<const InstructionSetFeatures> instruction_set_features( InstructionSetFeatures::FromCppDefines()); |