blob: 03b35f984a11466d3555dae2255dd345fdf3eb96 [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);
Jie Yang31720392021-07-22 21:45:45 -0700116
117 locationCode(result);
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800118}
119
120std::string Dimm::memoryDeviceLocator(std::string value)
121{
122 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
123 memoryDeviceLocator(value);
124}
125
126void Dimm::dimmType(const uint8_t type)
127{
128 std::map<uint8_t, DeviceType>::const_iterator it = dimmTypeTable.find(type);
129 if (it == dimmTypeTable.end())
130 {
131 memoryType(DeviceType::Unknown);
132 }
133 else
134 {
135 memoryType(it->second);
136 }
137}
138
139DeviceType Dimm::memoryType(DeviceType value)
140{
141 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
142 memoryType(value);
143}
144
145void Dimm::dimmTypeDetail(uint16_t detail)
146{
147 std::string result;
148 for (uint8_t index = 0; index < (8 * sizeof(detail)); index++)
149 {
150 if (detail & 0x01)
151 {
152 result += detailTable[index];
153 }
154 detail >>= 1;
155 }
156 memoryTypeDetail(result);
157}
158
159std::string Dimm::memoryTypeDetail(std::string value)
160{
161 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
162 memoryTypeDetail(value);
163}
164
165uint16_t Dimm::maxMemorySpeedInMhz(uint16_t value)
166{
167 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
168 maxMemorySpeedInMhz(value);
169}
170
171void Dimm::dimmManufacturer(const uint8_t positionNum, const uint8_t structLen,
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +0800172 uint8_t* dataIn)
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800173{
174 std::string result = positionToString(positionNum, structLen, dataIn);
175
Joshi-Mansi33c948a2021-03-20 00:58:50 +0530176 bool val = true;
177 if (result == "NO DIMM")
178 {
179 val = false;
180
181 // No dimm presence so making manufacturer value as "" (instead of
182 // NO DIMM - as there won't be any manufacturer for DIMM which is not
183 // present).
184 result = "";
185 }
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800186 manufacturer(result);
Joshi-Mansi33c948a2021-03-20 00:58:50 +0530187 present(val);
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800188}
189
190std::string Dimm::manufacturer(std::string value)
191{
192 return sdbusplus::xyz::openbmc_project::Inventory::Decorator::server::
193 Asset::manufacturer(value);
194}
195
Joshi-Mansi33c948a2021-03-20 00:58:50 +0530196bool Dimm::present(bool value)
197{
198 return sdbusplus::xyz::openbmc_project::Inventory::server::Item::present(
199 value);
200}
201
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800202void Dimm::dimmSerialNum(const uint8_t positionNum, const uint8_t structLen,
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +0800203 uint8_t* dataIn)
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800204{
205 std::string result = positionToString(positionNum, structLen, dataIn);
206
207 serialNumber(result);
208}
209
210std::string Dimm::serialNumber(std::string value)
211{
212 return sdbusplus::xyz::openbmc_project::Inventory::Decorator::server::
213 Asset::serialNumber(value);
214}
215
216void Dimm::dimmPartNum(const uint8_t positionNum, const uint8_t structLen,
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +0800217 uint8_t* dataIn)
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800218{
219 std::string result = positionToString(positionNum, structLen, dataIn);
220
221 partNumber(result);
222}
223
224std::string Dimm::partNumber(std::string value)
225{
226 return sdbusplus::xyz::openbmc_project::Inventory::Decorator::server::
227 Asset::partNumber(value);
228}
229
Jie Yang31720392021-07-22 21:45:45 -0700230std::string Dimm::locationCode(std::string value)
231{
232 return sdbusplus::xyz::openbmc_project::Inventory::Decorator::server::
233 LocationCode::locationCode(value);
234}
235
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800236uint8_t Dimm::memoryAttributes(uint8_t value)
237{
238 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
239 memoryAttributes(value);
240}
241
242uint16_t Dimm::memoryConfiguredSpeedInMhz(uint16_t value)
243{
244 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
245 memoryConfiguredSpeedInMhz(value);
246}
247
248} // namespace smbios
249} // namespace phosphor