xref: /openbmc/smbios-mdr/src/cpu.cpp (revision 19849573)
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 
1918a5ab91SZhikui Ren #include <bitset>
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 
2718a5ab91SZhikui Ren void Cpu::socket(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 
3218a5ab91SZhikui Ren     processor::socket(result);
3331720397SJie Yang 
3431720397SJie Yang     location::locationCode(result);
3543c6a1daSCheng C Yang }
3643c6a1daSCheng C Yang 
37800bb700SCharles Boyer static constexpr uint8_t processorFamily2Indicator = 0xfe;
38800bb700SCharles Boyer void Cpu::family(const uint8_t family, const uint16_t family2)
3943c6a1daSCheng C Yang {
40800bb700SCharles Boyer     std::map<uint8_t, const char*>::const_iterator it =
41800bb700SCharles Boyer         familyTable.find(family);
4243c6a1daSCheng C Yang     if (it == familyTable.end())
4343c6a1daSCheng C Yang     {
4418a5ab91SZhikui Ren         processor::family("Unknown Processor Family");
4543c6a1daSCheng C Yang     }
46800bb700SCharles Boyer     else if (it->first == processorFamily2Indicator)
47800bb700SCharles Boyer     {
48800bb700SCharles Boyer         std::map<uint16_t, const char*>::const_iterator it2 =
49800bb700SCharles Boyer             family2Table.find(family2);
50800bb700SCharles Boyer         if (it2 == family2Table.end())
51800bb700SCharles Boyer         {
52800bb700SCharles Boyer             processor::family("Unknown Processor Family");
53800bb700SCharles Boyer         }
54800bb700SCharles Boyer         else
55800bb700SCharles Boyer         {
56800bb700SCharles Boyer             processor::family(it2->second);
57*19849573SJiaqing Zhao             processor::effectiveFamily(family2);
58800bb700SCharles Boyer         }
59800bb700SCharles Boyer     }
6043c6a1daSCheng C Yang     else
6143c6a1daSCheng C Yang     {
6218a5ab91SZhikui Ren         processor::family(it->second);
63*19849573SJiaqing Zhao         processor::effectiveFamily(family);
6443c6a1daSCheng C Yang     }
6543c6a1daSCheng C Yang }
6643c6a1daSCheng C Yang 
6718a5ab91SZhikui Ren void Cpu::manufacturer(const uint8_t positionNum, const uint8_t structLen,
6843c6a1daSCheng C Yang                        uint8_t* dataIn)
6943c6a1daSCheng C Yang {
7043c6a1daSCheng C Yang     std::string result = positionToString(positionNum, structLen, dataIn);
7143c6a1daSCheng C Yang 
7218a5ab91SZhikui Ren     asset::manufacturer(result);
7343c6a1daSCheng C Yang }
7443c6a1daSCheng C Yang 
75e643169dSCharles Boyer void Cpu::partNumber(const uint8_t positionNum, const uint8_t structLen,
76e643169dSCharles Boyer                      uint8_t* dataIn)
77e643169dSCharles Boyer {
78e643169dSCharles Boyer     std::string result = positionToString(positionNum, structLen, dataIn);
79e643169dSCharles Boyer 
80e643169dSCharles Boyer     asset::partNumber(result);
81e643169dSCharles Boyer }
82e643169dSCharles Boyer 
83e643169dSCharles Boyer void Cpu::serialNumber(const uint8_t positionNum, const uint8_t structLen,
84e643169dSCharles Boyer                        uint8_t* dataIn)
85e643169dSCharles Boyer {
86e643169dSCharles Boyer     std::string result = positionToString(positionNum, structLen, dataIn);
87e643169dSCharles Boyer 
88e643169dSCharles Boyer     asset::serialNumber(result);
89e643169dSCharles Boyer }
90e643169dSCharles Boyer 
9118a5ab91SZhikui Ren void Cpu::version(const uint8_t positionNum, const uint8_t structLen,
9243c6a1daSCheng C Yang                   uint8_t* dataIn)
9343c6a1daSCheng C Yang {
9443c6a1daSCheng C Yang     std::string result;
9543c6a1daSCheng C Yang 
9643c6a1daSCheng C Yang     result = positionToString(positionNum, structLen, dataIn);
9743c6a1daSCheng C Yang 
9818a5ab91SZhikui Ren     rev::version(result);
9943c6a1daSCheng C Yang }
10043c6a1daSCheng C Yang 
10118a5ab91SZhikui Ren void Cpu::characteristics(uint16_t value)
10243c6a1daSCheng C Yang {
10318a5ab91SZhikui Ren     std::vector<processor::Capability> result;
10418a5ab91SZhikui Ren     std::optional<processor::Capability> cap;
10543c6a1daSCheng C Yang 
10618a5ab91SZhikui Ren     std::bitset<16> charBits = value;
10718a5ab91SZhikui Ren     for (uint8_t index = 0; index < charBits.size(); index++)
10843c6a1daSCheng C Yang     {
10918a5ab91SZhikui Ren         if (charBits.test(index))
11018a5ab91SZhikui Ren         {
11118a5ab91SZhikui Ren             if (cap = characteristicsTable[index])
11218a5ab91SZhikui Ren             {
11318a5ab91SZhikui Ren                 result.emplace_back(*cap);
11443c6a1daSCheng C Yang             }
11543c6a1daSCheng C Yang         }
11643c6a1daSCheng C Yang     }
11743c6a1daSCheng C Yang 
11818a5ab91SZhikui Ren     processor::characteristics(result);
11943c6a1daSCheng C Yang }
12043c6a1daSCheng C Yang 
12143c6a1daSCheng C Yang static constexpr uint8_t maxOldVersionCount = 0xff;
12218a5ab91SZhikui Ren void Cpu::infoUpdate(void)
12343c6a1daSCheng C Yang {
12443c6a1daSCheng C Yang     uint8_t* dataIn = storage;
12543c6a1daSCheng C Yang 
12643c6a1daSCheng C Yang     dataIn = getSMBIOSTypePtr(dataIn, processorsType);
12743c6a1daSCheng C Yang     if (dataIn == nullptr)
12843c6a1daSCheng C Yang     {
12943c6a1daSCheng C Yang         return;
13043c6a1daSCheng C Yang     }
13143c6a1daSCheng C Yang 
13243c6a1daSCheng C Yang     for (uint8_t index = 0; index < cpuNum; index++)
13343c6a1daSCheng C Yang     {
13443c6a1daSCheng C Yang         dataIn = smbiosNextPtr(dataIn);
13543c6a1daSCheng C Yang         if (dataIn == nullptr)
13643c6a1daSCheng C Yang         {
13743c6a1daSCheng C Yang             return;
13843c6a1daSCheng C Yang         }
13943c6a1daSCheng C Yang         dataIn = getSMBIOSTypePtr(dataIn, processorsType);
14043c6a1daSCheng C Yang         if (dataIn == nullptr)
14143c6a1daSCheng C Yang         {
14243c6a1daSCheng C Yang             return;
14343c6a1daSCheng C Yang         }
14443c6a1daSCheng C Yang     }
14543c6a1daSCheng C Yang 
14643c6a1daSCheng C Yang     auto cpuInfo = reinterpret_cast<struct ProcessorInfo*>(dataIn);
14743c6a1daSCheng C Yang 
148563570dfSJonathan Doman     socket(cpuInfo->socketDesignation, cpuInfo->length, dataIn); // offset 4h
149563570dfSJonathan Doman 
150563570dfSJonathan Doman     constexpr uint32_t socketPopulatedMask = 1 << 6;
151563570dfSJonathan Doman     if ((cpuInfo->status & socketPopulatedMask) == 0)
152563570dfSJonathan Doman     {
153563570dfSJonathan Doman         // Don't attempt to fill in any other details if the CPU is not present.
154563570dfSJonathan Doman         present(false);
155563570dfSJonathan Doman         return;
156563570dfSJonathan Doman     }
157563570dfSJonathan Doman     present(true);
158563570dfSJonathan Doman 
15918a5ab91SZhikui Ren     // this class is for type CPU  //offset 5h
160800bb700SCharles Boyer     family(cpuInfo->family, cpuInfo->family2); // offset 6h and 28h
16118a5ab91SZhikui Ren     manufacturer(cpuInfo->manufacturer, cpuInfo->length,
16243c6a1daSCheng C Yang                  dataIn);                               // offset 7h
16318a5ab91SZhikui Ren     id(cpuInfo->id);                                    // offset 8h
16418a5ab91SZhikui Ren     version(cpuInfo->version, cpuInfo->length, dataIn); // offset 10h
16518a5ab91SZhikui Ren     maxSpeedInMhz(cpuInfo->maxSpeed);                   // offset 14h
166e643169dSCharles Boyer     serialNumber(cpuInfo->serialNum, cpuInfo->length,
167e643169dSCharles Boyer                  dataIn); // offset 20h
168e643169dSCharles Boyer     partNumber(cpuInfo->partNum, cpuInfo->length,
169e643169dSCharles Boyer                dataIn);                          // offset 22h
17043c6a1daSCheng C Yang     if (cpuInfo->coreCount < maxOldVersionCount) // offset 23h or 2Ah
17143c6a1daSCheng C Yang     {
17218a5ab91SZhikui Ren         coreCount(cpuInfo->coreCount);
17343c6a1daSCheng C Yang     }
17443c6a1daSCheng C Yang     else
17543c6a1daSCheng C Yang     {
17618a5ab91SZhikui Ren         coreCount(cpuInfo->coreCount2);
17743c6a1daSCheng C Yang     }
17843c6a1daSCheng C Yang 
17943c6a1daSCheng C Yang     if (cpuInfo->threadCount < maxOldVersionCount) // offset 25h or 2Eh)
18043c6a1daSCheng C Yang     {
18118a5ab91SZhikui Ren         threadCount(cpuInfo->threadCount);
18243c6a1daSCheng C Yang     }
18343c6a1daSCheng C Yang     else
18443c6a1daSCheng C Yang     {
18518a5ab91SZhikui Ren         threadCount(cpuInfo->threadCount2);
18643c6a1daSCheng C Yang     }
18743c6a1daSCheng C Yang 
18818a5ab91SZhikui Ren     characteristics(cpuInfo->characteristics); // offset 26h
189e7cf3195SJie Yang 
190e7cf3195SJie Yang     if (!motherboardPath.empty())
191e7cf3195SJie Yang     {
192e7cf3195SJie Yang         std::vector<std::tuple<std::string, std::string, std::string>> assocs;
193e7cf3195SJie Yang         assocs.emplace_back("chassis", "processors", motherboardPath);
194e7cf3195SJie Yang         association::associations(assocs);
195e7cf3195SJie Yang     }
19643c6a1daSCheng C Yang }
19743c6a1daSCheng C Yang 
19843c6a1daSCheng C Yang } // namespace smbios
19943c6a1daSCheng C Yang } // namespace phosphor
200