Rashmica Gupta | 3adafbf | 2018-04-23 10:46:47 +1000 | [diff] [blame] | 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 | |
Guillaume Chatelet | 22a5362 | 2020-09-23 11:52:20 +0200 | [diff] [blame] | 15 | #include "cpuinfo_ppc.h" |
| 16 | |
Dr.-Ing. Patrick Siegl | 22c05ed | 2019-06-29 22:02:23 +0200 | [diff] [blame] | 17 | #include <assert.h> |
Rashmica Gupta | 3adafbf | 2018-04-23 10:46:47 +1000 | [diff] [blame] | 18 | #include <stdbool.h> |
| 19 | #include <string.h> |
| 20 | |
Rashmica Gupta | 3adafbf | 2018-04-23 10:46:47 +1000 | [diff] [blame] | 21 | #include "internal/bit_utils.h" |
| 22 | #include "internal/filesystem.h" |
Rashmica Gupta | 3adafbf | 2018-04-23 10:46:47 +1000 | [diff] [blame] | 23 | #include "internal/stack_line_reader.h" |
| 24 | #include "internal/string_view.h" |
| 25 | |
Guillaume Chatelet | 9a8f04b | 2020-10-12 11:50:35 +0200 | [diff] [blame] | 26 | // Generation of feature's getters/setters functions and kGetters, kSetters, |
| 27 | // kCpuInfoFlags and kHardwareCapabilities global tables. |
Guillaume Chatelet | cdab59a | 2020-10-13 13:05:04 +0200 | [diff] [blame] | 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) |
Guillaume Chatelet | 9a8f04b | 2020-10-12 11:50:35 +0200 | [diff] [blame] | 76 | #define DEFINE_TABLE_FEATURE_TYPE PPCFeatures |
Guillaume Chatelet | 9a8f04b | 2020-10-12 11:50:35 +0200 | [diff] [blame] | 77 | #include "define_tables.h" |
Rashmica Gupta | 3adafbf | 2018-04-23 10:46:47 +1000 | [diff] [blame] | 78 | |
| 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 | |
| 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 | |
| 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; |
Guillaume Chatelet | 9a8f04b | 2020-10-12 11:50:35 +0200 | [diff] [blame] | 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 | } |
Rashmica Gupta | 3adafbf | 2018-04-23 10:46:47 +1000 | [diff] [blame] | 129 | return info; |
| 130 | } |
| 131 | |
| 132 | static const PPCPlatformStrings kEmptyPPCPlatformStrings; |
| 133 | |
| 134 | PPCPlatformStrings GetPPCPlatformStrings(void) { |
| 135 | PPCPlatformStrings strings = kEmptyPPCPlatformStrings; |
| 136 | |
| 137 | FillProcCpuInfoData(&strings); |
Rashmica Gupta | c45e32f | 2018-05-02 14:30:25 +1000 | [diff] [blame] | 138 | strings.type = CpuFeatures_GetPlatformType(); |
Rashmica Gupta | 3adafbf | 2018-04-23 10:46:47 +1000 | [diff] [blame] | 139 | return strings; |
| 140 | } |
| 141 | |
| 142 | //////////////////////////////////////////////////////////////////////////////// |
| 143 | // Introspection functions |
| 144 | |
| 145 | int GetPPCFeaturesEnumValue(const PPCFeatures* features, |
| 146 | PPCFeaturesEnum value) { |
Guillaume Chatelet | 9a8f04b | 2020-10-12 11:50:35 +0200 | [diff] [blame] | 147 | if (value >= PPC_LAST_) return false; |
| 148 | return kGetters[value](features); |
Rashmica Gupta | 3adafbf | 2018-04-23 10:46:47 +1000 | [diff] [blame] | 149 | } |
| 150 | |
Rashmica Gupta | 3adafbf | 2018-04-23 10:46:47 +1000 | [diff] [blame] | 151 | const char* GetPPCFeaturesEnumName(PPCFeaturesEnum value) { |
Guillaume Chatelet | 9a8f04b | 2020-10-12 11:50:35 +0200 | [diff] [blame] | 152 | if (value >= PPC_LAST_) return "unknown feature"; |
| 153 | return kCpuInfoFlags[value]; |
Rashmica Gupta | 3adafbf | 2018-04-23 10:46:47 +1000 | [diff] [blame] | 154 | } |