xref: /openbmc/bmcweb/features/redfish/lib/memory.hpp (revision 3ccb3adb9a14783f6bef601506de9f8bcae22d51)
1ac6a4445SGunnar Mills /*
2ac6a4445SGunnar Mills // Copyright (c) 2018 Intel Corporation
3ac6a4445SGunnar Mills //
4ac6a4445SGunnar Mills // Licensed under the Apache License, Version 2.0 (the "License");
5ac6a4445SGunnar Mills // you may not use this file except in compliance with the License.
6ac6a4445SGunnar Mills // You may obtain a copy of the License at
7ac6a4445SGunnar Mills //
8ac6a4445SGunnar Mills //      http://www.apache.org/licenses/LICENSE-2.0
9ac6a4445SGunnar Mills //
10ac6a4445SGunnar Mills // Unless required by applicable law or agreed to in writing, software
11ac6a4445SGunnar Mills // distributed under the License is distributed on an "AS IS" BASIS,
12ac6a4445SGunnar Mills // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ac6a4445SGunnar Mills // See the License for the specific language governing permissions and
14ac6a4445SGunnar Mills // limitations under the License.
15ac6a4445SGunnar Mills */
16ac6a4445SGunnar Mills #pragma once
17ac6a4445SGunnar Mills 
18*3ccb3adbSEd Tanous #include "app.hpp"
19*3ccb3adbSEd Tanous #include "dbus_utility.hpp"
20ac6a4445SGunnar Mills #include "health.hpp"
21*3ccb3adbSEd Tanous #include "query.hpp"
22*3ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
23*3ccb3adbSEd Tanous #include "utils/collection.hpp"
24*3ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
25*3ccb3adbSEd Tanous #include "utils/hex_utils.hpp"
26*3ccb3adbSEd Tanous #include "utils/json_utils.hpp"
27ac6a4445SGunnar Mills 
28d7f04fd9SNan Zhou #include <nlohmann/json.hpp>
29c1343bf6SKrzysztof Grobelny #include <sdbusplus/asio/property.hpp>
30c1343bf6SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
31ac6a4445SGunnar Mills 
327a1dbc48SGeorge Liu #include <array>
337a1dbc48SGeorge Liu #include <string_view>
347a1dbc48SGeorge Liu 
35ac6a4445SGunnar Mills namespace redfish
36ac6a4445SGunnar Mills {
37ac6a4445SGunnar Mills 
38313efb1cSGunnar Mills inline std::string translateMemoryTypeToRedfish(const std::string& memoryType)
39313efb1cSGunnar Mills {
40313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR")
41313efb1cSGunnar Mills     {
42313efb1cSGunnar Mills         return "DDR";
43313efb1cSGunnar Mills     }
44313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2")
45313efb1cSGunnar Mills     {
46313efb1cSGunnar Mills         return "DDR2";
47313efb1cSGunnar Mills     }
48313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR3")
49313efb1cSGunnar Mills     {
50313efb1cSGunnar Mills         return "DDR3";
51313efb1cSGunnar Mills     }
52313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4")
53313efb1cSGunnar Mills     {
54313efb1cSGunnar Mills         return "DDR4";
55313efb1cSGunnar Mills     }
56313efb1cSGunnar Mills     if (memoryType ==
57313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4E_SDRAM")
58313efb1cSGunnar Mills     {
59313efb1cSGunnar Mills         return "DDR4E_SDRAM";
60313efb1cSGunnar Mills     }
6111a2f0f0SMansi Joshi     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR5")
6211a2f0f0SMansi Joshi     {
6311a2f0f0SMansi Joshi         return "DDR5";
6411a2f0f0SMansi Joshi     }
65313efb1cSGunnar Mills     if (memoryType ==
66313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR4_SDRAM")
67313efb1cSGunnar Mills     {
68313efb1cSGunnar Mills         return "LPDDR4_SDRAM";
69313efb1cSGunnar Mills     }
70313efb1cSGunnar Mills     if (memoryType ==
71313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR3_SDRAM")
72313efb1cSGunnar Mills     {
73313efb1cSGunnar Mills         return "LPDDR3_SDRAM";
74313efb1cSGunnar Mills     }
75313efb1cSGunnar Mills     if (memoryType ==
76313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM")
77313efb1cSGunnar Mills     {
78313efb1cSGunnar Mills         return "DDR2_SDRAM_FB_DIMM";
79313efb1cSGunnar Mills     }
800fda0f12SGeorge Liu     if (memoryType ==
810fda0f12SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM_PROB")
82313efb1cSGunnar Mills     {
83313efb1cSGunnar Mills         return "DDR2_SDRAM_FB_DIMM_PROBE";
84313efb1cSGunnar Mills     }
85313efb1cSGunnar Mills     if (memoryType ==
86313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR_SGRAM")
87313efb1cSGunnar Mills     {
88313efb1cSGunnar Mills         return "DDR_SGRAM";
89313efb1cSGunnar Mills     }
90313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.ROM")
91313efb1cSGunnar Mills     {
92313efb1cSGunnar Mills         return "ROM";
93313efb1cSGunnar Mills     }
94313efb1cSGunnar Mills     if (memoryType ==
95313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.SDRAM")
96313efb1cSGunnar Mills     {
97313efb1cSGunnar Mills         return "SDRAM";
98313efb1cSGunnar Mills     }
99313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.EDO")
100313efb1cSGunnar Mills     {
101313efb1cSGunnar Mills         return "EDO";
102313efb1cSGunnar Mills     }
103313efb1cSGunnar Mills     if (memoryType ==
104313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.FastPageMode")
105313efb1cSGunnar Mills     {
106313efb1cSGunnar Mills         return "FastPageMode";
107313efb1cSGunnar Mills     }
108313efb1cSGunnar Mills     if (memoryType ==
109313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.PipelinedNibble")
110313efb1cSGunnar Mills     {
111313efb1cSGunnar Mills         return "PipelinedNibble";
112313efb1cSGunnar Mills     }
113313efb1cSGunnar Mills     if (memoryType ==
114313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.Logical")
115313efb1cSGunnar Mills     {
116313efb1cSGunnar Mills         return "Logical";
117313efb1cSGunnar Mills     }
118313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM")
119313efb1cSGunnar Mills     {
120313efb1cSGunnar Mills         return "HBM";
121313efb1cSGunnar Mills     }
122313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM2")
123313efb1cSGunnar Mills     {
124313efb1cSGunnar Mills         return "HBM2";
125313efb1cSGunnar Mills     }
126ce34d514STyson Tuckerbear     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM3")
127ce34d514STyson Tuckerbear     {
128ce34d514STyson Tuckerbear         return "HBM3";
129ce34d514STyson Tuckerbear     }
130313efb1cSGunnar Mills     // This is values like Other or Unknown
131313efb1cSGunnar Mills     // Also D-Bus values:
132313efb1cSGunnar Mills     // DRAM
133313efb1cSGunnar Mills     // EDRAM
134313efb1cSGunnar Mills     // VRAM
135313efb1cSGunnar Mills     // SRAM
136313efb1cSGunnar Mills     // RAM
137313efb1cSGunnar Mills     // FLASH
138313efb1cSGunnar Mills     // EEPROM
139313efb1cSGunnar Mills     // FEPROM
140313efb1cSGunnar Mills     // EPROM
141313efb1cSGunnar Mills     // CDRAM
142313efb1cSGunnar Mills     // ThreeDRAM
143313efb1cSGunnar Mills     // RDRAM
144313efb1cSGunnar Mills     // FBD2
145313efb1cSGunnar Mills     // LPDDR_SDRAM
146313efb1cSGunnar Mills     // LPDDR2_SDRAM
14711a2f0f0SMansi Joshi     // LPDDR5_SDRAM
148313efb1cSGunnar Mills     return "";
149313efb1cSGunnar Mills }
150313efb1cSGunnar Mills 
151c1343bf6SKrzysztof Grobelny inline void dimmPropToHex(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
152c1343bf6SKrzysztof Grobelny                           const char* key, const uint16_t* value,
153d7f04fd9SNan Zhou                           const nlohmann::json::json_pointer& jsonPtr)
154ac6a4445SGunnar Mills {
155ac6a4445SGunnar Mills     if (value == nullptr)
156ac6a4445SGunnar Mills     {
157ac6a4445SGunnar Mills         return;
158ac6a4445SGunnar Mills     }
159d7f04fd9SNan Zhou     aResp->res.jsonValue[jsonPtr][key] = "0x" + intToHexString(*value, 4);
160ac6a4445SGunnar Mills }
161ac6a4445SGunnar Mills 
1628d1b46d7Szhanghch05 inline void getPersistentMemoryProperties(
1638d1b46d7Szhanghch05     const std::shared_ptr<bmcweb::AsyncResp>& aResp,
164c1343bf6SKrzysztof Grobelny     const dbus::utility::DBusPropertiesMap& properties,
165d7f04fd9SNan Zhou     const nlohmann::json::json_pointer& jsonPtr)
166ac6a4445SGunnar Mills {
167c1343bf6SKrzysztof Grobelny     const uint16_t* moduleManufacturerID = nullptr;
168c1343bf6SKrzysztof Grobelny     const uint16_t* moduleProductID = nullptr;
169c1343bf6SKrzysztof Grobelny     const uint16_t* subsystemVendorID = nullptr;
170c1343bf6SKrzysztof Grobelny     const uint16_t* subsystemDeviceID = nullptr;
171c1343bf6SKrzysztof Grobelny     const uint64_t* volatileRegionSizeLimitInKiB = nullptr;
172c1343bf6SKrzysztof Grobelny     const uint64_t* pmRegionSizeLimitInKiB = nullptr;
173c1343bf6SKrzysztof Grobelny     const uint64_t* volatileSizeInKiB = nullptr;
174c1343bf6SKrzysztof Grobelny     const uint64_t* pmSizeInKiB = nullptr;
175c1343bf6SKrzysztof Grobelny     const uint64_t* cacheSizeInKB = nullptr;
176c1343bf6SKrzysztof Grobelny     const uint64_t* voltaileRegionMaxSizeInKib = nullptr;
177c1343bf6SKrzysztof Grobelny     const uint64_t* pmRegionMaxSizeInKiB = nullptr;
178c1343bf6SKrzysztof Grobelny     const uint64_t* allocationIncrementInKiB = nullptr;
179c1343bf6SKrzysztof Grobelny     const uint64_t* allocationAlignmentInKiB = nullptr;
180c1343bf6SKrzysztof Grobelny     const uint64_t* volatileRegionNumberLimit = nullptr;
181c1343bf6SKrzysztof Grobelny     const uint64_t* pmRegionNumberLimit = nullptr;
182c1343bf6SKrzysztof Grobelny     const uint64_t* spareDeviceCount = nullptr;
183c1343bf6SKrzysztof Grobelny     const bool* isSpareDeviceInUse = nullptr;
184c1343bf6SKrzysztof Grobelny     const bool* isRankSpareEnabled = nullptr;
185c1343bf6SKrzysztof Grobelny     const std::vector<uint32_t>* maxAveragePowerLimitmW = nullptr;
186c1343bf6SKrzysztof Grobelny     const bool* configurationLocked = nullptr;
187c1343bf6SKrzysztof Grobelny     const std::string* allowedMemoryModes = nullptr;
188c1343bf6SKrzysztof Grobelny     const std::string* memoryMedia = nullptr;
189c1343bf6SKrzysztof Grobelny     const bool* configurationLockCapable = nullptr;
190c1343bf6SKrzysztof Grobelny     const bool* dataLockCapable = nullptr;
191c1343bf6SKrzysztof Grobelny     const bool* passphraseCapable = nullptr;
192c1343bf6SKrzysztof Grobelny     const uint64_t* maxPassphraseCount = nullptr;
193c1343bf6SKrzysztof Grobelny     const uint64_t* passphraseLockLimit = nullptr;
194c1343bf6SKrzysztof Grobelny 
195c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
196c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "ModuleManufacturerID",
197c1343bf6SKrzysztof Grobelny         moduleManufacturerID, "ModuleProductID", moduleProductID,
198c1343bf6SKrzysztof Grobelny         "SubsystemVendorID", subsystemVendorID, "SubsystemDeviceID",
199c1343bf6SKrzysztof Grobelny         subsystemDeviceID, "VolatileRegionSizeLimitInKiB",
200c1343bf6SKrzysztof Grobelny         volatileRegionSizeLimitInKiB, "PmRegionSizeLimitInKiB",
201c1343bf6SKrzysztof Grobelny         pmRegionSizeLimitInKiB, "VolatileSizeInKiB", volatileSizeInKiB,
202c1343bf6SKrzysztof Grobelny         "PmSizeInKiB", pmSizeInKiB, "CacheSizeInKB", cacheSizeInKB,
203c1343bf6SKrzysztof Grobelny         "VoltaileRegionMaxSizeInKib", voltaileRegionMaxSizeInKib,
204c1343bf6SKrzysztof Grobelny         "PmRegionMaxSizeInKiB", pmRegionMaxSizeInKiB,
205c1343bf6SKrzysztof Grobelny         "AllocationIncrementInKiB", allocationIncrementInKiB,
206c1343bf6SKrzysztof Grobelny         "AllocationAlignmentInKiB", allocationAlignmentInKiB,
207c1343bf6SKrzysztof Grobelny         "VolatileRegionNumberLimit", volatileRegionNumberLimit,
208c1343bf6SKrzysztof Grobelny         "PmRegionNumberLimit", pmRegionNumberLimit, "SpareDeviceCount",
209c1343bf6SKrzysztof Grobelny         spareDeviceCount, "IsSpareDeviceInUse", isSpareDeviceInUse,
210c1343bf6SKrzysztof Grobelny         "IsRankSpareEnabled", isRankSpareEnabled, "MaxAveragePowerLimitmW",
211c1343bf6SKrzysztof Grobelny         maxAveragePowerLimitmW, "ConfigurationLocked", configurationLocked,
212c1343bf6SKrzysztof Grobelny         "AllowedMemoryModes", allowedMemoryModes, "MemoryMedia", memoryMedia,
213c1343bf6SKrzysztof Grobelny         "ConfigurationLockCapable", configurationLockCapable, "DataLockCapable",
214c1343bf6SKrzysztof Grobelny         dataLockCapable, "PassphraseCapable", passphraseCapable,
215c1343bf6SKrzysztof Grobelny         "MaxPassphraseCount", maxPassphraseCount, "PassphraseLockLimit",
216c1343bf6SKrzysztof Grobelny         passphraseLockLimit);
217c1343bf6SKrzysztof Grobelny 
218c1343bf6SKrzysztof Grobelny     if (!success)
219ac6a4445SGunnar Mills     {
220c1343bf6SKrzysztof Grobelny         messages::internalError(aResp->res);
221c1343bf6SKrzysztof Grobelny         return;
222ac6a4445SGunnar Mills     }
223c1343bf6SKrzysztof Grobelny 
224c1343bf6SKrzysztof Grobelny     dimmPropToHex(aResp, "ModuleManufacturerID", moduleManufacturerID, jsonPtr);
225c1343bf6SKrzysztof Grobelny     dimmPropToHex(aResp, "ModuleProductID", moduleProductID, jsonPtr);
226ac6a4445SGunnar Mills     dimmPropToHex(aResp, "MemorySubsystemControllerManufacturerID",
227c1343bf6SKrzysztof Grobelny                   subsystemVendorID, jsonPtr);
228c1343bf6SKrzysztof Grobelny     dimmPropToHex(aResp, "MemorySubsystemControllerProductID",
229c1343bf6SKrzysztof Grobelny                   subsystemDeviceID, jsonPtr);
230ac6a4445SGunnar Mills 
231c1343bf6SKrzysztof Grobelny     if (volatileRegionSizeLimitInKiB != nullptr)
232ac6a4445SGunnar Mills     {
233d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["VolatileRegionSizeLimitMiB"] =
234c1343bf6SKrzysztof Grobelny             (*volatileRegionSizeLimitInKiB) >> 10;
235ac6a4445SGunnar Mills     }
236ac6a4445SGunnar Mills 
237c1343bf6SKrzysztof Grobelny     if (pmRegionSizeLimitInKiB != nullptr)
238ac6a4445SGunnar Mills     {
239d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["PersistentRegionSizeLimitMiB"] =
240c1343bf6SKrzysztof Grobelny             (*pmRegionSizeLimitInKiB) >> 10;
241ac6a4445SGunnar Mills     }
242ac6a4445SGunnar Mills 
243c1343bf6SKrzysztof Grobelny     if (volatileSizeInKiB != nullptr)
244ac6a4445SGunnar Mills     {
245ac6a4445SGunnar Mills 
246c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["VolatileSizeMiB"] =
247c1343bf6SKrzysztof Grobelny             (*volatileSizeInKiB) >> 10;
248ac6a4445SGunnar Mills     }
249c1343bf6SKrzysztof Grobelny 
250c1343bf6SKrzysztof Grobelny     if (pmSizeInKiB != nullptr)
251c1343bf6SKrzysztof Grobelny     {
252c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["NonVolatileSizeMiB"] =
253c1343bf6SKrzysztof Grobelny             (*pmSizeInKiB) >> 10;
254c1343bf6SKrzysztof Grobelny     }
255c1343bf6SKrzysztof Grobelny 
256c1343bf6SKrzysztof Grobelny     if (cacheSizeInKB != nullptr)
257c1343bf6SKrzysztof Grobelny     {
258c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["CacheSizeMiB"] = (*cacheSizeInKB >> 10);
259c1343bf6SKrzysztof Grobelny     }
260c1343bf6SKrzysztof Grobelny 
261c1343bf6SKrzysztof Grobelny     if (voltaileRegionMaxSizeInKib != nullptr)
262c1343bf6SKrzysztof Grobelny     {
263d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["VolatileRegionSizeMaxMiB"] =
264c1343bf6SKrzysztof Grobelny             (*voltaileRegionMaxSizeInKib) >> 10;
265ac6a4445SGunnar Mills     }
266ac6a4445SGunnar Mills 
267c1343bf6SKrzysztof Grobelny     if (pmRegionMaxSizeInKiB != nullptr)
268ac6a4445SGunnar Mills     {
269d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["PersistentRegionSizeMaxMiB"] =
270c1343bf6SKrzysztof Grobelny             (*pmRegionMaxSizeInKiB) >> 10;
271ac6a4445SGunnar Mills     }
272ac6a4445SGunnar Mills 
273c1343bf6SKrzysztof Grobelny     if (allocationIncrementInKiB != nullptr)
274ac6a4445SGunnar Mills     {
275d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["AllocationIncrementMiB"] =
276c1343bf6SKrzysztof Grobelny             (*allocationIncrementInKiB) >> 10;
277ac6a4445SGunnar Mills     }
278ac6a4445SGunnar Mills 
279c1343bf6SKrzysztof Grobelny     if (allocationAlignmentInKiB != nullptr)
280ac6a4445SGunnar Mills     {
281d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["AllocationAlignmentMiB"] =
282c1343bf6SKrzysztof Grobelny             (*allocationAlignmentInKiB) >> 10;
283ac6a4445SGunnar Mills     }
284c1343bf6SKrzysztof Grobelny 
285c1343bf6SKrzysztof Grobelny     if (volatileRegionNumberLimit != nullptr)
286ac6a4445SGunnar Mills     {
287c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["VolatileRegionNumberLimit"] =
288c1343bf6SKrzysztof Grobelny             *volatileRegionNumberLimit;
289ac6a4445SGunnar Mills     }
290c1343bf6SKrzysztof Grobelny 
291c1343bf6SKrzysztof Grobelny     if (pmRegionNumberLimit != nullptr)
292ac6a4445SGunnar Mills     {
293c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["PersistentRegionNumberLimit"] =
294c1343bf6SKrzysztof Grobelny             *pmRegionNumberLimit;
295ac6a4445SGunnar Mills     }
296c1343bf6SKrzysztof Grobelny 
297c1343bf6SKrzysztof Grobelny     if (spareDeviceCount != nullptr)
298ac6a4445SGunnar Mills     {
299c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["SpareDeviceCount"] = *spareDeviceCount;
300ac6a4445SGunnar Mills     }
301c1343bf6SKrzysztof Grobelny 
302c1343bf6SKrzysztof Grobelny     if (isSpareDeviceInUse != nullptr)
303ac6a4445SGunnar Mills     {
304c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["IsSpareDeviceEnabled"] =
305c1343bf6SKrzysztof Grobelny             *isSpareDeviceInUse;
306ac6a4445SGunnar Mills     }
307c1343bf6SKrzysztof Grobelny 
308c1343bf6SKrzysztof Grobelny     if (isRankSpareEnabled != nullptr)
309ac6a4445SGunnar Mills     {
310c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["IsRankSpareEnabled"] =
311c1343bf6SKrzysztof Grobelny             *isRankSpareEnabled;
312ac6a4445SGunnar Mills     }
313c1343bf6SKrzysztof Grobelny 
314c1343bf6SKrzysztof Grobelny     if (maxAveragePowerLimitmW != nullptr)
315ac6a4445SGunnar Mills     {
316c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["MaxTDPMilliWatts"] =
317c1343bf6SKrzysztof Grobelny             *maxAveragePowerLimitmW;
318ac6a4445SGunnar Mills     }
319c1343bf6SKrzysztof Grobelny 
320c1343bf6SKrzysztof Grobelny     if (configurationLocked != nullptr)
321ac6a4445SGunnar Mills     {
322c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["ConfigurationLocked"] =
323c1343bf6SKrzysztof Grobelny             *configurationLocked;
324ac6a4445SGunnar Mills     }
325c1343bf6SKrzysztof Grobelny 
326c1343bf6SKrzysztof Grobelny     if (allowedMemoryModes != nullptr)
327ac6a4445SGunnar Mills     {
32880badf7cSJiaqing Zhao         constexpr const std::array<const char*, 3> values{"Volatile", "PMEM",
32980badf7cSJiaqing Zhao                                                           "Block"};
330ac6a4445SGunnar Mills 
331ac6a4445SGunnar Mills         for (const char* v : values)
332ac6a4445SGunnar Mills         {
333c1343bf6SKrzysztof Grobelny             if (allowedMemoryModes->ends_with(v))
334ac6a4445SGunnar Mills             {
335d7f04fd9SNan Zhou                 aResp->res.jsonValue[jsonPtr]["OperatingMemoryModes"].push_back(
336d7f04fd9SNan Zhou                     v);
337ac6a4445SGunnar Mills                 break;
338ac6a4445SGunnar Mills             }
339ac6a4445SGunnar Mills         }
340ac6a4445SGunnar Mills     }
341c1343bf6SKrzysztof Grobelny 
342c1343bf6SKrzysztof Grobelny     if (memoryMedia != nullptr)
343ac6a4445SGunnar Mills     {
344ac6a4445SGunnar Mills         constexpr const std::array<const char*, 3> values{"DRAM", "NAND",
345ac6a4445SGunnar Mills                                                           "Intel3DXPoint"};
346ac6a4445SGunnar Mills 
347ac6a4445SGunnar Mills         for (const char* v : values)
348ac6a4445SGunnar Mills         {
349c1343bf6SKrzysztof Grobelny             if (memoryMedia->ends_with(v))
350ac6a4445SGunnar Mills             {
351d7f04fd9SNan Zhou                 aResp->res.jsonValue[jsonPtr]["MemoryMedia"].push_back(v);
352ac6a4445SGunnar Mills                 break;
353ac6a4445SGunnar Mills             }
354ac6a4445SGunnar Mills         }
355ac6a4445SGunnar Mills     }
356c1343bf6SKrzysztof Grobelny 
357c1343bf6SKrzysztof Grobelny     if (configurationLockCapable != nullptr)
358ac6a4445SGunnar Mills     {
359c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
360c1343bf6SKrzysztof Grobelny                             ["ConfigurationLockCapable"] =
361c1343bf6SKrzysztof Grobelny             *configurationLockCapable;
362ac6a4445SGunnar Mills     }
363c1343bf6SKrzysztof Grobelny 
364c1343bf6SKrzysztof Grobelny     if (dataLockCapable != nullptr)
365ac6a4445SGunnar Mills     {
366c1343bf6SKrzysztof Grobelny         aResp->res
367c1343bf6SKrzysztof Grobelny             .jsonValue[jsonPtr]["SecurityCapabilities"]["DataLockCapable"] =
368c1343bf6SKrzysztof Grobelny             *dataLockCapable;
369ac6a4445SGunnar Mills     }
370c1343bf6SKrzysztof Grobelny 
371c1343bf6SKrzysztof Grobelny     if (passphraseCapable != nullptr)
372c1343bf6SKrzysztof Grobelny     {
373c1343bf6SKrzysztof Grobelny         aResp->res
374c1343bf6SKrzysztof Grobelny             .jsonValue[jsonPtr]["SecurityCapabilities"]["PassphraseCapable"] =
375c1343bf6SKrzysztof Grobelny             *passphraseCapable;
376c1343bf6SKrzysztof Grobelny     }
377c1343bf6SKrzysztof Grobelny 
378c1343bf6SKrzysztof Grobelny     if (maxPassphraseCount != nullptr)
379c1343bf6SKrzysztof Grobelny     {
380c1343bf6SKrzysztof Grobelny         aResp->res
381c1343bf6SKrzysztof Grobelny             .jsonValue[jsonPtr]["SecurityCapabilities"]["MaxPassphraseCount"] =
382c1343bf6SKrzysztof Grobelny             *maxPassphraseCount;
383c1343bf6SKrzysztof Grobelny     }
384c1343bf6SKrzysztof Grobelny 
385c1343bf6SKrzysztof Grobelny     if (passphraseLockLimit != nullptr)
386c1343bf6SKrzysztof Grobelny     {
387c1343bf6SKrzysztof Grobelny         aResp->res
388c1343bf6SKrzysztof Grobelny             .jsonValue[jsonPtr]["SecurityCapabilities"]["PassphraseLockLimit"] =
389c1343bf6SKrzysztof Grobelny             *passphraseLockLimit;
390ac6a4445SGunnar Mills     }
391ac6a4445SGunnar Mills }
392ac6a4445SGunnar Mills 
3939a5aceacSNan Zhou inline void
3949a5aceacSNan Zhou     assembleDimmProperties(std::string_view dimmId,
3959a5aceacSNan Zhou                            const std::shared_ptr<bmcweb::AsyncResp>& aResp,
396d7f04fd9SNan Zhou                            const dbus::utility::DBusPropertiesMap& properties,
397d7f04fd9SNan Zhou                            const nlohmann::json::json_pointer& jsonPtr)
398ac6a4445SGunnar Mills {
399d7f04fd9SNan Zhou     aResp->res.jsonValue[jsonPtr]["Id"] = dimmId;
400d7f04fd9SNan Zhou     aResp->res.jsonValue[jsonPtr]["Name"] = "DIMM Slot";
401d7f04fd9SNan Zhou     aResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Enabled";
402d7f04fd9SNan Zhou     aResp->res.jsonValue[jsonPtr]["Status"]["Health"] = "OK";
403ac6a4445SGunnar Mills 
404c1343bf6SKrzysztof Grobelny     const uint16_t* memoryDataWidth = nullptr;
405c1343bf6SKrzysztof Grobelny     const size_t* memorySizeInKB = nullptr;
406c1343bf6SKrzysztof Grobelny     const std::string* partNumber = nullptr;
407c1343bf6SKrzysztof Grobelny     const std::string* serialNumber = nullptr;
408c1343bf6SKrzysztof Grobelny     const std::string* manufacturer = nullptr;
409c1343bf6SKrzysztof Grobelny     const uint16_t* revisionCode = nullptr;
410c1343bf6SKrzysztof Grobelny     const bool* present = nullptr;
411c1343bf6SKrzysztof Grobelny     const uint16_t* memoryTotalWidth = nullptr;
412c1343bf6SKrzysztof Grobelny     const std::string* ecc = nullptr;
413c1343bf6SKrzysztof Grobelny     const std::string* formFactor = nullptr;
414c1343bf6SKrzysztof Grobelny     const std::vector<uint16_t>* allowedSpeedsMT = nullptr;
415c1343bf6SKrzysztof Grobelny     const uint8_t* memoryAttributes = nullptr;
416c1343bf6SKrzysztof Grobelny     const uint16_t* memoryConfiguredSpeedInMhz = nullptr;
417c1343bf6SKrzysztof Grobelny     const std::string* memoryType = nullptr;
418c1343bf6SKrzysztof Grobelny     const std::string* channel = nullptr;
419c1343bf6SKrzysztof Grobelny     const std::string* memoryController = nullptr;
420c1343bf6SKrzysztof Grobelny     const std::string* slot = nullptr;
421c1343bf6SKrzysztof Grobelny     const std::string* socket = nullptr;
422c1343bf6SKrzysztof Grobelny     const std::string* sparePartNumber = nullptr;
423c1343bf6SKrzysztof Grobelny     const std::string* model = nullptr;
424c1343bf6SKrzysztof Grobelny     const std::string* locationCode = nullptr;
425ac6a4445SGunnar Mills 
426c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
427c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "MemoryDataWidth",
428c1343bf6SKrzysztof Grobelny         memoryDataWidth, "MemorySizeInKB", memorySizeInKB, "PartNumber",
429656472d9SNikhil Namjoshi         partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
430656472d9SNikhil Namjoshi         "RevisionCode", revisionCode, "Present", present, "MemoryTotalWidth",
431656472d9SNikhil Namjoshi         memoryTotalWidth, "ECC", ecc, "FormFactor", formFactor,
432656472d9SNikhil Namjoshi         "AllowedSpeedsMT", allowedSpeedsMT, "MemoryAttributes",
433c1343bf6SKrzysztof Grobelny         memoryAttributes, "MemoryConfiguredSpeedInMhz",
434c1343bf6SKrzysztof Grobelny         memoryConfiguredSpeedInMhz, "MemoryType", memoryType, "Channel",
435c1343bf6SKrzysztof Grobelny         channel, "MemoryController", memoryController, "Slot", slot, "Socket",
436c1343bf6SKrzysztof Grobelny         socket, "SparePartNumber", sparePartNumber, "Model", model,
437c1343bf6SKrzysztof Grobelny         "LocationCode", locationCode);
438c1343bf6SKrzysztof Grobelny 
439c1343bf6SKrzysztof Grobelny     if (!success)
440ac6a4445SGunnar Mills     {
441ac6a4445SGunnar Mills         messages::internalError(aResp->res);
442601af5edSChicago Duan         return;
443ac6a4445SGunnar Mills     }
444c1343bf6SKrzysztof Grobelny 
445c1343bf6SKrzysztof Grobelny     if (memoryDataWidth != nullptr)
446c1343bf6SKrzysztof Grobelny     {
447c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["DataWidthBits"] = *memoryDataWidth;
448c1343bf6SKrzysztof Grobelny     }
449c1343bf6SKrzysztof Grobelny 
450c1343bf6SKrzysztof Grobelny     if (memorySizeInKB != nullptr)
451c1343bf6SKrzysztof Grobelny     {
452c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["CapacityMiB"] = (*memorySizeInKB >> 10);
453c1343bf6SKrzysztof Grobelny     }
454c1343bf6SKrzysztof Grobelny 
455c1343bf6SKrzysztof Grobelny     if (partNumber != nullptr)
456c1343bf6SKrzysztof Grobelny     {
457c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["PartNumber"] = *partNumber;
458c1343bf6SKrzysztof Grobelny     }
459c1343bf6SKrzysztof Grobelny 
460c1343bf6SKrzysztof Grobelny     if (serialNumber != nullptr)
461c1343bf6SKrzysztof Grobelny     {
462c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["SerialNumber"] = *serialNumber;
463c1343bf6SKrzysztof Grobelny     }
464c1343bf6SKrzysztof Grobelny 
465c1343bf6SKrzysztof Grobelny     if (manufacturer != nullptr)
466c1343bf6SKrzysztof Grobelny     {
467c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["Manufacturer"] = *manufacturer;
468c1343bf6SKrzysztof Grobelny     }
469c1343bf6SKrzysztof Grobelny 
470c1343bf6SKrzysztof Grobelny     if (revisionCode != nullptr)
471c1343bf6SKrzysztof Grobelny     {
472d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["FirmwareRevision"] =
473c1343bf6SKrzysztof Grobelny             std::to_string(*revisionCode);
474ac6a4445SGunnar Mills     }
475c1343bf6SKrzysztof Grobelny 
476c1343bf6SKrzysztof Grobelny     if (present != nullptr && !*present)
4779a128eb3SJoshi-Mansi     {
478d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Absent";
4799a128eb3SJoshi-Mansi     }
480c1343bf6SKrzysztof Grobelny 
481c1343bf6SKrzysztof Grobelny     if (memoryTotalWidth != nullptr)
482ac6a4445SGunnar Mills     {
483c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["BusWidthBits"] = *memoryTotalWidth;
484ac6a4445SGunnar Mills     }
485c1343bf6SKrzysztof Grobelny 
486c1343bf6SKrzysztof Grobelny     if (ecc != nullptr)
487ac6a4445SGunnar Mills     {
488ac6a4445SGunnar Mills         constexpr const std::array<const char*, 4> values{
4899a5aceacSNan Zhou             "NoECC", "SingleBitECC", "MultiBitECC", "AddressParity"};
490ac6a4445SGunnar Mills 
491ac6a4445SGunnar Mills         for (const char* v : values)
492ac6a4445SGunnar Mills         {
493c1343bf6SKrzysztof Grobelny             if (ecc->ends_with(v))
494ac6a4445SGunnar Mills             {
495d7f04fd9SNan Zhou                 aResp->res.jsonValue[jsonPtr]["ErrorCorrection"] = v;
496ac6a4445SGunnar Mills                 break;
497ac6a4445SGunnar Mills             }
498ac6a4445SGunnar Mills         }
499ac6a4445SGunnar Mills     }
500c1343bf6SKrzysztof Grobelny 
501c1343bf6SKrzysztof Grobelny     if (formFactor != nullptr)
502ac6a4445SGunnar Mills     {
503ac6a4445SGunnar Mills         constexpr const std::array<const char*, 11> values{
5049a5aceacSNan Zhou             "RDIMM",       "UDIMM",       "SO_DIMM",      "LRDIMM",
5059a5aceacSNan Zhou             "Mini_RDIMM",  "Mini_UDIMM",  "SO_RDIMM_72b", "SO_UDIMM_72b",
5069a5aceacSNan Zhou             "SO_DIMM_16b", "SO_DIMM_32b", "Die"};
507ac6a4445SGunnar Mills 
508ac6a4445SGunnar Mills         for (const char* v : values)
509ac6a4445SGunnar Mills         {
510c1343bf6SKrzysztof Grobelny             if (formFactor->ends_with(v))
511ac6a4445SGunnar Mills             {
512d7f04fd9SNan Zhou                 aResp->res.jsonValue[jsonPtr]["BaseModuleType"] = v;
513ac6a4445SGunnar Mills                 break;
514ac6a4445SGunnar Mills             }
515ac6a4445SGunnar Mills         }
516ac6a4445SGunnar Mills     }
517c1343bf6SKrzysztof Grobelny 
518c1343bf6SKrzysztof Grobelny     if (allowedSpeedsMT != nullptr)
519ac6a4445SGunnar Mills     {
520d7f04fd9SNan Zhou         nlohmann::json& jValue =
521d7f04fd9SNan Zhou             aResp->res.jsonValue[jsonPtr]["AllowedSpeedsMHz"];
522ac6a4445SGunnar Mills         jValue = nlohmann::json::array();
523c1343bf6SKrzysztof Grobelny         for (uint16_t subVal : *allowedSpeedsMT)
524ac6a4445SGunnar Mills         {
525ac6a4445SGunnar Mills             jValue.push_back(subVal);
526ac6a4445SGunnar Mills         }
527ac6a4445SGunnar Mills     }
528ac6a4445SGunnar Mills 
529c1343bf6SKrzysztof Grobelny     if (memoryAttributes != nullptr)
530ac6a4445SGunnar Mills     {
531d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["RankCount"] =
532c1343bf6SKrzysztof Grobelny             static_cast<uint64_t>(*memoryAttributes);
533ac6a4445SGunnar Mills     }
534c1343bf6SKrzysztof Grobelny 
535c1343bf6SKrzysztof Grobelny     if (memoryConfiguredSpeedInMhz != nullptr)
536ac6a4445SGunnar Mills     {
537c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["OperatingSpeedMhz"] =
538c1343bf6SKrzysztof Grobelny             *memoryConfiguredSpeedInMhz;
539ac6a4445SGunnar Mills     }
540c1343bf6SKrzysztof Grobelny 
541c1343bf6SKrzysztof Grobelny     if (memoryType != nullptr)
542ac6a4445SGunnar Mills     {
543313efb1cSGunnar Mills         std::string memoryDeviceType =
544c1343bf6SKrzysztof Grobelny             translateMemoryTypeToRedfish(*memoryType);
545313efb1cSGunnar Mills         // Values like "Unknown" or "Other" will return empty
546313efb1cSGunnar Mills         // so just leave off
547313efb1cSGunnar Mills         if (!memoryDeviceType.empty())
548ac6a4445SGunnar Mills         {
549d7f04fd9SNan Zhou             aResp->res.jsonValue[jsonPtr]["MemoryDeviceType"] =
550d7f04fd9SNan Zhou                 memoryDeviceType;
551ac6a4445SGunnar Mills         }
552c1343bf6SKrzysztof Grobelny         if (memoryType->find("DDR") != std::string::npos)
553ac6a4445SGunnar Mills         {
554d7f04fd9SNan Zhou             aResp->res.jsonValue[jsonPtr]["MemoryType"] = "DRAM";
555ac6a4445SGunnar Mills         }
556c1343bf6SKrzysztof Grobelny         else if (memoryType->ends_with("Logical"))
557ac6a4445SGunnar Mills         {
558d7f04fd9SNan Zhou             aResp->res.jsonValue[jsonPtr]["MemoryType"] = "IntelOptane";
559ac6a4445SGunnar Mills         }
560ac6a4445SGunnar Mills     }
561c1343bf6SKrzysztof Grobelny 
562c1343bf6SKrzysztof Grobelny     if (channel != nullptr)
563ac6a4445SGunnar Mills     {
564c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Channel"] = *channel;
565c1343bf6SKrzysztof Grobelny     }
566c1343bf6SKrzysztof Grobelny 
567c1343bf6SKrzysztof Grobelny     if (memoryController != nullptr)
568ac6a4445SGunnar Mills     {
569c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["MemoryLocation"]["MemoryController"] =
570c1343bf6SKrzysztof Grobelny             *memoryController;
571ac6a4445SGunnar Mills     }
572c1343bf6SKrzysztof Grobelny 
573c1343bf6SKrzysztof Grobelny     if (slot != nullptr)
574ee135e24SSunnySrivastava1984     {
575c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Slot"] = *slot;
576c1343bf6SKrzysztof Grobelny     }
577c1343bf6SKrzysztof Grobelny 
578c1343bf6SKrzysztof Grobelny     if (socket != nullptr)
579ee135e24SSunnySrivastava1984     {
580c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Socket"] = *socket;
581ee135e24SSunnySrivastava1984     }
582c1343bf6SKrzysztof Grobelny 
583c1343bf6SKrzysztof Grobelny     if (sparePartNumber != nullptr)
584ee135e24SSunnySrivastava1984     {
585c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["SparePartNumber"] = *sparePartNumber;
586c1343bf6SKrzysztof Grobelny     }
587c1343bf6SKrzysztof Grobelny 
588c1343bf6SKrzysztof Grobelny     if (model != nullptr)
589ee135e24SSunnySrivastava1984     {
590c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["Model"] = *model;
591ee135e24SSunnySrivastava1984     }
592c1343bf6SKrzysztof Grobelny 
593c1343bf6SKrzysztof Grobelny     if (locationCode != nullptr)
594ee135e24SSunnySrivastava1984     {
595c1343bf6SKrzysztof Grobelny         aResp->res
596c1343bf6SKrzysztof Grobelny             .jsonValue[jsonPtr]["Location"]["PartLocation"]["ServiceLabel"] =
597c1343bf6SKrzysztof Grobelny             *locationCode;
598ee135e24SSunnySrivastava1984     }
599c1343bf6SKrzysztof Grobelny 
600c1343bf6SKrzysztof Grobelny     getPersistentMemoryProperties(aResp, properties, jsonPtr);
6019a5aceacSNan Zhou }
6029a5aceacSNan Zhou 
6039a5aceacSNan Zhou inline void getDimmDataByService(std::shared_ptr<bmcweb::AsyncResp> aResp,
6049a5aceacSNan Zhou                                  const std::string& dimmId,
6059a5aceacSNan Zhou                                  const std::string& service,
6069a5aceacSNan Zhou                                  const std::string& objPath)
6079a5aceacSNan Zhou {
6089a5aceacSNan Zhou     auto health = std::make_shared<HealthPopulate>(aResp);
6099a5aceacSNan Zhou     health->selfPath = objPath;
6109a5aceacSNan Zhou     health->populate();
6119a5aceacSNan Zhou 
6129a5aceacSNan Zhou     BMCWEB_LOG_DEBUG << "Get available system components.";
613c1343bf6SKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
614c1343bf6SKrzysztof Grobelny         *crow::connections::systemBus, service, objPath, "",
6159a5aceacSNan Zhou         [dimmId, aResp{std::move(aResp)}](
6169a5aceacSNan Zhou             const boost::system::error_code ec,
6179a5aceacSNan Zhou             const dbus::utility::DBusPropertiesMap& properties) {
6189a5aceacSNan Zhou         if (ec)
6199a5aceacSNan Zhou         {
6209a5aceacSNan Zhou             BMCWEB_LOG_DEBUG << "DBUS response error";
6219a5aceacSNan Zhou             messages::internalError(aResp->res);
6229a5aceacSNan Zhou             return;
6239a5aceacSNan Zhou         }
624d7f04fd9SNan Zhou         assembleDimmProperties(dimmId, aResp, properties, ""_json_pointer);
625c1343bf6SKrzysztof Grobelny         });
626ac6a4445SGunnar Mills }
627ac6a4445SGunnar Mills 
628ef00d7d4SNan Zhou inline void assembleDimmPartitionData(
629ef00d7d4SNan Zhou     const std::shared_ptr<bmcweb::AsyncResp>& aResp,
630d7f04fd9SNan Zhou     const dbus::utility::DBusPropertiesMap& properties,
631d7f04fd9SNan Zhou     const nlohmann::json::json_pointer& regionPtr)
632ac6a4445SGunnar Mills {
633c1343bf6SKrzysztof Grobelny     const std::string* memoryClassification = nullptr;
634c1343bf6SKrzysztof Grobelny     const uint64_t* offsetInKiB = nullptr;
635c1343bf6SKrzysztof Grobelny     const std::string* partitionId = nullptr;
636c1343bf6SKrzysztof Grobelny     const bool* passphraseState = nullptr;
637c1343bf6SKrzysztof Grobelny     const uint64_t* sizeInKiB = nullptr;
638c1343bf6SKrzysztof Grobelny 
639c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
640c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "MemoryClassification",
641c1343bf6SKrzysztof Grobelny         memoryClassification, "OffsetInKiB", offsetInKiB, "PartitionId",
642c1343bf6SKrzysztof Grobelny         partitionId, "PassphraseState", passphraseState, "SizeInKiB",
643c1343bf6SKrzysztof Grobelny         sizeInKiB);
644c1343bf6SKrzysztof Grobelny 
645c1343bf6SKrzysztof Grobelny     if (!success)
646c1343bf6SKrzysztof Grobelny     {
647c1343bf6SKrzysztof Grobelny         messages::internalError(aResp->res);
648c1343bf6SKrzysztof Grobelny         return;
649c1343bf6SKrzysztof Grobelny     }
650c1343bf6SKrzysztof Grobelny 
651d7f04fd9SNan Zhou     nlohmann::json::object_t partition;
652c1343bf6SKrzysztof Grobelny 
653c1343bf6SKrzysztof Grobelny     if (memoryClassification != nullptr)
654ac6a4445SGunnar Mills     {
655c1343bf6SKrzysztof Grobelny         partition["MemoryClassification"] = *memoryClassification;
656ac6a4445SGunnar Mills     }
657ac6a4445SGunnar Mills 
658c1343bf6SKrzysztof Grobelny     if (offsetInKiB != nullptr)
659ac6a4445SGunnar Mills     {
660c1343bf6SKrzysztof Grobelny         partition["OffsetMiB"] = (*offsetInKiB >> 10);
661ac6a4445SGunnar Mills     }
662ac6a4445SGunnar Mills 
663c1343bf6SKrzysztof Grobelny     if (partitionId != nullptr)
664ac6a4445SGunnar Mills     {
665c1343bf6SKrzysztof Grobelny         partition["RegionId"] = *partitionId;
666c1343bf6SKrzysztof Grobelny     }
667c1343bf6SKrzysztof Grobelny 
668c1343bf6SKrzysztof Grobelny     if (passphraseState != nullptr)
669ac6a4445SGunnar Mills     {
670c1343bf6SKrzysztof Grobelny         partition["PassphraseEnabled"] = *passphraseState;
671ac6a4445SGunnar Mills     }
672c1343bf6SKrzysztof Grobelny 
673c1343bf6SKrzysztof Grobelny     if (sizeInKiB != nullptr)
674ac6a4445SGunnar Mills     {
675c1343bf6SKrzysztof Grobelny         partition["SizeMiB"] = (*sizeInKiB >> 10);
676ac6a4445SGunnar Mills     }
677c1343bf6SKrzysztof Grobelny 
678d7f04fd9SNan Zhou     aResp->res.jsonValue[regionPtr].emplace_back(std::move(partition));
679ef00d7d4SNan Zhou }
680ef00d7d4SNan Zhou 
681ef00d7d4SNan Zhou inline void getDimmPartitionData(std::shared_ptr<bmcweb::AsyncResp> aResp,
682ef00d7d4SNan Zhou                                  const std::string& service,
683ef00d7d4SNan Zhou                                  const std::string& path)
684ef00d7d4SNan Zhou {
685c1343bf6SKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
686c1343bf6SKrzysztof Grobelny         *crow::connections::systemBus, service, path,
687c1343bf6SKrzysztof Grobelny         "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition",
688ef00d7d4SNan Zhou         [aResp{std::move(aResp)}](
689ef00d7d4SNan Zhou             const boost::system::error_code ec,
690ef00d7d4SNan Zhou             const dbus::utility::DBusPropertiesMap& properties) {
691ef00d7d4SNan Zhou         if (ec)
692ef00d7d4SNan Zhou         {
693ef00d7d4SNan Zhou             BMCWEB_LOG_DEBUG << "DBUS response error";
694ef00d7d4SNan Zhou             messages::internalError(aResp->res);
695ef00d7d4SNan Zhou 
696ef00d7d4SNan Zhou             return;
697ef00d7d4SNan Zhou         }
698d7f04fd9SNan Zhou         nlohmann::json::json_pointer regionPtr = "/Regions"_json_pointer;
699d7f04fd9SNan Zhou         assembleDimmPartitionData(aResp, properties, regionPtr);
700c1343bf6SKrzysztof Grobelny         }
701ac6a4445SGunnar Mills 
702c1343bf6SKrzysztof Grobelny     );
703ac6a4445SGunnar Mills }
704ac6a4445SGunnar Mills 
7058d1b46d7Szhanghch05 inline void getDimmData(std::shared_ptr<bmcweb::AsyncResp> aResp,
706ac6a4445SGunnar Mills                         const std::string& dimmId)
707ac6a4445SGunnar Mills {
708ac6a4445SGunnar Mills     BMCWEB_LOG_DEBUG << "Get available system dimm resources.";
709ac6a4445SGunnar Mills     crow::connections::systemBus->async_method_call(
710ac6a4445SGunnar Mills         [dimmId, aResp{std::move(aResp)}](
711ac6a4445SGunnar Mills             const boost::system::error_code ec,
712b9d36b47SEd Tanous             const dbus::utility::MapperGetSubTreeResponse& subtree) {
713ac6a4445SGunnar Mills         if (ec)
714ac6a4445SGunnar Mills         {
715ac6a4445SGunnar Mills             BMCWEB_LOG_DEBUG << "DBUS response error";
716ac6a4445SGunnar Mills             messages::internalError(aResp->res);
717ac6a4445SGunnar Mills 
718ac6a4445SGunnar Mills             return;
719ac6a4445SGunnar Mills         }
720ac6a4445SGunnar Mills         bool found = false;
72176686dccSNan Zhou         for (const auto& [rawPath, object] : subtree)
722ac6a4445SGunnar Mills         {
72376686dccSNan Zhou             sdbusplus::message::object_path path(rawPath);
724ac6a4445SGunnar Mills             for (const auto& [service, interfaces] : object)
725ac6a4445SGunnar Mills             {
726b9d36b47SEd Tanous                 for (const auto& interface : interfaces)
727ac6a4445SGunnar Mills                 {
728b9d36b47SEd Tanous                     if (interface ==
72976686dccSNan Zhou                             "xyz.openbmc_project.Inventory.Item.Dimm" &&
73076686dccSNan Zhou                         path.filename() == dimmId)
731b9d36b47SEd Tanous                     {
73276686dccSNan Zhou                         getDimmDataByService(aResp, dimmId, service, rawPath);
733ac6a4445SGunnar Mills                         found = true;
734ac6a4445SGunnar Mills                     }
735ac6a4445SGunnar Mills 
736b9d36b47SEd Tanous                     // partitions are separate as there can be multiple
737b9d36b47SEd Tanous                     // per
738ac6a4445SGunnar Mills                     // device, i.e.
739ac6a4445SGunnar Mills                     // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1
740ac6a4445SGunnar Mills                     // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2
741b9d36b47SEd Tanous                     if (interface ==
74276686dccSNan Zhou                             "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition" &&
74376686dccSNan Zhou                         path.parent_path().filename() == dimmId)
744ac6a4445SGunnar Mills                     {
74576686dccSNan Zhou                         getDimmPartitionData(aResp, service, rawPath);
746ac6a4445SGunnar Mills                     }
747ac6a4445SGunnar Mills                 }
748ac6a4445SGunnar Mills             }
749b9d36b47SEd Tanous         }
750ac6a4445SGunnar Mills         // Object not found
751ac6a4445SGunnar Mills         if (!found)
752ac6a4445SGunnar Mills         {
753ac6a4445SGunnar Mills             messages::resourceNotFound(aResp->res, "Memory", dimmId);
7541a1d5d6dSNan Zhou             return;
755ac6a4445SGunnar Mills         }
7561a1d5d6dSNan Zhou         // Set @odata only if object is found
7571a1d5d6dSNan Zhou         aResp->res.jsonValue["@odata.type"] = "#Memory.v1_11_0.Memory";
7581a1d5d6dSNan Zhou         aResp->res.jsonValue["@odata.id"] =
7591a1d5d6dSNan Zhou             "/redfish/v1/Systems/system/Memory/" + dimmId;
760ac6a4445SGunnar Mills         return;
761ac6a4445SGunnar Mills         },
762ac6a4445SGunnar Mills         "xyz.openbmc_project.ObjectMapper",
763ac6a4445SGunnar Mills         "/xyz/openbmc_project/object_mapper",
764ac6a4445SGunnar Mills         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
765ac6a4445SGunnar Mills         "/xyz/openbmc_project/inventory", 0,
766ac6a4445SGunnar Mills         std::array<const char*, 2>{
767ac6a4445SGunnar Mills             "xyz.openbmc_project.Inventory.Item.Dimm",
768ac6a4445SGunnar Mills             "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"});
769ac6a4445SGunnar Mills }
770ac6a4445SGunnar Mills 
7717e860f15SJohn Edward Broadbent inline void requestRoutesMemoryCollection(App& app)
772ac6a4445SGunnar Mills {
773ac6a4445SGunnar Mills     /**
774ac6a4445SGunnar Mills      * Functions triggers appropriate requests on DBus
775ac6a4445SGunnar Mills      */
77622d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/")
777ed398213SEd Tanous         .privileges(redfish::privileges::getMemoryCollection)
7787e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
77945ca1b86SEd Tanous             [&app](const crow::Request& req,
78022d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
78122d268cbSEd Tanous                    const std::string& systemName) {
7823ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
78345ca1b86SEd Tanous         {
78445ca1b86SEd Tanous             return;
78545ca1b86SEd Tanous         }
78622d268cbSEd Tanous         if (systemName != "system")
78722d268cbSEd Tanous         {
78822d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
78922d268cbSEd Tanous                                        systemName);
79022d268cbSEd Tanous             return;
79122d268cbSEd Tanous         }
79222d268cbSEd Tanous 
7938d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.type"] =
7948d1b46d7Szhanghch05             "#MemoryCollection.MemoryCollection";
7958d1b46d7Szhanghch05         asyncResp->res.jsonValue["Name"] = "Memory Module Collection";
7968d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.id"] =
7978d1b46d7Szhanghch05             "/redfish/v1/Systems/system/Memory";
798ac6a4445SGunnar Mills 
7997a1dbc48SGeorge Liu         constexpr std::array<std::string_view, 1> interfaces{
8007a1dbc48SGeorge Liu             "xyz.openbmc_project.Inventory.Item.Dimm"};
80105030b8eSGunnar Mills         collection_util::getCollectionMembers(
802ae9031f0SWilly Tu             asyncResp, boost::urls::url("/redfish/v1/Systems/system/Memory"),
8037a1dbc48SGeorge Liu             interfaces);
8047e860f15SJohn Edward Broadbent         });
805ac6a4445SGunnar Mills }
806ac6a4445SGunnar Mills 
8077e860f15SJohn Edward Broadbent inline void requestRoutesMemory(App& app)
8087e860f15SJohn Edward Broadbent {
809ac6a4445SGunnar Mills     /**
810ac6a4445SGunnar Mills      * Functions triggers appropriate requests on DBus
811ac6a4445SGunnar Mills      */
81222d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/<str>/")
813ed398213SEd Tanous         .privileges(redfish::privileges::getMemory)
8147e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
81545ca1b86SEd Tanous             [&app](const crow::Request& req,
8167e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
81722d268cbSEd Tanous                    const std::string& systemName, const std::string& dimmId) {
8183ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
81945ca1b86SEd Tanous         {
82045ca1b86SEd Tanous             return;
82145ca1b86SEd Tanous         }
82222d268cbSEd Tanous         if (systemName != "system")
82322d268cbSEd Tanous         {
82422d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
82522d268cbSEd Tanous                                        systemName);
82622d268cbSEd Tanous             return;
82722d268cbSEd Tanous         }
82822d268cbSEd Tanous 
829ac6a4445SGunnar Mills         getDimmData(asyncResp, dimmId);
8307e860f15SJohn Edward Broadbent         });
831ac6a4445SGunnar Mills }
832ac6a4445SGunnar Mills 
833ac6a4445SGunnar Mills } // namespace redfish
834