1 // Copyright 2017 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "cpuinfo_arm.h"
16 #include "filesystem_for_testing.h"
17 #include "hwcaps_for_testing.h"
18
19 #include "gtest/gtest.h"
20
21 namespace cpu_features {
22 namespace {
23
DisableHardwareCapabilities()24 void DisableHardwareCapabilities() { SetHardwareCapabilities(0, 0); }
25
TEST(CpuinfoArmTest,FromHardwareCap)26 TEST(CpuinfoArmTest, FromHardwareCap) {
27 SetHardwareCapabilities(ARM_HWCAP_NEON, ARM_HWCAP2_AES | ARM_HWCAP2_CRC32);
28 GetEmptyFilesystem(); // disabling /proc/cpuinfo
29 const auto info = GetArmInfo();
30 EXPECT_TRUE(info.features.vfp); // triggered by vfpv3
31 EXPECT_TRUE(info.features.vfpv3); // triggered by neon
32 EXPECT_TRUE(info.features.neon);
33 EXPECT_TRUE(info.features.aes);
34 EXPECT_TRUE(info.features.crc32);
35
36 EXPECT_FALSE(info.features.vfpv4);
37 EXPECT_FALSE(info.features.iwmmxt);
38 EXPECT_FALSE(info.features.crunch);
39 EXPECT_FALSE(info.features.thumbee);
40 EXPECT_FALSE(info.features.vfpv3d16);
41 EXPECT_FALSE(info.features.idiva);
42 EXPECT_FALSE(info.features.idivt);
43 EXPECT_FALSE(info.features.pmull);
44 EXPECT_FALSE(info.features.sha1);
45 EXPECT_FALSE(info.features.sha2);
46 }
47
TEST(CpuinfoArmTest,ODroidFromCpuInfo)48 TEST(CpuinfoArmTest, ODroidFromCpuInfo) {
49 DisableHardwareCapabilities();
50 auto& fs = GetEmptyFilesystem();
51 fs.CreateFile("/proc/cpuinfo", R"(processor : 0
52 model name : ARMv7 Processor rev 3 (v71)
53 BogoMIPS : 120.00
54 Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae
55 CPU implementer : 0x41
56 CPU architecture: 7
57 CPU variant : 0x2
58 CPU part : 0xc0f
59 CPU revision : 3)");
60 const auto info = GetArmInfo();
61 EXPECT_EQ(info.implementer, 0x41);
62 EXPECT_EQ(info.variant, 0x2);
63 EXPECT_EQ(info.part, 0xc0f);
64 EXPECT_EQ(info.revision, 3);
65 EXPECT_EQ(info.architecture, 7);
66
67 EXPECT_FALSE(info.features.swp);
68 EXPECT_TRUE(info.features.half);
69 EXPECT_TRUE(info.features.thumb);
70 EXPECT_FALSE(info.features._26bit);
71 EXPECT_TRUE(info.features.fastmult);
72 EXPECT_FALSE(info.features.fpa);
73 EXPECT_TRUE(info.features.vfp);
74 EXPECT_TRUE(info.features.edsp);
75 EXPECT_FALSE(info.features.java);
76 EXPECT_FALSE(info.features.iwmmxt);
77 EXPECT_FALSE(info.features.crunch);
78 EXPECT_FALSE(info.features.thumbee);
79 EXPECT_TRUE(info.features.neon);
80 EXPECT_TRUE(info.features.vfpv3);
81 EXPECT_FALSE(info.features.vfpv3d16);
82 EXPECT_TRUE(info.features.tls);
83 EXPECT_TRUE(info.features.vfpv4);
84 EXPECT_TRUE(info.features.idiva);
85 EXPECT_TRUE(info.features.idivt);
86 EXPECT_TRUE(info.features.vfpd32);
87 EXPECT_TRUE(info.features.lpae);
88 EXPECT_FALSE(info.features.evtstrm);
89 EXPECT_FALSE(info.features.aes);
90 EXPECT_FALSE(info.features.pmull);
91 EXPECT_FALSE(info.features.sha1);
92 EXPECT_FALSE(info.features.sha2);
93 EXPECT_FALSE(info.features.crc32);
94 }
95
96 // Linux test-case
TEST(CpuinfoArmTest,RaspberryPiZeroFromCpuInfo)97 TEST(CpuinfoArmTest, RaspberryPiZeroFromCpuInfo) {
98 DisableHardwareCapabilities();
99 auto& fs = GetEmptyFilesystem();
100 fs.CreateFile("/proc/cpuinfo", R"(processor : 0
101 model name : ARMv6-compatible processor rev 7 (v6l)
102 BogoMIPS : 697.95
103 Features : half thumb fastmult vfp edsp java tls
104 CPU implementer : 0x41
105 CPU architecture: 7
106 CPU variant : 0x0
107 CPU part : 0xb76
108 CPU revision : 7
109
110 Hardware : BCM2835
111 Revision : 9000c1
112 Serial : 000000006cd946f3)");
113 const auto info = GetArmInfo();
114 EXPECT_EQ(info.implementer, 0x41);
115 EXPECT_EQ(info.variant, 0x0);
116 EXPECT_EQ(info.part, 0xb76);
117 EXPECT_EQ(info.revision, 7);
118 EXPECT_EQ(info.architecture, 6);
119
120 EXPECT_FALSE(info.features.swp);
121 EXPECT_TRUE(info.features.half);
122 EXPECT_TRUE(info.features.thumb);
123 EXPECT_FALSE(info.features._26bit);
124 EXPECT_TRUE(info.features.fastmult);
125 EXPECT_FALSE(info.features.fpa);
126 EXPECT_TRUE(info.features.vfp);
127 EXPECT_TRUE(info.features.edsp);
128 EXPECT_TRUE(info.features.java);
129 EXPECT_FALSE(info.features.iwmmxt);
130 EXPECT_FALSE(info.features.crunch);
131 EXPECT_FALSE(info.features.thumbee);
132 EXPECT_FALSE(info.features.neon);
133 EXPECT_FALSE(info.features.vfpv3);
134 EXPECT_FALSE(info.features.vfpv3d16);
135 EXPECT_TRUE(info.features.tls);
136 EXPECT_FALSE(info.features.vfpv4);
137 EXPECT_FALSE(info.features.idiva);
138 EXPECT_FALSE(info.features.idivt);
139 EXPECT_FALSE(info.features.vfpd32);
140 EXPECT_FALSE(info.features.lpae);
141 EXPECT_FALSE(info.features.evtstrm);
142 EXPECT_FALSE(info.features.aes);
143 EXPECT_FALSE(info.features.pmull);
144 EXPECT_FALSE(info.features.sha1);
145 EXPECT_FALSE(info.features.sha2);
146 EXPECT_FALSE(info.features.crc32);
147 }
148
TEST(CpuinfoArmTest,MarvellArmadaFromCpuInfo)149 TEST(CpuinfoArmTest, MarvellArmadaFromCpuInfo) {
150 DisableHardwareCapabilities();
151 auto& fs = GetEmptyFilesystem();
152 fs.CreateFile("/proc/cpuinfo", R"(processor : 0
153 model name : ARMv7 Processor rev 1 (v7l)
154 BogoMIPS : 50.00
155 Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpd32
156 CPU implementer : 0x41
157 CPU architecture: 7
158 CPU variant : 0x4
159 CPU part : 0xc09
160 CPU revision : 1
161
162 processor : 1
163 model name : ARMv7 Processor rev 1 (v7l)
164 BogoMIPS : 50.00
165 Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpd32
166 CPU implementer : 0x41
167 CPU architecture: 7
168 CPU variant : 0x4
169 CPU part : 0xc09
170 CPU revision : 1
171
172 Hardware : Marvell Armada 380/385 (Device Tree)
173 Revision : 0000
174 Serial : 0000000000000000)");
175 const auto info = GetArmInfo();
176 EXPECT_EQ(info.implementer, 0x41);
177 EXPECT_EQ(info.variant, 0x4);
178 EXPECT_EQ(info.part, 0xc09);
179 EXPECT_EQ(info.revision, 1);
180 EXPECT_EQ(info.architecture, 7);
181
182 EXPECT_FALSE(info.features.swp);
183 EXPECT_TRUE(info.features.half);
184 EXPECT_TRUE(info.features.thumb);
185 EXPECT_FALSE(info.features._26bit);
186 EXPECT_TRUE(info.features.fastmult);
187 EXPECT_FALSE(info.features.fpa);
188 EXPECT_TRUE(info.features.vfp);
189 EXPECT_TRUE(info.features.edsp);
190 EXPECT_FALSE(info.features.java);
191 EXPECT_FALSE(info.features.iwmmxt);
192 EXPECT_FALSE(info.features.crunch);
193 EXPECT_FALSE(info.features.thumbee);
194 EXPECT_TRUE(info.features.neon);
195 EXPECT_TRUE(info.features.vfpv3);
196 EXPECT_FALSE(info.features.vfpv3d16);
197 EXPECT_TRUE(info.features.tls);
198 EXPECT_FALSE(info.features.vfpv4);
199 EXPECT_FALSE(info.features.idiva);
200 EXPECT_FALSE(info.features.idivt);
201 EXPECT_TRUE(info.features.vfpd32);
202 EXPECT_FALSE(info.features.lpae);
203 EXPECT_FALSE(info.features.evtstrm);
204 EXPECT_FALSE(info.features.aes);
205 EXPECT_FALSE(info.features.pmull);
206 EXPECT_FALSE(info.features.sha1);
207 EXPECT_FALSE(info.features.sha2);
208 EXPECT_FALSE(info.features.crc32);
209 }
210
211 // Android test-case
212 // http://code.google.com/p/android/issues/detail?id=10812
TEST(CpuinfoArmTest,InvalidArmv7)213 TEST(CpuinfoArmTest, InvalidArmv7) {
214 DisableHardwareCapabilities();
215 auto& fs = GetEmptyFilesystem();
216 fs.CreateFile("/proc/cpuinfo",
217 R"(Processor : ARMv6-compatible processor rev 6 (v6l)
218 BogoMIPS : 199.47
219 Features : swp half thumb fastmult vfp edsp java
220 CPU implementer : 0x41
221 CPU architecture: 7
222 CPU variant : 0x0
223 CPU part : 0xb76
224 CPU revision : 6
225
226 Hardware : SPICA
227 Revision : 0020
228 Serial : 33323613546d00ec )");
229 const auto info = GetArmInfo();
230 EXPECT_EQ(info.architecture, 6);
231
232 EXPECT_TRUE(info.features.swp);
233 EXPECT_TRUE(info.features.half);
234 EXPECT_TRUE(info.features.thumb);
235 EXPECT_FALSE(info.features._26bit);
236 EXPECT_TRUE(info.features.fastmult);
237 EXPECT_FALSE(info.features.fpa);
238 EXPECT_TRUE(info.features.vfp);
239 EXPECT_TRUE(info.features.edsp);
240 EXPECT_TRUE(info.features.java);
241 EXPECT_FALSE(info.features.iwmmxt);
242 EXPECT_FALSE(info.features.crunch);
243 EXPECT_FALSE(info.features.thumbee);
244 EXPECT_FALSE(info.features.neon);
245 EXPECT_FALSE(info.features.vfpv3);
246 EXPECT_FALSE(info.features.vfpv3d16);
247 EXPECT_FALSE(info.features.tls);
248 EXPECT_FALSE(info.features.vfpv4);
249 EXPECT_FALSE(info.features.idiva);
250 EXPECT_FALSE(info.features.idivt);
251 EXPECT_FALSE(info.features.vfpd32);
252 EXPECT_FALSE(info.features.lpae);
253 EXPECT_FALSE(info.features.evtstrm);
254 EXPECT_FALSE(info.features.aes);
255 EXPECT_FALSE(info.features.pmull);
256 EXPECT_FALSE(info.features.sha1);
257 EXPECT_FALSE(info.features.sha2);
258 EXPECT_FALSE(info.features.crc32);
259 }
260
261 // Android test-case
262 // https://crbug.com/341598.
TEST(CpuinfoArmTest,InvalidNeon)263 TEST(CpuinfoArmTest, InvalidNeon) {
264 auto& fs = GetEmptyFilesystem();
265 fs.CreateFile("/proc/cpuinfo",
266 R"(Processor: ARMv7 Processory rev 0 (v71)
267 processor: 0
268 BogoMIPS: 13.50
269
270 Processor: 1
271 BogoMIPS: 13.50
272
273 Features: swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt
274 CPU implementer : 0x51
275 CPU architecture: 7
276 CPU variant: 0x1
277 CPU part: 0x04d
278 CPU revision: 0
279
280 Hardware: SAMSUNG M2
281 Revision: 0010
282 Serial: 00001e030000354e)");
283 const auto info = GetArmInfo();
284 EXPECT_TRUE(info.features.swp);
285 EXPECT_FALSE(info.features.neon);
286 }
287
288 // The Nexus 4 (Qualcomm Krait) kernel configuration forgets to report IDIV
289 // support.
TEST(CpuinfoArmTest,Nexus4_0x510006f2)290 TEST(CpuinfoArmTest, Nexus4_0x510006f2) {
291 DisableHardwareCapabilities();
292 auto& fs = GetEmptyFilesystem();
293 fs.CreateFile("/proc/cpuinfo",
294 R"(CPU implementer : 0x51
295 CPU architecture: 7
296 CPU variant : 0x0
297 CPU part : 0x6f
298 CPU revision : 2)");
299 const auto info = GetArmInfo();
300 EXPECT_TRUE(info.features.idiva);
301 EXPECT_TRUE(info.features.idivt);
302
303 EXPECT_EQ(GetArmCpuId(&info), 0x510006f2);
304 }
305
306 // The Nexus 4 (Qualcomm Krait) kernel configuration forgets to report IDIV
307 // support.
TEST(CpuinfoArmTest,Nexus4_0x510006f3)308 TEST(CpuinfoArmTest, Nexus4_0x510006f3) {
309 DisableHardwareCapabilities();
310 auto& fs = GetEmptyFilesystem();
311 fs.CreateFile("/proc/cpuinfo",
312 R"(CPU implementer : 0x51
313 CPU architecture: 7
314 CPU variant : 0x0
315 CPU part : 0x6f
316 CPU revision : 3)");
317 const auto info = GetArmInfo();
318 EXPECT_TRUE(info.features.idiva);
319 EXPECT_TRUE(info.features.idivt);
320
321 EXPECT_EQ(GetArmCpuId(&info), 0x510006f3);
322 }
323
324 // The emulator-specific Android 4.2 kernel fails to report support for the
325 // 32-bit ARM IDIV instruction. Technically, this is a feature of the virtual
326 // CPU implemented by the emulator.
TEST(CpuinfoArmTest,EmulatorSpecificIdiv)327 TEST(CpuinfoArmTest, EmulatorSpecificIdiv) {
328 DisableHardwareCapabilities();
329 auto& fs = GetEmptyFilesystem();
330 fs.CreateFile("/proc/cpuinfo",
331 R"(Processor : ARMv7 Processor rev 0 (v7l)
332 BogoMIPS : 629.14
333 Features : swp half thumb fastmult vfp edsp neon vfpv3
334 CPU implementer : 0x41
335 CPU architecture: 7
336 CPU variant : 0x0
337 CPU part : 0xc08
338 CPU revision : 0
339
340 Hardware : Goldfish
341 Revision : 0000
342 Serial : 0000000000000000)");
343 const auto info = GetArmInfo();
344 EXPECT_TRUE(info.features.idiva);
345 }
346
347 } // namespace
348 } // namespace cpu_features
349