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