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