blob: 24401f906a8f15b4699c2c9d3cff4e9953bd92dc [file] [log] [blame]
Rashmica Gupta3adafbf2018-04-23 10:46:47 +10001// Copyright 2018 IBM.
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
Guillaume Chatelet22a53622020-09-23 11:52:20 +020015#include "cpuinfo_ppc.h"
16
Dr.-Ing. Patrick Siegl22c05ed2019-06-29 22:02:23 +020017#include <assert.h>
Rashmica Gupta3adafbf2018-04-23 10:46:47 +100018#include <stdbool.h>
19#include <string.h>
20
Rashmica Gupta3adafbf2018-04-23 10:46:47 +100021#include "internal/bit_utils.h"
22#include "internal/filesystem.h"
Rashmica Gupta3adafbf2018-04-23 10:46:47 +100023#include "internal/stack_line_reader.h"
24#include "internal/string_view.h"
25
Guillaume Chatelet9a8f04b2020-10-12 11:50:35 +020026// Generation of feature's getters/setters functions and kGetters, kSetters,
27// kCpuInfoFlags and kHardwareCapabilities global tables.
Guillaume Chateletcdab59a2020-10-13 13:05:04 +020028#define DEFINE_TABLE_FEATURES \
29 FEATURE(PPC_32, ppc32, "ppc32", PPC_FEATURE_32, 0) \
30 FEATURE(PPC_64, ppc64, "ppc64", PPC_FEATURE_64, 0) \
31 FEATURE(PPC_601_INSTR, ppc601, "ppc601", PPC_FEATURE_601_INSTR, 0) \
32 FEATURE(PPC_HAS_ALTIVEC, altivec, "altivec", PPC_FEATURE_HAS_ALTIVEC, 0) \
33 FEATURE(PPC_HAS_FPU, fpu, "fpu", PPC_FEATURE_HAS_FPU, 0) \
34 FEATURE(PPC_HAS_MMU, mmu, "mmu", PPC_FEATURE_HAS_MMU, 0) \
35 FEATURE(PPC_HAS_4xxMAC, mac_4xx, "4xxmac", PPC_FEATURE_HAS_4xxMAC, 0) \
36 FEATURE(PPC_UNIFIED_CACHE, unifiedcache, "ucache", \
37 PPC_FEATURE_UNIFIED_CACHE, 0) \
38 FEATURE(PPC_HAS_SPE, spe, "spe", PPC_FEATURE_HAS_SPE, 0) \
39 FEATURE(PPC_HAS_EFP_SINGLE, efpsingle, "efpsingle", \
40 PPC_FEATURE_HAS_EFP_SINGLE, 0) \
41 FEATURE(PPC_HAS_EFP_DOUBLE, efpdouble, "efpdouble", \
42 PPC_FEATURE_HAS_EFP_DOUBLE, 0) \
43 FEATURE(PPC_NO_TB, no_tb, "notb", PPC_FEATURE_NO_TB, 0) \
44 FEATURE(PPC_POWER4, power4, "power4", PPC_FEATURE_POWER4, 0) \
45 FEATURE(PPC_POWER5, power5, "power5", PPC_FEATURE_POWER5, 0) \
46 FEATURE(PPC_POWER5_PLUS, power5plus, "power5+", PPC_FEATURE_POWER5_PLUS, 0) \
47 FEATURE(PPC_CELL, cell, "cellbe", PPC_FEATURE_CELL, 0) \
48 FEATURE(PPC_BOOKE, booke, "booke", PPC_FEATURE_BOOKE, 0) \
49 FEATURE(PPC_SMT, smt, "smt", PPC_FEATURE_SMT, 0) \
50 FEATURE(PPC_ICACHE_SNOOP, icachesnoop, "ic_snoop", PPC_FEATURE_ICACHE_SNOOP, \
51 0) \
52 FEATURE(PPC_ARCH_2_05, arch205, "arch_2_05", PPC_FEATURE_ARCH_2_05, 0) \
53 FEATURE(PPC_PA6T, pa6t, "pa6t", PPC_FEATURE_PA6T, 0) \
54 FEATURE(PPC_HAS_DFP, dfp, "dfp", PPC_FEATURE_HAS_DFP, 0) \
55 FEATURE(PPC_POWER6_EXT, power6ext, "power6x", PPC_FEATURE_POWER6_EXT, 0) \
56 FEATURE(PPC_ARCH_2_06, arch206, "arch_2_06", PPC_FEATURE_ARCH_2_06, 0) \
57 FEATURE(PPC_HAS_VSX, vsx, "vsx", PPC_FEATURE_HAS_VSX, 0) \
58 FEATURE(PPC_PSERIES_PERFMON_COMPAT, pseries_perfmon_compat, "archpmu", \
59 PPC_FEATURE_PSERIES_PERFMON_COMPAT, 0) \
60 FEATURE(PPC_TRUE_LE, truele, "true_le", PPC_FEATURE_TRUE_LE, 0) \
61 FEATURE(PPC_PPC_LE, ppcle, "ppcle", PPC_FEATURE_PPC_LE, 0) \
62 FEATURE(PPC_ARCH_2_07, arch207, "arch_2_07", 0, PPC_FEATURE2_ARCH_2_07) \
63 FEATURE(PPC_HTM, htm, "htm", 0, PPC_FEATURE2_HTM) \
64 FEATURE(PPC_DSCR, dscr, "dscr", 0, PPC_FEATURE2_DSCR) \
65 FEATURE(PPC_EBB, ebb, "ebb", 0, PPC_FEATURE2_EBB) \
66 FEATURE(PPC_ISEL, isel, "isel", 0, PPC_FEATURE2_ISEL) \
67 FEATURE(PPC_TAR, tar, "tar", 0, PPC_FEATURE2_TAR) \
68 FEATURE(PPC_VEC_CRYPTO, vcrypto, "vcrypto", 0, PPC_FEATURE2_VEC_CRYPTO) \
69 FEATURE(PPC_HTM_NOSC, htm_nosc, "htm-nosc", 0, PPC_FEATURE2_HTM_NOSC) \
70 FEATURE(PPC_ARCH_3_00, arch300, "arch_3_00", 0, PPC_FEATURE2_ARCH_3_00) \
71 FEATURE(PPC_HAS_IEEE128, ieee128, "ieee128", 0, PPC_FEATURE2_HAS_IEEE128) \
72 FEATURE(PPC_DARN, darn, "darn", 0, PPC_FEATURE2_DARN) \
73 FEATURE(PPC_SCV, scv, "scv", 0, PPC_FEATURE2_SCV) \
74 FEATURE(PPC_HTM_NO_SUSPEND, htm_no_suspend, "htm-no-suspend", 0, \
75 PPC_FEATURE2_HTM_NO_SUSPEND)
Guillaume Chatelet9a8f04b2020-10-12 11:50:35 +020076#define DEFINE_TABLE_FEATURE_TYPE PPCFeatures
Guillaume Chatelet9a8f04b2020-10-12 11:50:35 +020077#include "define_tables.h"
Rashmica Gupta3adafbf2018-04-23 10:46:47 +100078
79static bool HandlePPCLine(const LineResult result,
80 PPCPlatformStrings* const strings) {
81 StringView line = result.line;
82 StringView key, value;
83 if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) {
84 if (CpuFeatures_StringView_HasWord(key, "platform")) {
85 CpuFeatures_StringView_CopyString(value, strings->platform,
86 sizeof(strings->platform));
87 } else if (CpuFeatures_StringView_IsEquals(key, str("model"))) {
88 CpuFeatures_StringView_CopyString(value, strings->model,
89 sizeof(strings->platform));
90 } else if (CpuFeatures_StringView_IsEquals(key, str("machine"))) {
91 CpuFeatures_StringView_CopyString(value, strings->machine,
92 sizeof(strings->platform));
93 } else if (CpuFeatures_StringView_IsEquals(key, str("cpu"))) {
94 CpuFeatures_StringView_CopyString(value, strings->cpu,
95 sizeof(strings->platform));
96 }
97 }
98 return !result.eof;
99}
100
101static void FillProcCpuInfoData(PPCPlatformStrings* const strings) {
102 const int fd = CpuFeatures_OpenFile("/proc/cpuinfo");
103 if (fd >= 0) {
104 StackLineReader reader;
105 StackLineReader_Initialize(&reader, fd);
106 for (;;) {
107 if (!HandlePPCLine(StackLineReader_NextLine(&reader), strings)) {
108 break;
109 }
110 }
111 CpuFeatures_CloseFile(fd);
112 }
113}
114
115static const PPCInfo kEmptyPPCInfo;
116
117PPCInfo GetPPCInfo(void) {
118 /*
119 * On Power feature flags aren't currently in cpuinfo so we only look at
120 * the auxilary vector.
121 */
122 PPCInfo info = kEmptyPPCInfo;
Guillaume Chatelet9a8f04b2020-10-12 11:50:35 +0200123 const HardwareCapabilities hwcaps = CpuFeatures_GetHardwareCapabilities();
124 for (size_t i = 0; i < PPC_LAST_; ++i) {
125 if (CpuFeatures_IsHwCapsSet(kHardwareCapabilities[i], hwcaps)) {
126 kSetters[i](&info.features, true);
127 }
128 }
Rashmica Gupta3adafbf2018-04-23 10:46:47 +1000129 return info;
130}
131
132static const PPCPlatformStrings kEmptyPPCPlatformStrings;
133
134PPCPlatformStrings GetPPCPlatformStrings(void) {
135 PPCPlatformStrings strings = kEmptyPPCPlatformStrings;
136
137 FillProcCpuInfoData(&strings);
Rashmica Guptac45e32f2018-05-02 14:30:25 +1000138 strings.type = CpuFeatures_GetPlatformType();
Rashmica Gupta3adafbf2018-04-23 10:46:47 +1000139 return strings;
140}
141
142////////////////////////////////////////////////////////////////////////////////
143// Introspection functions
144
145int GetPPCFeaturesEnumValue(const PPCFeatures* features,
146 PPCFeaturesEnum value) {
Guillaume Chatelet9a8f04b2020-10-12 11:50:35 +0200147 if (value >= PPC_LAST_) return false;
148 return kGetters[value](features);
Rashmica Gupta3adafbf2018-04-23 10:46:47 +1000149}
150
Rashmica Gupta3adafbf2018-04-23 10:46:47 +1000151const char* GetPPCFeaturesEnumName(PPCFeaturesEnum value) {
Guillaume Chatelet9a8f04b2020-10-12 11:50:35 +0200152 if (value >= PPC_LAST_) return "unknown feature";
153 return kCpuInfoFlags[value];
Rashmica Gupta3adafbf2018-04-23 10:46:47 +1000154}