blob: 83e959fe94c9382f83053ca26b9e419f33fe37b7 [file] [log] [blame]
Guillaume Chatelet3cc8f312020-10-12 08:55:20 +00001// Copyright 2017 Google LLC
Guillaume Chatelet439d3712018-02-01 10:03:09 +01002//
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_mips.h"
16
Guillaume Chatelet22a53622020-09-23 11:52:20 +020017#include <assert.h>
18
Guillaume Chatelet439d3712018-02-01 10:03:09 +010019#include "internal/filesystem.h"
Guillaume Chatelet9a8f04b2020-10-12 11:50:35 +020020#include "internal/hwcaps.h"
Guillaume Chatelet439d3712018-02-01 10:03:09 +010021#include "internal/stack_line_reader.h"
22#include "internal/string_view.h"
23
Guillaume Chatelet9a8f04b2020-10-12 11:50:35 +020024// Generation of feature's getters/setters functions and kGetters, kSetters,
25// kCpuInfoFlags and kHardwareCapabilities global tables.
Guillaume Chateletcdab59a2020-10-13 13:05:04 +020026#define DEFINE_TABLE_FEATURES \
27 FEATURE(MIPS_MSA, msa, "msa", MIPS_HWCAP_MSA, 0) \
28 FEATURE(MIPS_EVA, eva, "eva", 0, 0) \
29 FEATURE(MIPS_R6, r6, "r6", MIPS_HWCAP_R6, 0)
Guillaume Chatelet9a8f04b2020-10-12 11:50:35 +020030#define DEFINE_TABLE_FEATURE_TYPE MipsFeatures
Guillaume Chatelet9a8f04b2020-10-12 11:50:35 +020031#include "define_tables.h"
Guillaume Chatelet439d3712018-02-01 10:03:09 +010032
33static bool HandleMipsLine(const LineResult result,
34 MipsFeatures* const features) {
35 StringView key, value;
36 // See tests for an example.
Arvid Gerstmanna1ffdcb2018-04-26 10:31:03 +020037 if (CpuFeatures_StringView_GetAttributeKeyValue(result.line, &key, &value)) {
38 if (CpuFeatures_StringView_IsEquals(key, str("ASEs implemented"))) {
Guillaume Chatelet9a8f04b2020-10-12 11:50:35 +020039 for (size_t i = 0; i < MIPS_LAST_; ++i) {
40 kSetters[i](features,
41 CpuFeatures_StringView_HasWord(value, kCpuInfoFlags[i]));
42 }
Guillaume Chatelet439d3712018-02-01 10:03:09 +010043 }
44 }
45 return !result.eof;
46}
47
48static void FillProcCpuInfoData(MipsFeatures* const features) {
Arvid Gerstmanna1ffdcb2018-04-26 10:31:03 +020049 const int fd = CpuFeatures_OpenFile("/proc/cpuinfo");
Guillaume Chatelet439d3712018-02-01 10:03:09 +010050 if (fd >= 0) {
51 StackLineReader reader;
52 StackLineReader_Initialize(&reader, fd);
53 for (;;) {
54 if (!HandleMipsLine(StackLineReader_NextLine(&reader), features)) {
55 break;
56 }
57 }
Arvid Gerstmanna1ffdcb2018-04-26 10:31:03 +020058 CpuFeatures_CloseFile(fd);
Guillaume Chatelet439d3712018-02-01 10:03:09 +010059 }
60}
61
62static const MipsInfo kEmptyMipsInfo;
63
64MipsInfo GetMipsInfo(void) {
65 // capabilities are fetched from both getauxval and /proc/cpuinfo so we can
66 // have some information if the executable is sandboxed (aka no access to
67 // /proc/cpuinfo).
68 MipsInfo info = kEmptyMipsInfo;
69
70 FillProcCpuInfoData(&info.features);
Guillaume Chatelet9a8f04b2020-10-12 11:50:35 +020071 const HardwareCapabilities hwcaps = CpuFeatures_GetHardwareCapabilities();
72 for (size_t i = 0; i < MIPS_LAST_; ++i) {
73 if (CpuFeatures_IsHwCapsSet(kHardwareCapabilities[i], hwcaps)) {
74 kSetters[i](&info.features, true);
75 }
76 }
Guillaume Chatelet439d3712018-02-01 10:03:09 +010077 return info;
78}
79
80////////////////////////////////////////////////////////////////////////////////
81// Introspection functions
82
83int GetMipsFeaturesEnumValue(const MipsFeatures* features,
84 MipsFeaturesEnum value) {
Guillaume Chatelet9a8f04b2020-10-12 11:50:35 +020085 if (value >= MIPS_LAST_) return false;
86 return kGetters[value](features);
Guillaume Chatelet439d3712018-02-01 10:03:09 +010087}
88
89const char* GetMipsFeaturesEnumName(MipsFeaturesEnum value) {
Guillaume Chatelet9a8f04b2020-10-12 11:50:35 +020090 if (value >= MIPS_LAST_) return "unknown feature";
91 return kCpuInfoFlags[value];
Guillaume Chatelet439d3712018-02-01 10:03:09 +010092}