1 // 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
15 #include "cpu_features_macros.h"
16
17 #ifdef CPU_FEATURES_ARCH_PPC
18 #ifdef CPU_FEATURES_OS_LINUX
19
20 #include "cpuinfo_ppc.h"
21
22 ////////////////////////////////////////////////////////////////////////////////
23 // Definitions for introspection.
24 ////////////////////////////////////////////////////////////////////////////////
25 #define INTROSPECTION_TABLE \
26 LINE(PPC_32, ppc32, "ppc32", PPC_FEATURE_32, 0) \
27 LINE(PPC_64, ppc64, "ppc64", PPC_FEATURE_64, 0) \
28 LINE(PPC_601_INSTR, ppc601, "ppc601", PPC_FEATURE_601_INSTR, 0) \
29 LINE(PPC_HAS_ALTIVEC, altivec, "altivec", PPC_FEATURE_HAS_ALTIVEC, 0) \
30 LINE(PPC_HAS_FPU, fpu, "fpu", PPC_FEATURE_HAS_FPU, 0) \
31 LINE(PPC_HAS_MMU, mmu, "mmu", PPC_FEATURE_HAS_MMU, 0) \
32 LINE(PPC_HAS_4xxMAC, mac_4xx, "4xxmac", PPC_FEATURE_HAS_4xxMAC, 0) \
33 LINE(PPC_UNIFIED_CACHE, unifiedcache, "ucache", PPC_FEATURE_UNIFIED_CACHE, \
34 0) \
35 LINE(PPC_HAS_SPE, spe, "spe", PPC_FEATURE_HAS_SPE, 0) \
36 LINE(PPC_HAS_EFP_SINGLE, efpsingle, "efpsingle", PPC_FEATURE_HAS_EFP_SINGLE, \
37 0) \
38 LINE(PPC_HAS_EFP_DOUBLE, efpdouble, "efpdouble", PPC_FEATURE_HAS_EFP_DOUBLE, \
39 0) \
40 LINE(PPC_NO_TB, no_tb, "notb", PPC_FEATURE_NO_TB, 0) \
41 LINE(PPC_POWER4, power4, "power4", PPC_FEATURE_POWER4, 0) \
42 LINE(PPC_POWER5, power5, "power5", PPC_FEATURE_POWER5, 0) \
43 LINE(PPC_POWER5_PLUS, power5plus, "power5+", PPC_FEATURE_POWER5_PLUS, 0) \
44 LINE(PPC_CELL, cell, "cellbe", PPC_FEATURE_CELL, 0) \
45 LINE(PPC_BOOKE, booke, "booke", PPC_FEATURE_BOOKE, 0) \
46 LINE(PPC_SMT, smt, "smt", PPC_FEATURE_SMT, 0) \
47 LINE(PPC_ICACHE_SNOOP, icachesnoop, "ic_snoop", PPC_FEATURE_ICACHE_SNOOP, 0) \
48 LINE(PPC_ARCH_2_05, arch205, "arch_2_05", PPC_FEATURE_ARCH_2_05, 0) \
49 LINE(PPC_PA6T, pa6t, "pa6t", PPC_FEATURE_PA6T, 0) \
50 LINE(PPC_HAS_DFP, dfp, "dfp", PPC_FEATURE_HAS_DFP, 0) \
51 LINE(PPC_POWER6_EXT, power6ext, "power6x", PPC_FEATURE_POWER6_EXT, 0) \
52 LINE(PPC_ARCH_2_06, arch206, "arch_2_06", PPC_FEATURE_ARCH_2_06, 0) \
53 LINE(PPC_HAS_VSX, vsx, "vsx", PPC_FEATURE_HAS_VSX, 0) \
54 LINE(PPC_PSERIES_PERFMON_COMPAT, pseries_perfmon_compat, "archpmu", \
55 PPC_FEATURE_PSERIES_PERFMON_COMPAT, 0) \
56 LINE(PPC_TRUE_LE, truele, "true_le", PPC_FEATURE_TRUE_LE, 0) \
57 LINE(PPC_PPC_LE, ppcle, "ppcle", PPC_FEATURE_PPC_LE, 0) \
58 LINE(PPC_ARCH_2_07, arch207, "arch_2_07", 0, PPC_FEATURE2_ARCH_2_07) \
59 LINE(PPC_HTM, htm, "htm", 0, PPC_FEATURE2_HTM) \
60 LINE(PPC_DSCR, dscr, "dscr", 0, PPC_FEATURE2_DSCR) \
61 LINE(PPC_EBB, ebb, "ebb", 0, PPC_FEATURE2_EBB) \
62 LINE(PPC_ISEL, isel, "isel", 0, PPC_FEATURE2_ISEL) \
63 LINE(PPC_TAR, tar, "tar", 0, PPC_FEATURE2_TAR) \
64 LINE(PPC_VEC_CRYPTO, vcrypto, "vcrypto", 0, PPC_FEATURE2_VEC_CRYPTO) \
65 LINE(PPC_HTM_NOSC, htm_nosc, "htm-nosc", 0, PPC_FEATURE2_HTM_NOSC) \
66 LINE(PPC_ARCH_3_00, arch300, "arch_3_00", 0, PPC_FEATURE2_ARCH_3_00) \
67 LINE(PPC_HAS_IEEE128, ieee128, "ieee128", 0, PPC_FEATURE2_HAS_IEEE128) \
68 LINE(PPC_DARN, darn, "darn", 0, PPC_FEATURE2_DARN) \
69 LINE(PPC_SCV, scv, "scv", 0, PPC_FEATURE2_SCV) \
70 LINE(PPC_HTM_NO_SUSPEND, htm_no_suspend, "htm-no-suspend", 0, \
71 PPC_FEATURE2_HTM_NO_SUSPEND)
72 #undef PPC // Remove conflict with compiler generated preprocessor
73 #define INTROSPECTION_PREFIX PPC
74 #define INTROSPECTION_ENUM_PREFIX PPC
75 #include "define_introspection_and_hwcaps.inl"
76
77 ////////////////////////////////////////////////////////////////////////////////
78 // Implementation.
79 ////////////////////////////////////////////////////////////////////////////////
80
81 #include <stdbool.h>
82
83 #include "internal/bit_utils.h"
84 #include "internal/filesystem.h"
85 #include "internal/hwcaps.h"
86 #include "internal/stack_line_reader.h"
87 #include "internal/string_view.h"
88
HandlePPCLine(const LineResult result,PPCPlatformStrings * const strings)89 static bool HandlePPCLine(const LineResult result,
90 PPCPlatformStrings* const strings) {
91 StringView line = result.line;
92 StringView key, value;
93 if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) {
94 if (CpuFeatures_StringView_HasWord(key, "platform", ' ')) {
95 CpuFeatures_StringView_CopyString(value, strings->platform,
96 sizeof(strings->platform));
97 } else if (CpuFeatures_StringView_IsEquals(key, str("model"))) {
98 CpuFeatures_StringView_CopyString(value, strings->model,
99 sizeof(strings->platform));
100 } else if (CpuFeatures_StringView_IsEquals(key, str("machine"))) {
101 CpuFeatures_StringView_CopyString(value, strings->machine,
102 sizeof(strings->platform));
103 } else if (CpuFeatures_StringView_IsEquals(key, str("cpu"))) {
104 CpuFeatures_StringView_CopyString(value, strings->cpu,
105 sizeof(strings->platform));
106 }
107 }
108 return !result.eof;
109 }
110
FillProcCpuInfoData(PPCPlatformStrings * const strings)111 static void FillProcCpuInfoData(PPCPlatformStrings* const strings) {
112 const int fd = CpuFeatures_OpenFile("/proc/cpuinfo");
113 if (fd >= 0) {
114 StackLineReader reader;
115 StackLineReader_Initialize(&reader, fd);
116 for (;;) {
117 if (!HandlePPCLine(StackLineReader_NextLine(&reader), strings)) {
118 break;
119 }
120 }
121 CpuFeatures_CloseFile(fd);
122 }
123 }
124
125 static const PPCInfo kEmptyPPCInfo;
126
GetPPCInfo(void)127 PPCInfo GetPPCInfo(void) {
128 /*
129 * On Power feature flags aren't currently in cpuinfo so we only look at
130 * the auxilary vector.
131 */
132 PPCInfo info = kEmptyPPCInfo;
133 const HardwareCapabilities hwcaps = CpuFeatures_GetHardwareCapabilities();
134 for (size_t i = 0; i < PPC_LAST_; ++i) {
135 if (CpuFeatures_IsHwCapsSet(kHardwareCapabilities[i], hwcaps)) {
136 kSetters[i](&info.features, true);
137 }
138 }
139 return info;
140 }
141
142 static const PPCPlatformStrings kEmptyPPCPlatformStrings;
143
GetPPCPlatformStrings(void)144 PPCPlatformStrings GetPPCPlatformStrings(void) {
145 PPCPlatformStrings strings = kEmptyPPCPlatformStrings;
146 const char* platform = CpuFeatures_GetPlatformPointer();
147 const char* base_platform = CpuFeatures_GetBasePlatformPointer();
148
149 FillProcCpuInfoData(&strings);
150
151 if (platform != NULL)
152 CpuFeatures_StringView_CopyString(str(platform), strings.type.platform,
153 sizeof(strings.type.platform));
154 if (base_platform != NULL)
155 CpuFeatures_StringView_CopyString(str(base_platform),
156 strings.type.base_platform,
157 sizeof(strings.type.base_platform));
158
159 return strings;
160 }
161
162 #endif // CPU_FEATURES_OS_LINUX
163 #endif // CPU_FEATURES_ARCH_PPC
164