xref: /openbmc/smbios-mdr/src/dimm.cpp (revision 2ca7a0f3)
1 /*
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 
21 namespace phosphor
22 {
23 namespace smbios
24 {
25 
26 using DeviceType =
27     sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::DeviceType;
28 
29 static constexpr uint16_t maxOldDimmSize = 0x7fff;
30 void 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 
80 uint16_t Dimm::memoryDataWidth(uint16_t value)
81 {
82     return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
83         memoryDataWidth(value);
84 }
85 
86 static constexpr uint16_t baseNewVersionDimmSize = 0x8000;
87 static constexpr uint16_t dimmSizeUnit = 1024;
88 void 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 
98 void Dimm::dimmSizeExt(uint32_t size)
99 {
100     size = size * dimmSizeUnit;
101     memorySizeInKB(size);
102 }
103 
104 uint32_t Dimm::memorySizeInKB(uint32_t value)
105 {
106     return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
107         memorySizeInKB(value);
108 }
109 
110 void 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 
118 std::string Dimm::memoryDeviceLocator(std::string value)
119 {
120     return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
121         memoryDeviceLocator(value);
122 }
123 
124 void 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 
137 DeviceType Dimm::memoryType(DeviceType value)
138 {
139     return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
140         memoryType(value);
141 }
142 
143 void 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 
157 std::string Dimm::memoryTypeDetail(std::string value)
158 {
159     return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
160         memoryTypeDetail(value);
161 }
162 
163 uint16_t Dimm::maxMemorySpeedInMhz(uint16_t value)
164 {
165     return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
166         maxMemorySpeedInMhz(value);
167 }
168 
169 void 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 
177 std::string Dimm::manufacturer(std::string value)
178 {
179     return sdbusplus::xyz::openbmc_project::Inventory::Decorator::server::
180         Asset::manufacturer(value);
181 }
182 
183 void 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 
191 std::string Dimm::serialNumber(std::string value)
192 {
193     return sdbusplus::xyz::openbmc_project::Inventory::Decorator::server::
194         Asset::serialNumber(value);
195 }
196 
197 void 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 
205 std::string Dimm::partNumber(std::string value)
206 {
207     return sdbusplus::xyz::openbmc_project::Inventory::Decorator::server::
208         Asset::partNumber(value);
209 }
210 
211 uint8_t Dimm::memoryAttributes(uint8_t value)
212 {
213     return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::
214         memoryAttributes(value);
215 }
216 
217 uint16_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
225