blob: daab15baeff489bcfa1b51a377e8866dedb297d2 [file] [log] [blame]
Cheng C Yang43c6a1d2019-12-19 00:48:34 +08001/*
2// Copyright (c) 2018 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16
17#include "cpu.hpp"
18
Zhikui Ren18a5ab92020-09-01 21:35:20 -070019#include <bitset>
Cheng C Yang43c6a1d2019-12-19 00:48:34 +080020#include <map>
21
22namespace phosphor
23{
24namespace smbios
25{
26
Zhikui Ren18a5ab92020-09-01 21:35:20 -070027void Cpu::socket(const uint8_t positionNum, const uint8_t structLen,
28 uint8_t* dataIn)
Cheng C Yang43c6a1d2019-12-19 00:48:34 +080029{
30 std::string result = positionToString(positionNum, structLen, dataIn);
31
Zhikui Ren18a5ab92020-09-01 21:35:20 -070032 processor::socket(result);
Jie Yang31720392021-07-22 21:45:45 -070033
34 location::locationCode(result);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +080035}
36
Charles Boyer800bb702021-08-31 17:09:19 -050037static constexpr uint8_t processorFamily2Indicator = 0xfe;
38void Cpu::family(const uint8_t family, const uint16_t family2)
Cheng C Yang43c6a1d2019-12-19 00:48:34 +080039{
Charles Boyer800bb702021-08-31 17:09:19 -050040 std::map<uint8_t, const char*>::const_iterator it =
41 familyTable.find(family);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +080042 if (it == familyTable.end())
43 {
Zhikui Ren18a5ab92020-09-01 21:35:20 -070044 processor::family("Unknown Processor Family");
Cheng C Yang43c6a1d2019-12-19 00:48:34 +080045 }
Charles Boyer800bb702021-08-31 17:09:19 -050046 else if (it->first == processorFamily2Indicator)
47 {
48 std::map<uint16_t, const char*>::const_iterator it2 =
49 family2Table.find(family2);
50 if (it2 == family2Table.end())
51 {
52 processor::family("Unknown Processor Family");
53 }
54 else
55 {
56 processor::family(it2->second);
57 }
58 }
Cheng C Yang43c6a1d2019-12-19 00:48:34 +080059 else
60 {
Zhikui Ren18a5ab92020-09-01 21:35:20 -070061 processor::family(it->second);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +080062 }
63}
64
Zhikui Ren18a5ab92020-09-01 21:35:20 -070065void Cpu::manufacturer(const uint8_t positionNum, const uint8_t structLen,
66 uint8_t* dataIn)
Cheng C Yang43c6a1d2019-12-19 00:48:34 +080067{
68 std::string result = positionToString(positionNum, structLen, dataIn);
69
Zhikui Ren18a5ab92020-09-01 21:35:20 -070070 asset::manufacturer(result);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +080071}
72
Charles Boyere6431692021-08-31 16:47:47 -050073void Cpu::partNumber(const uint8_t positionNum, const uint8_t structLen,
74 uint8_t* dataIn)
75{
76 std::string result = positionToString(positionNum, structLen, dataIn);
77
78 asset::partNumber(result);
79}
80
81void Cpu::serialNumber(const uint8_t positionNum, const uint8_t structLen,
82 uint8_t* dataIn)
83{
84 std::string result = positionToString(positionNum, structLen, dataIn);
85
86 asset::serialNumber(result);
87}
88
Zhikui Ren18a5ab92020-09-01 21:35:20 -070089void Cpu::version(const uint8_t positionNum, const uint8_t structLen,
90 uint8_t* dataIn)
Cheng C Yang43c6a1d2019-12-19 00:48:34 +080091{
92 std::string result;
93
94 result = positionToString(positionNum, structLen, dataIn);
95
Zhikui Ren18a5ab92020-09-01 21:35:20 -070096 rev::version(result);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +080097}
98
Zhikui Ren18a5ab92020-09-01 21:35:20 -070099void Cpu::characteristics(uint16_t value)
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800100{
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700101 std::vector<processor::Capability> result;
102 std::optional<processor::Capability> cap;
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800103
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700104 std::bitset<16> charBits = value;
105 for (uint8_t index = 0; index < charBits.size(); index++)
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800106 {
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700107 if (charBits.test(index))
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800108 {
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700109 if (cap = characteristicsTable[index])
110 {
111 result.emplace_back(*cap);
112 }
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800113 }
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800114 }
115
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700116 processor::characteristics(result);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800117}
118
119static constexpr uint8_t maxOldVersionCount = 0xff;
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700120void Cpu::infoUpdate(void)
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800121{
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +0800122 uint8_t* dataIn = storage;
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800123
124 dataIn = getSMBIOSTypePtr(dataIn, processorsType);
125 if (dataIn == nullptr)
126 {
127 return;
128 }
129
130 for (uint8_t index = 0; index < cpuNum; index++)
131 {
132 dataIn = smbiosNextPtr(dataIn);
133 if (dataIn == nullptr)
134 {
135 return;
136 }
137 dataIn = getSMBIOSTypePtr(dataIn, processorsType);
138 if (dataIn == nullptr)
139 {
140 return;
141 }
142 }
143
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +0800144 auto cpuInfo = reinterpret_cast<struct ProcessorInfo*>(dataIn);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800145
Jonathan Doman563570d2021-05-24 10:52:43 -0700146 socket(cpuInfo->socketDesignation, cpuInfo->length, dataIn); // offset 4h
147
148 constexpr uint32_t socketPopulatedMask = 1 << 6;
149 if ((cpuInfo->status & socketPopulatedMask) == 0)
150 {
151 // Don't attempt to fill in any other details if the CPU is not present.
152 present(false);
153 return;
154 }
155 present(true);
156
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700157 // this class is for type CPU //offset 5h
Charles Boyer800bb702021-08-31 17:09:19 -0500158 family(cpuInfo->family, cpuInfo->family2); // offset 6h and 28h
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700159 manufacturer(cpuInfo->manufacturer, cpuInfo->length,
160 dataIn); // offset 7h
161 id(cpuInfo->id); // offset 8h
162 version(cpuInfo->version, cpuInfo->length, dataIn); // offset 10h
163 maxSpeedInMhz(cpuInfo->maxSpeed); // offset 14h
Charles Boyere6431692021-08-31 16:47:47 -0500164 serialNumber(cpuInfo->serialNum, cpuInfo->length,
165 dataIn); // offset 20h
166 partNumber(cpuInfo->partNum, cpuInfo->length,
167 dataIn); // offset 22h
168 if (cpuInfo->coreCount < maxOldVersionCount) // offset 23h or 2Ah
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800169 {
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700170 coreCount(cpuInfo->coreCount);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800171 }
172 else
173 {
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700174 coreCount(cpuInfo->coreCount2);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800175 }
176
177 if (cpuInfo->threadCount < maxOldVersionCount) // offset 25h or 2Eh)
178 {
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700179 threadCount(cpuInfo->threadCount);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800180 }
181 else
182 {
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700183 threadCount(cpuInfo->threadCount2);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800184 }
185
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700186 characteristics(cpuInfo->characteristics); // offset 26h
Jie Yange7cf3192021-08-20 11:21:43 -0700187
188 if (!motherboardPath.empty())
189 {
190 std::vector<std::tuple<std::string, std::string, std::string>> assocs;
191 assocs.emplace_back("chassis", "processors", motherboardPath);
192 association::associations(assocs);
193 }
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800194}
195
196} // namespace smbios
197} // namespace phosphor