blob: e2cfbc6a6be679c204f5a4fa77d7d756f6428f92 [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
77 return;
78}
79
80uint16_t Dimm::memoryDataWidth(uint16_t value)
81{
82 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
83 memoryDataWidth(value);
84}
85
86static constexpr uint16_t baseNewVersionDimmSize = 0x8000;
87static constexpr uint16_t dimmSizeUnit = 1024;
88void Dimm::dimmSize(const uint16_t size)
89{
Jason M. Billse7770992021-05-14 13:24:33 -070090 size_t result = size & maxOldDimmSize;
Cheng C Yang8c3fab62019-12-19 00:51:06 +080091 if (0 == (size & baseNewVersionDimmSize))
92 {
93 result = result * dimmSizeUnit;
94 }
95 memorySizeInKB(result);
96}
97
Jason M. Billse7770992021-05-14 13:24:33 -070098void Dimm::dimmSizeExt(size_t size)
Cheng C Yang8c3fab62019-12-19 00:51:06 +080099{
100 size = size * dimmSizeUnit;
101 memorySizeInKB(size);
102}
103
Jason M. Billse7770992021-05-14 13:24:33 -0700104size_t Dimm::memorySizeInKB(size_t value)
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800105{
106 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
107 memorySizeInKB(value);
108}
109
110void Dimm::dimmDeviceLocator(const uint8_t positionNum, const uint8_t structLen,
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +0800111 uint8_t* dataIn)
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800112{
113 std::string result = positionToString(positionNum, structLen, dataIn);
114
115 memoryDeviceLocator(result);
116}
117
118std::string Dimm::memoryDeviceLocator(std::string value)
119{
120 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
121 memoryDeviceLocator(value);
122}
123
124void Dimm::dimmType(const uint8_t type)
125{
126 std::map<uint8_t, DeviceType>::const_iterator it = dimmTypeTable.find(type);
127 if (it == dimmTypeTable.end())
128 {
129 memoryType(DeviceType::Unknown);
130 }
131 else
132 {
133 memoryType(it->second);
134 }
135}
136
137DeviceType Dimm::memoryType(DeviceType value)
138{
139 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
140 memoryType(value);
141}
142
143void Dimm::dimmTypeDetail(uint16_t detail)
144{
145 std::string result;
146 for (uint8_t index = 0; index < (8 * sizeof(detail)); index++)
147 {
148 if (detail & 0x01)
149 {
150 result += detailTable[index];
151 }
152 detail >>= 1;
153 }
154 memoryTypeDetail(result);
155}
156
157std::string Dimm::memoryTypeDetail(std::string value)
158{
159 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
160 memoryTypeDetail(value);
161}
162
163uint16_t Dimm::maxMemorySpeedInMhz(uint16_t value)
164{
165 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
166 maxMemorySpeedInMhz(value);
167}
168
169void Dimm::dimmManufacturer(const uint8_t positionNum, const uint8_t structLen,
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +0800170 uint8_t* dataIn)
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800171{
172 std::string result = positionToString(positionNum, structLen, dataIn);
173
Joshi-Mansi33c948a2021-03-20 00:58:50 +0530174 bool val = true;
175 if (result == "NO DIMM")
176 {
177 val = false;
178
179 // No dimm presence so making manufacturer value as "" (instead of
180 // NO DIMM - as there won't be any manufacturer for DIMM which is not
181 // present).
182 result = "";
183 }
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800184 manufacturer(result);
Joshi-Mansi33c948a2021-03-20 00:58:50 +0530185 present(val);
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800186}
187
188std::string Dimm::manufacturer(std::string value)
189{
190 return sdbusplus::xyz::openbmc_project::Inventory::Decorator::server::
191 Asset::manufacturer(value);
192}
193
Joshi-Mansi33c948a2021-03-20 00:58:50 +0530194bool Dimm::present(bool value)
195{
196 return sdbusplus::xyz::openbmc_project::Inventory::server::Item::present(
197 value);
198}
199
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800200void Dimm::dimmSerialNum(const uint8_t positionNum, const uint8_t structLen,
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +0800201 uint8_t* dataIn)
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800202{
203 std::string result = positionToString(positionNum, structLen, dataIn);
204
205 serialNumber(result);
206}
207
208std::string Dimm::serialNumber(std::string value)
209{
210 return sdbusplus::xyz::openbmc_project::Inventory::Decorator::server::
211 Asset::serialNumber(value);
212}
213
214void Dimm::dimmPartNum(const uint8_t positionNum, const uint8_t structLen,
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +0800215 uint8_t* dataIn)
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800216{
217 std::string result = positionToString(positionNum, structLen, dataIn);
218
219 partNumber(result);
220}
221
222std::string Dimm::partNumber(std::string value)
223{
224 return sdbusplus::xyz::openbmc_project::Inventory::Decorator::server::
225 Asset::partNumber(value);
226}
227
228uint8_t Dimm::memoryAttributes(uint8_t value)
229{
230 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
231 memoryAttributes(value);
232}
233
234uint16_t Dimm::memoryConfiguredSpeedInMhz(uint16_t value)
235{
236 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
237 memoryConfiguredSpeedInMhz(value);
238}
239
240} // namespace smbios
241} // namespace phosphor