1 // Copyright 2017 Google Inc.
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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.
15 #include "cpuinfo_aarch64.h"
17 #include "internal/filesystem.h"
18 #include "internal/hwcaps.h"
19 #include "internal/linux_features_aggregator.h"
20 #include "internal/stack_line_reader.h"
21 #include "internal/string_view.h"
25 DECLARE_SETTER(Aarch64Features, fp)
26 DECLARE_SETTER(Aarch64Features, asimd)
27 DECLARE_SETTER(Aarch64Features, aes)
28 DECLARE_SETTER(Aarch64Features, pmull)
29 DECLARE_SETTER(Aarch64Features, sha1)
30 DECLARE_SETTER(Aarch64Features, sha2)
31 DECLARE_SETTER(Aarch64Features, crc32)
33 static const CapabilityConfig kConfigs[] = {
34 {{AARCH64_HWCAP_FP, 0}, "fp", &set_fp}, //
35 {{AARCH64_HWCAP_ASIMD, 0}, "asimd", &set_asimd}, //
36 {{AARCH64_HWCAP_AES, 0}, "aes", &set_aes}, //
37 {{AARCH64_HWCAP_PMULL, 0}, "pmull", &set_pmull}, //
38 {{AARCH64_HWCAP_SHA1, 0}, "sha1", &set_sha1}, //
39 {{AARCH64_HWCAP_SHA2, 0}, "sha2", &set_sha2}, //
40 {{AARCH64_HWCAP_CRC32, 0}, "crc32", &set_crc32}, //
43 static const size_t kConfigsSize = sizeof(kConfigs) / sizeof(CapabilityConfig);
45 static bool HandleAarch64Line(const LineResult result,
46 Aarch64Info* const info) {
47 StringView line = result.line;
48 StringView key, value;
49 if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) {
50 if (CpuFeatures_StringView_IsEquals(key, str("Features"))) {
51 CpuFeatures_SetFromFlags(kConfigsSize, kConfigs, value, &info->features);
52 } else if (CpuFeatures_StringView_IsEquals(key, str("CPU implementer"))) {
53 info->implementer = CpuFeatures_StringView_ParsePositiveNumber(value);
54 } else if (CpuFeatures_StringView_IsEquals(key, str("CPU variant"))) {
55 info->variant = CpuFeatures_StringView_ParsePositiveNumber(value);
56 } else if (CpuFeatures_StringView_IsEquals(key, str("CPU part"))) {
57 info->part = CpuFeatures_StringView_ParsePositiveNumber(value);
58 } else if (CpuFeatures_StringView_IsEquals(key, str("CPU revision"))) {
59 info->revision = CpuFeatures_StringView_ParsePositiveNumber(value);
65 static void FillProcCpuInfoData(Aarch64Info* const info) {
66 const int fd = CpuFeatures_OpenFile("/proc/cpuinfo");
68 StackLineReader reader;
69 StackLineReader_Initialize(&reader, fd);
71 if (!HandleAarch64Line(StackLineReader_NextLine(&reader), info)) {
75 CpuFeatures_CloseFile(fd);
79 static const Aarch64Info kEmptyAarch64Info;
81 Aarch64Info GetAarch64Info(void) {
82 // capabilities are fetched from both getauxval and /proc/cpuinfo so we can
83 // have some information if the executable is sandboxed (aka no access to
85 Aarch64Info info = kEmptyAarch64Info;
87 FillProcCpuInfoData(&info);
88 CpuFeatures_OverrideFromHwCaps(kConfigsSize, kConfigs,
89 CpuFeatures_GetHardwareCapabilities(),
95 ////////////////////////////////////////////////////////////////////////////////
96 // Introspection functions
98 int GetAarch64FeaturesEnumValue(const Aarch64Features* features,
99 Aarch64FeaturesEnum value) {
104 return features->asimd;
106 return features->aes;
108 return features->pmull;
110 return features->sha1;
112 return features->sha2;
114 return features->crc32;
121 const char* GetAarch64FeaturesEnumName(Aarch64FeaturesEnum value) {
140 return "unknown feature";