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 19 #include <bitset> 20 #include <map> 21 22 namespace phosphor 23 { 24 namespace smbios 25 { 26 27 void Cpu::socket(const uint8_t positionNum, const uint8_t structLen, 28 uint8_t* dataIn) 29 { 30 std::string result = positionToString(positionNum, structLen, dataIn); 31 32 processor::socket(result); 33 34 location::locationCode(result); 35 } 36 37 static constexpr uint8_t processorFamily2Indicator = 0xfe; 38 void Cpu::family(const uint8_t family, const uint16_t family2) 39 { 40 std::map<uint8_t, const char*>::const_iterator it = 41 familyTable.find(family); 42 if (it == familyTable.end()) 43 { 44 processor::family("Unknown Processor Family"); 45 } 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); 57 } 58 } 59 else 60 { 61 processor::family(it->second); 62 } 63 } 64 65 void Cpu::manufacturer(const uint8_t positionNum, const uint8_t structLen, 66 uint8_t* dataIn) 67 { 68 std::string result = positionToString(positionNum, structLen, dataIn); 69 70 asset::manufacturer(result); 71 } 72 73 void Cpu::partNumber(const uint8_t positionNum, const uint8_t structLen, 74 uint8_t* dataIn) 75 { 76 std::string result = positionToString(positionNum, structLen, dataIn); 77 78 asset::partNumber(result); 79 } 80 81 void Cpu::serialNumber(const uint8_t positionNum, const uint8_t structLen, 82 uint8_t* dataIn) 83 { 84 std::string result = positionToString(positionNum, structLen, dataIn); 85 86 asset::serialNumber(result); 87 } 88 89 void Cpu::version(const uint8_t positionNum, const uint8_t structLen, 90 uint8_t* dataIn) 91 { 92 std::string result; 93 94 result = positionToString(positionNum, structLen, dataIn); 95 96 rev::version(result); 97 } 98 99 void Cpu::characteristics(uint16_t value) 100 { 101 std::vector<processor::Capability> result; 102 std::optional<processor::Capability> cap; 103 104 std::bitset<16> charBits = value; 105 for (uint8_t index = 0; index < charBits.size(); index++) 106 { 107 if (charBits.test(index)) 108 { 109 if (cap = characteristicsTable[index]) 110 { 111 result.emplace_back(*cap); 112 } 113 } 114 } 115 116 processor::characteristics(result); 117 } 118 119 static constexpr uint8_t maxOldVersionCount = 0xff; 120 void Cpu::infoUpdate(void) 121 { 122 uint8_t* dataIn = storage; 123 124 dataIn = getSMBIOSTypePtr(dataIn, processorsType); 125 if (dataIn == nullptr) 126 { 127 return; 128 } 129 130 for (uint8_t index = 0; index < cpuNum; index++) 131 { 132 dataIn = smbiosNextPtr(dataIn); 133 if (dataIn == nullptr) 134 { 135 return; 136 } 137 dataIn = getSMBIOSTypePtr(dataIn, processorsType); 138 if (dataIn == nullptr) 139 { 140 return; 141 } 142 } 143 144 auto cpuInfo = reinterpret_cast<struct ProcessorInfo*>(dataIn); 145 146 socket(cpuInfo->socketDesignation, cpuInfo->length, dataIn); // offset 4h 147 148 constexpr uint32_t socketPopulatedMask = 1 << 6; 149 if ((cpuInfo->status & socketPopulatedMask) == 0) 150 { 151 // Don't attempt to fill in any other details if the CPU is not present. 152 present(false); 153 return; 154 } 155 present(true); 156 157 // this class is for type CPU //offset 5h 158 family(cpuInfo->family, cpuInfo->family2); // offset 6h and 28h 159 manufacturer(cpuInfo->manufacturer, cpuInfo->length, 160 dataIn); // offset 7h 161 id(cpuInfo->id); // offset 8h 162 version(cpuInfo->version, cpuInfo->length, dataIn); // offset 10h 163 maxSpeedInMhz(cpuInfo->maxSpeed); // offset 14h 164 serialNumber(cpuInfo->serialNum, cpuInfo->length, 165 dataIn); // offset 20h 166 partNumber(cpuInfo->partNum, cpuInfo->length, 167 dataIn); // offset 22h 168 if (cpuInfo->coreCount < maxOldVersionCount) // offset 23h or 2Ah 169 { 170 coreCount(cpuInfo->coreCount); 171 } 172 else 173 { 174 coreCount(cpuInfo->coreCount2); 175 } 176 177 if (cpuInfo->threadCount < maxOldVersionCount) // offset 25h or 2Eh) 178 { 179 threadCount(cpuInfo->threadCount); 180 } 181 else 182 { 183 threadCount(cpuInfo->threadCount2); 184 } 185 186 characteristics(cpuInfo->characteristics); // offset 26h 187 188 if (!motherboardPath.empty()) 189 { 190 std::vector<std::tuple<std::string, std::string, std::string>> assocs; 191 assocs.emplace_back("chassis", "processors", motherboardPath); 192 association::associations(assocs); 193 } 194 } 195 196 } // namespace smbios 197 } // namespace phosphor 198