blob: ffef3cf1a903438a490d5fffd43967c49413a6f9 [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
19#include <iostream>
20#include <map>
21
22namespace phosphor
23{
24namespace smbios
25{
26
27void Cpu::cpuSocket(const uint8_t positionNum, const uint8_t structLen,
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +080028 uint8_t* dataIn)
Cheng C Yang43c6a1d2019-12-19 00:48:34 +080029{
30 std::string result = positionToString(positionNum, structLen, dataIn);
31
32 processorSocket(result);
33}
34
35std::string Cpu::processorSocket(std::string value)
36{
37 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu::
38 processorSocket(value);
39}
40
41void Cpu::cpuType(const uint8_t value)
42{
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +080043 std::map<uint8_t, const char*>::const_iterator it =
Cheng C Yang43c6a1d2019-12-19 00:48:34 +080044 processorTypeTable.find(value);
45 if (it == processorTypeTable.end())
46 {
47 processorType("Unknown Processor Type");
48 }
49 else
50 {
51 processorType(it->second);
52 }
53}
54
55std::string Cpu::processorType(std::string value)
56{
57 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu::
58 processorType(value);
59}
60
61void Cpu::cpuFamily(const uint8_t value)
62{
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +080063 std::map<uint8_t, const char*>::const_iterator it = familyTable.find(value);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +080064 if (it == familyTable.end())
65 {
66 processorFamily("Unknown Processor Family");
67 }
68 else
69 {
70 processorFamily(it->second);
71 }
72}
73
74std::string Cpu::processorFamily(std::string value)
75{
76 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu::
77 processorFamily(value);
78}
79
80void Cpu::cpuManufacturer(const uint8_t positionNum, const uint8_t structLen,
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +080081 uint8_t* dataIn)
Cheng C Yang43c6a1d2019-12-19 00:48:34 +080082{
83 std::string result = positionToString(positionNum, structLen, dataIn);
84
85 manufacturer(result);
86}
87
88std::string Cpu::manufacturer(std::string value)
89{
90 return sdbusplus::xyz::openbmc_project::Inventory::Decorator::server::
91 Asset::manufacturer(value);
92}
93
94uint32_t Cpu::processorId(uint32_t value)
95{
96 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu::
97 processorId(value);
98}
99
100void Cpu::cpuVersion(const uint8_t positionNum, const uint8_t structLen,
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +0800101 uint8_t* dataIn)
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800102{
103 std::string result;
104
105 result = positionToString(positionNum, structLen, dataIn);
106
107 processorVersion(result);
108}
109
110std::string Cpu::processorVersion(std::string value)
111{
112 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu::
113 processorVersion(value);
114}
115
116uint16_t Cpu::processorMaxSpeed(uint16_t value)
117{
118 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu::
119 processorMaxSpeed(value);
120}
121
122void Cpu::cpuCharacteristics(uint16_t value)
123{
124 std::string result = "";
125 for (uint8_t index = 0; index < (8 * sizeof(value)); index++)
126 {
127 if (value & 0x01)
128 {
129 result += characteristicsTable[index];
130 }
131 value >>= 1;
132 }
133
134 processorCharacteristics(result);
135}
136
137std::string Cpu::processorCharacteristics(std::string value)
138{
139 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu::
140 processorCharacteristics(value);
141}
142
143uint16_t Cpu::processorCoreCount(uint16_t value)
144{
145 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu::
146 processorCoreCount(value);
147}
148
149uint16_t Cpu::processorThreadCount(uint16_t value)
150{
151 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Cpu::
152 processorThreadCount(value);
153}
154
155static constexpr const uint8_t populateMask = 1 << 6;
156static constexpr const uint8_t statusMask = 0x07;
157void Cpu::cpuStatus(uint8_t value)
158{
159 if (!(value & populateMask))
160 {
161 present(false);
162 functional(false);
163 return;
164 }
165 present(true);
166 if ((value & statusMask) == 1)
167 {
168 functional(true);
169 }
170 else
171 {
172 functional(false);
173 }
174}
175
176bool Cpu::present(bool value)
177{
178 return sdbusplus::xyz::openbmc_project::Inventory::server::Item::present(
179 value);
180}
181
182bool Cpu::functional(bool value)
183{
184 return sdbusplus::xyz::openbmc_project::State::Decorator::server::
185 OperationalStatus::functional(value);
186}
187
188static constexpr uint8_t maxOldVersionCount = 0xff;
189void Cpu::processorInfoUpdate(void)
190{
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +0800191 uint8_t* dataIn = storage;
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800192
193 dataIn = getSMBIOSTypePtr(dataIn, processorsType);
194 if (dataIn == nullptr)
195 {
196 return;
197 }
198
199 for (uint8_t index = 0; index < cpuNum; index++)
200 {
201 dataIn = smbiosNextPtr(dataIn);
202 if (dataIn == nullptr)
203 {
204 return;
205 }
206 dataIn = getSMBIOSTypePtr(dataIn, processorsType);
207 if (dataIn == nullptr)
208 {
209 return;
210 }
211 }
212
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +0800213 auto cpuInfo = reinterpret_cast<struct ProcessorInfo*>(dataIn);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800214
215 cpuSocket(cpuInfo->socketDesignation, cpuInfo->length,
216 dataIn); // offset 4h
217 cpuType(cpuInfo->processorType); // offset 5h
218 cpuFamily(cpuInfo->family); // offset 6h
219 cpuManufacturer(cpuInfo->manufacturer, cpuInfo->length,
220 dataIn); // offset 7h
221 processorId(cpuInfo->id); // offset 8h
222 cpuVersion(cpuInfo->version, cpuInfo->length, dataIn); // offset 10h
223 processorMaxSpeed(cpuInfo->maxSpeed); // offset 14h
224 if (cpuInfo->coreCount < maxOldVersionCount) // offset 23h or 2Ah
225 {
226 processorCoreCount(cpuInfo->coreCount);
227 }
228 else
229 {
230 processorCoreCount(cpuInfo->coreCount2);
231 }
232
233 if (cpuInfo->threadCount < maxOldVersionCount) // offset 25h or 2Eh)
234 {
235 processorThreadCount(cpuInfo->threadCount);
236 }
237 else
238 {
239 processorThreadCount(cpuInfo->threadCount2);
240 }
241
242 cpuCharacteristics(cpuInfo->characteristics); // offset 26h
243
244 cpuStatus(cpuInfo->status);
245}
246
247} // namespace smbios
248} // namespace phosphor