| /* |
| // Copyright (c) 2018 Intel Corporation |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| */ |
| |
| #include "cpu.hpp" |
| |
| #include <iostream> |
| #include <map> |
| |
| namespace phosphor |
| { |
| namespace smbios |
| { |
| |
| void Cpu::cpuSocket(const uint8_t positionNum, const uint8_t structLen, |
| uint8_t *dataIn) |
| { |
| std::string result = positionToString(positionNum, structLen, dataIn); |
| |
| processorSocket(result); |
| } |
| |
| std::string Cpu::processorSocket(std::string value) |
| { |
| return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu:: |
| processorSocket(value); |
| } |
| |
| void Cpu::cpuType(const uint8_t value) |
| { |
| std::map<uint8_t, const char *>::const_iterator it = |
| processorTypeTable.find(value); |
| if (it == processorTypeTable.end()) |
| { |
| processorType("Unknown Processor Type"); |
| } |
| else |
| { |
| processorType(it->second); |
| } |
| } |
| |
| std::string Cpu::processorType(std::string value) |
| { |
| return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu:: |
| processorType(value); |
| } |
| |
| void Cpu::cpuFamily(const uint8_t value) |
| { |
| std::map<uint8_t, const char *>::const_iterator it = |
| familyTable.find(value); |
| if (it == familyTable.end()) |
| { |
| processorFamily("Unknown Processor Family"); |
| } |
| else |
| { |
| processorFamily(it->second); |
| } |
| } |
| |
| std::string Cpu::processorFamily(std::string value) |
| { |
| return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu:: |
| processorFamily(value); |
| } |
| |
| void Cpu::cpuManufacturer(const uint8_t positionNum, const uint8_t structLen, |
| uint8_t *dataIn) |
| { |
| std::string result = positionToString(positionNum, structLen, dataIn); |
| |
| manufacturer(result); |
| } |
| |
| std::string Cpu::manufacturer(std::string value) |
| { |
| return sdbusplus::xyz::openbmc_project::Inventory::Decorator::server:: |
| Asset::manufacturer(value); |
| } |
| |
| uint32_t Cpu::processorId(uint32_t value) |
| { |
| return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu:: |
| processorId(value); |
| } |
| |
| void Cpu::cpuVersion(const uint8_t positionNum, const uint8_t structLen, |
| uint8_t *dataIn) |
| { |
| std::string result; |
| |
| result = positionToString(positionNum, structLen, dataIn); |
| |
| processorVersion(result); |
| } |
| |
| std::string Cpu::processorVersion(std::string value) |
| { |
| return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu:: |
| processorVersion(value); |
| } |
| |
| uint16_t Cpu::processorMaxSpeed(uint16_t value) |
| { |
| return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu:: |
| processorMaxSpeed(value); |
| } |
| |
| void Cpu::cpuCharacteristics(uint16_t value) |
| { |
| std::string result = ""; |
| for (uint8_t index = 0; index < (8 * sizeof(value)); index++) |
| { |
| if (value & 0x01) |
| { |
| result += characteristicsTable[index]; |
| } |
| value >>= 1; |
| } |
| |
| processorCharacteristics(result); |
| } |
| |
| std::string Cpu::processorCharacteristics(std::string value) |
| { |
| return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu:: |
| processorCharacteristics(value); |
| } |
| |
| uint16_t Cpu::processorCoreCount(uint16_t value) |
| { |
| return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu:: |
| processorCoreCount(value); |
| } |
| |
| uint16_t Cpu::processorThreadCount(uint16_t value) |
| { |
| return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu:: |
| processorThreadCount(value); |
| } |
| |
| static constexpr const uint8_t populateMask = 1 << 6; |
| static constexpr const uint8_t statusMask = 0x07; |
| void Cpu::cpuStatus(uint8_t value) |
| { |
| if (!(value & populateMask)) |
| { |
| present(false); |
| functional(false); |
| return; |
| } |
| present(true); |
| if ((value & statusMask) == 1) |
| { |
| functional(true); |
| } |
| else |
| { |
| functional(false); |
| } |
| } |
| |
| bool Cpu::present(bool value) |
| { |
| return sdbusplus::xyz::openbmc_project::Inventory::server::Item::present( |
| value); |
| } |
| |
| bool Cpu::functional(bool value) |
| { |
| return sdbusplus::xyz::openbmc_project::State::Decorator::server:: |
| OperationalStatus::functional(value); |
| } |
| |
| static constexpr uint8_t maxOldVersionCount = 0xff; |
| void Cpu::processorInfoUpdate(void) |
| { |
| uint8_t *dataIn = storage; |
| |
| dataIn = getSMBIOSTypePtr(dataIn, processorsType); |
| if (dataIn == nullptr) |
| { |
| return; |
| } |
| |
| for (uint8_t index = 0; index < cpuNum; index++) |
| { |
| dataIn = smbiosNextPtr(dataIn); |
| if (dataIn == nullptr) |
| { |
| return; |
| } |
| dataIn = getSMBIOSTypePtr(dataIn, processorsType); |
| if (dataIn == nullptr) |
| { |
| return; |
| } |
| } |
| |
| auto cpuInfo = reinterpret_cast<struct ProcessorInfo *>(dataIn); |
| |
| cpuSocket(cpuInfo->socketDesignation, cpuInfo->length, |
| dataIn); // offset 4h |
| cpuType(cpuInfo->processorType); // offset 5h |
| cpuFamily(cpuInfo->family); // offset 6h |
| cpuManufacturer(cpuInfo->manufacturer, cpuInfo->length, |
| dataIn); // offset 7h |
| processorId(cpuInfo->id); // offset 8h |
| cpuVersion(cpuInfo->version, cpuInfo->length, dataIn); // offset 10h |
| processorMaxSpeed(cpuInfo->maxSpeed); // offset 14h |
| if (cpuInfo->coreCount < maxOldVersionCount) // offset 23h or 2Ah |
| { |
| processorCoreCount(cpuInfo->coreCount); |
| } |
| else |
| { |
| processorCoreCount(cpuInfo->coreCount2); |
| } |
| |
| if (cpuInfo->threadCount < maxOldVersionCount) // offset 25h or 2Eh) |
| { |
| processorThreadCount(cpuInfo->threadCount); |
| } |
| else |
| { |
| processorThreadCount(cpuInfo->threadCount2); |
| } |
| |
| cpuCharacteristics(cpuInfo->characteristics); // offset 26h |
| |
| cpuStatus(cpuInfo->status); |
| } |
| |
| } // namespace smbios |
| } // namespace phosphor |