blob: db4170ae3887fb083c4fe6b1f1bfb40253b09145 [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{
32 uint8_t *dataIn = storage;
33
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
54 auto memoryInfo = reinterpret_cast<struct MemoryInfo *>(dataIn);
55
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{
90 uint32_t result = size & maxOldDimmSize;
91 if (0 == (size & baseNewVersionDimmSize))
92 {
93 result = result * dimmSizeUnit;
94 }
95 memorySizeInKB(result);
96}
97
98void Dimm::dimmSizeExt(uint32_t size)
99{
100 size = size * dimmSizeUnit;
101 memorySizeInKB(size);
102}
103
104uint32_t Dimm::memorySizeInKB(uint32_t value)
105{
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,
111 uint8_t *dataIn)
112{
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,
170 uint8_t *dataIn)
171{
172 std::string result = positionToString(positionNum, structLen, dataIn);
173
174 manufacturer(result);
175}
176
177std::string Dimm::manufacturer(std::string value)
178{
179 return sdbusplus::xyz::openbmc_project::Inventory::Decorator::server::
180 Asset::manufacturer(value);
181}
182
183void Dimm::dimmSerialNum(const uint8_t positionNum, const uint8_t structLen,
184 uint8_t *dataIn)
185{
186 std::string result = positionToString(positionNum, structLen, dataIn);
187
188 serialNumber(result);
189}
190
191std::string Dimm::serialNumber(std::string value)
192{
193 return sdbusplus::xyz::openbmc_project::Inventory::Decorator::server::
194 Asset::serialNumber(value);
195}
196
197void Dimm::dimmPartNum(const uint8_t positionNum, const uint8_t structLen,
198 uint8_t *dataIn)
199{
200 std::string result = positionToString(positionNum, structLen, dataIn);
201
202 partNumber(result);
203}
204
205std::string Dimm::partNumber(std::string value)
206{
207 return sdbusplus::xyz::openbmc_project::Inventory::Decorator::server::
208 Asset::partNumber(value);
209}
210
211uint8_t Dimm::memoryAttributes(uint8_t value)
212{
213 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
214 memoryAttributes(value);
215}
216
217uint16_t Dimm::memoryConfiguredSpeedInMhz(uint16_t value)
218{
219 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
220 memoryConfiguredSpeedInMhz(value);
221}
222
223} // namespace smbios
224} // namespace phosphor