• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 Google LLC
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 
17 #include "filesystem_for_testing.h"
18 #include "gtest/gtest.h"
19 #include "hwcaps_for_testing.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   // check some random features with EnumValue():
48   EXPECT_TRUE(GetArmFeaturesEnumValue(&info.features, ARM_VFP));
49   EXPECT_FALSE(GetArmFeaturesEnumValue(&info.features, ARM_VFPV4));
50   // out of bound EnumValue() check
51   EXPECT_FALSE(GetArmFeaturesEnumValue(&info.features, (ArmFeaturesEnum)~0x0));
52 }
53 
TEST(CpuinfoArmTest,ODroidFromCpuInfo)54 TEST(CpuinfoArmTest, ODroidFromCpuInfo) {
55   DisableHardwareCapabilities();
56   auto& fs = GetEmptyFilesystem();
57   fs.CreateFile("/proc/cpuinfo", R"(processor       : 0
58 model name      : ARMv7 Processor rev 3 (v71)
59 BogoMIPS        : 120.00
60 Features        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae
61 CPU implementer : 0x41
62 CPU architecture: 7
63 CPU variant     : 0x2
64 CPU part        : 0xc0f
65 CPU revision    : 3)");
66   const auto info = GetArmInfo();
67   EXPECT_EQ(info.implementer, 0x41);
68   EXPECT_EQ(info.variant, 0x2);
69   EXPECT_EQ(info.part, 0xc0f);
70   EXPECT_EQ(info.revision, 3);
71   EXPECT_EQ(info.architecture, 7);
72 
73   EXPECT_FALSE(info.features.swp);
74   EXPECT_TRUE(info.features.half);
75   EXPECT_TRUE(info.features.thumb);
76   EXPECT_FALSE(info.features._26bit);
77   EXPECT_TRUE(info.features.fastmult);
78   EXPECT_FALSE(info.features.fpa);
79   EXPECT_TRUE(info.features.vfp);
80   EXPECT_TRUE(info.features.edsp);
81   EXPECT_FALSE(info.features.java);
82   EXPECT_FALSE(info.features.iwmmxt);
83   EXPECT_FALSE(info.features.crunch);
84   EXPECT_FALSE(info.features.thumbee);
85   EXPECT_TRUE(info.features.neon);
86   EXPECT_TRUE(info.features.vfpv3);
87   EXPECT_FALSE(info.features.vfpv3d16);
88   EXPECT_TRUE(info.features.tls);
89   EXPECT_TRUE(info.features.vfpv4);
90   EXPECT_TRUE(info.features.idiva);
91   EXPECT_TRUE(info.features.idivt);
92   EXPECT_TRUE(info.features.vfpd32);
93   EXPECT_TRUE(info.features.lpae);
94   EXPECT_FALSE(info.features.evtstrm);
95   EXPECT_FALSE(info.features.aes);
96   EXPECT_FALSE(info.features.pmull);
97   EXPECT_FALSE(info.features.sha1);
98   EXPECT_FALSE(info.features.sha2);
99   EXPECT_FALSE(info.features.crc32);
100 }
101 
102 // Linux test-case
TEST(CpuinfoArmTest,RaspberryPiZeroFromCpuInfo)103 TEST(CpuinfoArmTest, RaspberryPiZeroFromCpuInfo) {
104   DisableHardwareCapabilities();
105   auto& fs = GetEmptyFilesystem();
106   fs.CreateFile("/proc/cpuinfo", R"(processor       : 0
107 model name      : ARMv6-compatible processor rev 7 (v6l)
108 BogoMIPS        : 697.95
109 Features        : half thumb fastmult vfp edsp java tls
110 CPU implementer : 0x41
111 CPU architecture: 7
112 CPU variant     : 0x0
113 CPU part        : 0xb76
114 CPU revision    : 7
115 
116 Hardware        : BCM2835
117 Revision        : 9000c1
118 Serial          : 000000006cd946f3)");
119   const auto info = GetArmInfo();
120   EXPECT_EQ(info.implementer, 0x41);
121   EXPECT_EQ(info.variant, 0x0);
122   EXPECT_EQ(info.part, 0xb76);
123   EXPECT_EQ(info.revision, 7);
124   EXPECT_EQ(info.architecture, 6);
125 
126   EXPECT_FALSE(info.features.swp);
127   EXPECT_TRUE(info.features.half);
128   EXPECT_TRUE(info.features.thumb);
129   EXPECT_FALSE(info.features._26bit);
130   EXPECT_TRUE(info.features.fastmult);
131   EXPECT_FALSE(info.features.fpa);
132   EXPECT_TRUE(info.features.vfp);
133   EXPECT_TRUE(info.features.edsp);
134   EXPECT_TRUE(info.features.java);
135   EXPECT_FALSE(info.features.iwmmxt);
136   EXPECT_FALSE(info.features.crunch);
137   EXPECT_FALSE(info.features.thumbee);
138   EXPECT_FALSE(info.features.neon);
139   EXPECT_FALSE(info.features.vfpv3);
140   EXPECT_FALSE(info.features.vfpv3d16);
141   EXPECT_TRUE(info.features.tls);
142   EXPECT_FALSE(info.features.vfpv4);
143   EXPECT_FALSE(info.features.idiva);
144   EXPECT_FALSE(info.features.idivt);
145   EXPECT_FALSE(info.features.vfpd32);
146   EXPECT_FALSE(info.features.lpae);
147   EXPECT_FALSE(info.features.evtstrm);
148   EXPECT_FALSE(info.features.aes);
149   EXPECT_FALSE(info.features.pmull);
150   EXPECT_FALSE(info.features.sha1);
151   EXPECT_FALSE(info.features.sha2);
152   EXPECT_FALSE(info.features.crc32);
153 }
154 
TEST(CpuinfoArmTest,MarvellArmadaFromCpuInfo)155 TEST(CpuinfoArmTest, MarvellArmadaFromCpuInfo) {
156   DisableHardwareCapabilities();
157   auto& fs = GetEmptyFilesystem();
158   fs.CreateFile("/proc/cpuinfo", R"(processor       : 0
159 model name      : ARMv7 Processor rev 1 (v7l)
160 BogoMIPS        : 50.00
161 Features        : half thumb fastmult vfp edsp neon vfpv3 tls vfpd32
162 CPU implementer : 0x41
163 CPU architecture: 7
164 CPU variant     : 0x4
165 CPU part        : 0xc09
166 CPU revision    : 1
167 
168 processor       : 1
169 model name      : ARMv7 Processor rev 1 (v7l)
170 BogoMIPS        : 50.00
171 Features        : half thumb fastmult vfp edsp neon vfpv3 tls vfpd32
172 CPU implementer : 0x41
173 CPU architecture: 7
174 CPU variant     : 0x4
175 CPU part        : 0xc09
176 CPU revision    : 1
177 
178 Hardware        : Marvell Armada 380/385 (Device Tree)
179 Revision        : 0000
180 Serial          : 0000000000000000)");
181   const auto info = GetArmInfo();
182   EXPECT_EQ(info.implementer, 0x41);
183   EXPECT_EQ(info.variant, 0x4);
184   EXPECT_EQ(info.part, 0xc09);
185   EXPECT_EQ(info.revision, 1);
186   EXPECT_EQ(info.architecture, 7);
187 
188   EXPECT_FALSE(info.features.swp);
189   EXPECT_TRUE(info.features.half);
190   EXPECT_TRUE(info.features.thumb);
191   EXPECT_FALSE(info.features._26bit);
192   EXPECT_TRUE(info.features.fastmult);
193   EXPECT_FALSE(info.features.fpa);
194   EXPECT_TRUE(info.features.vfp);
195   EXPECT_TRUE(info.features.edsp);
196   EXPECT_FALSE(info.features.java);
197   EXPECT_FALSE(info.features.iwmmxt);
198   EXPECT_FALSE(info.features.crunch);
199   EXPECT_FALSE(info.features.thumbee);
200   EXPECT_TRUE(info.features.neon);
201   EXPECT_TRUE(info.features.vfpv3);
202   EXPECT_FALSE(info.features.vfpv3d16);
203   EXPECT_TRUE(info.features.tls);
204   EXPECT_FALSE(info.features.vfpv4);
205   EXPECT_FALSE(info.features.idiva);
206   EXPECT_FALSE(info.features.idivt);
207   EXPECT_TRUE(info.features.vfpd32);
208   EXPECT_FALSE(info.features.lpae);
209   EXPECT_FALSE(info.features.evtstrm);
210   EXPECT_FALSE(info.features.aes);
211   EXPECT_FALSE(info.features.pmull);
212   EXPECT_FALSE(info.features.sha1);
213   EXPECT_FALSE(info.features.sha2);
214   EXPECT_FALSE(info.features.crc32);
215 }
216 
217 // Android test-case
218 // http://code.google.com/p/android/issues/detail?id=10812
TEST(CpuinfoArmTest,InvalidArmv7)219 TEST(CpuinfoArmTest, InvalidArmv7) {
220   DisableHardwareCapabilities();
221   auto& fs = GetEmptyFilesystem();
222   fs.CreateFile("/proc/cpuinfo",
223                 R"(Processor       : ARMv6-compatible processor rev 6 (v6l)
224 BogoMIPS        : 199.47
225 Features        : swp half thumb fastmult vfp edsp java
226 CPU implementer : 0x41
227 CPU architecture: 7
228 CPU variant     : 0x0
229 CPU part        : 0xb76
230 CPU revision    : 6
231 
232 Hardware        : SPICA
233 Revision        : 0020
234 Serial          : 33323613546d00ec )");
235   const auto info = GetArmInfo();
236   EXPECT_EQ(info.architecture, 6);
237 
238   EXPECT_TRUE(info.features.swp);
239   EXPECT_TRUE(info.features.half);
240   EXPECT_TRUE(info.features.thumb);
241   EXPECT_FALSE(info.features._26bit);
242   EXPECT_TRUE(info.features.fastmult);
243   EXPECT_FALSE(info.features.fpa);
244   EXPECT_TRUE(info.features.vfp);
245   EXPECT_TRUE(info.features.edsp);
246   EXPECT_TRUE(info.features.java);
247   EXPECT_FALSE(info.features.iwmmxt);
248   EXPECT_FALSE(info.features.crunch);
249   EXPECT_FALSE(info.features.thumbee);
250   EXPECT_FALSE(info.features.neon);
251   EXPECT_FALSE(info.features.vfpv3);
252   EXPECT_FALSE(info.features.vfpv3d16);
253   EXPECT_FALSE(info.features.tls);
254   EXPECT_FALSE(info.features.vfpv4);
255   EXPECT_FALSE(info.features.idiva);
256   EXPECT_FALSE(info.features.idivt);
257   EXPECT_FALSE(info.features.vfpd32);
258   EXPECT_FALSE(info.features.lpae);
259   EXPECT_FALSE(info.features.evtstrm);
260   EXPECT_FALSE(info.features.aes);
261   EXPECT_FALSE(info.features.pmull);
262   EXPECT_FALSE(info.features.sha1);
263   EXPECT_FALSE(info.features.sha2);
264   EXPECT_FALSE(info.features.crc32);
265 }
266 
267 // Android test-case
268 // https://crbug.com/341598.
TEST(CpuinfoArmTest,InvalidNeon)269 TEST(CpuinfoArmTest, InvalidNeon) {
270   auto& fs = GetEmptyFilesystem();
271   fs.CreateFile("/proc/cpuinfo",
272                 R"(Processor: ARMv7 Processory rev 0 (v71)
273 processor: 0
274 BogoMIPS: 13.50
275 
276 Processor: 1
277 BogoMIPS: 13.50
278 
279 Features: swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt
280 CPU implementer : 0x51
281 CPU architecture: 7
282 CPU variant: 0x1
283 CPU part: 0x04d
284 CPU revision: 0
285 
286 Hardware: SAMSUNG M2
287 Revision: 0010
288 Serial: 00001e030000354e)");
289   const auto info = GetArmInfo();
290   EXPECT_TRUE(info.features.swp);
291   EXPECT_FALSE(info.features.neon);
292 }
293 
294 // The Nexus 4 (Qualcomm Krait) kernel configuration forgets to report IDIV
295 // support.
TEST(CpuinfoArmTest,Nexus4_0x510006f2)296 TEST(CpuinfoArmTest, Nexus4_0x510006f2) {
297   DisableHardwareCapabilities();
298   auto& fs = GetEmptyFilesystem();
299   fs.CreateFile("/proc/cpuinfo",
300                 R"(CPU implementer	: 0x51
301 CPU architecture: 7
302 CPU variant	: 0x0
303 CPU part	: 0x6f
304 CPU revision	: 2)");
305   const auto info = GetArmInfo();
306   EXPECT_TRUE(info.features.idiva);
307   EXPECT_TRUE(info.features.idivt);
308 
309   EXPECT_EQ(GetArmCpuId(&info), 0x510006f2);
310 }
311 
312 // The Nexus 4 (Qualcomm Krait) kernel configuration forgets to report IDIV
313 // support.
TEST(CpuinfoArmTest,Nexus4_0x510006f3)314 TEST(CpuinfoArmTest, Nexus4_0x510006f3) {
315   DisableHardwareCapabilities();
316   auto& fs = GetEmptyFilesystem();
317   fs.CreateFile("/proc/cpuinfo",
318                 R"(CPU implementer	: 0x51
319 CPU architecture: 7
320 CPU variant	: 0x0
321 CPU part	: 0x6f
322 CPU revision	: 3)");
323   const auto info = GetArmInfo();
324   EXPECT_TRUE(info.features.idiva);
325   EXPECT_TRUE(info.features.idivt);
326 
327   EXPECT_EQ(GetArmCpuId(&info), 0x510006f3);
328 }
329 
330 // The emulator-specific Android 4.2 kernel fails to report support for the
331 // 32-bit ARM IDIV instruction. Technically, this is a feature of the virtual
332 // CPU implemented by the emulator.
TEST(CpuinfoArmTest,EmulatorSpecificIdiv)333 TEST(CpuinfoArmTest, EmulatorSpecificIdiv) {
334   DisableHardwareCapabilities();
335   auto& fs = GetEmptyFilesystem();
336   fs.CreateFile("/proc/cpuinfo",
337                 R"(Processor	: ARMv7 Processor rev 0 (v7l)
338 BogoMIPS	: 629.14
339 Features	: swp half thumb fastmult vfp edsp neon vfpv3
340 CPU implementer	: 0x41
341 CPU architecture: 7
342 CPU variant	: 0x0
343 CPU part	: 0xc08
344 CPU revision	: 0
345 
346 Hardware	: Goldfish
347 Revision	: 0000
348 Serial		: 0000000000000000)");
349   const auto info = GetArmInfo();
350   EXPECT_TRUE(info.features.idiva);
351 }
352 
353 }  // namespace
354 }  // namespace cpu_features
355