143c6a1daSCheng C Yang /* 243c6a1daSCheng C Yang // Copyright (c) 2018 Intel Corporation 343c6a1daSCheng C Yang // 443c6a1daSCheng C Yang // Licensed under the Apache License, Version 2.0 (the "License"); 543c6a1daSCheng C Yang // you may not use this file except in compliance with the License. 643c6a1daSCheng C Yang // You may obtain a copy of the License at 743c6a1daSCheng C Yang // 843c6a1daSCheng C Yang // http://www.apache.org/licenses/LICENSE-2.0 943c6a1daSCheng C Yang // 1043c6a1daSCheng C Yang // Unless required by applicable law or agreed to in writing, software 1143c6a1daSCheng C Yang // distributed under the License is distributed on an "AS IS" BASIS, 1243c6a1daSCheng C Yang // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1343c6a1daSCheng C Yang // See the License for the specific language governing permissions and 1443c6a1daSCheng C Yang // limitations under the License. 1543c6a1daSCheng C Yang */ 1643c6a1daSCheng C Yang 1743c6a1daSCheng C Yang #include "cpu.hpp" 1843c6a1daSCheng C Yang 1918a5ab91SZhikui Ren #include <bitset> 2043c6a1daSCheng C Yang #include <map> 2143c6a1daSCheng C Yang 2243c6a1daSCheng C Yang namespace phosphor 2343c6a1daSCheng C Yang { 2443c6a1daSCheng C Yang namespace smbios 2543c6a1daSCheng C Yang { 2643c6a1daSCheng C Yang 2718a5ab91SZhikui Ren void Cpu::socket(const uint8_t positionNum, const uint8_t structLen, 2843c6a1daSCheng C Yang uint8_t* dataIn) 2943c6a1daSCheng C Yang { 3043c6a1daSCheng C Yang std::string result = positionToString(positionNum, structLen, dataIn); 3143c6a1daSCheng C Yang 3218a5ab91SZhikui Ren processor::socket(result); 3331720397SJie Yang 3431720397SJie Yang location::locationCode(result); 3543c6a1daSCheng C Yang } 3643c6a1daSCheng C Yang 37800bb700SCharles Boyer static constexpr uint8_t processorFamily2Indicator = 0xfe; 38800bb700SCharles Boyer void Cpu::family(const uint8_t family, const uint16_t family2) 3943c6a1daSCheng C Yang { 40800bb700SCharles Boyer std::map<uint8_t, const char*>::const_iterator it = 41800bb700SCharles Boyer familyTable.find(family); 4243c6a1daSCheng C Yang if (it == familyTable.end()) 4343c6a1daSCheng C Yang { 4418a5ab91SZhikui Ren processor::family("Unknown Processor Family"); 4543c6a1daSCheng C Yang } 46800bb700SCharles Boyer else if (it->first == processorFamily2Indicator) 47800bb700SCharles Boyer { 48800bb700SCharles Boyer std::map<uint16_t, const char*>::const_iterator it2 = 49800bb700SCharles Boyer family2Table.find(family2); 50800bb700SCharles Boyer if (it2 == family2Table.end()) 51800bb700SCharles Boyer { 52800bb700SCharles Boyer processor::family("Unknown Processor Family"); 53800bb700SCharles Boyer } 54800bb700SCharles Boyer else 55800bb700SCharles Boyer { 56800bb700SCharles Boyer processor::family(it2->second); 57*19849573SJiaqing Zhao processor::effectiveFamily(family2); 58800bb700SCharles Boyer } 59800bb700SCharles Boyer } 6043c6a1daSCheng C Yang else 6143c6a1daSCheng C Yang { 6218a5ab91SZhikui Ren processor::family(it->second); 63*19849573SJiaqing Zhao processor::effectiveFamily(family); 6443c6a1daSCheng C Yang } 6543c6a1daSCheng C Yang } 6643c6a1daSCheng C Yang 6718a5ab91SZhikui Ren void Cpu::manufacturer(const uint8_t positionNum, const uint8_t structLen, 6843c6a1daSCheng C Yang uint8_t* dataIn) 6943c6a1daSCheng C Yang { 7043c6a1daSCheng C Yang std::string result = positionToString(positionNum, structLen, dataIn); 7143c6a1daSCheng C Yang 7218a5ab91SZhikui Ren asset::manufacturer(result); 7343c6a1daSCheng C Yang } 7443c6a1daSCheng C Yang 75e643169dSCharles Boyer void Cpu::partNumber(const uint8_t positionNum, const uint8_t structLen, 76e643169dSCharles Boyer uint8_t* dataIn) 77e643169dSCharles Boyer { 78e643169dSCharles Boyer std::string result = positionToString(positionNum, structLen, dataIn); 79e643169dSCharles Boyer 80e643169dSCharles Boyer asset::partNumber(result); 81e643169dSCharles Boyer } 82e643169dSCharles Boyer 83e643169dSCharles Boyer void Cpu::serialNumber(const uint8_t positionNum, const uint8_t structLen, 84e643169dSCharles Boyer uint8_t* dataIn) 85e643169dSCharles Boyer { 86e643169dSCharles Boyer std::string result = positionToString(positionNum, structLen, dataIn); 87e643169dSCharles Boyer 88e643169dSCharles Boyer asset::serialNumber(result); 89e643169dSCharles Boyer } 90e643169dSCharles Boyer 9118a5ab91SZhikui Ren void Cpu::version(const uint8_t positionNum, const uint8_t structLen, 9243c6a1daSCheng C Yang uint8_t* dataIn) 9343c6a1daSCheng C Yang { 9443c6a1daSCheng C Yang std::string result; 9543c6a1daSCheng C Yang 9643c6a1daSCheng C Yang result = positionToString(positionNum, structLen, dataIn); 9743c6a1daSCheng C Yang 9818a5ab91SZhikui Ren rev::version(result); 9943c6a1daSCheng C Yang } 10043c6a1daSCheng C Yang 10118a5ab91SZhikui Ren void Cpu::characteristics(uint16_t value) 10243c6a1daSCheng C Yang { 10318a5ab91SZhikui Ren std::vector<processor::Capability> result; 10418a5ab91SZhikui Ren std::optional<processor::Capability> cap; 10543c6a1daSCheng C Yang 10618a5ab91SZhikui Ren std::bitset<16> charBits = value; 10718a5ab91SZhikui Ren for (uint8_t index = 0; index < charBits.size(); index++) 10843c6a1daSCheng C Yang { 10918a5ab91SZhikui Ren if (charBits.test(index)) 11018a5ab91SZhikui Ren { 11118a5ab91SZhikui Ren if (cap = characteristicsTable[index]) 11218a5ab91SZhikui Ren { 11318a5ab91SZhikui Ren result.emplace_back(*cap); 11443c6a1daSCheng C Yang } 11543c6a1daSCheng C Yang } 11643c6a1daSCheng C Yang } 11743c6a1daSCheng C Yang 11818a5ab91SZhikui Ren processor::characteristics(result); 11943c6a1daSCheng C Yang } 12043c6a1daSCheng C Yang 12143c6a1daSCheng C Yang static constexpr uint8_t maxOldVersionCount = 0xff; 12218a5ab91SZhikui Ren void Cpu::infoUpdate(void) 12343c6a1daSCheng C Yang { 12443c6a1daSCheng C Yang uint8_t* dataIn = storage; 12543c6a1daSCheng C Yang 12643c6a1daSCheng C Yang dataIn = getSMBIOSTypePtr(dataIn, processorsType); 12743c6a1daSCheng C Yang if (dataIn == nullptr) 12843c6a1daSCheng C Yang { 12943c6a1daSCheng C Yang return; 13043c6a1daSCheng C Yang } 13143c6a1daSCheng C Yang 13243c6a1daSCheng C Yang for (uint8_t index = 0; index < cpuNum; index++) 13343c6a1daSCheng C Yang { 13443c6a1daSCheng C Yang dataIn = smbiosNextPtr(dataIn); 13543c6a1daSCheng C Yang if (dataIn == nullptr) 13643c6a1daSCheng C Yang { 13743c6a1daSCheng C Yang return; 13843c6a1daSCheng C Yang } 13943c6a1daSCheng C Yang dataIn = getSMBIOSTypePtr(dataIn, processorsType); 14043c6a1daSCheng C Yang if (dataIn == nullptr) 14143c6a1daSCheng C Yang { 14243c6a1daSCheng C Yang return; 14343c6a1daSCheng C Yang } 14443c6a1daSCheng C Yang } 14543c6a1daSCheng C Yang 14643c6a1daSCheng C Yang auto cpuInfo = reinterpret_cast<struct ProcessorInfo*>(dataIn); 14743c6a1daSCheng C Yang 148563570dfSJonathan Doman socket(cpuInfo->socketDesignation, cpuInfo->length, dataIn); // offset 4h 149563570dfSJonathan Doman 150563570dfSJonathan Doman constexpr uint32_t socketPopulatedMask = 1 << 6; 151563570dfSJonathan Doman if ((cpuInfo->status & socketPopulatedMask) == 0) 152563570dfSJonathan Doman { 153563570dfSJonathan Doman // Don't attempt to fill in any other details if the CPU is not present. 154563570dfSJonathan Doman present(false); 155563570dfSJonathan Doman return; 156563570dfSJonathan Doman } 157563570dfSJonathan Doman present(true); 158563570dfSJonathan Doman 15918a5ab91SZhikui Ren // this class is for type CPU //offset 5h 160800bb700SCharles Boyer family(cpuInfo->family, cpuInfo->family2); // offset 6h and 28h 16118a5ab91SZhikui Ren manufacturer(cpuInfo->manufacturer, cpuInfo->length, 16243c6a1daSCheng C Yang dataIn); // offset 7h 16318a5ab91SZhikui Ren id(cpuInfo->id); // offset 8h 16418a5ab91SZhikui Ren version(cpuInfo->version, cpuInfo->length, dataIn); // offset 10h 16518a5ab91SZhikui Ren maxSpeedInMhz(cpuInfo->maxSpeed); // offset 14h 166e643169dSCharles Boyer serialNumber(cpuInfo->serialNum, cpuInfo->length, 167e643169dSCharles Boyer dataIn); // offset 20h 168e643169dSCharles Boyer partNumber(cpuInfo->partNum, cpuInfo->length, 169e643169dSCharles Boyer dataIn); // offset 22h 17043c6a1daSCheng C Yang if (cpuInfo->coreCount < maxOldVersionCount) // offset 23h or 2Ah 17143c6a1daSCheng C Yang { 17218a5ab91SZhikui Ren coreCount(cpuInfo->coreCount); 17343c6a1daSCheng C Yang } 17443c6a1daSCheng C Yang else 17543c6a1daSCheng C Yang { 17618a5ab91SZhikui Ren coreCount(cpuInfo->coreCount2); 17743c6a1daSCheng C Yang } 17843c6a1daSCheng C Yang 17943c6a1daSCheng C Yang if (cpuInfo->threadCount < maxOldVersionCount) // offset 25h or 2Eh) 18043c6a1daSCheng C Yang { 18118a5ab91SZhikui Ren threadCount(cpuInfo->threadCount); 18243c6a1daSCheng C Yang } 18343c6a1daSCheng C Yang else 18443c6a1daSCheng C Yang { 18518a5ab91SZhikui Ren threadCount(cpuInfo->threadCount2); 18643c6a1daSCheng C Yang } 18743c6a1daSCheng C Yang 18818a5ab91SZhikui Ren characteristics(cpuInfo->characteristics); // offset 26h 189e7cf3195SJie Yang 190e7cf3195SJie Yang if (!motherboardPath.empty()) 191e7cf3195SJie Yang { 192e7cf3195SJie Yang std::vector<std::tuple<std::string, std::string, std::string>> assocs; 193e7cf3195SJie Yang assocs.emplace_back("chassis", "processors", motherboardPath); 194e7cf3195SJie Yang association::associations(assocs); 195e7cf3195SJie Yang } 19643c6a1daSCheng C Yang } 19743c6a1daSCheng C Yang 19843c6a1daSCheng C Yang } // namespace smbios 19943c6a1daSCheng C Yang } // namespace phosphor 200