1 // Licensed under the Apache License, Version 2.0 (the "License");
2 // you may not use this file except in compliance with the License.
3 // You may obtain a copy of the License at
4 //
5 // http://www.apache.org/licenses/LICENSE-2.0
6 //
7 // Unless required by applicable law or agreed to in writing, software
8 // distributed under the License is distributed on an "AS IS" BASIS,
9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 // See the License for the specific language governing permissions and
11 // limitations under the License.
12
13 #include "cpu_features_macros.h"
14
15 #ifdef CPU_FEATURES_ARCH_MIPS
16 #if defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)
17
18 #include "cpuinfo_mips.h"
19
20 ////////////////////////////////////////////////////////////////////////////////
21 // Definitions for introspection.
22 ////////////////////////////////////////////////////////////////////////////////
23 #define INTROSPECTION_TABLE \
24 LINE(MIPS_MSA, msa, "msa", MIPS_HWCAP_MSA, 0) \
25 LINE(MIPS_EVA, eva, "eva", 0, 0) \
26 LINE(MIPS_R6, r6, "r6", MIPS_HWCAP_R6, 0)
27 #define INTROSPECTION_PREFIX Mips
28 #define INTROSPECTION_ENUM_PREFIX MIPS
29 #include "define_introspection_and_hwcaps.inl"
30
31 ////////////////////////////////////////////////////////////////////////////////
32 // Implementation.
33 ////////////////////////////////////////////////////////////////////////////////
34
35 #include "internal/filesystem.h"
36 #include "internal/hwcaps.h"
37 #include "internal/stack_line_reader.h"
38 #include "internal/string_view.h"
39
HandleMipsLine(const LineResult result,MipsFeatures * const features)40 static bool HandleMipsLine(const LineResult result,
41 MipsFeatures* const features) {
42 StringView key, value;
43 // See tests for an example.
44 if (CpuFeatures_StringView_GetAttributeKeyValue(result.line, &key, &value)) {
45 if (CpuFeatures_StringView_IsEquals(key, str("ASEs implemented"))) {
46 for (size_t i = 0; i < MIPS_LAST_; ++i) {
47 kSetters[i](features, CpuFeatures_StringView_HasWord(
48 value, kCpuInfoFlags[i], ' '));
49 }
50 }
51 }
52 return !result.eof;
53 }
54
FillProcCpuInfoData(MipsFeatures * const features)55 static void FillProcCpuInfoData(MipsFeatures* const features) {
56 const int fd = CpuFeatures_OpenFile("/proc/cpuinfo");
57 if (fd >= 0) {
58 StackLineReader reader;
59 StackLineReader_Initialize(&reader, fd);
60 for (;;) {
61 if (!HandleMipsLine(StackLineReader_NextLine(&reader), features)) {
62 break;
63 }
64 }
65 CpuFeatures_CloseFile(fd);
66 }
67 }
68
69 static const MipsInfo kEmptyMipsInfo;
70
GetMipsInfo(void)71 MipsInfo GetMipsInfo(void) {
72 // capabilities are fetched from both getauxval and /proc/cpuinfo so we can
73 // have some information if the executable is sandboxed (aka no access to
74 // /proc/cpuinfo).
75 MipsInfo info = kEmptyMipsInfo;
76
77 FillProcCpuInfoData(&info.features);
78 const HardwareCapabilities hwcaps = CpuFeatures_GetHardwareCapabilities();
79 for (size_t i = 0; i < MIPS_LAST_; ++i) {
80 if (CpuFeatures_IsHwCapsSet(kHardwareCapabilities[i], hwcaps)) {
81 kSetters[i](&info.features, true);
82 }
83 }
84 return info;
85 }
86
87 #endif // defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)
88 #endif // CPU_FEATURES_ARCH_MIPS
89