blob: d9fd212862ec9f24c5c07e5ff3c8981d3e0ea8f1 [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);
Jiaqing Zhao19849572022-06-13 21:10:45 +080057 processor::effectiveFamily(family2);
Charles Boyer800bb702021-08-31 17:09:19 -050058 }
59 }
Cheng C Yang43c6a1d2019-12-19 00:48:34 +080060 else
61 {
Zhikui Ren18a5ab92020-09-01 21:35:20 -070062 processor::family(it->second);
Jiaqing Zhao19849572022-06-13 21:10:45 +080063 processor::effectiveFamily(family);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +080064 }
65}
66
Zhikui Ren18a5ab92020-09-01 21:35:20 -070067void Cpu::manufacturer(const uint8_t positionNum, const uint8_t structLen,
68 uint8_t* dataIn)
Cheng C Yang43c6a1d2019-12-19 00:48:34 +080069{
70 std::string result = positionToString(positionNum, structLen, dataIn);
71
Zhikui Ren18a5ab92020-09-01 21:35:20 -070072 asset::manufacturer(result);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +080073}
74
Charles Boyere6431692021-08-31 16:47:47 -050075void Cpu::partNumber(const uint8_t positionNum, const uint8_t structLen,
76 uint8_t* dataIn)
77{
78 std::string result = positionToString(positionNum, structLen, dataIn);
79
80 asset::partNumber(result);
81}
82
83void Cpu::serialNumber(const uint8_t positionNum, const uint8_t structLen,
84 uint8_t* dataIn)
85{
86 std::string result = positionToString(positionNum, structLen, dataIn);
87
88 asset::serialNumber(result);
89}
90
Zhikui Ren18a5ab92020-09-01 21:35:20 -070091void Cpu::version(const uint8_t positionNum, const uint8_t structLen,
92 uint8_t* dataIn)
Cheng C Yang43c6a1d2019-12-19 00:48:34 +080093{
94 std::string result;
95
96 result = positionToString(positionNum, structLen, dataIn);
97
Zhikui Ren18a5ab92020-09-01 21:35:20 -070098 rev::version(result);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +080099}
100
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700101void Cpu::characteristics(uint16_t value)
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800102{
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700103 std::vector<processor::Capability> result;
104 std::optional<processor::Capability> cap;
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800105
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700106 std::bitset<16> charBits = value;
107 for (uint8_t index = 0; index < charBits.size(); index++)
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800108 {
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700109 if (charBits.test(index))
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800110 {
Jonathan Domanf2d8bb42023-07-26 10:13:34 -0700111 if ((cap = characteristicsTable[index]))
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700112 {
113 result.emplace_back(*cap);
114 }
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800115 }
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800116 }
117
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700118 processor::characteristics(result);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800119}
120
121static constexpr uint8_t maxOldVersionCount = 0xff;
Brandon Kim5a122a62023-05-04 04:25:03 +0000122void Cpu::infoUpdate(uint8_t* smbiosTableStorage,
123 const std::string& motherboard)
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800124{
Brandon Kim5a122a62023-05-04 04:25:03 +0000125 storage = smbiosTableStorage;
126 motherboardPath = motherboard;
127
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +0800128 uint8_t* dataIn = storage;
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800129
130 dataIn = getSMBIOSTypePtr(dataIn, processorsType);
131 if (dataIn == nullptr)
132 {
133 return;
134 }
135
136 for (uint8_t index = 0; index < cpuNum; index++)
137 {
138 dataIn = smbiosNextPtr(dataIn);
139 if (dataIn == nullptr)
140 {
141 return;
142 }
143 dataIn = getSMBIOSTypePtr(dataIn, processorsType);
144 if (dataIn == nullptr)
145 {
146 return;
147 }
148 }
149
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +0800150 auto cpuInfo = reinterpret_cast<struct ProcessorInfo*>(dataIn);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800151
Jonathan Doman563570d2021-05-24 10:52:43 -0700152 socket(cpuInfo->socketDesignation, cpuInfo->length, dataIn); // offset 4h
153
154 constexpr uint32_t socketPopulatedMask = 1 << 6;
155 if ((cpuInfo->status & socketPopulatedMask) == 0)
156 {
157 // Don't attempt to fill in any other details if the CPU is not present.
158 present(false);
159 return;
160 }
161 present(true);
162
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700163 // this class is for type CPU //offset 5h
Charles Boyer800bb702021-08-31 17:09:19 -0500164 family(cpuInfo->family, cpuInfo->family2); // offset 6h and 28h
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700165 manufacturer(cpuInfo->manufacturer, cpuInfo->length,
Patrick Williamsc39d3df2023-05-10 07:51:14 -0500166 dataIn); // offset 7h
167 id(cpuInfo->id); // offset 8h
Zhikui Ren59616932023-03-24 09:02:20 -0700168
169 // Step, EffectiveFamily, EffectiveModel computation for Intel processors.
170 std::map<uint8_t, const char*>::const_iterator it =
171 familyTable.find(cpuInfo->family);
172 if (it != familyTable.end())
173 {
174 std::string familyStr = it->second;
175 if ((familyStr.find(" Xeon ") != std::string::npos) ||
176 (familyStr.find(" Intel ") != std::string::npos))
177 {
178 // Processor ID field
179 // SteppinID: 4;
180 // Model: 4;
181 // Family: 4;
182 // Type: 2;
183 // Reserved1: 2;
184 // XModel: 4;
185 // XFamily: 8;
186 // Reserved2: 4;
187 uint16_t cpuStep = cpuInfo->id & 0xf;
188 uint16_t cpuModel = (cpuInfo->id & 0xf0) >> 4;
189 uint16_t cpuFamily = (cpuInfo->id & 0xf00) >> 8;
190 uint16_t cpuXModel = (cpuInfo->id & 0xf0000) >> 16;
191 uint16_t cpuXFamily = (cpuInfo->id & 0xff00000) >> 20;
192 step(cpuStep);
193 if (cpuFamily == 0xf)
194 {
195 effectiveFamily(cpuXFamily + cpuFamily);
196 }
197 else
198 {
199 effectiveFamily(cpuFamily);
200 }
201 if (cpuFamily == 0x6 || cpuFamily == 0xf)
202 {
203 effectiveModel((cpuXModel << 4) | cpuModel);
204 }
205 else
206 {
207 effectiveModel(cpuModel);
208 }
209 }
210 }
211
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700212 version(cpuInfo->version, cpuInfo->length, dataIn); // offset 10h
213 maxSpeedInMhz(cpuInfo->maxSpeed); // offset 14h
Charles Boyere6431692021-08-31 16:47:47 -0500214 serialNumber(cpuInfo->serialNum, cpuInfo->length,
Patrick Williamsc39d3df2023-05-10 07:51:14 -0500215 dataIn); // offset 20h
Charles Boyere6431692021-08-31 16:47:47 -0500216 partNumber(cpuInfo->partNum, cpuInfo->length,
Patrick Williamsc39d3df2023-05-10 07:51:14 -0500217 dataIn); // offset 22h
218 if (cpuInfo->coreCount < maxOldVersionCount) // offset 23h or 2Ah
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800219 {
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700220 coreCount(cpuInfo->coreCount);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800221 }
222 else
223 {
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700224 coreCount(cpuInfo->coreCount2);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800225 }
226
227 if (cpuInfo->threadCount < maxOldVersionCount) // offset 25h or 2Eh)
228 {
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700229 threadCount(cpuInfo->threadCount);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800230 }
231 else
232 {
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700233 threadCount(cpuInfo->threadCount2);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800234 }
235
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700236 characteristics(cpuInfo->characteristics); // offset 26h
Jie Yange7cf3192021-08-20 11:21:43 -0700237
238 if (!motherboardPath.empty())
239 {
240 std::vector<std::tuple<std::string, std::string, std::string>> assocs;
241 assocs.emplace_back("chassis", "processors", motherboardPath);
242 association::associations(assocs);
243 }
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800244}
245
246} // namespace smbios
247} // namespace phosphor