blob: ff4a070d7d2803a0dbfa9b0ebc863715faa276b5 [file] [log] [blame]
Cheng C Yang8c3fab62019-12-19 00:51:06 +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 "dimm.hpp"
18
19#include "mdrv2.hpp"
20
21namespace phosphor
22{
23namespace smbios
24{
25
26using DeviceType =
27 sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::DeviceType;
28
29static constexpr uint16_t maxOldDimmSize = 0x7fff;
30void Dimm::memoryInfoUpdate(void)
31{
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +080032 uint8_t* dataIn = storage;
Cheng C Yang8c3fab62019-12-19 00:51:06 +080033
34 dataIn = getSMBIOSTypePtr(dataIn, memoryDeviceType);
35
36 if (dataIn == nullptr)
37 {
38 return;
39 }
40 for (uint8_t index = 0; index < dimmNum; index++)
41 {
42 dataIn = smbiosNextPtr(dataIn);
43 if (dataIn == nullptr)
44 {
45 return;
46 }
47 dataIn = getSMBIOSTypePtr(dataIn, memoryDeviceType);
48 if (dataIn == nullptr)
49 {
50 return;
51 }
52 }
53
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +080054 auto memoryInfo = reinterpret_cast<struct MemoryInfo*>(dataIn);
Cheng C Yang8c3fab62019-12-19 00:51:06 +080055
56 memoryDataWidth(memoryInfo->dataWidth);
57
58 if (memoryInfo->size == maxOldDimmSize)
59 {
60 dimmSizeExt(memoryInfo->extendedSize);
61 }
62 else
63 {
64 dimmSize(memoryInfo->size);
65 }
66
67 dimmDeviceLocator(memoryInfo->deviceLocator, memoryInfo->length, dataIn);
68 dimmType(memoryInfo->memoryType);
69 dimmTypeDetail(memoryInfo->typeDetail);
70 maxMemorySpeedInMhz(memoryInfo->speed);
71 dimmManufacturer(memoryInfo->manufacturer, memoryInfo->length, dataIn);
72 dimmSerialNum(memoryInfo->serialNum, memoryInfo->length, dataIn);
73 dimmPartNum(memoryInfo->partNum, memoryInfo->length, dataIn);
74 memoryAttributes(memoryInfo->attributes);
75 memoryConfiguredSpeedInMhz(memoryInfo->confClockSpeed);
76
Jie Yange7cf3192021-08-20 11:21:43 -070077 if (!motherboardPath.empty())
78 {
79 std::vector<std::tuple<std::string, std::string, std::string>> assocs;
80 assocs.emplace_back("chassis", "memories", motherboardPath);
81 association::associations(assocs);
82 }
83
Cheng C Yang8c3fab62019-12-19 00:51:06 +080084 return;
85}
86
87uint16_t Dimm::memoryDataWidth(uint16_t value)
88{
89 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
90 memoryDataWidth(value);
91}
92
93static constexpr uint16_t baseNewVersionDimmSize = 0x8000;
94static constexpr uint16_t dimmSizeUnit = 1024;
95void Dimm::dimmSize(const uint16_t size)
96{
Jason M. Billse7770992021-05-14 13:24:33 -070097 size_t result = size & maxOldDimmSize;
Cheng C Yang8c3fab62019-12-19 00:51:06 +080098 if (0 == (size & baseNewVersionDimmSize))
99 {
100 result = result * dimmSizeUnit;
101 }
102 memorySizeInKB(result);
103}
104
Jason M. Billse7770992021-05-14 13:24:33 -0700105void Dimm::dimmSizeExt(size_t size)
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800106{
107 size = size * dimmSizeUnit;
108 memorySizeInKB(size);
109}
110
Jason M. Billse7770992021-05-14 13:24:33 -0700111size_t Dimm::memorySizeInKB(size_t value)
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800112{
113 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
114 memorySizeInKB(value);
115}
116
117void Dimm::dimmDeviceLocator(const uint8_t positionNum, const uint8_t structLen,
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +0800118 uint8_t* dataIn)
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800119{
120 std::string result = positionToString(positionNum, structLen, dataIn);
121
122 memoryDeviceLocator(result);
Jie Yang31720392021-07-22 21:45:45 -0700123
124 locationCode(result);
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800125}
126
127std::string Dimm::memoryDeviceLocator(std::string value)
128{
129 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
130 memoryDeviceLocator(value);
131}
132
133void Dimm::dimmType(const uint8_t type)
134{
135 std::map<uint8_t, DeviceType>::const_iterator it = dimmTypeTable.find(type);
136 if (it == dimmTypeTable.end())
137 {
138 memoryType(DeviceType::Unknown);
139 }
140 else
141 {
142 memoryType(it->second);
143 }
144}
145
146DeviceType Dimm::memoryType(DeviceType value)
147{
148 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
149 memoryType(value);
150}
151
152void Dimm::dimmTypeDetail(uint16_t detail)
153{
154 std::string result;
155 for (uint8_t index = 0; index < (8 * sizeof(detail)); index++)
156 {
157 if (detail & 0x01)
158 {
159 result += detailTable[index];
160 }
161 detail >>= 1;
162 }
163 memoryTypeDetail(result);
164}
165
166std::string Dimm::memoryTypeDetail(std::string value)
167{
168 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
169 memoryTypeDetail(value);
170}
171
172uint16_t Dimm::maxMemorySpeedInMhz(uint16_t value)
173{
174 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
175 maxMemorySpeedInMhz(value);
176}
177
178void Dimm::dimmManufacturer(const uint8_t positionNum, const uint8_t structLen,
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +0800179 uint8_t* dataIn)
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800180{
181 std::string result = positionToString(positionNum, structLen, dataIn);
182
Joshi-Mansi33c948a2021-03-20 00:58:50 +0530183 bool val = true;
184 if (result == "NO DIMM")
185 {
186 val = false;
187
188 // No dimm presence so making manufacturer value as "" (instead of
189 // NO DIMM - as there won't be any manufacturer for DIMM which is not
190 // present).
191 result = "";
192 }
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800193 manufacturer(result);
Joshi-Mansi33c948a2021-03-20 00:58:50 +0530194 present(val);
Tim Leedc469c72021-07-20 10:55:58 +0800195 functional(val);
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800196}
197
198std::string Dimm::manufacturer(std::string value)
199{
200 return sdbusplus::xyz::openbmc_project::Inventory::Decorator::server::
201 Asset::manufacturer(value);
202}
203
Joshi-Mansi33c948a2021-03-20 00:58:50 +0530204bool Dimm::present(bool value)
205{
206 return sdbusplus::xyz::openbmc_project::Inventory::server::Item::present(
207 value);
208}
209
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800210void Dimm::dimmSerialNum(const uint8_t positionNum, const uint8_t structLen,
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +0800211 uint8_t* dataIn)
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800212{
213 std::string result = positionToString(positionNum, structLen, dataIn);
214
215 serialNumber(result);
216}
217
218std::string Dimm::serialNumber(std::string value)
219{
220 return sdbusplus::xyz::openbmc_project::Inventory::Decorator::server::
221 Asset::serialNumber(value);
222}
223
224void Dimm::dimmPartNum(const uint8_t positionNum, const uint8_t structLen,
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +0800225 uint8_t* dataIn)
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800226{
227 std::string result = positionToString(positionNum, structLen, dataIn);
228
229 partNumber(result);
230}
231
232std::string Dimm::partNumber(std::string value)
233{
234 return sdbusplus::xyz::openbmc_project::Inventory::Decorator::server::
235 Asset::partNumber(value);
236}
237
Jie Yang31720392021-07-22 21:45:45 -0700238std::string Dimm::locationCode(std::string value)
239{
240 return sdbusplus::xyz::openbmc_project::Inventory::Decorator::server::
241 LocationCode::locationCode(value);
242}
243
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800244uint8_t Dimm::memoryAttributes(uint8_t value)
245{
246 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
247 memoryAttributes(value);
248}
249
250uint16_t Dimm::memoryConfiguredSpeedInMhz(uint16_t value)
251{
252 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
253 memoryConfiguredSpeedInMhz(value);
254}
255
Tim Leedc469c72021-07-20 10:55:58 +0800256bool Dimm::functional(bool value)
257{
258 return sdbusplus::xyz::openbmc_project::State::Decorator::server::
259 OperationalStatus::functional(value);
260}
261
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800262} // namespace smbios
263} // namespace phosphor