1*43c6a1daSCheng C Yang /* 2*43c6a1daSCheng C Yang // Copyright (c) 2018 Intel Corporation 3*43c6a1daSCheng C Yang // 4*43c6a1daSCheng C Yang // Licensed under the Apache License, Version 2.0 (the "License"); 5*43c6a1daSCheng C Yang // you may not use this file except in compliance with the License. 6*43c6a1daSCheng C Yang // You may obtain a copy of the License at 7*43c6a1daSCheng C Yang // 8*43c6a1daSCheng C Yang // http://www.apache.org/licenses/LICENSE-2.0 9*43c6a1daSCheng C Yang // 10*43c6a1daSCheng C Yang // Unless required by applicable law or agreed to in writing, software 11*43c6a1daSCheng C Yang // distributed under the License is distributed on an "AS IS" BASIS, 12*43c6a1daSCheng C Yang // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*43c6a1daSCheng C Yang // See the License for the specific language governing permissions and 14*43c6a1daSCheng C Yang // limitations under the License. 15*43c6a1daSCheng C Yang */ 16*43c6a1daSCheng C Yang 17*43c6a1daSCheng C Yang #include "cpu.hpp" 18*43c6a1daSCheng C Yang 19*43c6a1daSCheng C Yang #include <iostream> 20*43c6a1daSCheng C Yang #include <map> 21*43c6a1daSCheng C Yang 22*43c6a1daSCheng C Yang namespace phosphor 23*43c6a1daSCheng C Yang { 24*43c6a1daSCheng C Yang namespace smbios 25*43c6a1daSCheng C Yang { 26*43c6a1daSCheng C Yang 27*43c6a1daSCheng C Yang void Cpu::cpuSocket(const uint8_t positionNum, const uint8_t structLen, 28*43c6a1daSCheng C Yang uint8_t *dataIn) 29*43c6a1daSCheng C Yang { 30*43c6a1daSCheng C Yang std::string result = positionToString(positionNum, structLen, dataIn); 31*43c6a1daSCheng C Yang 32*43c6a1daSCheng C Yang processorSocket(result); 33*43c6a1daSCheng C Yang } 34*43c6a1daSCheng C Yang 35*43c6a1daSCheng C Yang std::string Cpu::processorSocket(std::string value) 36*43c6a1daSCheng C Yang { 37*43c6a1daSCheng C Yang return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu:: 38*43c6a1daSCheng C Yang processorSocket(value); 39*43c6a1daSCheng C Yang } 40*43c6a1daSCheng C Yang 41*43c6a1daSCheng C Yang void Cpu::cpuType(const uint8_t value) 42*43c6a1daSCheng C Yang { 43*43c6a1daSCheng C Yang std::map<uint8_t, const char *>::const_iterator it = 44*43c6a1daSCheng C Yang processorTypeTable.find(value); 45*43c6a1daSCheng C Yang if (it == processorTypeTable.end()) 46*43c6a1daSCheng C Yang { 47*43c6a1daSCheng C Yang processorType("Unknown Processor Type"); 48*43c6a1daSCheng C Yang } 49*43c6a1daSCheng C Yang else 50*43c6a1daSCheng C Yang { 51*43c6a1daSCheng C Yang processorType(it->second); 52*43c6a1daSCheng C Yang } 53*43c6a1daSCheng C Yang } 54*43c6a1daSCheng C Yang 55*43c6a1daSCheng C Yang std::string Cpu::processorType(std::string value) 56*43c6a1daSCheng C Yang { 57*43c6a1daSCheng C Yang return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu:: 58*43c6a1daSCheng C Yang processorType(value); 59*43c6a1daSCheng C Yang } 60*43c6a1daSCheng C Yang 61*43c6a1daSCheng C Yang void Cpu::cpuFamily(const uint8_t value) 62*43c6a1daSCheng C Yang { 63*43c6a1daSCheng C Yang std::map<uint8_t, const char *>::const_iterator it = 64*43c6a1daSCheng C Yang familyTable.find(value); 65*43c6a1daSCheng C Yang if (it == familyTable.end()) 66*43c6a1daSCheng C Yang { 67*43c6a1daSCheng C Yang processorFamily("Unknown Processor Family"); 68*43c6a1daSCheng C Yang } 69*43c6a1daSCheng C Yang else 70*43c6a1daSCheng C Yang { 71*43c6a1daSCheng C Yang processorFamily(it->second); 72*43c6a1daSCheng C Yang } 73*43c6a1daSCheng C Yang } 74*43c6a1daSCheng C Yang 75*43c6a1daSCheng C Yang std::string Cpu::processorFamily(std::string value) 76*43c6a1daSCheng C Yang { 77*43c6a1daSCheng C Yang return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu:: 78*43c6a1daSCheng C Yang processorFamily(value); 79*43c6a1daSCheng C Yang } 80*43c6a1daSCheng C Yang 81*43c6a1daSCheng C Yang void Cpu::cpuManufacturer(const uint8_t positionNum, const uint8_t structLen, 82*43c6a1daSCheng C Yang uint8_t *dataIn) 83*43c6a1daSCheng C Yang { 84*43c6a1daSCheng C Yang std::string result = positionToString(positionNum, structLen, dataIn); 85*43c6a1daSCheng C Yang 86*43c6a1daSCheng C Yang manufacturer(result); 87*43c6a1daSCheng C Yang } 88*43c6a1daSCheng C Yang 89*43c6a1daSCheng C Yang std::string Cpu::manufacturer(std::string value) 90*43c6a1daSCheng C Yang { 91*43c6a1daSCheng C Yang return sdbusplus::xyz::openbmc_project::Inventory::Decorator::server:: 92*43c6a1daSCheng C Yang Asset::manufacturer(value); 93*43c6a1daSCheng C Yang } 94*43c6a1daSCheng C Yang 95*43c6a1daSCheng C Yang uint32_t Cpu::processorId(uint32_t value) 96*43c6a1daSCheng C Yang { 97*43c6a1daSCheng C Yang return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu:: 98*43c6a1daSCheng C Yang processorId(value); 99*43c6a1daSCheng C Yang } 100*43c6a1daSCheng C Yang 101*43c6a1daSCheng C Yang void Cpu::cpuVersion(const uint8_t positionNum, const uint8_t structLen, 102*43c6a1daSCheng C Yang uint8_t *dataIn) 103*43c6a1daSCheng C Yang { 104*43c6a1daSCheng C Yang std::string result; 105*43c6a1daSCheng C Yang 106*43c6a1daSCheng C Yang result = positionToString(positionNum, structLen, dataIn); 107*43c6a1daSCheng C Yang 108*43c6a1daSCheng C Yang processorVersion(result); 109*43c6a1daSCheng C Yang } 110*43c6a1daSCheng C Yang 111*43c6a1daSCheng C Yang std::string Cpu::processorVersion(std::string value) 112*43c6a1daSCheng C Yang { 113*43c6a1daSCheng C Yang return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu:: 114*43c6a1daSCheng C Yang processorVersion(value); 115*43c6a1daSCheng C Yang } 116*43c6a1daSCheng C Yang 117*43c6a1daSCheng C Yang uint16_t Cpu::processorMaxSpeed(uint16_t value) 118*43c6a1daSCheng C Yang { 119*43c6a1daSCheng C Yang return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu:: 120*43c6a1daSCheng C Yang processorMaxSpeed(value); 121*43c6a1daSCheng C Yang } 122*43c6a1daSCheng C Yang 123*43c6a1daSCheng C Yang void Cpu::cpuCharacteristics(uint16_t value) 124*43c6a1daSCheng C Yang { 125*43c6a1daSCheng C Yang std::string result = ""; 126*43c6a1daSCheng C Yang for (uint8_t index = 0; index < (8 * sizeof(value)); index++) 127*43c6a1daSCheng C Yang { 128*43c6a1daSCheng C Yang if (value & 0x01) 129*43c6a1daSCheng C Yang { 130*43c6a1daSCheng C Yang result += characteristicsTable[index]; 131*43c6a1daSCheng C Yang } 132*43c6a1daSCheng C Yang value >>= 1; 133*43c6a1daSCheng C Yang } 134*43c6a1daSCheng C Yang 135*43c6a1daSCheng C Yang processorCharacteristics(result); 136*43c6a1daSCheng C Yang } 137*43c6a1daSCheng C Yang 138*43c6a1daSCheng C Yang std::string Cpu::processorCharacteristics(std::string value) 139*43c6a1daSCheng C Yang { 140*43c6a1daSCheng C Yang return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu:: 141*43c6a1daSCheng C Yang processorCharacteristics(value); 142*43c6a1daSCheng C Yang } 143*43c6a1daSCheng C Yang 144*43c6a1daSCheng C Yang uint16_t Cpu::processorCoreCount(uint16_t value) 145*43c6a1daSCheng C Yang { 146*43c6a1daSCheng C Yang return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu:: 147*43c6a1daSCheng C Yang processorCoreCount(value); 148*43c6a1daSCheng C Yang } 149*43c6a1daSCheng C Yang 150*43c6a1daSCheng C Yang uint16_t Cpu::processorThreadCount(uint16_t value) 151*43c6a1daSCheng C Yang { 152*43c6a1daSCheng C Yang return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu:: 153*43c6a1daSCheng C Yang processorThreadCount(value); 154*43c6a1daSCheng C Yang } 155*43c6a1daSCheng C Yang 156*43c6a1daSCheng C Yang static constexpr const uint8_t populateMask = 1 << 6; 157*43c6a1daSCheng C Yang static constexpr const uint8_t statusMask = 0x07; 158*43c6a1daSCheng C Yang void Cpu::cpuStatus(uint8_t value) 159*43c6a1daSCheng C Yang { 160*43c6a1daSCheng C Yang if (!(value & populateMask)) 161*43c6a1daSCheng C Yang { 162*43c6a1daSCheng C Yang present(false); 163*43c6a1daSCheng C Yang functional(false); 164*43c6a1daSCheng C Yang return; 165*43c6a1daSCheng C Yang } 166*43c6a1daSCheng C Yang present(true); 167*43c6a1daSCheng C Yang if ((value & statusMask) == 1) 168*43c6a1daSCheng C Yang { 169*43c6a1daSCheng C Yang functional(true); 170*43c6a1daSCheng C Yang } 171*43c6a1daSCheng C Yang else 172*43c6a1daSCheng C Yang { 173*43c6a1daSCheng C Yang functional(false); 174*43c6a1daSCheng C Yang } 175*43c6a1daSCheng C Yang } 176*43c6a1daSCheng C Yang 177*43c6a1daSCheng C Yang bool Cpu::present(bool value) 178*43c6a1daSCheng C Yang { 179*43c6a1daSCheng C Yang return sdbusplus::xyz::openbmc_project::Inventory::server::Item::present( 180*43c6a1daSCheng C Yang value); 181*43c6a1daSCheng C Yang } 182*43c6a1daSCheng C Yang 183*43c6a1daSCheng C Yang bool Cpu::functional(bool value) 184*43c6a1daSCheng C Yang { 185*43c6a1daSCheng C Yang return sdbusplus::xyz::openbmc_project::State::Decorator::server:: 186*43c6a1daSCheng C Yang OperationalStatus::functional(value); 187*43c6a1daSCheng C Yang } 188*43c6a1daSCheng C Yang 189*43c6a1daSCheng C Yang static constexpr uint8_t maxOldVersionCount = 0xff; 190*43c6a1daSCheng C Yang void Cpu::processorInfoUpdate(void) 191*43c6a1daSCheng C Yang { 192*43c6a1daSCheng C Yang uint8_t *dataIn = storage; 193*43c6a1daSCheng C Yang 194*43c6a1daSCheng C Yang dataIn = getSMBIOSTypePtr(dataIn, processorsType); 195*43c6a1daSCheng C Yang if (dataIn == nullptr) 196*43c6a1daSCheng C Yang { 197*43c6a1daSCheng C Yang return; 198*43c6a1daSCheng C Yang } 199*43c6a1daSCheng C Yang 200*43c6a1daSCheng C Yang for (uint8_t index = 0; index < cpuNum; index++) 201*43c6a1daSCheng C Yang { 202*43c6a1daSCheng C Yang dataIn = smbiosNextPtr(dataIn); 203*43c6a1daSCheng C Yang if (dataIn == nullptr) 204*43c6a1daSCheng C Yang { 205*43c6a1daSCheng C Yang return; 206*43c6a1daSCheng C Yang } 207*43c6a1daSCheng C Yang dataIn = getSMBIOSTypePtr(dataIn, processorsType); 208*43c6a1daSCheng C Yang if (dataIn == nullptr) 209*43c6a1daSCheng C Yang { 210*43c6a1daSCheng C Yang return; 211*43c6a1daSCheng C Yang } 212*43c6a1daSCheng C Yang } 213*43c6a1daSCheng C Yang 214*43c6a1daSCheng C Yang auto cpuInfo = reinterpret_cast<struct ProcessorInfo *>(dataIn); 215*43c6a1daSCheng C Yang 216*43c6a1daSCheng C Yang cpuSocket(cpuInfo->socketDesignation, cpuInfo->length, 217*43c6a1daSCheng C Yang dataIn); // offset 4h 218*43c6a1daSCheng C Yang cpuType(cpuInfo->processorType); // offset 5h 219*43c6a1daSCheng C Yang cpuFamily(cpuInfo->family); // offset 6h 220*43c6a1daSCheng C Yang cpuManufacturer(cpuInfo->manufacturer, cpuInfo->length, 221*43c6a1daSCheng C Yang dataIn); // offset 7h 222*43c6a1daSCheng C Yang processorId(cpuInfo->id); // offset 8h 223*43c6a1daSCheng C Yang cpuVersion(cpuInfo->version, cpuInfo->length, dataIn); // offset 10h 224*43c6a1daSCheng C Yang processorMaxSpeed(cpuInfo->maxSpeed); // offset 14h 225*43c6a1daSCheng C Yang if (cpuInfo->coreCount < maxOldVersionCount) // offset 23h or 2Ah 226*43c6a1daSCheng C Yang { 227*43c6a1daSCheng C Yang processorCoreCount(cpuInfo->coreCount); 228*43c6a1daSCheng C Yang } 229*43c6a1daSCheng C Yang else 230*43c6a1daSCheng C Yang { 231*43c6a1daSCheng C Yang processorCoreCount(cpuInfo->coreCount2); 232*43c6a1daSCheng C Yang } 233*43c6a1daSCheng C Yang 234*43c6a1daSCheng C Yang if (cpuInfo->threadCount < maxOldVersionCount) // offset 25h or 2Eh) 235*43c6a1daSCheng C Yang { 236*43c6a1daSCheng C Yang processorThreadCount(cpuInfo->threadCount); 237*43c6a1daSCheng C Yang } 238*43c6a1daSCheng C Yang else 239*43c6a1daSCheng C Yang { 240*43c6a1daSCheng C Yang processorThreadCount(cpuInfo->threadCount2); 241*43c6a1daSCheng C Yang } 242*43c6a1daSCheng C Yang 243*43c6a1daSCheng C Yang cpuCharacteristics(cpuInfo->characteristics); // offset 26h 244*43c6a1daSCheng C Yang 245*43c6a1daSCheng C Yang cpuStatus(cpuInfo->status); 246*43c6a1daSCheng C Yang } 247*43c6a1daSCheng C Yang 248*43c6a1daSCheng C Yang } // namespace smbios 249*43c6a1daSCheng C Yang } // namespace phosphor 250