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 1943c6a1daSCheng C Yang #include <iostream> 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 2743c6a1daSCheng C Yang void Cpu::cpuSocket(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 3243c6a1daSCheng C Yang processorSocket(result); 3343c6a1daSCheng C Yang } 3443c6a1daSCheng C Yang 3543c6a1daSCheng C Yang std::string Cpu::processorSocket(std::string value) 3643c6a1daSCheng C Yang { 3743c6a1daSCheng C Yang return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu:: 3843c6a1daSCheng C Yang processorSocket(value); 3943c6a1daSCheng C Yang } 4043c6a1daSCheng C Yang 4143c6a1daSCheng C Yang void Cpu::cpuType(const uint8_t value) 4243c6a1daSCheng C Yang { 4343c6a1daSCheng C Yang std::map<uint8_t, const char*>::const_iterator it = 4443c6a1daSCheng C Yang processorTypeTable.find(value); 4543c6a1daSCheng C Yang if (it == processorTypeTable.end()) 4643c6a1daSCheng C Yang { 4743c6a1daSCheng C Yang processorType("Unknown Processor Type"); 4843c6a1daSCheng C Yang } 4943c6a1daSCheng C Yang else 5043c6a1daSCheng C Yang { 5143c6a1daSCheng C Yang processorType(it->second); 5243c6a1daSCheng C Yang } 5343c6a1daSCheng C Yang } 5443c6a1daSCheng C Yang 5543c6a1daSCheng C Yang std::string Cpu::processorType(std::string value) 5643c6a1daSCheng C Yang { 5743c6a1daSCheng C Yang return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu:: 5843c6a1daSCheng C Yang processorType(value); 5943c6a1daSCheng C Yang } 6043c6a1daSCheng C Yang 6143c6a1daSCheng C Yang void Cpu::cpuFamily(const uint8_t value) 6243c6a1daSCheng C Yang { 63*2ca7a0f3SCheng C Yang std::map<uint8_t, const char*>::const_iterator it = familyTable.find(value); 6443c6a1daSCheng C Yang if (it == familyTable.end()) 6543c6a1daSCheng C Yang { 6643c6a1daSCheng C Yang processorFamily("Unknown Processor Family"); 6743c6a1daSCheng C Yang } 6843c6a1daSCheng C Yang else 6943c6a1daSCheng C Yang { 7043c6a1daSCheng C Yang processorFamily(it->second); 7143c6a1daSCheng C Yang } 7243c6a1daSCheng C Yang } 7343c6a1daSCheng C Yang 7443c6a1daSCheng C Yang std::string Cpu::processorFamily(std::string value) 7543c6a1daSCheng C Yang { 7643c6a1daSCheng C Yang return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu:: 7743c6a1daSCheng C Yang processorFamily(value); 7843c6a1daSCheng C Yang } 7943c6a1daSCheng C Yang 8043c6a1daSCheng C Yang void Cpu::cpuManufacturer(const uint8_t positionNum, const uint8_t structLen, 8143c6a1daSCheng C Yang uint8_t* dataIn) 8243c6a1daSCheng C Yang { 8343c6a1daSCheng C Yang std::string result = positionToString(positionNum, structLen, dataIn); 8443c6a1daSCheng C Yang 8543c6a1daSCheng C Yang manufacturer(result); 8643c6a1daSCheng C Yang } 8743c6a1daSCheng C Yang 8843c6a1daSCheng C Yang std::string Cpu::manufacturer(std::string value) 8943c6a1daSCheng C Yang { 9043c6a1daSCheng C Yang return sdbusplus::xyz::openbmc_project::Inventory::Decorator::server:: 9143c6a1daSCheng C Yang Asset::manufacturer(value); 9243c6a1daSCheng C Yang } 9343c6a1daSCheng C Yang 9443c6a1daSCheng C Yang uint32_t Cpu::processorId(uint32_t value) 9543c6a1daSCheng C Yang { 9643c6a1daSCheng C Yang return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu:: 9743c6a1daSCheng C Yang processorId(value); 9843c6a1daSCheng C Yang } 9943c6a1daSCheng C Yang 10043c6a1daSCheng C Yang void Cpu::cpuVersion(const uint8_t positionNum, const uint8_t structLen, 10143c6a1daSCheng C Yang uint8_t* dataIn) 10243c6a1daSCheng C Yang { 10343c6a1daSCheng C Yang std::string result; 10443c6a1daSCheng C Yang 10543c6a1daSCheng C Yang result = positionToString(positionNum, structLen, dataIn); 10643c6a1daSCheng C Yang 10743c6a1daSCheng C Yang processorVersion(result); 10843c6a1daSCheng C Yang } 10943c6a1daSCheng C Yang 11043c6a1daSCheng C Yang std::string Cpu::processorVersion(std::string value) 11143c6a1daSCheng C Yang { 11243c6a1daSCheng C Yang return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu:: 11343c6a1daSCheng C Yang processorVersion(value); 11443c6a1daSCheng C Yang } 11543c6a1daSCheng C Yang 11643c6a1daSCheng C Yang uint16_t Cpu::processorMaxSpeed(uint16_t value) 11743c6a1daSCheng C Yang { 11843c6a1daSCheng C Yang return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu:: 11943c6a1daSCheng C Yang processorMaxSpeed(value); 12043c6a1daSCheng C Yang } 12143c6a1daSCheng C Yang 12243c6a1daSCheng C Yang void Cpu::cpuCharacteristics(uint16_t value) 12343c6a1daSCheng C Yang { 12443c6a1daSCheng C Yang std::string result = ""; 12543c6a1daSCheng C Yang for (uint8_t index = 0; index < (8 * sizeof(value)); index++) 12643c6a1daSCheng C Yang { 12743c6a1daSCheng C Yang if (value & 0x01) 12843c6a1daSCheng C Yang { 12943c6a1daSCheng C Yang result += characteristicsTable[index]; 13043c6a1daSCheng C Yang } 13143c6a1daSCheng C Yang value >>= 1; 13243c6a1daSCheng C Yang } 13343c6a1daSCheng C Yang 13443c6a1daSCheng C Yang processorCharacteristics(result); 13543c6a1daSCheng C Yang } 13643c6a1daSCheng C Yang 13743c6a1daSCheng C Yang std::string Cpu::processorCharacteristics(std::string value) 13843c6a1daSCheng C Yang { 13943c6a1daSCheng C Yang return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu:: 14043c6a1daSCheng C Yang processorCharacteristics(value); 14143c6a1daSCheng C Yang } 14243c6a1daSCheng C Yang 14343c6a1daSCheng C Yang uint16_t Cpu::processorCoreCount(uint16_t value) 14443c6a1daSCheng C Yang { 14543c6a1daSCheng C Yang return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu:: 14643c6a1daSCheng C Yang processorCoreCount(value); 14743c6a1daSCheng C Yang } 14843c6a1daSCheng C Yang 14943c6a1daSCheng C Yang uint16_t Cpu::processorThreadCount(uint16_t value) 15043c6a1daSCheng C Yang { 15143c6a1daSCheng C Yang return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu:: 15243c6a1daSCheng C Yang processorThreadCount(value); 15343c6a1daSCheng C Yang } 15443c6a1daSCheng C Yang 15543c6a1daSCheng C Yang static constexpr const uint8_t populateMask = 1 << 6; 15643c6a1daSCheng C Yang static constexpr const uint8_t statusMask = 0x07; 15743c6a1daSCheng C Yang void Cpu::cpuStatus(uint8_t value) 15843c6a1daSCheng C Yang { 15943c6a1daSCheng C Yang if (!(value & populateMask)) 16043c6a1daSCheng C Yang { 16143c6a1daSCheng C Yang present(false); 16243c6a1daSCheng C Yang functional(false); 16343c6a1daSCheng C Yang return; 16443c6a1daSCheng C Yang } 16543c6a1daSCheng C Yang present(true); 16643c6a1daSCheng C Yang if ((value & statusMask) == 1) 16743c6a1daSCheng C Yang { 16843c6a1daSCheng C Yang functional(true); 16943c6a1daSCheng C Yang } 17043c6a1daSCheng C Yang else 17143c6a1daSCheng C Yang { 17243c6a1daSCheng C Yang functional(false); 17343c6a1daSCheng C Yang } 17443c6a1daSCheng C Yang } 17543c6a1daSCheng C Yang 17643c6a1daSCheng C Yang bool Cpu::present(bool value) 17743c6a1daSCheng C Yang { 17843c6a1daSCheng C Yang return sdbusplus::xyz::openbmc_project::Inventory::server::Item::present( 17943c6a1daSCheng C Yang value); 18043c6a1daSCheng C Yang } 18143c6a1daSCheng C Yang 18243c6a1daSCheng C Yang bool Cpu::functional(bool value) 18343c6a1daSCheng C Yang { 18443c6a1daSCheng C Yang return sdbusplus::xyz::openbmc_project::State::Decorator::server:: 18543c6a1daSCheng C Yang OperationalStatus::functional(value); 18643c6a1daSCheng C Yang } 18743c6a1daSCheng C Yang 18843c6a1daSCheng C Yang static constexpr uint8_t maxOldVersionCount = 0xff; 18943c6a1daSCheng C Yang void Cpu::processorInfoUpdate(void) 19043c6a1daSCheng C Yang { 19143c6a1daSCheng C Yang uint8_t* dataIn = storage; 19243c6a1daSCheng C Yang 19343c6a1daSCheng C Yang dataIn = getSMBIOSTypePtr(dataIn, processorsType); 19443c6a1daSCheng C Yang if (dataIn == nullptr) 19543c6a1daSCheng C Yang { 19643c6a1daSCheng C Yang return; 19743c6a1daSCheng C Yang } 19843c6a1daSCheng C Yang 19943c6a1daSCheng C Yang for (uint8_t index = 0; index < cpuNum; index++) 20043c6a1daSCheng C Yang { 20143c6a1daSCheng C Yang dataIn = smbiosNextPtr(dataIn); 20243c6a1daSCheng C Yang if (dataIn == nullptr) 20343c6a1daSCheng C Yang { 20443c6a1daSCheng C Yang return; 20543c6a1daSCheng C Yang } 20643c6a1daSCheng C Yang dataIn = getSMBIOSTypePtr(dataIn, processorsType); 20743c6a1daSCheng C Yang if (dataIn == nullptr) 20843c6a1daSCheng C Yang { 20943c6a1daSCheng C Yang return; 21043c6a1daSCheng C Yang } 21143c6a1daSCheng C Yang } 21243c6a1daSCheng C Yang 21343c6a1daSCheng C Yang auto cpuInfo = reinterpret_cast<struct ProcessorInfo*>(dataIn); 21443c6a1daSCheng C Yang 21543c6a1daSCheng C Yang cpuSocket(cpuInfo->socketDesignation, cpuInfo->length, 21643c6a1daSCheng C Yang dataIn); // offset 4h 21743c6a1daSCheng C Yang cpuType(cpuInfo->processorType); // offset 5h 21843c6a1daSCheng C Yang cpuFamily(cpuInfo->family); // offset 6h 21943c6a1daSCheng C Yang cpuManufacturer(cpuInfo->manufacturer, cpuInfo->length, 22043c6a1daSCheng C Yang dataIn); // offset 7h 22143c6a1daSCheng C Yang processorId(cpuInfo->id); // offset 8h 22243c6a1daSCheng C Yang cpuVersion(cpuInfo->version, cpuInfo->length, dataIn); // offset 10h 22343c6a1daSCheng C Yang processorMaxSpeed(cpuInfo->maxSpeed); // offset 14h 22443c6a1daSCheng C Yang if (cpuInfo->coreCount < maxOldVersionCount) // offset 23h or 2Ah 22543c6a1daSCheng C Yang { 22643c6a1daSCheng C Yang processorCoreCount(cpuInfo->coreCount); 22743c6a1daSCheng C Yang } 22843c6a1daSCheng C Yang else 22943c6a1daSCheng C Yang { 23043c6a1daSCheng C Yang processorCoreCount(cpuInfo->coreCount2); 23143c6a1daSCheng C Yang } 23243c6a1daSCheng C Yang 23343c6a1daSCheng C Yang if (cpuInfo->threadCount < maxOldVersionCount) // offset 25h or 2Eh) 23443c6a1daSCheng C Yang { 23543c6a1daSCheng C Yang processorThreadCount(cpuInfo->threadCount); 23643c6a1daSCheng C Yang } 23743c6a1daSCheng C Yang else 23843c6a1daSCheng C Yang { 23943c6a1daSCheng C Yang processorThreadCount(cpuInfo->threadCount2); 24043c6a1daSCheng C Yang } 24143c6a1daSCheng C Yang 24243c6a1daSCheng C Yang cpuCharacteristics(cpuInfo->characteristics); // offset 26h 24343c6a1daSCheng C Yang 24443c6a1daSCheng C Yang cpuStatus(cpuInfo->status); 24543c6a1daSCheng C Yang } 24643c6a1daSCheng C Yang 24743c6a1daSCheng C Yang } // namespace smbios 24843c6a1daSCheng C Yang } // namespace phosphor 249