• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "cpuinfo_ppc.h"
16 
17 #include <assert.h>
18 #include <stdbool.h>
19 #include <string.h>
20 
21 #include "internal/bit_utils.h"
22 #include "internal/filesystem.h"
23 #include "internal/stack_line_reader.h"
24 #include "internal/string_view.h"
25 
26 // Generation of feature's getters/setters functions and kGetters, kSetters,
27 // kCpuInfoFlags and kHardwareCapabilities global tables.
28 #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)
76 #define DEFINE_TABLE_FEATURE_TYPE PPCFeatures
77 #include "define_tables.h"
78 
HandlePPCLine(const LineResult result,PPCPlatformStrings * const strings)79 static 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 
FillProcCpuInfoData(PPCPlatformStrings * const strings)101 static 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 
115 static const PPCInfo kEmptyPPCInfo;
116 
GetPPCInfo(void)117 PPCInfo 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;
123   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   }
129   return info;
130 }
131 
132 static const PPCPlatformStrings kEmptyPPCPlatformStrings;
133 
GetPPCPlatformStrings(void)134 PPCPlatformStrings GetPPCPlatformStrings(void) {
135   PPCPlatformStrings strings = kEmptyPPCPlatformStrings;
136 
137   FillProcCpuInfoData(&strings);
138   strings.type = CpuFeatures_GetPlatformType();
139   return strings;
140 }
141 
142 ////////////////////////////////////////////////////////////////////////////////
143 // Introspection functions
144 
GetPPCFeaturesEnumValue(const PPCFeatures * features,PPCFeaturesEnum value)145 int GetPPCFeaturesEnumValue(const PPCFeatures* features,
146                             PPCFeaturesEnum value) {
147   if (value >= PPC_LAST_) return false;
148   return kGetters[value](features);
149 }
150 
GetPPCFeaturesEnumName(PPCFeaturesEnum value)151 const char* GetPPCFeaturesEnumName(PPCFeaturesEnum value) {
152   if (value >= PPC_LAST_) return "unknown feature";
153   return kCpuInfoFlags[value];
154 }
155