blob: 613bb5c7654952c4b1b9ea9c9f40b85dd997ccc2 [file] [log] [blame]
Ian Rogersd582fa42014-11-05 23:46:43 -08001/*
2 * Copyright (C) 2014 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 "instruction_set_features_arm64.h"
18
19#include <fstream>
20#include <sstream>
21
22#include "base/stringprintf.h"
23#include "utils.h" // For Trim.
24
25namespace art {
26
27const Arm64InstructionSetFeatures* Arm64InstructionSetFeatures::FromVariant(
Andreas Gampeca714582015-04-03 19:41:34 -070028 const std::string& variant, std::string* error_msg) {
Ian Rogersd582fa42014-11-05 23:46:43 -080029 const bool smp = true; // Conservative default.
Ian Rogersd9df6702014-11-17 16:43:15 -080030
31 // Look for variants that need a fix for a53 erratum 835769.
32 static const char* arm64_variants_with_a53_835769_bug[] = {
Tim Murray00fd8c22015-06-11 17:09:18 -070033 "default", "generic", "cortex-a53" // Pessimistically assume all generic ARM64s are A53s.
Ian Rogersd9df6702014-11-17 16:43:15 -080034 };
35 bool needs_a53_835769_fix = FindVariantInArray(arm64_variants_with_a53_835769_bug,
36 arraysize(arm64_variants_with_a53_835769_bug),
37 variant);
38
39 if (!needs_a53_835769_fix) {
40 // Check to see if this is an expected variant.
41 static const char* arm64_known_variants[] = {
Ajay Dudani74974ab2015-11-12 14:28:58 -080042 "denver64", "kryo"
Ian Rogersd9df6702014-11-17 16:43:15 -080043 };
44 if (!FindVariantInArray(arm64_known_variants, arraysize(arm64_known_variants), variant)) {
45 std::ostringstream os;
46 os << "Unexpected CPU variant for Arm64: " << variant;
47 *error_msg = os.str();
48 return nullptr;
49 }
50 }
Vladimir Marko20f85592015-03-19 10:07:02 +000051
52 // The variants that need a fix for 843419 are the same that need a fix for 835769.
53 bool needs_a53_843419_fix = needs_a53_835769_fix;
54
55 return new Arm64InstructionSetFeatures(smp, needs_a53_835769_fix, needs_a53_843419_fix);
Ian Rogersd582fa42014-11-05 23:46:43 -080056}
57
58const Arm64InstructionSetFeatures* Arm64InstructionSetFeatures::FromBitmap(uint32_t bitmap) {
59 bool smp = (bitmap & kSmpBitfield) != 0;
60 bool is_a53 = (bitmap & kA53Bitfield) != 0;
Vladimir Marko20f85592015-03-19 10:07:02 +000061 return new Arm64InstructionSetFeatures(smp, is_a53, is_a53);
Ian Rogersd582fa42014-11-05 23:46:43 -080062}
63
64const Arm64InstructionSetFeatures* Arm64InstructionSetFeatures::FromCppDefines() {
Ian Rogersd582fa42014-11-05 23:46:43 -080065 const bool smp = true;
Ian Rogersd582fa42014-11-05 23:46:43 -080066 const bool is_a53 = true; // Pessimistically assume all ARM64s are A53s.
Vladimir Marko20f85592015-03-19 10:07:02 +000067 return new Arm64InstructionSetFeatures(smp, is_a53, is_a53);
Ian Rogersd582fa42014-11-05 23:46:43 -080068}
69
70const Arm64InstructionSetFeatures* Arm64InstructionSetFeatures::FromCpuInfo() {
71 // Look in /proc/cpuinfo for features we need. Only use this when we can guarantee that
72 // the kernel puts the appropriate feature flags in here. Sometimes it doesn't.
73 bool smp = false;
74 const bool is_a53 = true; // Conservative default.
75
76 std::ifstream in("/proc/cpuinfo");
77 if (!in.fail()) {
78 while (!in.eof()) {
79 std::string line;
80 std::getline(in, line);
81 if (!in.eof()) {
82 LOG(INFO) << "cpuinfo line: " << line;
83 if (line.find("processor") != std::string::npos && line.find(": 1") != std::string::npos) {
84 smp = true;
85 }
86 }
87 }
88 in.close();
89 } else {
90 LOG(ERROR) << "Failed to open /proc/cpuinfo";
91 }
Vladimir Marko20f85592015-03-19 10:07:02 +000092 return new Arm64InstructionSetFeatures(smp, is_a53, is_a53);
Ian Rogersd582fa42014-11-05 23:46:43 -080093}
94
95const Arm64InstructionSetFeatures* Arm64InstructionSetFeatures::FromHwcap() {
96 bool smp = sysconf(_SC_NPROCESSORS_CONF) > 1;
97 const bool is_a53 = true; // Pessimistically assume all ARM64s are A53s.
Vladimir Marko20f85592015-03-19 10:07:02 +000098 return new Arm64InstructionSetFeatures(smp, is_a53, is_a53);
Ian Rogersd582fa42014-11-05 23:46:43 -080099}
100
101const Arm64InstructionSetFeatures* Arm64InstructionSetFeatures::FromAssembly() {
102 UNIMPLEMENTED(WARNING);
103 return FromCppDefines();
104}
105
106bool Arm64InstructionSetFeatures::Equals(const InstructionSetFeatures* other) const {
107 if (kArm64 != other->GetInstructionSet()) {
108 return false;
109 }
110 const Arm64InstructionSetFeatures* other_as_arm = other->AsArm64InstructionSetFeatures();
111 return fix_cortex_a53_835769_ == other_as_arm->fix_cortex_a53_835769_;
112}
113
114uint32_t Arm64InstructionSetFeatures::AsBitmap() const {
115 return (IsSmp() ? kSmpBitfield : 0) | (fix_cortex_a53_835769_ ? kA53Bitfield : 0);
116}
117
118std::string Arm64InstructionSetFeatures::GetFeatureString() const {
119 std::string result;
120 if (IsSmp()) {
121 result += "smp";
122 } else {
123 result += "-smp";
124 }
125 if (fix_cortex_a53_835769_) {
126 result += ",a53";
127 } else {
128 result += ",-a53";
129 }
130 return result;
131}
132
133const InstructionSetFeatures* Arm64InstructionSetFeatures::AddFeaturesFromSplitString(
134 const bool smp, const std::vector<std::string>& features, std::string* error_msg) const {
135 bool is_a53 = fix_cortex_a53_835769_;
136 for (auto i = features.begin(); i != features.end(); i++) {
137 std::string feature = Trim(*i);
138 if (feature == "a53") {
139 is_a53 = true;
140 } else if (feature == "-a53") {
141 is_a53 = false;
142 } else {
143 *error_msg = StringPrintf("Unknown instruction set feature: '%s'", feature.c_str());
144 return nullptr;
145 }
146 }
Vladimir Marko20f85592015-03-19 10:07:02 +0000147 return new Arm64InstructionSetFeatures(smp, is_a53, is_a53);
Ian Rogersd582fa42014-11-05 23:46:43 -0800148}
149
150} // namespace art