1 // Copyright 2018 The BoringSSL Authors
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 //     https://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 "cpu_arm_linux.h"
16 
17 #include <string.h>
18 
19 #include <gtest/gtest.h>
20 
21 
22 namespace {
23 
TEST(ARMLinuxTest,CPUInfo)24 TEST(ARMLinuxTest, CPUInfo) {
25   struct CPUInfoTest {
26     const char *cpuinfo;
27     unsigned long hwcap2;
28   } kTests[] = {
29       // Nexus 4 from https://crbug.com/341598#c43
30       {
31           "Processor       : ARMv7 Processor rev 2 (v7l)\n"
32           "processor       : 0\n"
33           "BogoMIPS        : 13.53\n"
34           "\n"
35           "processor       : 1\n"
36           "BogoMIPS        : 13.53\n"
37           "\n"
38           "processor       : 2\n"
39           "BogoMIPS        : 13.53\n"
40           "\n"
41           "processor       : 3\n"
42           "BogoMIPS        : 13.53\n"
43           "\n"
44           "Features        : swp half thumb fastmult vfp edsp neon vfpv3 tls "
45           "vfpv4 \n"
46           "CPU implementer : 0x51\n"
47           "CPU architecture: 7\n"
48           "CPU variant     : 0x0\n"
49           "CPU part        : 0x06f\n"
50           "CPU revision    : 2\n"
51           "\n"
52           "Hardware        : QCT APQ8064 MAKO\n"
53           "Revision        : 000b\n"
54           "Serial          : 0000000000000000\n",
55           0,
56       },
57       // Pixel 2 (truncated slightly)
58       {
59           "Processor       : AArch64 Processor rev 1 (aarch64)\n"
60           "processor       : 0\n"
61           "BogoMIPS        : 38.00\n"
62           "Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32\n"
63           "CPU implementer : 0x51\n"
64           "CPU architecture: 8\n"
65           "CPU variant     : 0xa\n"
66           "CPU part        : 0x801\n"
67           "CPU revision    : 4\n"
68           "\n"
69           "processor       : 1\n"
70           "BogoMIPS        : 38.00\n"
71           "Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32\n"
72           "CPU implementer : 0x51\n"
73           "CPU architecture: 8\n"
74           "CPU variant     : 0xa\n"
75           "CPU part        : 0x801\n"
76           "CPU revision    : 4\n"
77           "\n"
78           "processor       : 2\n"
79           "BogoMIPS        : 38.00\n"
80           "Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32\n"
81           "CPU implementer : 0x51\n"
82           "CPU architecture: 8\n"
83           "CPU variant     : 0xa\n"
84           "CPU part        : 0x801\n"
85           "CPU revision    : 4\n"
86           "\n"
87           "processor       : 3\n"
88           "BogoMIPS        : 38.00\n"
89           "Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32\n"
90           "CPU implementer : 0x51\n"
91           "CPU architecture: 8\n"
92           "CPU variant     : 0xa\n"
93           "CPU part        : 0x801\n"
94           "CPU revision    : 4\n"
95           // (Extra processors omitted.)
96           "\n"
97           "Hardware        : Qualcomm Technologies, Inc MSM8998\n",
98           CRYPTO_HWCAP2_AES | CRYPTO_HWCAP2_PMULL | CRYPTO_HWCAP2_SHA1 |
99               CRYPTO_HWCAP2_SHA2,
100       },
101       // Garbage should be tolerated.
102       {
103           "Blah blah blah this is definitely an ARM CPU",
104           0,
105       },
106       // A hypothetical ARMv8 CPU without crc32 (and thus no trailing space
107       // after the last crypto entry).
108       {
109           "Features        : aes pmull sha1 sha2\n"
110           "CPU architecture: 8\n",
111           CRYPTO_HWCAP2_AES | CRYPTO_HWCAP2_PMULL | CRYPTO_HWCAP2_SHA1 |
112               CRYPTO_HWCAP2_SHA2,
113       },
114       // Various combinations of ARMv8 flags.
115       {
116           "Features        : aes sha1 sha2\n"
117           "CPU architecture: 8\n",
118           CRYPTO_HWCAP2_AES | CRYPTO_HWCAP2_SHA1 | CRYPTO_HWCAP2_SHA2,
119       },
120       {
121           "Features        : pmull sha2\n"
122           "CPU architecture: 8\n",
123           CRYPTO_HWCAP2_PMULL | CRYPTO_HWCAP2_SHA2,
124       },
125       {
126           "Features        : aes aes   aes not_aes aes aes \n"
127           "CPU architecture: 8\n",
128           CRYPTO_HWCAP2_AES,
129       },
130       {
131           "Features        : \n"
132           "CPU architecture: 8\n",
133           0,
134       },
135       {
136           "Features        : nothing\n"
137           "CPU architecture: 8\n",
138           0,
139       },
140       // If opening /proc/cpuinfo fails, we process the empty string.
141       {
142           "",
143           0,
144       },
145   };
146 
147   for (const auto &t : kTests) {
148     SCOPED_TRACE(t.cpuinfo);
149     STRING_PIECE sp = {t.cpuinfo, strlen(t.cpuinfo)};
150     EXPECT_EQ(t.hwcap2, crypto_get_arm_hwcap2_from_cpuinfo(&sp));
151   }
152 }
153 
154 }  // namespace
155