xref: /openbmc/smbios-mdr/src/cpu.cpp (revision 2ca7a0f3)
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