| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 1 | /* | 
|  | 2 | // Copyright (c) 2018 Intel Corporation | 
|  | 3 | // | 
|  | 4 | // Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 5 | // you may not use this file except in compliance with the License. | 
|  | 6 | // You may obtain a copy of the License at | 
|  | 7 | // | 
|  | 8 | //      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 9 | // | 
|  | 10 | // Unless required by applicable law or agreed to in writing, software | 
|  | 11 | // distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 13 | // See the License for the specific language governing permissions and | 
|  | 14 | // limitations under the License. | 
|  | 15 | */ | 
|  | 16 |  | 
|  | 17 | #include "cpu.hpp" | 
|  | 18 |  | 
| Zhikui Ren | 18a5ab9 | 2020-09-01 21:35:20 -0700 | [diff] [blame] | 19 | #include <bitset> | 
| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 20 | #include <map> | 
|  | 21 |  | 
|  | 22 | namespace phosphor | 
|  | 23 | { | 
|  | 24 | namespace smbios | 
|  | 25 | { | 
|  | 26 |  | 
| Zhikui Ren | 18a5ab9 | 2020-09-01 21:35:20 -0700 | [diff] [blame] | 27 | void Cpu::socket(const uint8_t positionNum, const uint8_t structLen, | 
|  | 28 | uint8_t* dataIn) | 
| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 29 | { | 
|  | 30 | std::string result = positionToString(positionNum, structLen, dataIn); | 
|  | 31 |  | 
| Zhikui Ren | 18a5ab9 | 2020-09-01 21:35:20 -0700 | [diff] [blame] | 32 | processor::socket(result); | 
| Jie Yang | 3172039 | 2021-07-22 21:45:45 -0700 | [diff] [blame] | 33 |  | 
|  | 34 | location::locationCode(result); | 
| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 35 | } | 
|  | 36 |  | 
| Charles Boyer | 800bb70 | 2021-08-31 17:09:19 -0500 | [diff] [blame] | 37 | static constexpr uint8_t processorFamily2Indicator = 0xfe; | 
|  | 38 | void Cpu::family(const uint8_t family, const uint16_t family2) | 
| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 39 | { | 
| Charles Boyer | 800bb70 | 2021-08-31 17:09:19 -0500 | [diff] [blame] | 40 | std::map<uint8_t, const char*>::const_iterator it = | 
|  | 41 | familyTable.find(family); | 
| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 42 | if (it == familyTable.end()) | 
|  | 43 | { | 
| Zhikui Ren | 18a5ab9 | 2020-09-01 21:35:20 -0700 | [diff] [blame] | 44 | processor::family("Unknown Processor Family"); | 
| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 45 | } | 
| Charles Boyer | 800bb70 | 2021-08-31 17:09:19 -0500 | [diff] [blame] | 46 | else if (it->first == processorFamily2Indicator) | 
|  | 47 | { | 
|  | 48 | std::map<uint16_t, const char*>::const_iterator it2 = | 
|  | 49 | family2Table.find(family2); | 
|  | 50 | if (it2 == family2Table.end()) | 
|  | 51 | { | 
|  | 52 | processor::family("Unknown Processor Family"); | 
|  | 53 | } | 
|  | 54 | else | 
|  | 55 | { | 
|  | 56 | processor::family(it2->second); | 
| Jiaqing Zhao | 1984957 | 2022-06-13 21:10:45 +0800 | [diff] [blame] | 57 | processor::effectiveFamily(family2); | 
| Charles Boyer | 800bb70 | 2021-08-31 17:09:19 -0500 | [diff] [blame] | 58 | } | 
|  | 59 | } | 
| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 60 | else | 
|  | 61 | { | 
| Zhikui Ren | 18a5ab9 | 2020-09-01 21:35:20 -0700 | [diff] [blame] | 62 | processor::family(it->second); | 
| Jiaqing Zhao | 1984957 | 2022-06-13 21:10:45 +0800 | [diff] [blame] | 63 | processor::effectiveFamily(family); | 
| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 64 | } | 
|  | 65 | } | 
|  | 66 |  | 
| Zhikui Ren | 18a5ab9 | 2020-09-01 21:35:20 -0700 | [diff] [blame] | 67 | void Cpu::manufacturer(const uint8_t positionNum, const uint8_t structLen, | 
|  | 68 | uint8_t* dataIn) | 
| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 69 | { | 
|  | 70 | std::string result = positionToString(positionNum, structLen, dataIn); | 
|  | 71 |  | 
| Zhikui Ren | 18a5ab9 | 2020-09-01 21:35:20 -0700 | [diff] [blame] | 72 | asset::manufacturer(result); | 
| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 73 | } | 
|  | 74 |  | 
| Charles Boyer | e643169 | 2021-08-31 16:47:47 -0500 | [diff] [blame] | 75 | void Cpu::partNumber(const uint8_t positionNum, const uint8_t structLen, | 
|  | 76 | uint8_t* dataIn) | 
|  | 77 | { | 
|  | 78 | std::string result = positionToString(positionNum, structLen, dataIn); | 
|  | 79 |  | 
|  | 80 | asset::partNumber(result); | 
|  | 81 | } | 
|  | 82 |  | 
|  | 83 | void Cpu::serialNumber(const uint8_t positionNum, const uint8_t structLen, | 
|  | 84 | uint8_t* dataIn) | 
|  | 85 | { | 
|  | 86 | std::string result = positionToString(positionNum, structLen, dataIn); | 
|  | 87 |  | 
|  | 88 | asset::serialNumber(result); | 
|  | 89 | } | 
|  | 90 |  | 
| Zhikui Ren | 18a5ab9 | 2020-09-01 21:35:20 -0700 | [diff] [blame] | 91 | void Cpu::version(const uint8_t positionNum, const uint8_t structLen, | 
|  | 92 | uint8_t* dataIn) | 
| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 93 | { | 
|  | 94 | std::string result; | 
|  | 95 |  | 
|  | 96 | result = positionToString(positionNum, structLen, dataIn); | 
|  | 97 |  | 
| Zhikui Ren | 18a5ab9 | 2020-09-01 21:35:20 -0700 | [diff] [blame] | 98 | rev::version(result); | 
| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 99 | } | 
|  | 100 |  | 
| Zhikui Ren | 18a5ab9 | 2020-09-01 21:35:20 -0700 | [diff] [blame] | 101 | void Cpu::characteristics(uint16_t value) | 
| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 102 | { | 
| Zhikui Ren | 18a5ab9 | 2020-09-01 21:35:20 -0700 | [diff] [blame] | 103 | std::vector<processor::Capability> result; | 
|  | 104 | std::optional<processor::Capability> cap; | 
| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 105 |  | 
| Zhikui Ren | 18a5ab9 | 2020-09-01 21:35:20 -0700 | [diff] [blame] | 106 | std::bitset<16> charBits = value; | 
|  | 107 | for (uint8_t index = 0; index < charBits.size(); index++) | 
| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 108 | { | 
| Zhikui Ren | 18a5ab9 | 2020-09-01 21:35:20 -0700 | [diff] [blame] | 109 | if (charBits.test(index)) | 
| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 110 | { | 
| Jonathan Doman | f2d8bb4 | 2023-07-26 10:13:34 -0700 | [diff] [blame] | 111 | if ((cap = characteristicsTable[index])) | 
| Zhikui Ren | 18a5ab9 | 2020-09-01 21:35:20 -0700 | [diff] [blame] | 112 | { | 
|  | 113 | result.emplace_back(*cap); | 
|  | 114 | } | 
| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 115 | } | 
| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 116 | } | 
|  | 117 |  | 
| Zhikui Ren | 18a5ab9 | 2020-09-01 21:35:20 -0700 | [diff] [blame] | 118 | processor::characteristics(result); | 
| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 119 | } | 
|  | 120 |  | 
|  | 121 | static constexpr uint8_t maxOldVersionCount = 0xff; | 
| Brandon Kim | 5a122a6 | 2023-05-04 04:25:03 +0000 | [diff] [blame] | 122 | void Cpu::infoUpdate(uint8_t* smbiosTableStorage, | 
|  | 123 | const std::string& motherboard) | 
| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 124 | { | 
| Brandon Kim | 5a122a6 | 2023-05-04 04:25:03 +0000 | [diff] [blame] | 125 | storage = smbiosTableStorage; | 
|  | 126 | motherboardPath = motherboard; | 
|  | 127 |  | 
| Cheng C Yang | 2ca7a0f | 2019-12-19 10:46:42 +0800 | [diff] [blame] | 128 | uint8_t* dataIn = storage; | 
| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 129 |  | 
|  | 130 | dataIn = getSMBIOSTypePtr(dataIn, processorsType); | 
|  | 131 | if (dataIn == nullptr) | 
|  | 132 | { | 
|  | 133 | return; | 
|  | 134 | } | 
|  | 135 |  | 
|  | 136 | for (uint8_t index = 0; index < cpuNum; index++) | 
|  | 137 | { | 
|  | 138 | dataIn = smbiosNextPtr(dataIn); | 
|  | 139 | if (dataIn == nullptr) | 
|  | 140 | { | 
|  | 141 | return; | 
|  | 142 | } | 
|  | 143 | dataIn = getSMBIOSTypePtr(dataIn, processorsType); | 
|  | 144 | if (dataIn == nullptr) | 
|  | 145 | { | 
|  | 146 | return; | 
|  | 147 | } | 
|  | 148 | } | 
|  | 149 |  | 
| Cheng C Yang | 2ca7a0f | 2019-12-19 10:46:42 +0800 | [diff] [blame] | 150 | auto cpuInfo = reinterpret_cast<struct ProcessorInfo*>(dataIn); | 
| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 151 |  | 
| Jonathan Doman | 563570d | 2021-05-24 10:52:43 -0700 | [diff] [blame] | 152 | socket(cpuInfo->socketDesignation, cpuInfo->length, dataIn); // offset 4h | 
|  | 153 |  | 
|  | 154 | constexpr uint32_t socketPopulatedMask = 1 << 6; | 
| David Wang | e05a542 | 2023-08-23 17:15:32 +0800 | [diff] [blame] | 155 | constexpr uint32_t statusMask = 0x07; | 
| Jonathan Doman | 563570d | 2021-05-24 10:52:43 -0700 | [diff] [blame] | 156 | if ((cpuInfo->status & socketPopulatedMask) == 0) | 
|  | 157 | { | 
|  | 158 | // Don't attempt to fill in any other details if the CPU is not present. | 
|  | 159 | present(false); | 
| David Wang | e05a542 | 2023-08-23 17:15:32 +0800 | [diff] [blame] | 160 | functional(false); | 
| Jonathan Doman | 563570d | 2021-05-24 10:52:43 -0700 | [diff] [blame] | 161 | return; | 
|  | 162 | } | 
|  | 163 | present(true); | 
| David Wang | e05a542 | 2023-08-23 17:15:32 +0800 | [diff] [blame] | 164 | if ((cpuInfo->status & statusMask) == 1) | 
|  | 165 | { | 
|  | 166 | functional(true); | 
|  | 167 | } | 
|  | 168 | else | 
|  | 169 | { | 
|  | 170 | functional(false); | 
|  | 171 | } | 
| Jonathan Doman | 563570d | 2021-05-24 10:52:43 -0700 | [diff] [blame] | 172 |  | 
| Zhikui Ren | 18a5ab9 | 2020-09-01 21:35:20 -0700 | [diff] [blame] | 173 | // this class is for type CPU  //offset 5h | 
| Charles Boyer | 800bb70 | 2021-08-31 17:09:19 -0500 | [diff] [blame] | 174 | family(cpuInfo->family, cpuInfo->family2); // offset 6h and 28h | 
| Zhikui Ren | 18a5ab9 | 2020-09-01 21:35:20 -0700 | [diff] [blame] | 175 | manufacturer(cpuInfo->manufacturer, cpuInfo->length, | 
| Patrick Williams | c39d3df | 2023-05-10 07:51:14 -0500 | [diff] [blame] | 176 | dataIn);                      // offset 7h | 
|  | 177 | id(cpuInfo->id);                           // offset 8h | 
| Zhikui Ren | 5961693 | 2023-03-24 09:02:20 -0700 | [diff] [blame] | 178 |  | 
|  | 179 | // Step, EffectiveFamily, EffectiveModel computation for Intel processors. | 
|  | 180 | std::map<uint8_t, const char*>::const_iterator it = | 
|  | 181 | familyTable.find(cpuInfo->family); | 
|  | 182 | if (it != familyTable.end()) | 
|  | 183 | { | 
|  | 184 | std::string familyStr = it->second; | 
|  | 185 | if ((familyStr.find(" Xeon ") != std::string::npos) || | 
| Konda Reddy Kachana | 0f7704a | 2024-02-21 05:42:32 +0000 | [diff] [blame^] | 186 | (familyStr.find(" Intel ") != std::string::npos) || | 
|  | 187 | (familyStr.find(" Zen ") != std::string::npos)) | 
| Zhikui Ren | 5961693 | 2023-03-24 09:02:20 -0700 | [diff] [blame] | 188 | { | 
|  | 189 | // Processor ID field | 
|  | 190 | // SteppinID:   4; | 
|  | 191 | // Model:       4; | 
|  | 192 | // Family:      4; | 
|  | 193 | // Type:        2; | 
|  | 194 | // Reserved1:   2; | 
|  | 195 | // XModel:      4; | 
|  | 196 | // XFamily:     8; | 
|  | 197 | // Reserved2:   4; | 
|  | 198 | uint16_t cpuStep = cpuInfo->id & 0xf; | 
|  | 199 | uint16_t cpuModel = (cpuInfo->id & 0xf0) >> 4; | 
|  | 200 | uint16_t cpuFamily = (cpuInfo->id & 0xf00) >> 8; | 
|  | 201 | uint16_t cpuXModel = (cpuInfo->id & 0xf0000) >> 16; | 
|  | 202 | uint16_t cpuXFamily = (cpuInfo->id & 0xff00000) >> 20; | 
|  | 203 | step(cpuStep); | 
|  | 204 | if (cpuFamily == 0xf) | 
|  | 205 | { | 
|  | 206 | effectiveFamily(cpuXFamily + cpuFamily); | 
|  | 207 | } | 
|  | 208 | else | 
|  | 209 | { | 
|  | 210 | effectiveFamily(cpuFamily); | 
|  | 211 | } | 
|  | 212 | if (cpuFamily == 0x6 || cpuFamily == 0xf) | 
|  | 213 | { | 
|  | 214 | effectiveModel((cpuXModel << 4) | cpuModel); | 
|  | 215 | } | 
|  | 216 | else | 
|  | 217 | { | 
|  | 218 | effectiveModel(cpuModel); | 
|  | 219 | } | 
|  | 220 | } | 
|  | 221 | } | 
|  | 222 |  | 
| Zhikui Ren | 18a5ab9 | 2020-09-01 21:35:20 -0700 | [diff] [blame] | 223 | version(cpuInfo->version, cpuInfo->length, dataIn); // offset 10h | 
|  | 224 | maxSpeedInMhz(cpuInfo->maxSpeed);                   // offset 14h | 
| Charles Boyer | e643169 | 2021-08-31 16:47:47 -0500 | [diff] [blame] | 225 | serialNumber(cpuInfo->serialNum, cpuInfo->length, | 
| Patrick Williams | c39d3df | 2023-05-10 07:51:14 -0500 | [diff] [blame] | 226 | dataIn);                               // offset 20h | 
| Charles Boyer | e643169 | 2021-08-31 16:47:47 -0500 | [diff] [blame] | 227 | partNumber(cpuInfo->partNum, cpuInfo->length, | 
| Patrick Williams | c39d3df | 2023-05-10 07:51:14 -0500 | [diff] [blame] | 228 | dataIn);                                 // offset 22h | 
|  | 229 | if (cpuInfo->coreCount < maxOldVersionCount)        // offset 23h or 2Ah | 
| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 230 | { | 
| Zhikui Ren | 18a5ab9 | 2020-09-01 21:35:20 -0700 | [diff] [blame] | 231 | coreCount(cpuInfo->coreCount); | 
| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 232 | } | 
|  | 233 | else | 
|  | 234 | { | 
| Zhikui Ren | 18a5ab9 | 2020-09-01 21:35:20 -0700 | [diff] [blame] | 235 | coreCount(cpuInfo->coreCount2); | 
| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 236 | } | 
|  | 237 |  | 
|  | 238 | if (cpuInfo->threadCount < maxOldVersionCount) // offset 25h or 2Eh) | 
|  | 239 | { | 
| Zhikui Ren | 18a5ab9 | 2020-09-01 21:35:20 -0700 | [diff] [blame] | 240 | threadCount(cpuInfo->threadCount); | 
| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 241 | } | 
|  | 242 | else | 
|  | 243 | { | 
| Zhikui Ren | 18a5ab9 | 2020-09-01 21:35:20 -0700 | [diff] [blame] | 244 | threadCount(cpuInfo->threadCount2); | 
| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 245 | } | 
|  | 246 |  | 
| Zhikui Ren | 18a5ab9 | 2020-09-01 21:35:20 -0700 | [diff] [blame] | 247 | characteristics(cpuInfo->characteristics); // offset 26h | 
| Jie Yang | e7cf319 | 2021-08-20 11:21:43 -0700 | [diff] [blame] | 248 |  | 
|  | 249 | if (!motherboardPath.empty()) | 
|  | 250 | { | 
|  | 251 | std::vector<std::tuple<std::string, std::string, std::string>> assocs; | 
|  | 252 | assocs.emplace_back("chassis", "processors", motherboardPath); | 
|  | 253 | association::associations(assocs); | 
|  | 254 | } | 
| Cheng C Yang | 43c6a1d | 2019-12-19 00:48:34 +0800 | [diff] [blame] | 255 | } | 
|  | 256 |  | 
|  | 257 | } // namespace smbios | 
|  | 258 | } // namespace phosphor |