xref: /aosp_15_r20/external/cronet/third_party/cpu_features/src/test/cpuinfo_aarch64_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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_aarch64.h"
16 
17 #include <set>
18 
19 #include "filesystem_for_testing.h"
20 #include "gtest/gtest.h"
21 #include "hwcaps_for_testing.h"
22 #if defined(CPU_FEATURES_OS_WINDOWS)
23 #include "internal/windows_utils.h"
24 #endif  // CPU_FEATURES_OS_WINDOWS
25 
26 namespace cpu_features {
27 class FakeCpuAarch64 {
28  public:
29 #if defined(CPU_FEATURES_OS_WINDOWS)
GetWindowsIsProcessorFeaturePresent(DWORD dwProcessorFeature)30   bool GetWindowsIsProcessorFeaturePresent(DWORD dwProcessorFeature) {
31     return windows_isprocessorfeaturepresent_.count(dwProcessorFeature);
32   }
33 
SetWindowsIsProcessorFeaturePresent(DWORD dwProcessorFeature)34   void SetWindowsIsProcessorFeaturePresent(DWORD dwProcessorFeature) {
35     windows_isprocessorfeaturepresent_.insert(dwProcessorFeature);
36   }
37 
GetWindowsNativeSystemInfoProcessorRevision() const38   WORD GetWindowsNativeSystemInfoProcessorRevision() const {
39     return processor_revision_;
40   }
41 
SetWindowsNativeSystemInfoProcessorRevision(WORD wProcessorRevision)42   void SetWindowsNativeSystemInfoProcessorRevision(WORD wProcessorRevision) {
43     processor_revision_ = wProcessorRevision;
44   }
45 
46  private:
47   std::set<DWORD> windows_isprocessorfeaturepresent_;
48   WORD processor_revision_{};
49 #endif  // CPU_FEATURES_OS_WINDOWS
50 };
51 
52 static FakeCpuAarch64* g_fake_cpu_instance = nullptr;
53 
cpu()54 static FakeCpuAarch64& cpu() {
55   assert(g_fake_cpu_instance != nullptr);
56   return *g_fake_cpu_instance;
57 }
58 
59 #if defined(CPU_FEATURES_OS_WINDOWS)
GetWindowsIsProcessorFeaturePresent(DWORD dwProcessorFeature)60 extern "C" bool GetWindowsIsProcessorFeaturePresent(DWORD dwProcessorFeature) {
61   return cpu().GetWindowsIsProcessorFeaturePresent(dwProcessorFeature);
62 }
63 
GetWindowsNativeSystemInfoProcessorRevision()64 extern "C" WORD GetWindowsNativeSystemInfoProcessorRevision() {
65   return cpu().GetWindowsNativeSystemInfoProcessorRevision();
66 }
67 #endif  // CPU_FEATURES_OS_WINDOWS
68 
69 namespace {
70 
71 class CpuidAarch64Test : public ::testing::Test {
72  protected:
SetUp()73   void SetUp() override {
74     assert(g_fake_cpu_instance == nullptr);
75     g_fake_cpu_instance = new FakeCpuAarch64();
76   }
TearDown()77   void TearDown() override {
78     delete g_fake_cpu_instance;
79     g_fake_cpu_instance = nullptr;
80   }
81 };
82 
TEST(CpuinfoAarch64Test,Aarch64FeaturesEnum)83 TEST(CpuinfoAarch64Test, Aarch64FeaturesEnum) {
84   const char* last_name = GetAarch64FeaturesEnumName(AARCH64_LAST_);
85   EXPECT_STREQ(last_name, "unknown_feature");
86   for (int i = static_cast<int>(AARCH64_FP);
87        i != static_cast<int>(AARCH64_LAST_); ++i) {
88     const auto feature = static_cast<Aarch64FeaturesEnum>(i);
89     const char* name = GetAarch64FeaturesEnumName(feature);
90     ASSERT_FALSE(name == nullptr);
91     EXPECT_STRNE(name, "");
92     EXPECT_STRNE(name, last_name);
93   }
94 }
95 
96 #if defined(CPU_FEATURES_OS_LINUX)
DisableHardwareCapabilities()97 void DisableHardwareCapabilities() { SetHardwareCapabilities(0, 0); }
98 
TEST(CpuinfoAarch64Test,FromHardwareCap)99 TEST(CpuinfoAarch64Test, FromHardwareCap) {
100   ResetHwcaps();
101   SetHardwareCapabilities(AARCH64_HWCAP_FP | AARCH64_HWCAP_AES, 0);
102   GetEmptyFilesystem();  // disabling /proc/cpuinfo
103   const auto info = GetAarch64Info();
104   EXPECT_TRUE(info.features.fp);
105   EXPECT_FALSE(info.features.asimd);
106   EXPECT_FALSE(info.features.evtstrm);
107   EXPECT_TRUE(info.features.aes);
108   EXPECT_FALSE(info.features.pmull);
109   EXPECT_FALSE(info.features.sha1);
110   EXPECT_FALSE(info.features.sha2);
111   EXPECT_FALSE(info.features.crc32);
112   EXPECT_FALSE(info.features.atomics);
113   EXPECT_FALSE(info.features.fphp);
114   EXPECT_FALSE(info.features.asimdhp);
115   EXPECT_FALSE(info.features.cpuid);
116   EXPECT_FALSE(info.features.asimdrdm);
117   EXPECT_FALSE(info.features.jscvt);
118   EXPECT_FALSE(info.features.fcma);
119   EXPECT_FALSE(info.features.lrcpc);
120   EXPECT_FALSE(info.features.dcpop);
121   EXPECT_FALSE(info.features.sha3);
122   EXPECT_FALSE(info.features.sm3);
123   EXPECT_FALSE(info.features.sm4);
124   EXPECT_FALSE(info.features.asimddp);
125   EXPECT_FALSE(info.features.sha512);
126   EXPECT_FALSE(info.features.sve);
127   EXPECT_FALSE(info.features.asimdfhm);
128   EXPECT_FALSE(info.features.dit);
129   EXPECT_FALSE(info.features.uscat);
130   EXPECT_FALSE(info.features.ilrcpc);
131   EXPECT_FALSE(info.features.flagm);
132   EXPECT_FALSE(info.features.ssbs);
133   EXPECT_FALSE(info.features.sb);
134   EXPECT_FALSE(info.features.paca);
135   EXPECT_FALSE(info.features.pacg);
136 }
137 
TEST(CpuinfoAarch64Test,FromHardwareCap2)138 TEST(CpuinfoAarch64Test, FromHardwareCap2) {
139   ResetHwcaps();
140   SetHardwareCapabilities(AARCH64_HWCAP_FP,
141                           AARCH64_HWCAP2_SVE2 | AARCH64_HWCAP2_BTI);
142   GetEmptyFilesystem();  // disabling /proc/cpuinfo
143   const auto info = GetAarch64Info();
144   EXPECT_TRUE(info.features.fp);
145 
146   EXPECT_TRUE(info.features.sve2);
147   EXPECT_TRUE(info.features.bti);
148 
149   EXPECT_FALSE(info.features.dcpodp);
150   EXPECT_FALSE(info.features.sveaes);
151   EXPECT_FALSE(info.features.svepmull);
152   EXPECT_FALSE(info.features.svebitperm);
153   EXPECT_FALSE(info.features.svesha3);
154   EXPECT_FALSE(info.features.svesm4);
155   EXPECT_FALSE(info.features.flagm2);
156   EXPECT_FALSE(info.features.frint);
157   EXPECT_FALSE(info.features.svei8mm);
158   EXPECT_FALSE(info.features.svef32mm);
159   EXPECT_FALSE(info.features.svef64mm);
160   EXPECT_FALSE(info.features.svebf16);
161   EXPECT_FALSE(info.features.i8mm);
162   EXPECT_FALSE(info.features.bf16);
163   EXPECT_FALSE(info.features.dgh);
164   EXPECT_FALSE(info.features.rng);
165 }
166 
TEST(CpuinfoAarch64Test,ARMCortexA53)167 TEST(CpuinfoAarch64Test, ARMCortexA53) {
168   ResetHwcaps();
169   auto& fs = GetEmptyFilesystem();
170   fs.CreateFile("/proc/cpuinfo",
171                 R"(Processor   : AArch64 Processor rev 3 (aarch64)
172 processor   : 0
173 processor   : 1
174 processor   : 2
175 processor   : 3
176 processor   : 4
177 processor   : 5
178 processor   : 6
179 processor   : 7
180 Features    : fp asimd evtstrm aes pmull sha1 sha2 crc32
181 CPU implementer : 0x41
182 CPU architecture: AArch64
183 CPU variant : 0x0
184 CPU part    : 0xd03
185 CPU revision    : 3)");
186   const auto info = GetAarch64Info();
187   EXPECT_EQ(info.implementer, 0x41);
188   EXPECT_EQ(info.variant, 0x0);
189   EXPECT_EQ(info.part, 0xd03);
190   EXPECT_EQ(info.revision, 3);
191 
192   EXPECT_TRUE(info.features.fp);
193   EXPECT_TRUE(info.features.asimd);
194   EXPECT_TRUE(info.features.evtstrm);
195   EXPECT_TRUE(info.features.aes);
196   EXPECT_TRUE(info.features.pmull);
197   EXPECT_TRUE(info.features.sha1);
198   EXPECT_TRUE(info.features.sha2);
199   EXPECT_TRUE(info.features.crc32);
200 
201   EXPECT_FALSE(info.features.atomics);
202   EXPECT_FALSE(info.features.fphp);
203   EXPECT_FALSE(info.features.asimdhp);
204   EXPECT_FALSE(info.features.cpuid);
205   EXPECT_FALSE(info.features.asimdrdm);
206   EXPECT_FALSE(info.features.jscvt);
207   EXPECT_FALSE(info.features.fcma);
208   EXPECT_FALSE(info.features.lrcpc);
209   EXPECT_FALSE(info.features.dcpop);
210   EXPECT_FALSE(info.features.sha3);
211   EXPECT_FALSE(info.features.sm3);
212   EXPECT_FALSE(info.features.sm4);
213   EXPECT_FALSE(info.features.asimddp);
214   EXPECT_FALSE(info.features.sha512);
215   EXPECT_FALSE(info.features.sve);
216   EXPECT_FALSE(info.features.asimdfhm);
217   EXPECT_FALSE(info.features.dit);
218   EXPECT_FALSE(info.features.uscat);
219   EXPECT_FALSE(info.features.ilrcpc);
220   EXPECT_FALSE(info.features.flagm);
221   EXPECT_FALSE(info.features.ssbs);
222   EXPECT_FALSE(info.features.sb);
223   EXPECT_FALSE(info.features.paca);
224   EXPECT_FALSE(info.features.pacg);
225   EXPECT_FALSE(info.features.dcpodp);
226   EXPECT_FALSE(info.features.sve2);
227   EXPECT_FALSE(info.features.sveaes);
228   EXPECT_FALSE(info.features.svepmull);
229   EXPECT_FALSE(info.features.svebitperm);
230   EXPECT_FALSE(info.features.svesha3);
231   EXPECT_FALSE(info.features.svesm4);
232   EXPECT_FALSE(info.features.flagm2);
233   EXPECT_FALSE(info.features.frint);
234   EXPECT_FALSE(info.features.svei8mm);
235   EXPECT_FALSE(info.features.svef32mm);
236   EXPECT_FALSE(info.features.svef64mm);
237   EXPECT_FALSE(info.features.svebf16);
238   EXPECT_FALSE(info.features.i8mm);
239   EXPECT_FALSE(info.features.bf16);
240   EXPECT_FALSE(info.features.dgh);
241   EXPECT_FALSE(info.features.rng);
242   EXPECT_FALSE(info.features.bti);
243   EXPECT_FALSE(info.features.mte);
244   EXPECT_FALSE(info.features.ecv);
245   EXPECT_FALSE(info.features.afp);
246   EXPECT_FALSE(info.features.rpres);
247 }
248 #endif  // CPU_FEATURES_OS_LINUX
249 
250 #if defined(CPU_FEATURES_OS_WINDOWS)
TEST_F(CpuidAarch64Test,WINDOWS_AARCH64_RPI4)251 TEST_F(CpuidAarch64Test, WINDOWS_AARCH64_RPI4) {
252   cpu().SetWindowsNativeSystemInfoProcessorRevision(0x03);
253   cpu().SetWindowsIsProcessorFeaturePresent(PF_ARM_VFP_32_REGISTERS_AVAILABLE);
254   cpu().SetWindowsIsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE);
255   cpu().SetWindowsIsProcessorFeaturePresent(
256       PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE);
257 
258   const auto info = GetAarch64Info();
259 
260   EXPECT_EQ(info.revision, 0x03);
261   EXPECT_TRUE(info.features.fp);
262   EXPECT_TRUE(info.features.asimd);
263   EXPECT_TRUE(info.features.crc32);
264   EXPECT_FALSE(info.features.aes);
265   EXPECT_FALSE(info.features.sha1);
266   EXPECT_FALSE(info.features.sha2);
267   EXPECT_FALSE(info.features.pmull);
268   EXPECT_FALSE(info.features.atomics);
269   EXPECT_FALSE(info.features.asimddp);
270   EXPECT_FALSE(info.features.jscvt);
271   EXPECT_FALSE(info.features.lrcpc);
272 }
273 #endif  // CPU_FEATURES_OS_WINDOWS
274 
275 }  // namespace
276 }  // namespace cpu_features
277