xref: /openbmc/bmcweb/features/redfish/lib/memory.hpp (revision 40e9b92ec19acffb46f83a6e55b18974da5d708e)
1*40e9b92eSEd Tanous // SPDX-License-Identifier: Apache-2.0
2*40e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright OpenBMC Authors
3*40e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright 2018 Intel Corporation
4ac6a4445SGunnar Mills #pragma once
5ac6a4445SGunnar Mills 
613451e39SWilly Tu #include "bmcweb_config.h"
713451e39SWilly Tu 
83ccb3adbSEd Tanous #include "app.hpp"
93ccb3adbSEd Tanous #include "dbus_utility.hpp"
10539d8c6bSEd Tanous #include "generated/enums/memory.hpp"
11539d8c6bSEd Tanous #include "generated/enums/resource.hpp"
123ccb3adbSEd Tanous #include "query.hpp"
133ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
143ccb3adbSEd Tanous #include "utils/collection.hpp"
153ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
163ccb3adbSEd Tanous #include "utils/hex_utils.hpp"
173ccb3adbSEd Tanous #include "utils/json_utils.hpp"
18ac6a4445SGunnar Mills 
19e99073f5SGeorge Liu #include <boost/system/error_code.hpp>
20ef4c65b7SEd Tanous #include <boost/url/format.hpp>
21d7f04fd9SNan Zhou #include <nlohmann/json.hpp>
22c1343bf6SKrzysztof Grobelny #include <sdbusplus/asio/property.hpp>
23c1343bf6SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
24ac6a4445SGunnar Mills 
257a1dbc48SGeorge Liu #include <array>
267a1dbc48SGeorge Liu #include <string_view>
277a1dbc48SGeorge Liu 
28ac6a4445SGunnar Mills namespace redfish
29ac6a4445SGunnar Mills {
30ac6a4445SGunnar Mills 
31313efb1cSGunnar Mills inline std::string translateMemoryTypeToRedfish(const std::string& memoryType)
32313efb1cSGunnar Mills {
33313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR")
34313efb1cSGunnar Mills     {
35313efb1cSGunnar Mills         return "DDR";
36313efb1cSGunnar Mills     }
37313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2")
38313efb1cSGunnar Mills     {
39313efb1cSGunnar Mills         return "DDR2";
40313efb1cSGunnar Mills     }
41313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR3")
42313efb1cSGunnar Mills     {
43313efb1cSGunnar Mills         return "DDR3";
44313efb1cSGunnar Mills     }
45313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4")
46313efb1cSGunnar Mills     {
47313efb1cSGunnar Mills         return "DDR4";
48313efb1cSGunnar Mills     }
49313efb1cSGunnar Mills     if (memoryType ==
50313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4E_SDRAM")
51313efb1cSGunnar Mills     {
52313efb1cSGunnar Mills         return "DDR4E_SDRAM";
53313efb1cSGunnar Mills     }
5411a2f0f0SMansi Joshi     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR5")
5511a2f0f0SMansi Joshi     {
5611a2f0f0SMansi Joshi         return "DDR5";
5711a2f0f0SMansi Joshi     }
58313efb1cSGunnar Mills     if (memoryType ==
59313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR4_SDRAM")
60313efb1cSGunnar Mills     {
61313efb1cSGunnar Mills         return "LPDDR4_SDRAM";
62313efb1cSGunnar Mills     }
63313efb1cSGunnar Mills     if (memoryType ==
64313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR3_SDRAM")
65313efb1cSGunnar Mills     {
66313efb1cSGunnar Mills         return "LPDDR3_SDRAM";
67313efb1cSGunnar Mills     }
68313efb1cSGunnar Mills     if (memoryType ==
69313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM")
70313efb1cSGunnar Mills     {
71313efb1cSGunnar Mills         return "DDR2_SDRAM_FB_DIMM";
72313efb1cSGunnar Mills     }
730fda0f12SGeorge Liu     if (memoryType ==
740fda0f12SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM_PROB")
75313efb1cSGunnar Mills     {
76313efb1cSGunnar Mills         return "DDR2_SDRAM_FB_DIMM_PROBE";
77313efb1cSGunnar Mills     }
78313efb1cSGunnar Mills     if (memoryType ==
79313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR_SGRAM")
80313efb1cSGunnar Mills     {
81313efb1cSGunnar Mills         return "DDR_SGRAM";
82313efb1cSGunnar Mills     }
83313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.ROM")
84313efb1cSGunnar Mills     {
85313efb1cSGunnar Mills         return "ROM";
86313efb1cSGunnar Mills     }
87313efb1cSGunnar Mills     if (memoryType ==
88313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.SDRAM")
89313efb1cSGunnar Mills     {
90313efb1cSGunnar Mills         return "SDRAM";
91313efb1cSGunnar Mills     }
92313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.EDO")
93313efb1cSGunnar Mills     {
94313efb1cSGunnar Mills         return "EDO";
95313efb1cSGunnar Mills     }
96313efb1cSGunnar Mills     if (memoryType ==
97313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.FastPageMode")
98313efb1cSGunnar Mills     {
99313efb1cSGunnar Mills         return "FastPageMode";
100313efb1cSGunnar Mills     }
101313efb1cSGunnar Mills     if (memoryType ==
102313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.PipelinedNibble")
103313efb1cSGunnar Mills     {
104313efb1cSGunnar Mills         return "PipelinedNibble";
105313efb1cSGunnar Mills     }
106313efb1cSGunnar Mills     if (memoryType ==
107313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.Logical")
108313efb1cSGunnar Mills     {
109313efb1cSGunnar Mills         return "Logical";
110313efb1cSGunnar Mills     }
111313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM")
112313efb1cSGunnar Mills     {
113313efb1cSGunnar Mills         return "HBM";
114313efb1cSGunnar Mills     }
115313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM2")
116313efb1cSGunnar Mills     {
117313efb1cSGunnar Mills         return "HBM2";
118313efb1cSGunnar Mills     }
119ce34d514STyson Tuckerbear     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM3")
120ce34d514STyson Tuckerbear     {
121ce34d514STyson Tuckerbear         return "HBM3";
122ce34d514STyson Tuckerbear     }
123313efb1cSGunnar Mills     // This is values like Other or Unknown
124313efb1cSGunnar Mills     // Also D-Bus values:
125313efb1cSGunnar Mills     // DRAM
126313efb1cSGunnar Mills     // EDRAM
127313efb1cSGunnar Mills     // VRAM
128313efb1cSGunnar Mills     // SRAM
129313efb1cSGunnar Mills     // RAM
130313efb1cSGunnar Mills     // FLASH
131313efb1cSGunnar Mills     // EEPROM
132313efb1cSGunnar Mills     // FEPROM
133313efb1cSGunnar Mills     // EPROM
134313efb1cSGunnar Mills     // CDRAM
135313efb1cSGunnar Mills     // ThreeDRAM
136313efb1cSGunnar Mills     // RDRAM
137313efb1cSGunnar Mills     // FBD2
138313efb1cSGunnar Mills     // LPDDR_SDRAM
139313efb1cSGunnar Mills     // LPDDR2_SDRAM
14011a2f0f0SMansi Joshi     // LPDDR5_SDRAM
141313efb1cSGunnar Mills     return "";
142313efb1cSGunnar Mills }
143313efb1cSGunnar Mills 
144ac106bf6SEd Tanous inline void dimmPropToHex(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
145c1343bf6SKrzysztof Grobelny                           const char* key, const uint16_t* value,
146d7f04fd9SNan Zhou                           const nlohmann::json::json_pointer& jsonPtr)
147ac6a4445SGunnar Mills {
148ac6a4445SGunnar Mills     if (value == nullptr)
149ac6a4445SGunnar Mills     {
150ac6a4445SGunnar Mills         return;
151ac6a4445SGunnar Mills     }
152ac106bf6SEd Tanous     asyncResp->res.jsonValue[jsonPtr][key] = "0x" + intToHexString(*value, 4);
153ac6a4445SGunnar Mills }
154ac6a4445SGunnar Mills 
1558d1b46d7Szhanghch05 inline void getPersistentMemoryProperties(
156ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
157c1343bf6SKrzysztof Grobelny     const dbus::utility::DBusPropertiesMap& properties,
158d7f04fd9SNan Zhou     const nlohmann::json::json_pointer& jsonPtr)
159ac6a4445SGunnar Mills {
160c1343bf6SKrzysztof Grobelny     const uint16_t* moduleManufacturerID = nullptr;
161c1343bf6SKrzysztof Grobelny     const uint16_t* moduleProductID = nullptr;
162c1343bf6SKrzysztof Grobelny     const uint16_t* subsystemVendorID = nullptr;
163c1343bf6SKrzysztof Grobelny     const uint16_t* subsystemDeviceID = nullptr;
164c1343bf6SKrzysztof Grobelny     const uint64_t* volatileRegionSizeLimitInKiB = nullptr;
165c1343bf6SKrzysztof Grobelny     const uint64_t* pmRegionSizeLimitInKiB = nullptr;
166c1343bf6SKrzysztof Grobelny     const uint64_t* volatileSizeInKiB = nullptr;
167c1343bf6SKrzysztof Grobelny     const uint64_t* pmSizeInKiB = nullptr;
168c1343bf6SKrzysztof Grobelny     const uint64_t* cacheSizeInKB = nullptr;
169c1343bf6SKrzysztof Grobelny     const uint64_t* voltaileRegionMaxSizeInKib = nullptr;
170c1343bf6SKrzysztof Grobelny     const uint64_t* pmRegionMaxSizeInKiB = nullptr;
171c1343bf6SKrzysztof Grobelny     const uint64_t* allocationIncrementInKiB = nullptr;
172c1343bf6SKrzysztof Grobelny     const uint64_t* allocationAlignmentInKiB = nullptr;
173c1343bf6SKrzysztof Grobelny     const uint64_t* volatileRegionNumberLimit = nullptr;
174c1343bf6SKrzysztof Grobelny     const uint64_t* pmRegionNumberLimit = nullptr;
175c1343bf6SKrzysztof Grobelny     const uint64_t* spareDeviceCount = nullptr;
176c1343bf6SKrzysztof Grobelny     const bool* isSpareDeviceInUse = nullptr;
177c1343bf6SKrzysztof Grobelny     const bool* isRankSpareEnabled = nullptr;
178c1343bf6SKrzysztof Grobelny     const std::vector<uint32_t>* maxAveragePowerLimitmW = nullptr;
179c1343bf6SKrzysztof Grobelny     const bool* configurationLocked = nullptr;
180c1343bf6SKrzysztof Grobelny     const std::string* allowedMemoryModes = nullptr;
181c1343bf6SKrzysztof Grobelny     const std::string* memoryMedia = nullptr;
182c1343bf6SKrzysztof Grobelny     const bool* configurationLockCapable = nullptr;
183c1343bf6SKrzysztof Grobelny     const bool* dataLockCapable = nullptr;
184c1343bf6SKrzysztof Grobelny     const bool* passphraseCapable = nullptr;
185c1343bf6SKrzysztof Grobelny     const uint64_t* maxPassphraseCount = nullptr;
186c1343bf6SKrzysztof Grobelny     const uint64_t* passphraseLockLimit = nullptr;
187c1343bf6SKrzysztof Grobelny 
188c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
189c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "ModuleManufacturerID",
190c1343bf6SKrzysztof Grobelny         moduleManufacturerID, "ModuleProductID", moduleProductID,
191c1343bf6SKrzysztof Grobelny         "SubsystemVendorID", subsystemVendorID, "SubsystemDeviceID",
192c1343bf6SKrzysztof Grobelny         subsystemDeviceID, "VolatileRegionSizeLimitInKiB",
193c1343bf6SKrzysztof Grobelny         volatileRegionSizeLimitInKiB, "PmRegionSizeLimitInKiB",
194c1343bf6SKrzysztof Grobelny         pmRegionSizeLimitInKiB, "VolatileSizeInKiB", volatileSizeInKiB,
195c1343bf6SKrzysztof Grobelny         "PmSizeInKiB", pmSizeInKiB, "CacheSizeInKB", cacheSizeInKB,
196c1343bf6SKrzysztof Grobelny         "VoltaileRegionMaxSizeInKib", voltaileRegionMaxSizeInKib,
197c1343bf6SKrzysztof Grobelny         "PmRegionMaxSizeInKiB", pmRegionMaxSizeInKiB,
198c1343bf6SKrzysztof Grobelny         "AllocationIncrementInKiB", allocationIncrementInKiB,
199c1343bf6SKrzysztof Grobelny         "AllocationAlignmentInKiB", allocationAlignmentInKiB,
200c1343bf6SKrzysztof Grobelny         "VolatileRegionNumberLimit", volatileRegionNumberLimit,
201c1343bf6SKrzysztof Grobelny         "PmRegionNumberLimit", pmRegionNumberLimit, "SpareDeviceCount",
202c1343bf6SKrzysztof Grobelny         spareDeviceCount, "IsSpareDeviceInUse", isSpareDeviceInUse,
203c1343bf6SKrzysztof Grobelny         "IsRankSpareEnabled", isRankSpareEnabled, "MaxAveragePowerLimitmW",
204c1343bf6SKrzysztof Grobelny         maxAveragePowerLimitmW, "ConfigurationLocked", configurationLocked,
205c1343bf6SKrzysztof Grobelny         "AllowedMemoryModes", allowedMemoryModes, "MemoryMedia", memoryMedia,
206c1343bf6SKrzysztof Grobelny         "ConfigurationLockCapable", configurationLockCapable, "DataLockCapable",
207c1343bf6SKrzysztof Grobelny         dataLockCapable, "PassphraseCapable", passphraseCapable,
208c1343bf6SKrzysztof Grobelny         "MaxPassphraseCount", maxPassphraseCount, "PassphraseLockLimit",
209c1343bf6SKrzysztof Grobelny         passphraseLockLimit);
210c1343bf6SKrzysztof Grobelny 
211c1343bf6SKrzysztof Grobelny     if (!success)
212ac6a4445SGunnar Mills     {
213ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
214c1343bf6SKrzysztof Grobelny         return;
215ac6a4445SGunnar Mills     }
216c1343bf6SKrzysztof Grobelny 
217ac106bf6SEd Tanous     dimmPropToHex(asyncResp, "ModuleManufacturerID", moduleManufacturerID,
218ac106bf6SEd Tanous                   jsonPtr);
219ac106bf6SEd Tanous     dimmPropToHex(asyncResp, "ModuleProductID", moduleProductID, jsonPtr);
220ac106bf6SEd Tanous     dimmPropToHex(asyncResp, "MemorySubsystemControllerManufacturerID",
221c1343bf6SKrzysztof Grobelny                   subsystemVendorID, jsonPtr);
222ac106bf6SEd Tanous     dimmPropToHex(asyncResp, "MemorySubsystemControllerProductID",
223c1343bf6SKrzysztof Grobelny                   subsystemDeviceID, jsonPtr);
224ac6a4445SGunnar Mills 
225c1343bf6SKrzysztof Grobelny     if (volatileRegionSizeLimitInKiB != nullptr)
226ac6a4445SGunnar Mills     {
227ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["VolatileRegionSizeLimitMiB"] =
228c1343bf6SKrzysztof Grobelny             (*volatileRegionSizeLimitInKiB) >> 10;
229ac6a4445SGunnar Mills     }
230ac6a4445SGunnar Mills 
231c1343bf6SKrzysztof Grobelny     if (pmRegionSizeLimitInKiB != nullptr)
232ac6a4445SGunnar Mills     {
233ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["PersistentRegionSizeLimitMiB"] =
234c1343bf6SKrzysztof Grobelny             (*pmRegionSizeLimitInKiB) >> 10;
235ac6a4445SGunnar Mills     }
236ac6a4445SGunnar Mills 
237c1343bf6SKrzysztof Grobelny     if (volatileSizeInKiB != nullptr)
238ac6a4445SGunnar Mills     {
239ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["VolatileSizeMiB"] =
240c1343bf6SKrzysztof Grobelny             (*volatileSizeInKiB) >> 10;
241ac6a4445SGunnar Mills     }
242c1343bf6SKrzysztof Grobelny 
243c1343bf6SKrzysztof Grobelny     if (pmSizeInKiB != nullptr)
244c1343bf6SKrzysztof Grobelny     {
245ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["NonVolatileSizeMiB"] =
246ac106bf6SEd Tanous             (*pmSizeInKiB) >> 10;
247c1343bf6SKrzysztof Grobelny     }
248c1343bf6SKrzysztof Grobelny 
249c1343bf6SKrzysztof Grobelny     if (cacheSizeInKB != nullptr)
250c1343bf6SKrzysztof Grobelny     {
251ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["CacheSizeMiB"] =
252ac106bf6SEd Tanous             (*cacheSizeInKB >> 10);
253c1343bf6SKrzysztof Grobelny     }
254c1343bf6SKrzysztof Grobelny 
255c1343bf6SKrzysztof Grobelny     if (voltaileRegionMaxSizeInKib != nullptr)
256c1343bf6SKrzysztof Grobelny     {
257ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["VolatileRegionSizeMaxMiB"] =
258c1343bf6SKrzysztof Grobelny             (*voltaileRegionMaxSizeInKib) >> 10;
259ac6a4445SGunnar Mills     }
260ac6a4445SGunnar Mills 
261c1343bf6SKrzysztof Grobelny     if (pmRegionMaxSizeInKiB != nullptr)
262ac6a4445SGunnar Mills     {
263ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["PersistentRegionSizeMaxMiB"] =
264c1343bf6SKrzysztof Grobelny             (*pmRegionMaxSizeInKiB) >> 10;
265ac6a4445SGunnar Mills     }
266ac6a4445SGunnar Mills 
267c1343bf6SKrzysztof Grobelny     if (allocationIncrementInKiB != nullptr)
268ac6a4445SGunnar Mills     {
269ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["AllocationIncrementMiB"] =
270c1343bf6SKrzysztof Grobelny             (*allocationIncrementInKiB) >> 10;
271ac6a4445SGunnar Mills     }
272ac6a4445SGunnar Mills 
273c1343bf6SKrzysztof Grobelny     if (allocationAlignmentInKiB != nullptr)
274ac6a4445SGunnar Mills     {
275ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["AllocationAlignmentMiB"] =
276c1343bf6SKrzysztof Grobelny             (*allocationAlignmentInKiB) >> 10;
277ac6a4445SGunnar Mills     }
278c1343bf6SKrzysztof Grobelny 
279c1343bf6SKrzysztof Grobelny     if (volatileRegionNumberLimit != nullptr)
280ac6a4445SGunnar Mills     {
281ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["VolatileRegionNumberLimit"] =
282c1343bf6SKrzysztof Grobelny             *volatileRegionNumberLimit;
283ac6a4445SGunnar Mills     }
284c1343bf6SKrzysztof Grobelny 
285c1343bf6SKrzysztof Grobelny     if (pmRegionNumberLimit != nullptr)
286ac6a4445SGunnar Mills     {
287ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["PersistentRegionNumberLimit"] =
288c1343bf6SKrzysztof Grobelny             *pmRegionNumberLimit;
289ac6a4445SGunnar Mills     }
290c1343bf6SKrzysztof Grobelny 
291c1343bf6SKrzysztof Grobelny     if (spareDeviceCount != nullptr)
292ac6a4445SGunnar Mills     {
293ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SpareDeviceCount"] =
294ac106bf6SEd Tanous             *spareDeviceCount;
295ac6a4445SGunnar Mills     }
296c1343bf6SKrzysztof Grobelny 
297c1343bf6SKrzysztof Grobelny     if (isSpareDeviceInUse != nullptr)
298ac6a4445SGunnar Mills     {
299ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["IsSpareDeviceEnabled"] =
300c1343bf6SKrzysztof Grobelny             *isSpareDeviceInUse;
301ac6a4445SGunnar Mills     }
302c1343bf6SKrzysztof Grobelny 
303c1343bf6SKrzysztof Grobelny     if (isRankSpareEnabled != nullptr)
304ac6a4445SGunnar Mills     {
305ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["IsRankSpareEnabled"] =
306c1343bf6SKrzysztof Grobelny             *isRankSpareEnabled;
307ac6a4445SGunnar Mills     }
308c1343bf6SKrzysztof Grobelny 
309c1343bf6SKrzysztof Grobelny     if (maxAveragePowerLimitmW != nullptr)
310ac6a4445SGunnar Mills     {
311ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MaxTDPMilliWatts"] =
312c1343bf6SKrzysztof Grobelny             *maxAveragePowerLimitmW;
313ac6a4445SGunnar Mills     }
314c1343bf6SKrzysztof Grobelny 
315c1343bf6SKrzysztof Grobelny     if (configurationLocked != nullptr)
316ac6a4445SGunnar Mills     {
317ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["ConfigurationLocked"] =
318c1343bf6SKrzysztof Grobelny             *configurationLocked;
319ac6a4445SGunnar Mills     }
320c1343bf6SKrzysztof Grobelny 
321c1343bf6SKrzysztof Grobelny     if (allowedMemoryModes != nullptr)
322ac6a4445SGunnar Mills     {
32380badf7cSJiaqing Zhao         constexpr const std::array<const char*, 3> values{"Volatile", "PMEM",
32480badf7cSJiaqing Zhao                                                           "Block"};
325ac6a4445SGunnar Mills 
326ac6a4445SGunnar Mills         for (const char* v : values)
327ac6a4445SGunnar Mills         {
328c1343bf6SKrzysztof Grobelny             if (allowedMemoryModes->ends_with(v))
329ac6a4445SGunnar Mills             {
330ac106bf6SEd Tanous                 asyncResp->res.jsonValue[jsonPtr]["OperatingMemoryModes"]
331ac106bf6SEd Tanous                     .push_back(v);
332ac6a4445SGunnar Mills                 break;
333ac6a4445SGunnar Mills             }
334ac6a4445SGunnar Mills         }
335ac6a4445SGunnar Mills     }
336c1343bf6SKrzysztof Grobelny 
337c1343bf6SKrzysztof Grobelny     if (memoryMedia != nullptr)
338ac6a4445SGunnar Mills     {
339ac6a4445SGunnar Mills         constexpr const std::array<const char*, 3> values{"DRAM", "NAND",
340ac6a4445SGunnar Mills                                                           "Intel3DXPoint"};
341ac6a4445SGunnar Mills 
342ac6a4445SGunnar Mills         for (const char* v : values)
343ac6a4445SGunnar Mills         {
344c1343bf6SKrzysztof Grobelny             if (memoryMedia->ends_with(v))
345ac6a4445SGunnar Mills             {
346ac106bf6SEd Tanous                 asyncResp->res.jsonValue[jsonPtr]["MemoryMedia"].push_back(v);
347ac6a4445SGunnar Mills                 break;
348ac6a4445SGunnar Mills             }
349ac6a4445SGunnar Mills         }
350ac6a4445SGunnar Mills     }
351c1343bf6SKrzysztof Grobelny 
352c1343bf6SKrzysztof Grobelny     if (configurationLockCapable != nullptr)
353ac6a4445SGunnar Mills     {
354ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
355c1343bf6SKrzysztof Grobelny                                 ["ConfigurationLockCapable"] =
356c1343bf6SKrzysztof Grobelny             *configurationLockCapable;
357ac6a4445SGunnar Mills     }
358c1343bf6SKrzysztof Grobelny 
359c1343bf6SKrzysztof Grobelny     if (dataLockCapable != nullptr)
360ac6a4445SGunnar Mills     {
361bd79bce8SPatrick Williams         asyncResp->res
362bd79bce8SPatrick Williams             .jsonValue[jsonPtr]["SecurityCapabilities"]["DataLockCapable"] =
363bd79bce8SPatrick Williams             *dataLockCapable;
364ac6a4445SGunnar Mills     }
365c1343bf6SKrzysztof Grobelny 
366c1343bf6SKrzysztof Grobelny     if (passphraseCapable != nullptr)
367c1343bf6SKrzysztof Grobelny     {
368bd79bce8SPatrick Williams         asyncResp->res
369bd79bce8SPatrick Williams             .jsonValue[jsonPtr]["SecurityCapabilities"]["PassphraseCapable"] =
370bd79bce8SPatrick Williams             *passphraseCapable;
371c1343bf6SKrzysztof Grobelny     }
372c1343bf6SKrzysztof Grobelny 
373c1343bf6SKrzysztof Grobelny     if (maxPassphraseCount != nullptr)
374c1343bf6SKrzysztof Grobelny     {
375bd79bce8SPatrick Williams         asyncResp->res
376bd79bce8SPatrick Williams             .jsonValue[jsonPtr]["SecurityCapabilities"]["MaxPassphraseCount"] =
377bd79bce8SPatrick Williams             *maxPassphraseCount;
378c1343bf6SKrzysztof Grobelny     }
379c1343bf6SKrzysztof Grobelny 
380c1343bf6SKrzysztof Grobelny     if (passphraseLockLimit != nullptr)
381c1343bf6SKrzysztof Grobelny     {
382bd79bce8SPatrick Williams         asyncResp->res
383bd79bce8SPatrick Williams             .jsonValue[jsonPtr]["SecurityCapabilities"]["PassphraseLockLimit"] =
384bd79bce8SPatrick Williams             *passphraseLockLimit;
385ac6a4445SGunnar Mills     }
386ac6a4445SGunnar Mills }
387ac6a4445SGunnar Mills 
388bd79bce8SPatrick Williams inline void assembleDimmProperties(
389bd79bce8SPatrick Williams     std::string_view dimmId,
390ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
391d7f04fd9SNan Zhou     const dbus::utility::DBusPropertiesMap& properties,
392d7f04fd9SNan Zhou     const nlohmann::json::json_pointer& jsonPtr)
393ac6a4445SGunnar Mills {
394ac106bf6SEd Tanous     asyncResp->res.jsonValue[jsonPtr]["Id"] = dimmId;
395ac106bf6SEd Tanous     asyncResp->res.jsonValue[jsonPtr]["Name"] = "DIMM Slot";
396539d8c6bSEd Tanous     asyncResp->res.jsonValue[jsonPtr]["Status"]["State"] =
397539d8c6bSEd Tanous         resource::State::Enabled;
398539d8c6bSEd Tanous     asyncResp->res.jsonValue[jsonPtr]["Status"]["Health"] =
399539d8c6bSEd Tanous         resource::Health::OK;
400ac6a4445SGunnar Mills 
401c1343bf6SKrzysztof Grobelny     const uint16_t* memoryDataWidth = nullptr;
402c1343bf6SKrzysztof Grobelny     const size_t* memorySizeInKB = nullptr;
403c1343bf6SKrzysztof Grobelny     const std::string* partNumber = nullptr;
404c1343bf6SKrzysztof Grobelny     const std::string* serialNumber = nullptr;
405c1343bf6SKrzysztof Grobelny     const std::string* manufacturer = nullptr;
406c1343bf6SKrzysztof Grobelny     const uint16_t* revisionCode = nullptr;
407c1343bf6SKrzysztof Grobelny     const bool* present = nullptr;
408c1343bf6SKrzysztof Grobelny     const uint16_t* memoryTotalWidth = nullptr;
409c1343bf6SKrzysztof Grobelny     const std::string* ecc = nullptr;
410c1343bf6SKrzysztof Grobelny     const std::string* formFactor = nullptr;
411c1343bf6SKrzysztof Grobelny     const std::vector<uint16_t>* allowedSpeedsMT = nullptr;
4126995c1ceSGeorge Liu     const size_t* memoryAttributes = nullptr;
413c1343bf6SKrzysztof Grobelny     const uint16_t* memoryConfiguredSpeedInMhz = nullptr;
414c1343bf6SKrzysztof Grobelny     const std::string* memoryType = nullptr;
4156fde5971SJayaprakash Mutyala     const std::uint8_t* channel = nullptr;
4166fde5971SJayaprakash Mutyala     const std::uint8_t* memoryController = nullptr;
4176fde5971SJayaprakash Mutyala     const std::uint8_t* slot = nullptr;
4186fde5971SJayaprakash Mutyala     const std::uint8_t* socket = nullptr;
419c1343bf6SKrzysztof Grobelny     const std::string* sparePartNumber = nullptr;
420c1343bf6SKrzysztof Grobelny     const std::string* model = nullptr;
421c1343bf6SKrzysztof Grobelny     const std::string* locationCode = nullptr;
422ac6a4445SGunnar Mills 
423c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
424c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "MemoryDataWidth",
425c1343bf6SKrzysztof Grobelny         memoryDataWidth, "MemorySizeInKB", memorySizeInKB, "PartNumber",
426656472d9SNikhil Namjoshi         partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
427656472d9SNikhil Namjoshi         "RevisionCode", revisionCode, "Present", present, "MemoryTotalWidth",
428656472d9SNikhil Namjoshi         memoryTotalWidth, "ECC", ecc, "FormFactor", formFactor,
429656472d9SNikhil Namjoshi         "AllowedSpeedsMT", allowedSpeedsMT, "MemoryAttributes",
430c1343bf6SKrzysztof Grobelny         memoryAttributes, "MemoryConfiguredSpeedInMhz",
431c1343bf6SKrzysztof Grobelny         memoryConfiguredSpeedInMhz, "MemoryType", memoryType, "Channel",
432c1343bf6SKrzysztof Grobelny         channel, "MemoryController", memoryController, "Slot", slot, "Socket",
433c1343bf6SKrzysztof Grobelny         socket, "SparePartNumber", sparePartNumber, "Model", model,
434c1343bf6SKrzysztof Grobelny         "LocationCode", locationCode);
435c1343bf6SKrzysztof Grobelny 
436c1343bf6SKrzysztof Grobelny     if (!success)
437ac6a4445SGunnar Mills     {
438ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
439601af5edSChicago Duan         return;
440ac6a4445SGunnar Mills     }
441c1343bf6SKrzysztof Grobelny 
442c1343bf6SKrzysztof Grobelny     if (memoryDataWidth != nullptr)
443c1343bf6SKrzysztof Grobelny     {
444ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["DataWidthBits"] = *memoryDataWidth;
445c1343bf6SKrzysztof Grobelny     }
446c1343bf6SKrzysztof Grobelny 
447c1343bf6SKrzysztof Grobelny     if (memorySizeInKB != nullptr)
448c1343bf6SKrzysztof Grobelny     {
449ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["CapacityMiB"] =
450ac106bf6SEd Tanous             (*memorySizeInKB >> 10);
451c1343bf6SKrzysztof Grobelny     }
452c1343bf6SKrzysztof Grobelny 
453c1343bf6SKrzysztof Grobelny     if (partNumber != nullptr)
454c1343bf6SKrzysztof Grobelny     {
455ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["PartNumber"] = *partNumber;
456c1343bf6SKrzysztof Grobelny     }
457c1343bf6SKrzysztof Grobelny 
458c1343bf6SKrzysztof Grobelny     if (serialNumber != nullptr)
459c1343bf6SKrzysztof Grobelny     {
460ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SerialNumber"] = *serialNumber;
461c1343bf6SKrzysztof Grobelny     }
462c1343bf6SKrzysztof Grobelny 
463c1343bf6SKrzysztof Grobelny     if (manufacturer != nullptr)
464c1343bf6SKrzysztof Grobelny     {
465ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["Manufacturer"] = *manufacturer;
466c1343bf6SKrzysztof Grobelny     }
467c1343bf6SKrzysztof Grobelny 
468c1343bf6SKrzysztof Grobelny     if (revisionCode != nullptr)
469c1343bf6SKrzysztof Grobelny     {
470ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["FirmwareRevision"] =
471c1343bf6SKrzysztof Grobelny             std::to_string(*revisionCode);
472ac6a4445SGunnar Mills     }
473c1343bf6SKrzysztof Grobelny 
474c1343bf6SKrzysztof Grobelny     if (present != nullptr && !*present)
4759a128eb3SJoshi-Mansi     {
476539d8c6bSEd Tanous         asyncResp->res.jsonValue[jsonPtr]["Status"]["State"] =
477539d8c6bSEd Tanous             resource::State::Absent;
4789a128eb3SJoshi-Mansi     }
479c1343bf6SKrzysztof Grobelny 
480c1343bf6SKrzysztof Grobelny     if (memoryTotalWidth != nullptr)
481ac6a4445SGunnar Mills     {
482ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["BusWidthBits"] = *memoryTotalWidth;
483ac6a4445SGunnar Mills     }
484c1343bf6SKrzysztof Grobelny 
485c1343bf6SKrzysztof Grobelny     if (ecc != nullptr)
486ac6a4445SGunnar Mills     {
487ac6a4445SGunnar Mills         constexpr const std::array<const char*, 4> values{
4889a5aceacSNan Zhou             "NoECC", "SingleBitECC", "MultiBitECC", "AddressParity"};
489ac6a4445SGunnar Mills 
490ac6a4445SGunnar Mills         for (const char* v : values)
491ac6a4445SGunnar Mills         {
492c1343bf6SKrzysztof Grobelny             if (ecc->ends_with(v))
493ac6a4445SGunnar Mills             {
494ac106bf6SEd Tanous                 asyncResp->res.jsonValue[jsonPtr]["ErrorCorrection"] = v;
495ac6a4445SGunnar Mills                 break;
496ac6a4445SGunnar Mills             }
497ac6a4445SGunnar Mills         }
498ac6a4445SGunnar Mills     }
499c1343bf6SKrzysztof Grobelny 
500c1343bf6SKrzysztof Grobelny     if (formFactor != nullptr)
501ac6a4445SGunnar Mills     {
502ac6a4445SGunnar Mills         constexpr const std::array<const char*, 11> values{
5039a5aceacSNan Zhou             "RDIMM",       "UDIMM",       "SO_DIMM",      "LRDIMM",
5049a5aceacSNan Zhou             "Mini_RDIMM",  "Mini_UDIMM",  "SO_RDIMM_72b", "SO_UDIMM_72b",
5059a5aceacSNan Zhou             "SO_DIMM_16b", "SO_DIMM_32b", "Die"};
506ac6a4445SGunnar Mills 
507ac6a4445SGunnar Mills         for (const char* v : values)
508ac6a4445SGunnar Mills         {
509c1343bf6SKrzysztof Grobelny             if (formFactor->ends_with(v))
510ac6a4445SGunnar Mills             {
511ac106bf6SEd Tanous                 asyncResp->res.jsonValue[jsonPtr]["BaseModuleType"] = v;
512ac6a4445SGunnar Mills                 break;
513ac6a4445SGunnar Mills             }
514ac6a4445SGunnar Mills         }
515ac6a4445SGunnar Mills     }
516c1343bf6SKrzysztof Grobelny 
517c1343bf6SKrzysztof Grobelny     if (allowedSpeedsMT != nullptr)
518ac6a4445SGunnar Mills     {
519d7f04fd9SNan Zhou         nlohmann::json& jValue =
520ac106bf6SEd Tanous             asyncResp->res.jsonValue[jsonPtr]["AllowedSpeedsMHz"];
521ac6a4445SGunnar Mills         jValue = nlohmann::json::array();
522c1343bf6SKrzysztof Grobelny         for (uint16_t subVal : *allowedSpeedsMT)
523ac6a4445SGunnar Mills         {
524ac6a4445SGunnar Mills             jValue.push_back(subVal);
525ac6a4445SGunnar Mills         }
526ac6a4445SGunnar Mills     }
527ac6a4445SGunnar Mills 
528c1343bf6SKrzysztof Grobelny     if (memoryAttributes != nullptr)
529ac6a4445SGunnar Mills     {
5306995c1ceSGeorge Liu         asyncResp->res.jsonValue[jsonPtr]["RankCount"] = *memoryAttributes;
531ac6a4445SGunnar Mills     }
532c1343bf6SKrzysztof Grobelny 
533c1343bf6SKrzysztof Grobelny     if (memoryConfiguredSpeedInMhz != nullptr)
534ac6a4445SGunnar Mills     {
535ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["OperatingSpeedMhz"] =
536c1343bf6SKrzysztof Grobelny             *memoryConfiguredSpeedInMhz;
537ac6a4445SGunnar Mills     }
538c1343bf6SKrzysztof Grobelny 
539c1343bf6SKrzysztof Grobelny     if (memoryType != nullptr)
540ac6a4445SGunnar Mills     {
541313efb1cSGunnar Mills         std::string memoryDeviceType =
542c1343bf6SKrzysztof Grobelny             translateMemoryTypeToRedfish(*memoryType);
543313efb1cSGunnar Mills         // Values like "Unknown" or "Other" will return empty
544313efb1cSGunnar Mills         // so just leave off
545313efb1cSGunnar Mills         if (!memoryDeviceType.empty())
546ac6a4445SGunnar Mills         {
547ac106bf6SEd Tanous             asyncResp->res.jsonValue[jsonPtr]["MemoryDeviceType"] =
548d7f04fd9SNan Zhou                 memoryDeviceType;
549ac6a4445SGunnar Mills         }
550c1343bf6SKrzysztof Grobelny         if (memoryType->find("DDR") != std::string::npos)
551ac6a4445SGunnar Mills         {
552539d8c6bSEd Tanous             asyncResp->res.jsonValue[jsonPtr]["MemoryType"] =
553539d8c6bSEd Tanous                 memory::MemoryType::DRAM;
554ac6a4445SGunnar Mills         }
555c1343bf6SKrzysztof Grobelny         else if (memoryType->ends_with("Logical"))
556ac6a4445SGunnar Mills         {
557539d8c6bSEd Tanous             asyncResp->res.jsonValue[jsonPtr]["MemoryType"] =
558539d8c6bSEd Tanous                 memory::MemoryType::IntelOptane;
559ac6a4445SGunnar Mills         }
560ac6a4445SGunnar Mills     }
561c1343bf6SKrzysztof Grobelny 
562c1343bf6SKrzysztof Grobelny     if (channel != nullptr)
563ac6a4445SGunnar Mills     {
564ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Channel"] =
565ac106bf6SEd Tanous             *channel;
566c1343bf6SKrzysztof Grobelny     }
567c1343bf6SKrzysztof Grobelny 
568c1343bf6SKrzysztof Grobelny     if (memoryController != nullptr)
569ac6a4445SGunnar Mills     {
570bd79bce8SPatrick Williams         asyncResp->res
571bd79bce8SPatrick Williams             .jsonValue[jsonPtr]["MemoryLocation"]["MemoryController"] =
572bd79bce8SPatrick Williams             *memoryController;
573ac6a4445SGunnar Mills     }
574c1343bf6SKrzysztof Grobelny 
575c1343bf6SKrzysztof Grobelny     if (slot != nullptr)
576ee135e24SSunnySrivastava1984     {
577ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Slot"] = *slot;
578c1343bf6SKrzysztof Grobelny     }
579c1343bf6SKrzysztof Grobelny 
580c1343bf6SKrzysztof Grobelny     if (socket != nullptr)
581ee135e24SSunnySrivastava1984     {
582ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Socket"] = *socket;
583ee135e24SSunnySrivastava1984     }
584c1343bf6SKrzysztof Grobelny 
585c1343bf6SKrzysztof Grobelny     if (sparePartNumber != nullptr)
586ee135e24SSunnySrivastava1984     {
587ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SparePartNumber"] = *sparePartNumber;
588c1343bf6SKrzysztof Grobelny     }
589c1343bf6SKrzysztof Grobelny 
590c1343bf6SKrzysztof Grobelny     if (model != nullptr)
591ee135e24SSunnySrivastava1984     {
592ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["Model"] = *model;
593ee135e24SSunnySrivastava1984     }
594c1343bf6SKrzysztof Grobelny 
595c1343bf6SKrzysztof Grobelny     if (locationCode != nullptr)
596ee135e24SSunnySrivastava1984     {
597bd79bce8SPatrick Williams         asyncResp->res
598bd79bce8SPatrick Williams             .jsonValue[jsonPtr]["Location"]["PartLocation"]["ServiceLabel"] =
599bd79bce8SPatrick Williams             *locationCode;
600ee135e24SSunnySrivastava1984     }
601c1343bf6SKrzysztof Grobelny 
602ac106bf6SEd Tanous     getPersistentMemoryProperties(asyncResp, properties, jsonPtr);
6039a5aceacSNan Zhou }
6049a5aceacSNan Zhou 
605bd79bce8SPatrick Williams inline void getDimmDataByService(
606bd79bce8SPatrick Williams     std::shared_ptr<bmcweb::AsyncResp> asyncResp, const std::string& dimmId,
607bd79bce8SPatrick Williams     const std::string& service, const std::string& objPath)
6089a5aceacSNan Zhou {
60962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get available system components.");
610deae6a78SEd Tanous     dbus::utility::getAllProperties(
611deae6a78SEd Tanous         service, objPath, "",
612ac106bf6SEd Tanous         [dimmId, asyncResp{std::move(asyncResp)}](
6135e7e2dc5SEd Tanous             const boost::system::error_code& ec,
6149a5aceacSNan Zhou             const dbus::utility::DBusPropertiesMap& properties) {
6159a5aceacSNan Zhou             if (ec)
6169a5aceacSNan Zhou             {
61762598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error");
618ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
6199a5aceacSNan Zhou                 return;
6209a5aceacSNan Zhou             }
621bd79bce8SPatrick Williams             assembleDimmProperties(dimmId, asyncResp, properties,
622bd79bce8SPatrick Williams                                    ""_json_pointer);
623c1343bf6SKrzysztof Grobelny         });
624ac6a4445SGunnar Mills }
625ac6a4445SGunnar Mills 
626ef00d7d4SNan Zhou inline void assembleDimmPartitionData(
627ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
628d7f04fd9SNan Zhou     const dbus::utility::DBusPropertiesMap& properties,
629d7f04fd9SNan Zhou     const nlohmann::json::json_pointer& regionPtr)
630ac6a4445SGunnar Mills {
631c1343bf6SKrzysztof Grobelny     const std::string* memoryClassification = nullptr;
632c1343bf6SKrzysztof Grobelny     const uint64_t* offsetInKiB = nullptr;
633c1343bf6SKrzysztof Grobelny     const std::string* partitionId = nullptr;
634c1343bf6SKrzysztof Grobelny     const bool* passphraseState = nullptr;
635c1343bf6SKrzysztof Grobelny     const uint64_t* sizeInKiB = nullptr;
636c1343bf6SKrzysztof Grobelny 
637c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
638c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "MemoryClassification",
639c1343bf6SKrzysztof Grobelny         memoryClassification, "OffsetInKiB", offsetInKiB, "PartitionId",
640c1343bf6SKrzysztof Grobelny         partitionId, "PassphraseState", passphraseState, "SizeInKiB",
641c1343bf6SKrzysztof Grobelny         sizeInKiB);
642c1343bf6SKrzysztof Grobelny 
643c1343bf6SKrzysztof Grobelny     if (!success)
644c1343bf6SKrzysztof Grobelny     {
645ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
646c1343bf6SKrzysztof Grobelny         return;
647c1343bf6SKrzysztof Grobelny     }
648c1343bf6SKrzysztof Grobelny 
649d7f04fd9SNan Zhou     nlohmann::json::object_t partition;
650c1343bf6SKrzysztof Grobelny 
651c1343bf6SKrzysztof Grobelny     if (memoryClassification != nullptr)
652ac6a4445SGunnar Mills     {
653c1343bf6SKrzysztof Grobelny         partition["MemoryClassification"] = *memoryClassification;
654ac6a4445SGunnar Mills     }
655ac6a4445SGunnar Mills 
656c1343bf6SKrzysztof Grobelny     if (offsetInKiB != nullptr)
657ac6a4445SGunnar Mills     {
658c1343bf6SKrzysztof Grobelny         partition["OffsetMiB"] = (*offsetInKiB >> 10);
659ac6a4445SGunnar Mills     }
660ac6a4445SGunnar Mills 
661c1343bf6SKrzysztof Grobelny     if (partitionId != nullptr)
662ac6a4445SGunnar Mills     {
663c1343bf6SKrzysztof Grobelny         partition["RegionId"] = *partitionId;
664c1343bf6SKrzysztof Grobelny     }
665c1343bf6SKrzysztof Grobelny 
666c1343bf6SKrzysztof Grobelny     if (passphraseState != nullptr)
667ac6a4445SGunnar Mills     {
668c1343bf6SKrzysztof Grobelny         partition["PassphraseEnabled"] = *passphraseState;
669ac6a4445SGunnar Mills     }
670c1343bf6SKrzysztof Grobelny 
671c1343bf6SKrzysztof Grobelny     if (sizeInKiB != nullptr)
672ac6a4445SGunnar Mills     {
673c1343bf6SKrzysztof Grobelny         partition["SizeMiB"] = (*sizeInKiB >> 10);
674ac6a4445SGunnar Mills     }
675c1343bf6SKrzysztof Grobelny 
676ac106bf6SEd Tanous     asyncResp->res.jsonValue[regionPtr].emplace_back(std::move(partition));
677ef00d7d4SNan Zhou }
678ef00d7d4SNan Zhou 
679ac106bf6SEd Tanous inline void getDimmPartitionData(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
680ef00d7d4SNan Zhou                                  const std::string& service,
681ef00d7d4SNan Zhou                                  const std::string& path)
682ef00d7d4SNan Zhou {
683deae6a78SEd Tanous     dbus::utility::getAllProperties(
684deae6a78SEd Tanous         service, path,
685c1343bf6SKrzysztof Grobelny         "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition",
686ac106bf6SEd Tanous         [asyncResp{std::move(asyncResp)}](
6875e7e2dc5SEd Tanous             const boost::system::error_code& ec,
688ef00d7d4SNan Zhou             const dbus::utility::DBusPropertiesMap& properties) {
689ef00d7d4SNan Zhou             if (ec)
690ef00d7d4SNan Zhou             {
69162598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error");
692ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
693ef00d7d4SNan Zhou 
694ef00d7d4SNan Zhou                 return;
695ef00d7d4SNan Zhou             }
696d7f04fd9SNan Zhou             nlohmann::json::json_pointer regionPtr = "/Regions"_json_pointer;
697ac106bf6SEd Tanous             assembleDimmPartitionData(asyncResp, properties, regionPtr);
698c1343bf6SKrzysztof Grobelny         }
699ac6a4445SGunnar Mills 
700c1343bf6SKrzysztof Grobelny     );
701ac6a4445SGunnar Mills }
702ac6a4445SGunnar Mills 
703ac106bf6SEd Tanous inline void getDimmData(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
704ac6a4445SGunnar Mills                         const std::string& dimmId)
705ac6a4445SGunnar Mills {
70662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get available system dimm resources.");
707e99073f5SGeorge Liu     constexpr std::array<std::string_view, 2> dimmInterfaces = {
708e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Dimm",
709e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"};
710e99073f5SGeorge Liu     dbus::utility::getSubTree(
711e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, dimmInterfaces,
712ac106bf6SEd Tanous         [dimmId, asyncResp{std::move(asyncResp)}](
713e99073f5SGeorge Liu             const boost::system::error_code& ec,
714b9d36b47SEd Tanous             const dbus::utility::MapperGetSubTreeResponse& subtree) {
715ac6a4445SGunnar Mills             if (ec)
716ac6a4445SGunnar Mills             {
71762598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error");
718ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
719ac6a4445SGunnar Mills 
720ac6a4445SGunnar Mills                 return;
721ac6a4445SGunnar Mills             }
722ac6a4445SGunnar Mills             bool found = false;
72376686dccSNan Zhou             for (const auto& [rawPath, object] : subtree)
724ac6a4445SGunnar Mills             {
72576686dccSNan Zhou                 sdbusplus::message::object_path path(rawPath);
726ac6a4445SGunnar Mills                 for (const auto& [service, interfaces] : object)
727ac6a4445SGunnar Mills                 {
728b9d36b47SEd Tanous                     for (const auto& interface : interfaces)
729ac6a4445SGunnar Mills                     {
730b9d36b47SEd Tanous                         if (interface ==
73176686dccSNan Zhou                                 "xyz.openbmc_project.Inventory.Item.Dimm" &&
73276686dccSNan Zhou                             path.filename() == dimmId)
733b9d36b47SEd Tanous                         {
734ac106bf6SEd Tanous                             getDimmDataByService(asyncResp, dimmId, service,
735ac106bf6SEd Tanous                                                  rawPath);
736ac6a4445SGunnar Mills                             found = true;
737ac6a4445SGunnar Mills                         }
738ac6a4445SGunnar Mills 
739b9d36b47SEd Tanous                         // partitions are separate as there can be multiple
740b9d36b47SEd Tanous                         // per
741ac6a4445SGunnar Mills                         // device, i.e.
742ac6a4445SGunnar Mills                         // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1
743ac6a4445SGunnar Mills                         // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2
744b9d36b47SEd Tanous                         if (interface ==
74576686dccSNan Zhou                                 "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition" &&
74676686dccSNan Zhou                             path.parent_path().filename() == dimmId)
747ac6a4445SGunnar Mills                         {
748ac106bf6SEd Tanous                             getDimmPartitionData(asyncResp, service, rawPath);
749ac6a4445SGunnar Mills                         }
750ac6a4445SGunnar Mills                     }
751ac6a4445SGunnar Mills                 }
752b9d36b47SEd Tanous             }
753ac6a4445SGunnar Mills             // Object not found
754ac6a4445SGunnar Mills             if (!found)
755ac6a4445SGunnar Mills             {
756ac106bf6SEd Tanous                 messages::resourceNotFound(asyncResp->res, "Memory", dimmId);
7571a1d5d6dSNan Zhou                 return;
758ac6a4445SGunnar Mills             }
7591a1d5d6dSNan Zhou             // Set @odata only if object is found
760ac106bf6SEd Tanous             asyncResp->res.jsonValue["@odata.type"] = "#Memory.v1_11_0.Memory";
761ac106bf6SEd Tanous             asyncResp->res.jsonValue["@odata.id"] =
762253f11b8SEd Tanous                 boost::urls::format("/redfish/v1/Systems/{}/Memory/{}",
763253f11b8SEd Tanous                                     BMCWEB_REDFISH_SYSTEM_URI_NAME, dimmId);
764ac6a4445SGunnar Mills             return;
765e99073f5SGeorge Liu         });
766ac6a4445SGunnar Mills }
767ac6a4445SGunnar Mills 
7687e860f15SJohn Edward Broadbent inline void requestRoutesMemoryCollection(App& app)
769ac6a4445SGunnar Mills {
770ac6a4445SGunnar Mills     /**
771ac6a4445SGunnar Mills      * Functions triggers appropriate requests on DBus
772ac6a4445SGunnar Mills      */
77322d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/")
774ed398213SEd Tanous         .privileges(redfish::privileges::getMemoryCollection)
7757e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
77645ca1b86SEd Tanous             [&app](const crow::Request& req,
77722d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
77822d268cbSEd Tanous                    const std::string& systemName) {
7793ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
78045ca1b86SEd Tanous                 {
78145ca1b86SEd Tanous                     return;
78245ca1b86SEd Tanous                 }
78325b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
7847f3e84a1SEd Tanous                 {
7857f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
7867f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
7877f3e84a1SEd Tanous                                                systemName);
7887f3e84a1SEd Tanous                     return;
7897f3e84a1SEd Tanous                 }
790253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
79122d268cbSEd Tanous                 {
79222d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
79322d268cbSEd Tanous                                                systemName);
79422d268cbSEd Tanous                     return;
79522d268cbSEd Tanous                 }
79622d268cbSEd Tanous 
7978d1b46d7Szhanghch05                 asyncResp->res.jsonValue["@odata.type"] =
7988d1b46d7Szhanghch05                     "#MemoryCollection.MemoryCollection";
7998d1b46d7Szhanghch05                 asyncResp->res.jsonValue["Name"] = "Memory Module Collection";
800bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["@odata.id"] =
801bd79bce8SPatrick Williams                     boost::urls::format("/redfish/v1/Systems/{}/Memory",
802bd79bce8SPatrick Williams                                         BMCWEB_REDFISH_SYSTEM_URI_NAME);
803ac6a4445SGunnar Mills 
8047a1dbc48SGeorge Liu                 constexpr std::array<std::string_view, 1> interfaces{
8057a1dbc48SGeorge Liu                     "xyz.openbmc_project.Inventory.Item.Dimm"};
80605030b8eSGunnar Mills                 collection_util::getCollectionMembers(
807253f11b8SEd Tanous                     asyncResp,
808253f11b8SEd Tanous                     boost::urls::format("/redfish/v1/Systems/{}/Memory",
809253f11b8SEd Tanous                                         BMCWEB_REDFISH_SYSTEM_URI_NAME),
81036b5f1edSLakshmi Yadlapati                     interfaces, "/xyz/openbmc_project/inventory");
8117e860f15SJohn Edward Broadbent             });
812ac6a4445SGunnar Mills }
813ac6a4445SGunnar Mills 
8147e860f15SJohn Edward Broadbent inline void requestRoutesMemory(App& app)
8157e860f15SJohn Edward Broadbent {
816ac6a4445SGunnar Mills     /**
817ac6a4445SGunnar Mills      * Functions triggers appropriate requests on DBus
818ac6a4445SGunnar Mills      */
81922d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/<str>/")
820ed398213SEd Tanous         .privileges(redfish::privileges::getMemory)
8217e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
82245ca1b86SEd Tanous             [&app](const crow::Request& req,
8237e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
82422d268cbSEd Tanous                    const std::string& systemName, const std::string& dimmId) {
8253ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
82645ca1b86SEd Tanous                 {
82745ca1b86SEd Tanous                     return;
82845ca1b86SEd Tanous                 }
8297f3e84a1SEd Tanous 
83025b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
8317f3e84a1SEd Tanous                 {
8327f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
8337f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
8347f3e84a1SEd Tanous                                                systemName);
8357f3e84a1SEd Tanous                     return;
8367f3e84a1SEd Tanous                 }
8377f3e84a1SEd Tanous 
838253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
83922d268cbSEd Tanous                 {
84022d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
84122d268cbSEd Tanous                                                systemName);
84222d268cbSEd Tanous                     return;
84322d268cbSEd Tanous                 }
84422d268cbSEd Tanous 
845ac6a4445SGunnar Mills                 getDimmData(asyncResp, dimmId);
8467e860f15SJohn Edward Broadbent             });
847ac6a4445SGunnar Mills }
848ac6a4445SGunnar Mills 
849ac6a4445SGunnar Mills } // namespace redfish
850