xref: /openbmc/bmcweb/features/redfish/lib/memory.hpp (revision 7fe6d5345a8db26b3382e73ceea44ddad407099d)
140e9b92eSEd Tanous // SPDX-License-Identifier: Apache-2.0
240e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright OpenBMC Authors
340e9b92eSEd 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"
9d7857201SEd Tanous #include "async_resp.hpp"
103ccb3adbSEd Tanous #include "dbus_utility.hpp"
11d7857201SEd Tanous #include "error_messages.hpp"
12539d8c6bSEd Tanous #include "generated/enums/memory.hpp"
13539d8c6bSEd Tanous #include "generated/enums/resource.hpp"
14d7857201SEd Tanous #include "http_request.hpp"
15d7857201SEd Tanous #include "logging.hpp"
163ccb3adbSEd Tanous #include "query.hpp"
173ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
183ccb3adbSEd Tanous #include "utils/collection.hpp"
193ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
203ccb3adbSEd Tanous #include "utils/hex_utils.hpp"
21ac6a4445SGunnar Mills 
22d7857201SEd Tanous #include <boost/beast/http/verb.hpp>
23e99073f5SGeorge Liu #include <boost/system/error_code.hpp>
24ef4c65b7SEd Tanous #include <boost/url/format.hpp>
25d7f04fd9SNan Zhou #include <nlohmann/json.hpp>
26d7857201SEd Tanous #include <sdbusplus/message/native_types.hpp>
27c1343bf6SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
28ac6a4445SGunnar Mills 
297a1dbc48SGeorge Liu #include <array>
30d7857201SEd Tanous #include <cstddef>
31d7857201SEd Tanous #include <cstdint>
32d7857201SEd Tanous #include <memory>
33d7857201SEd Tanous #include <string>
347a1dbc48SGeorge Liu #include <string_view>
35d7857201SEd Tanous #include <utility>
36d7857201SEd Tanous #include <vector>
377a1dbc48SGeorge Liu 
38ac6a4445SGunnar Mills namespace redfish
39ac6a4445SGunnar Mills {
40ac6a4445SGunnar Mills 
41313efb1cSGunnar Mills inline std::string translateMemoryTypeToRedfish(const std::string& memoryType)
42313efb1cSGunnar Mills {
43313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR")
44313efb1cSGunnar Mills     {
45313efb1cSGunnar Mills         return "DDR";
46313efb1cSGunnar Mills     }
47313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2")
48313efb1cSGunnar Mills     {
49313efb1cSGunnar Mills         return "DDR2";
50313efb1cSGunnar Mills     }
51313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR3")
52313efb1cSGunnar Mills     {
53313efb1cSGunnar Mills         return "DDR3";
54313efb1cSGunnar Mills     }
55313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4")
56313efb1cSGunnar Mills     {
57313efb1cSGunnar Mills         return "DDR4";
58313efb1cSGunnar Mills     }
59313efb1cSGunnar Mills     if (memoryType ==
60313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4E_SDRAM")
61313efb1cSGunnar Mills     {
62313efb1cSGunnar Mills         return "DDR4E_SDRAM";
63313efb1cSGunnar Mills     }
6411a2f0f0SMansi Joshi     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR5")
6511a2f0f0SMansi Joshi     {
6611a2f0f0SMansi Joshi         return "DDR5";
6711a2f0f0SMansi Joshi     }
68313efb1cSGunnar Mills     if (memoryType ==
69313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR4_SDRAM")
70313efb1cSGunnar Mills     {
71313efb1cSGunnar Mills         return "LPDDR4_SDRAM";
72313efb1cSGunnar Mills     }
73313efb1cSGunnar Mills     if (memoryType ==
74313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR3_SDRAM")
75313efb1cSGunnar Mills     {
76313efb1cSGunnar Mills         return "LPDDR3_SDRAM";
77313efb1cSGunnar Mills     }
78313efb1cSGunnar Mills     if (memoryType ==
79313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM")
80313efb1cSGunnar Mills     {
81313efb1cSGunnar Mills         return "DDR2_SDRAM_FB_DIMM";
82313efb1cSGunnar Mills     }
830fda0f12SGeorge Liu     if (memoryType ==
840fda0f12SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM_PROB")
85313efb1cSGunnar Mills     {
86313efb1cSGunnar Mills         return "DDR2_SDRAM_FB_DIMM_PROBE";
87313efb1cSGunnar Mills     }
88313efb1cSGunnar Mills     if (memoryType ==
89313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR_SGRAM")
90313efb1cSGunnar Mills     {
91313efb1cSGunnar Mills         return "DDR_SGRAM";
92313efb1cSGunnar Mills     }
93313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.ROM")
94313efb1cSGunnar Mills     {
95313efb1cSGunnar Mills         return "ROM";
96313efb1cSGunnar Mills     }
97313efb1cSGunnar Mills     if (memoryType ==
98313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.SDRAM")
99313efb1cSGunnar Mills     {
100313efb1cSGunnar Mills         return "SDRAM";
101313efb1cSGunnar Mills     }
102313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.EDO")
103313efb1cSGunnar Mills     {
104313efb1cSGunnar Mills         return "EDO";
105313efb1cSGunnar Mills     }
106313efb1cSGunnar Mills     if (memoryType ==
107313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.FastPageMode")
108313efb1cSGunnar Mills     {
109313efb1cSGunnar Mills         return "FastPageMode";
110313efb1cSGunnar Mills     }
111313efb1cSGunnar Mills     if (memoryType ==
112313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.PipelinedNibble")
113313efb1cSGunnar Mills     {
114313efb1cSGunnar Mills         return "PipelinedNibble";
115313efb1cSGunnar Mills     }
116313efb1cSGunnar Mills     if (memoryType ==
117313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.Logical")
118313efb1cSGunnar Mills     {
119313efb1cSGunnar Mills         return "Logical";
120313efb1cSGunnar Mills     }
121313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM")
122313efb1cSGunnar Mills     {
123313efb1cSGunnar Mills         return "HBM";
124313efb1cSGunnar Mills     }
125313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM2")
126313efb1cSGunnar Mills     {
127313efb1cSGunnar Mills         return "HBM2";
128313efb1cSGunnar Mills     }
129ce34d514STyson Tuckerbear     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM3")
130ce34d514STyson Tuckerbear     {
131ce34d514STyson Tuckerbear         return "HBM3";
132ce34d514STyson Tuckerbear     }
133313efb1cSGunnar Mills     // This is values like Other or Unknown
134313efb1cSGunnar Mills     // Also D-Bus values:
135313efb1cSGunnar Mills     // DRAM
136313efb1cSGunnar Mills     // EDRAM
137313efb1cSGunnar Mills     // VRAM
138313efb1cSGunnar Mills     // SRAM
139313efb1cSGunnar Mills     // RAM
140313efb1cSGunnar Mills     // FLASH
141313efb1cSGunnar Mills     // EEPROM
142313efb1cSGunnar Mills     // FEPROM
143313efb1cSGunnar Mills     // EPROM
144313efb1cSGunnar Mills     // CDRAM
145313efb1cSGunnar Mills     // ThreeDRAM
146313efb1cSGunnar Mills     // RDRAM
147313efb1cSGunnar Mills     // FBD2
148313efb1cSGunnar Mills     // LPDDR_SDRAM
149313efb1cSGunnar Mills     // LPDDR2_SDRAM
15011a2f0f0SMansi Joshi     // LPDDR5_SDRAM
151313efb1cSGunnar Mills     return "";
152313efb1cSGunnar Mills }
153313efb1cSGunnar Mills 
154ac106bf6SEd Tanous inline void dimmPropToHex(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
155c1343bf6SKrzysztof Grobelny                           const char* key, const uint16_t* value,
156d7f04fd9SNan Zhou                           const nlohmann::json::json_pointer& jsonPtr)
157ac6a4445SGunnar Mills {
158ac6a4445SGunnar Mills     if (value == nullptr)
159ac6a4445SGunnar Mills     {
160ac6a4445SGunnar Mills         return;
161ac6a4445SGunnar Mills     }
162ac106bf6SEd Tanous     asyncResp->res.jsonValue[jsonPtr][key] = "0x" + intToHexString(*value, 4);
163ac6a4445SGunnar Mills }
164ac6a4445SGunnar Mills 
1658d1b46d7Szhanghch05 inline void getPersistentMemoryProperties(
166ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
167c1343bf6SKrzysztof Grobelny     const dbus::utility::DBusPropertiesMap& properties,
168d7f04fd9SNan Zhou     const nlohmann::json::json_pointer& jsonPtr)
169ac6a4445SGunnar Mills {
170c1343bf6SKrzysztof Grobelny     const uint16_t* moduleManufacturerID = nullptr;
171c1343bf6SKrzysztof Grobelny     const uint16_t* moduleProductID = nullptr;
172c1343bf6SKrzysztof Grobelny     const uint16_t* subsystemVendorID = nullptr;
173c1343bf6SKrzysztof Grobelny     const uint16_t* subsystemDeviceID = nullptr;
174c1343bf6SKrzysztof Grobelny     const uint64_t* volatileRegionSizeLimitInKiB = nullptr;
175c1343bf6SKrzysztof Grobelny     const uint64_t* pmRegionSizeLimitInKiB = nullptr;
176c1343bf6SKrzysztof Grobelny     const uint64_t* volatileSizeInKiB = nullptr;
177c1343bf6SKrzysztof Grobelny     const uint64_t* pmSizeInKiB = nullptr;
178c1343bf6SKrzysztof Grobelny     const uint64_t* cacheSizeInKB = nullptr;
179c1343bf6SKrzysztof Grobelny     const uint64_t* voltaileRegionMaxSizeInKib = nullptr;
180c1343bf6SKrzysztof Grobelny     const uint64_t* pmRegionMaxSizeInKiB = nullptr;
181c1343bf6SKrzysztof Grobelny     const uint64_t* allocationIncrementInKiB = nullptr;
182c1343bf6SKrzysztof Grobelny     const uint64_t* allocationAlignmentInKiB = nullptr;
183c1343bf6SKrzysztof Grobelny     const uint64_t* volatileRegionNumberLimit = nullptr;
184c1343bf6SKrzysztof Grobelny     const uint64_t* pmRegionNumberLimit = nullptr;
185c1343bf6SKrzysztof Grobelny     const uint64_t* spareDeviceCount = nullptr;
186c1343bf6SKrzysztof Grobelny     const bool* isSpareDeviceInUse = nullptr;
187c1343bf6SKrzysztof Grobelny     const bool* isRankSpareEnabled = nullptr;
188c1343bf6SKrzysztof Grobelny     const std::vector<uint32_t>* maxAveragePowerLimitmW = nullptr;
189c1343bf6SKrzysztof Grobelny     const bool* configurationLocked = nullptr;
190c1343bf6SKrzysztof Grobelny     const std::string* allowedMemoryModes = nullptr;
191c1343bf6SKrzysztof Grobelny     const std::string* memoryMedia = nullptr;
192c1343bf6SKrzysztof Grobelny     const bool* configurationLockCapable = nullptr;
193c1343bf6SKrzysztof Grobelny     const bool* dataLockCapable = nullptr;
194c1343bf6SKrzysztof Grobelny     const bool* passphraseCapable = nullptr;
195c1343bf6SKrzysztof Grobelny     const uint64_t* maxPassphraseCount = nullptr;
196c1343bf6SKrzysztof Grobelny     const uint64_t* passphraseLockLimit = nullptr;
197c1343bf6SKrzysztof Grobelny 
198c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
199c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "ModuleManufacturerID",
200c1343bf6SKrzysztof Grobelny         moduleManufacturerID, "ModuleProductID", moduleProductID,
201c1343bf6SKrzysztof Grobelny         "SubsystemVendorID", subsystemVendorID, "SubsystemDeviceID",
202c1343bf6SKrzysztof Grobelny         subsystemDeviceID, "VolatileRegionSizeLimitInKiB",
203c1343bf6SKrzysztof Grobelny         volatileRegionSizeLimitInKiB, "PmRegionSizeLimitInKiB",
204c1343bf6SKrzysztof Grobelny         pmRegionSizeLimitInKiB, "VolatileSizeInKiB", volatileSizeInKiB,
205c1343bf6SKrzysztof Grobelny         "PmSizeInKiB", pmSizeInKiB, "CacheSizeInKB", cacheSizeInKB,
206c1343bf6SKrzysztof Grobelny         "VoltaileRegionMaxSizeInKib", voltaileRegionMaxSizeInKib,
207c1343bf6SKrzysztof Grobelny         "PmRegionMaxSizeInKiB", pmRegionMaxSizeInKiB,
208c1343bf6SKrzysztof Grobelny         "AllocationIncrementInKiB", allocationIncrementInKiB,
209c1343bf6SKrzysztof Grobelny         "AllocationAlignmentInKiB", allocationAlignmentInKiB,
210c1343bf6SKrzysztof Grobelny         "VolatileRegionNumberLimit", volatileRegionNumberLimit,
211c1343bf6SKrzysztof Grobelny         "PmRegionNumberLimit", pmRegionNumberLimit, "SpareDeviceCount",
212c1343bf6SKrzysztof Grobelny         spareDeviceCount, "IsSpareDeviceInUse", isSpareDeviceInUse,
213c1343bf6SKrzysztof Grobelny         "IsRankSpareEnabled", isRankSpareEnabled, "MaxAveragePowerLimitmW",
214c1343bf6SKrzysztof Grobelny         maxAveragePowerLimitmW, "ConfigurationLocked", configurationLocked,
215c1343bf6SKrzysztof Grobelny         "AllowedMemoryModes", allowedMemoryModes, "MemoryMedia", memoryMedia,
216c1343bf6SKrzysztof Grobelny         "ConfigurationLockCapable", configurationLockCapable, "DataLockCapable",
217c1343bf6SKrzysztof Grobelny         dataLockCapable, "PassphraseCapable", passphraseCapable,
218c1343bf6SKrzysztof Grobelny         "MaxPassphraseCount", maxPassphraseCount, "PassphraseLockLimit",
219c1343bf6SKrzysztof Grobelny         passphraseLockLimit);
220c1343bf6SKrzysztof Grobelny 
221c1343bf6SKrzysztof Grobelny     if (!success)
222ac6a4445SGunnar Mills     {
223ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
224c1343bf6SKrzysztof Grobelny         return;
225ac6a4445SGunnar Mills     }
226c1343bf6SKrzysztof Grobelny 
227ac106bf6SEd Tanous     dimmPropToHex(asyncResp, "ModuleManufacturerID", moduleManufacturerID,
228ac106bf6SEd Tanous                   jsonPtr);
229ac106bf6SEd Tanous     dimmPropToHex(asyncResp, "ModuleProductID", moduleProductID, jsonPtr);
230ac106bf6SEd Tanous     dimmPropToHex(asyncResp, "MemorySubsystemControllerManufacturerID",
231c1343bf6SKrzysztof Grobelny                   subsystemVendorID, jsonPtr);
232ac106bf6SEd Tanous     dimmPropToHex(asyncResp, "MemorySubsystemControllerProductID",
233c1343bf6SKrzysztof Grobelny                   subsystemDeviceID, jsonPtr);
234ac6a4445SGunnar Mills 
235c1343bf6SKrzysztof Grobelny     if (volatileRegionSizeLimitInKiB != nullptr)
236ac6a4445SGunnar Mills     {
237ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["VolatileRegionSizeLimitMiB"] =
238c1343bf6SKrzysztof Grobelny             (*volatileRegionSizeLimitInKiB) >> 10;
239ac6a4445SGunnar Mills     }
240ac6a4445SGunnar Mills 
241c1343bf6SKrzysztof Grobelny     if (pmRegionSizeLimitInKiB != nullptr)
242ac6a4445SGunnar Mills     {
243ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["PersistentRegionSizeLimitMiB"] =
244c1343bf6SKrzysztof Grobelny             (*pmRegionSizeLimitInKiB) >> 10;
245ac6a4445SGunnar Mills     }
246ac6a4445SGunnar Mills 
247c1343bf6SKrzysztof Grobelny     if (volatileSizeInKiB != nullptr)
248ac6a4445SGunnar Mills     {
249ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["VolatileSizeMiB"] =
250c1343bf6SKrzysztof Grobelny             (*volatileSizeInKiB) >> 10;
251ac6a4445SGunnar Mills     }
252c1343bf6SKrzysztof Grobelny 
253c1343bf6SKrzysztof Grobelny     if (pmSizeInKiB != nullptr)
254c1343bf6SKrzysztof Grobelny     {
255ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["NonVolatileSizeMiB"] =
256ac106bf6SEd Tanous             (*pmSizeInKiB) >> 10;
257c1343bf6SKrzysztof Grobelny     }
258c1343bf6SKrzysztof Grobelny 
259c1343bf6SKrzysztof Grobelny     if (cacheSizeInKB != nullptr)
260c1343bf6SKrzysztof Grobelny     {
261ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["CacheSizeMiB"] =
262ac106bf6SEd Tanous             (*cacheSizeInKB >> 10);
263c1343bf6SKrzysztof Grobelny     }
264c1343bf6SKrzysztof Grobelny 
265c1343bf6SKrzysztof Grobelny     if (voltaileRegionMaxSizeInKib != nullptr)
266c1343bf6SKrzysztof Grobelny     {
267ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["VolatileRegionSizeMaxMiB"] =
268c1343bf6SKrzysztof Grobelny             (*voltaileRegionMaxSizeInKib) >> 10;
269ac6a4445SGunnar Mills     }
270ac6a4445SGunnar Mills 
271c1343bf6SKrzysztof Grobelny     if (pmRegionMaxSizeInKiB != nullptr)
272ac6a4445SGunnar Mills     {
273ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["PersistentRegionSizeMaxMiB"] =
274c1343bf6SKrzysztof Grobelny             (*pmRegionMaxSizeInKiB) >> 10;
275ac6a4445SGunnar Mills     }
276ac6a4445SGunnar Mills 
277c1343bf6SKrzysztof Grobelny     if (allocationIncrementInKiB != nullptr)
278ac6a4445SGunnar Mills     {
279ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["AllocationIncrementMiB"] =
280c1343bf6SKrzysztof Grobelny             (*allocationIncrementInKiB) >> 10;
281ac6a4445SGunnar Mills     }
282ac6a4445SGunnar Mills 
283c1343bf6SKrzysztof Grobelny     if (allocationAlignmentInKiB != nullptr)
284ac6a4445SGunnar Mills     {
285ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["AllocationAlignmentMiB"] =
286c1343bf6SKrzysztof Grobelny             (*allocationAlignmentInKiB) >> 10;
287ac6a4445SGunnar Mills     }
288c1343bf6SKrzysztof Grobelny 
289c1343bf6SKrzysztof Grobelny     if (volatileRegionNumberLimit != nullptr)
290ac6a4445SGunnar Mills     {
291ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["VolatileRegionNumberLimit"] =
292c1343bf6SKrzysztof Grobelny             *volatileRegionNumberLimit;
293ac6a4445SGunnar Mills     }
294c1343bf6SKrzysztof Grobelny 
295c1343bf6SKrzysztof Grobelny     if (pmRegionNumberLimit != nullptr)
296ac6a4445SGunnar Mills     {
297ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["PersistentRegionNumberLimit"] =
298c1343bf6SKrzysztof Grobelny             *pmRegionNumberLimit;
299ac6a4445SGunnar Mills     }
300c1343bf6SKrzysztof Grobelny 
301c1343bf6SKrzysztof Grobelny     if (spareDeviceCount != nullptr)
302ac6a4445SGunnar Mills     {
303ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SpareDeviceCount"] =
304ac106bf6SEd Tanous             *spareDeviceCount;
305ac6a4445SGunnar Mills     }
306c1343bf6SKrzysztof Grobelny 
307c1343bf6SKrzysztof Grobelny     if (isSpareDeviceInUse != nullptr)
308ac6a4445SGunnar Mills     {
309ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["IsSpareDeviceEnabled"] =
310c1343bf6SKrzysztof Grobelny             *isSpareDeviceInUse;
311ac6a4445SGunnar Mills     }
312c1343bf6SKrzysztof Grobelny 
313c1343bf6SKrzysztof Grobelny     if (isRankSpareEnabled != nullptr)
314ac6a4445SGunnar Mills     {
315ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["IsRankSpareEnabled"] =
316c1343bf6SKrzysztof Grobelny             *isRankSpareEnabled;
317ac6a4445SGunnar Mills     }
318c1343bf6SKrzysztof Grobelny 
319c1343bf6SKrzysztof Grobelny     if (maxAveragePowerLimitmW != nullptr)
320ac6a4445SGunnar Mills     {
321ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MaxTDPMilliWatts"] =
322c1343bf6SKrzysztof Grobelny             *maxAveragePowerLimitmW;
323ac6a4445SGunnar Mills     }
324c1343bf6SKrzysztof Grobelny 
325c1343bf6SKrzysztof Grobelny     if (configurationLocked != nullptr)
326ac6a4445SGunnar Mills     {
327ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["ConfigurationLocked"] =
328c1343bf6SKrzysztof Grobelny             *configurationLocked;
329ac6a4445SGunnar Mills     }
330c1343bf6SKrzysztof Grobelny 
331c1343bf6SKrzysztof Grobelny     if (allowedMemoryModes != nullptr)
332ac6a4445SGunnar Mills     {
33380badf7cSJiaqing Zhao         constexpr const std::array<const char*, 3> values{"Volatile", "PMEM",
33480badf7cSJiaqing Zhao                                                           "Block"};
335ac6a4445SGunnar Mills 
336ac6a4445SGunnar Mills         for (const char* v : values)
337ac6a4445SGunnar Mills         {
338c1343bf6SKrzysztof Grobelny             if (allowedMemoryModes->ends_with(v))
339ac6a4445SGunnar Mills             {
340ac106bf6SEd Tanous                 asyncResp->res.jsonValue[jsonPtr]["OperatingMemoryModes"]
341ac106bf6SEd Tanous                     .push_back(v);
342ac6a4445SGunnar Mills                 break;
343ac6a4445SGunnar Mills             }
344ac6a4445SGunnar Mills         }
345ac6a4445SGunnar Mills     }
346c1343bf6SKrzysztof Grobelny 
347c1343bf6SKrzysztof Grobelny     if (memoryMedia != nullptr)
348ac6a4445SGunnar Mills     {
349ac6a4445SGunnar Mills         constexpr const std::array<const char*, 3> values{"DRAM", "NAND",
350ac6a4445SGunnar Mills                                                           "Intel3DXPoint"};
351ac6a4445SGunnar Mills 
352ac6a4445SGunnar Mills         for (const char* v : values)
353ac6a4445SGunnar Mills         {
354c1343bf6SKrzysztof Grobelny             if (memoryMedia->ends_with(v))
355ac6a4445SGunnar Mills             {
356ac106bf6SEd Tanous                 asyncResp->res.jsonValue[jsonPtr]["MemoryMedia"].push_back(v);
357ac6a4445SGunnar Mills                 break;
358ac6a4445SGunnar Mills             }
359ac6a4445SGunnar Mills         }
360ac6a4445SGunnar Mills     }
361c1343bf6SKrzysztof Grobelny 
362c1343bf6SKrzysztof Grobelny     if (configurationLockCapable != nullptr)
363ac6a4445SGunnar Mills     {
364ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
365c1343bf6SKrzysztof Grobelny                                 ["ConfigurationLockCapable"] =
366c1343bf6SKrzysztof Grobelny             *configurationLockCapable;
367ac6a4445SGunnar Mills     }
368c1343bf6SKrzysztof Grobelny 
369c1343bf6SKrzysztof Grobelny     if (dataLockCapable != nullptr)
370ac6a4445SGunnar Mills     {
371bd79bce8SPatrick Williams         asyncResp->res
372bd79bce8SPatrick Williams             .jsonValue[jsonPtr]["SecurityCapabilities"]["DataLockCapable"] =
373bd79bce8SPatrick Williams             *dataLockCapable;
374ac6a4445SGunnar Mills     }
375c1343bf6SKrzysztof Grobelny 
376c1343bf6SKrzysztof Grobelny     if (passphraseCapable != nullptr)
377c1343bf6SKrzysztof Grobelny     {
378bd79bce8SPatrick Williams         asyncResp->res
379bd79bce8SPatrick Williams             .jsonValue[jsonPtr]["SecurityCapabilities"]["PassphraseCapable"] =
380bd79bce8SPatrick Williams             *passphraseCapable;
381c1343bf6SKrzysztof Grobelny     }
382c1343bf6SKrzysztof Grobelny 
383c1343bf6SKrzysztof Grobelny     if (maxPassphraseCount != nullptr)
384c1343bf6SKrzysztof Grobelny     {
385bd79bce8SPatrick Williams         asyncResp->res
386bd79bce8SPatrick Williams             .jsonValue[jsonPtr]["SecurityCapabilities"]["MaxPassphraseCount"] =
387bd79bce8SPatrick Williams             *maxPassphraseCount;
388c1343bf6SKrzysztof Grobelny     }
389c1343bf6SKrzysztof Grobelny 
390c1343bf6SKrzysztof Grobelny     if (passphraseLockLimit != nullptr)
391c1343bf6SKrzysztof Grobelny     {
392bd79bce8SPatrick Williams         asyncResp->res
393bd79bce8SPatrick Williams             .jsonValue[jsonPtr]["SecurityCapabilities"]["PassphraseLockLimit"] =
394bd79bce8SPatrick Williams             *passphraseLockLimit;
395ac6a4445SGunnar Mills     }
396ac6a4445SGunnar Mills }
397ac6a4445SGunnar Mills 
398bd79bce8SPatrick Williams inline void assembleDimmProperties(
399bd79bce8SPatrick Williams     std::string_view dimmId,
400ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
401d7f04fd9SNan Zhou     const dbus::utility::DBusPropertiesMap& properties,
402d7f04fd9SNan Zhou     const nlohmann::json::json_pointer& jsonPtr)
403ac6a4445SGunnar Mills {
404ac106bf6SEd Tanous     asyncResp->res.jsonValue[jsonPtr]["Id"] = dimmId;
405ac106bf6SEd Tanous     asyncResp->res.jsonValue[jsonPtr]["Name"] = "DIMM Slot";
406539d8c6bSEd Tanous     asyncResp->res.jsonValue[jsonPtr]["Status"]["State"] =
407539d8c6bSEd Tanous         resource::State::Enabled;
408539d8c6bSEd Tanous     asyncResp->res.jsonValue[jsonPtr]["Status"]["Health"] =
409539d8c6bSEd Tanous         resource::Health::OK;
410ac6a4445SGunnar Mills 
411c1343bf6SKrzysztof Grobelny     const uint16_t* memoryDataWidth = nullptr;
412c1343bf6SKrzysztof Grobelny     const size_t* memorySizeInKB = nullptr;
413c1343bf6SKrzysztof Grobelny     const std::string* partNumber = nullptr;
414c1343bf6SKrzysztof Grobelny     const std::string* serialNumber = nullptr;
415c1343bf6SKrzysztof Grobelny     const std::string* manufacturer = nullptr;
416c1343bf6SKrzysztof Grobelny     const uint16_t* revisionCode = nullptr;
417c1343bf6SKrzysztof Grobelny     const bool* present = nullptr;
418c1343bf6SKrzysztof Grobelny     const uint16_t* memoryTotalWidth = nullptr;
419c1343bf6SKrzysztof Grobelny     const std::string* ecc = nullptr;
420c1343bf6SKrzysztof Grobelny     const std::string* formFactor = nullptr;
421c1343bf6SKrzysztof Grobelny     const std::vector<uint16_t>* allowedSpeedsMT = nullptr;
4226995c1ceSGeorge Liu     const size_t* memoryAttributes = nullptr;
423c1343bf6SKrzysztof Grobelny     const uint16_t* memoryConfiguredSpeedInMhz = nullptr;
424c1343bf6SKrzysztof Grobelny     const std::string* memoryType = nullptr;
4256fde5971SJayaprakash Mutyala     const std::uint8_t* channel = nullptr;
4266fde5971SJayaprakash Mutyala     const std::uint8_t* memoryController = nullptr;
4276fde5971SJayaprakash Mutyala     const std::uint8_t* slot = nullptr;
4286fde5971SJayaprakash Mutyala     const std::uint8_t* socket = nullptr;
429c1343bf6SKrzysztof Grobelny     const std::string* sparePartNumber = nullptr;
430c1343bf6SKrzysztof Grobelny     const std::string* model = nullptr;
431c1343bf6SKrzysztof Grobelny     const std::string* locationCode = nullptr;
432*7fe6d534SGeorge Liu     const bool* functional = nullptr;
433ac6a4445SGunnar Mills 
434c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
435c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "MemoryDataWidth",
436c1343bf6SKrzysztof Grobelny         memoryDataWidth, "MemorySizeInKB", memorySizeInKB, "PartNumber",
437656472d9SNikhil Namjoshi         partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
438656472d9SNikhil Namjoshi         "RevisionCode", revisionCode, "Present", present, "MemoryTotalWidth",
439656472d9SNikhil Namjoshi         memoryTotalWidth, "ECC", ecc, "FormFactor", formFactor,
440656472d9SNikhil Namjoshi         "AllowedSpeedsMT", allowedSpeedsMT, "MemoryAttributes",
441c1343bf6SKrzysztof Grobelny         memoryAttributes, "MemoryConfiguredSpeedInMhz",
442c1343bf6SKrzysztof Grobelny         memoryConfiguredSpeedInMhz, "MemoryType", memoryType, "Channel",
443c1343bf6SKrzysztof Grobelny         channel, "MemoryController", memoryController, "Slot", slot, "Socket",
444c1343bf6SKrzysztof Grobelny         socket, "SparePartNumber", sparePartNumber, "Model", model,
445*7fe6d534SGeorge Liu         "LocationCode", locationCode, "Functional", functional);
446c1343bf6SKrzysztof Grobelny 
447c1343bf6SKrzysztof Grobelny     if (!success)
448ac6a4445SGunnar Mills     {
449ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
450601af5edSChicago Duan         return;
451ac6a4445SGunnar Mills     }
452c1343bf6SKrzysztof Grobelny 
453c1343bf6SKrzysztof Grobelny     if (memoryDataWidth != nullptr)
454c1343bf6SKrzysztof Grobelny     {
455ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["DataWidthBits"] = *memoryDataWidth;
456c1343bf6SKrzysztof Grobelny     }
457c1343bf6SKrzysztof Grobelny 
458c1343bf6SKrzysztof Grobelny     if (memorySizeInKB != nullptr)
459c1343bf6SKrzysztof Grobelny     {
460ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["CapacityMiB"] =
461ac106bf6SEd Tanous             (*memorySizeInKB >> 10);
462c1343bf6SKrzysztof Grobelny     }
463c1343bf6SKrzysztof Grobelny 
464c1343bf6SKrzysztof Grobelny     if (partNumber != nullptr)
465c1343bf6SKrzysztof Grobelny     {
466ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["PartNumber"] = *partNumber;
467c1343bf6SKrzysztof Grobelny     }
468c1343bf6SKrzysztof Grobelny 
469c1343bf6SKrzysztof Grobelny     if (serialNumber != nullptr)
470c1343bf6SKrzysztof Grobelny     {
471ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SerialNumber"] = *serialNumber;
472c1343bf6SKrzysztof Grobelny     }
473c1343bf6SKrzysztof Grobelny 
474c1343bf6SKrzysztof Grobelny     if (manufacturer != nullptr)
475c1343bf6SKrzysztof Grobelny     {
476ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["Manufacturer"] = *manufacturer;
477c1343bf6SKrzysztof Grobelny     }
478c1343bf6SKrzysztof Grobelny 
479c1343bf6SKrzysztof Grobelny     if (revisionCode != nullptr)
480c1343bf6SKrzysztof Grobelny     {
481ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["FirmwareRevision"] =
482c1343bf6SKrzysztof Grobelny             std::to_string(*revisionCode);
483ac6a4445SGunnar Mills     }
484c1343bf6SKrzysztof Grobelny 
485c1343bf6SKrzysztof Grobelny     if (present != nullptr && !*present)
4869a128eb3SJoshi-Mansi     {
487539d8c6bSEd Tanous         asyncResp->res.jsonValue[jsonPtr]["Status"]["State"] =
488539d8c6bSEd Tanous             resource::State::Absent;
4899a128eb3SJoshi-Mansi     }
490c1343bf6SKrzysztof Grobelny 
491*7fe6d534SGeorge Liu     if (functional != nullptr)
492*7fe6d534SGeorge Liu     {
493*7fe6d534SGeorge Liu         if (!*functional)
494*7fe6d534SGeorge Liu         {
495*7fe6d534SGeorge Liu             asyncResp->res.jsonValue[jsonPtr]["Status"]["Health"] =
496*7fe6d534SGeorge Liu                 resource::Health::Critical;
497*7fe6d534SGeorge Liu         }
498*7fe6d534SGeorge Liu     }
499*7fe6d534SGeorge Liu 
500c1343bf6SKrzysztof Grobelny     if (memoryTotalWidth != nullptr)
501ac6a4445SGunnar Mills     {
502ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["BusWidthBits"] = *memoryTotalWidth;
503ac6a4445SGunnar Mills     }
504c1343bf6SKrzysztof Grobelny 
505c1343bf6SKrzysztof Grobelny     if (ecc != nullptr)
506ac6a4445SGunnar Mills     {
507ac6a4445SGunnar Mills         constexpr const std::array<const char*, 4> values{
5089a5aceacSNan Zhou             "NoECC", "SingleBitECC", "MultiBitECC", "AddressParity"};
509ac6a4445SGunnar Mills 
510ac6a4445SGunnar Mills         for (const char* v : values)
511ac6a4445SGunnar Mills         {
512c1343bf6SKrzysztof Grobelny             if (ecc->ends_with(v))
513ac6a4445SGunnar Mills             {
514ac106bf6SEd Tanous                 asyncResp->res.jsonValue[jsonPtr]["ErrorCorrection"] = v;
515ac6a4445SGunnar Mills                 break;
516ac6a4445SGunnar Mills             }
517ac6a4445SGunnar Mills         }
518ac6a4445SGunnar Mills     }
519c1343bf6SKrzysztof Grobelny 
520c1343bf6SKrzysztof Grobelny     if (formFactor != nullptr)
521ac6a4445SGunnar Mills     {
522ac6a4445SGunnar Mills         constexpr const std::array<const char*, 11> values{
5239a5aceacSNan Zhou             "RDIMM",       "UDIMM",       "SO_DIMM",      "LRDIMM",
5249a5aceacSNan Zhou             "Mini_RDIMM",  "Mini_UDIMM",  "SO_RDIMM_72b", "SO_UDIMM_72b",
5259a5aceacSNan Zhou             "SO_DIMM_16b", "SO_DIMM_32b", "Die"};
526ac6a4445SGunnar Mills 
527ac6a4445SGunnar Mills         for (const char* v : values)
528ac6a4445SGunnar Mills         {
529c1343bf6SKrzysztof Grobelny             if (formFactor->ends_with(v))
530ac6a4445SGunnar Mills             {
531ac106bf6SEd Tanous                 asyncResp->res.jsonValue[jsonPtr]["BaseModuleType"] = v;
532ac6a4445SGunnar Mills                 break;
533ac6a4445SGunnar Mills             }
534ac6a4445SGunnar Mills         }
535ac6a4445SGunnar Mills     }
536c1343bf6SKrzysztof Grobelny 
537c1343bf6SKrzysztof Grobelny     if (allowedSpeedsMT != nullptr)
538ac6a4445SGunnar Mills     {
539d7f04fd9SNan Zhou         nlohmann::json& jValue =
540ac106bf6SEd Tanous             asyncResp->res.jsonValue[jsonPtr]["AllowedSpeedsMHz"];
541ac6a4445SGunnar Mills         jValue = nlohmann::json::array();
542c1343bf6SKrzysztof Grobelny         for (uint16_t subVal : *allowedSpeedsMT)
543ac6a4445SGunnar Mills         {
544ac6a4445SGunnar Mills             jValue.push_back(subVal);
545ac6a4445SGunnar Mills         }
546ac6a4445SGunnar Mills     }
547ac6a4445SGunnar Mills 
548c1343bf6SKrzysztof Grobelny     if (memoryAttributes != nullptr)
549ac6a4445SGunnar Mills     {
5506995c1ceSGeorge Liu         asyncResp->res.jsonValue[jsonPtr]["RankCount"] = *memoryAttributes;
551ac6a4445SGunnar Mills     }
552c1343bf6SKrzysztof Grobelny 
553c1343bf6SKrzysztof Grobelny     if (memoryConfiguredSpeedInMhz != nullptr)
554ac6a4445SGunnar Mills     {
555ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["OperatingSpeedMhz"] =
556c1343bf6SKrzysztof Grobelny             *memoryConfiguredSpeedInMhz;
557ac6a4445SGunnar Mills     }
558c1343bf6SKrzysztof Grobelny 
559c1343bf6SKrzysztof Grobelny     if (memoryType != nullptr)
560ac6a4445SGunnar Mills     {
561313efb1cSGunnar Mills         std::string memoryDeviceType =
562c1343bf6SKrzysztof Grobelny             translateMemoryTypeToRedfish(*memoryType);
563313efb1cSGunnar Mills         // Values like "Unknown" or "Other" will return empty
564313efb1cSGunnar Mills         // so just leave off
565313efb1cSGunnar Mills         if (!memoryDeviceType.empty())
566ac6a4445SGunnar Mills         {
567ac106bf6SEd Tanous             asyncResp->res.jsonValue[jsonPtr]["MemoryDeviceType"] =
568d7f04fd9SNan Zhou                 memoryDeviceType;
569ac6a4445SGunnar Mills         }
570c1343bf6SKrzysztof Grobelny         if (memoryType->find("DDR") != std::string::npos)
571ac6a4445SGunnar Mills         {
572539d8c6bSEd Tanous             asyncResp->res.jsonValue[jsonPtr]["MemoryType"] =
573539d8c6bSEd Tanous                 memory::MemoryType::DRAM;
574ac6a4445SGunnar Mills         }
575c1343bf6SKrzysztof Grobelny         else if (memoryType->ends_with("Logical"))
576ac6a4445SGunnar Mills         {
577539d8c6bSEd Tanous             asyncResp->res.jsonValue[jsonPtr]["MemoryType"] =
578539d8c6bSEd Tanous                 memory::MemoryType::IntelOptane;
579ac6a4445SGunnar Mills         }
580ac6a4445SGunnar Mills     }
581c1343bf6SKrzysztof Grobelny 
582c1343bf6SKrzysztof Grobelny     if (channel != nullptr)
583ac6a4445SGunnar Mills     {
584ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Channel"] =
585ac106bf6SEd Tanous             *channel;
586c1343bf6SKrzysztof Grobelny     }
587c1343bf6SKrzysztof Grobelny 
588c1343bf6SKrzysztof Grobelny     if (memoryController != nullptr)
589ac6a4445SGunnar Mills     {
590bd79bce8SPatrick Williams         asyncResp->res
591bd79bce8SPatrick Williams             .jsonValue[jsonPtr]["MemoryLocation"]["MemoryController"] =
592bd79bce8SPatrick Williams             *memoryController;
593ac6a4445SGunnar Mills     }
594c1343bf6SKrzysztof Grobelny 
595c1343bf6SKrzysztof Grobelny     if (slot != nullptr)
596ee135e24SSunnySrivastava1984     {
597ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Slot"] = *slot;
598c1343bf6SKrzysztof Grobelny     }
599c1343bf6SKrzysztof Grobelny 
600c1343bf6SKrzysztof Grobelny     if (socket != nullptr)
601ee135e24SSunnySrivastava1984     {
602ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Socket"] = *socket;
603ee135e24SSunnySrivastava1984     }
604c1343bf6SKrzysztof Grobelny 
605c1343bf6SKrzysztof Grobelny     if (sparePartNumber != nullptr)
606ee135e24SSunnySrivastava1984     {
607ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SparePartNumber"] = *sparePartNumber;
608c1343bf6SKrzysztof Grobelny     }
609c1343bf6SKrzysztof Grobelny 
610c1343bf6SKrzysztof Grobelny     if (model != nullptr)
611ee135e24SSunnySrivastava1984     {
612ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["Model"] = *model;
613ee135e24SSunnySrivastava1984     }
614c1343bf6SKrzysztof Grobelny 
615c1343bf6SKrzysztof Grobelny     if (locationCode != nullptr)
616ee135e24SSunnySrivastava1984     {
617bd79bce8SPatrick Williams         asyncResp->res
618bd79bce8SPatrick Williams             .jsonValue[jsonPtr]["Location"]["PartLocation"]["ServiceLabel"] =
619bd79bce8SPatrick Williams             *locationCode;
620ee135e24SSunnySrivastava1984     }
621c1343bf6SKrzysztof Grobelny 
622ac106bf6SEd Tanous     getPersistentMemoryProperties(asyncResp, properties, jsonPtr);
6239a5aceacSNan Zhou }
6249a5aceacSNan Zhou 
625bd79bce8SPatrick Williams inline void getDimmDataByService(
626bd79bce8SPatrick Williams     std::shared_ptr<bmcweb::AsyncResp> asyncResp, const std::string& dimmId,
627bd79bce8SPatrick Williams     const std::string& service, const std::string& objPath)
6289a5aceacSNan Zhou {
62962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get available system components.");
630deae6a78SEd Tanous     dbus::utility::getAllProperties(
631deae6a78SEd Tanous         service, objPath, "",
632ac106bf6SEd Tanous         [dimmId, asyncResp{std::move(asyncResp)}](
6335e7e2dc5SEd Tanous             const boost::system::error_code& ec,
6349a5aceacSNan Zhou             const dbus::utility::DBusPropertiesMap& properties) {
6359a5aceacSNan Zhou             if (ec)
6369a5aceacSNan Zhou             {
63762598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error");
638ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
6399a5aceacSNan Zhou                 return;
6409a5aceacSNan Zhou             }
641bd79bce8SPatrick Williams             assembleDimmProperties(dimmId, asyncResp, properties,
642bd79bce8SPatrick Williams                                    ""_json_pointer);
643c1343bf6SKrzysztof Grobelny         });
644ac6a4445SGunnar Mills }
645ac6a4445SGunnar Mills 
646ef00d7d4SNan Zhou inline void assembleDimmPartitionData(
647ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
648d7f04fd9SNan Zhou     const dbus::utility::DBusPropertiesMap& properties,
649d7f04fd9SNan Zhou     const nlohmann::json::json_pointer& regionPtr)
650ac6a4445SGunnar Mills {
651c1343bf6SKrzysztof Grobelny     const std::string* memoryClassification = nullptr;
652c1343bf6SKrzysztof Grobelny     const uint64_t* offsetInKiB = nullptr;
653c1343bf6SKrzysztof Grobelny     const std::string* partitionId = nullptr;
654c1343bf6SKrzysztof Grobelny     const bool* passphraseState = nullptr;
655c1343bf6SKrzysztof Grobelny     const uint64_t* sizeInKiB = nullptr;
656c1343bf6SKrzysztof Grobelny 
657c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
658c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "MemoryClassification",
659c1343bf6SKrzysztof Grobelny         memoryClassification, "OffsetInKiB", offsetInKiB, "PartitionId",
660c1343bf6SKrzysztof Grobelny         partitionId, "PassphraseState", passphraseState, "SizeInKiB",
661c1343bf6SKrzysztof Grobelny         sizeInKiB);
662c1343bf6SKrzysztof Grobelny 
663c1343bf6SKrzysztof Grobelny     if (!success)
664c1343bf6SKrzysztof Grobelny     {
665ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
666c1343bf6SKrzysztof Grobelny         return;
667c1343bf6SKrzysztof Grobelny     }
668c1343bf6SKrzysztof Grobelny 
669d7f04fd9SNan Zhou     nlohmann::json::object_t partition;
670c1343bf6SKrzysztof Grobelny 
671c1343bf6SKrzysztof Grobelny     if (memoryClassification != nullptr)
672ac6a4445SGunnar Mills     {
673c1343bf6SKrzysztof Grobelny         partition["MemoryClassification"] = *memoryClassification;
674ac6a4445SGunnar Mills     }
675ac6a4445SGunnar Mills 
676c1343bf6SKrzysztof Grobelny     if (offsetInKiB != nullptr)
677ac6a4445SGunnar Mills     {
678c1343bf6SKrzysztof Grobelny         partition["OffsetMiB"] = (*offsetInKiB >> 10);
679ac6a4445SGunnar Mills     }
680ac6a4445SGunnar Mills 
681c1343bf6SKrzysztof Grobelny     if (partitionId != nullptr)
682ac6a4445SGunnar Mills     {
683c1343bf6SKrzysztof Grobelny         partition["RegionId"] = *partitionId;
684c1343bf6SKrzysztof Grobelny     }
685c1343bf6SKrzysztof Grobelny 
686c1343bf6SKrzysztof Grobelny     if (passphraseState != nullptr)
687ac6a4445SGunnar Mills     {
688c1343bf6SKrzysztof Grobelny         partition["PassphraseEnabled"] = *passphraseState;
689ac6a4445SGunnar Mills     }
690c1343bf6SKrzysztof Grobelny 
691c1343bf6SKrzysztof Grobelny     if (sizeInKiB != nullptr)
692ac6a4445SGunnar Mills     {
693c1343bf6SKrzysztof Grobelny         partition["SizeMiB"] = (*sizeInKiB >> 10);
694ac6a4445SGunnar Mills     }
695c1343bf6SKrzysztof Grobelny 
696ac106bf6SEd Tanous     asyncResp->res.jsonValue[regionPtr].emplace_back(std::move(partition));
697ef00d7d4SNan Zhou }
698ef00d7d4SNan Zhou 
699ac106bf6SEd Tanous inline void getDimmPartitionData(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
700ef00d7d4SNan Zhou                                  const std::string& service,
701ef00d7d4SNan Zhou                                  const std::string& path)
702ef00d7d4SNan Zhou {
703deae6a78SEd Tanous     dbus::utility::getAllProperties(
704deae6a78SEd Tanous         service, path,
705c1343bf6SKrzysztof Grobelny         "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition",
706ac106bf6SEd Tanous         [asyncResp{std::move(asyncResp)}](
7075e7e2dc5SEd Tanous             const boost::system::error_code& ec,
708ef00d7d4SNan Zhou             const dbus::utility::DBusPropertiesMap& properties) {
709ef00d7d4SNan Zhou             if (ec)
710ef00d7d4SNan Zhou             {
71162598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error");
712ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
713ef00d7d4SNan Zhou 
714ef00d7d4SNan Zhou                 return;
715ef00d7d4SNan Zhou             }
716d7f04fd9SNan Zhou             nlohmann::json::json_pointer regionPtr = "/Regions"_json_pointer;
717ac106bf6SEd Tanous             assembleDimmPartitionData(asyncResp, properties, regionPtr);
718c1343bf6SKrzysztof Grobelny         }
719ac6a4445SGunnar Mills 
720c1343bf6SKrzysztof Grobelny     );
721ac6a4445SGunnar Mills }
722ac6a4445SGunnar Mills 
723ac106bf6SEd Tanous inline void getDimmData(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
724ac6a4445SGunnar Mills                         const std::string& dimmId)
725ac6a4445SGunnar Mills {
72662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get available system dimm resources.");
727e99073f5SGeorge Liu     constexpr std::array<std::string_view, 2> dimmInterfaces = {
728e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Dimm",
729e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"};
730e99073f5SGeorge Liu     dbus::utility::getSubTree(
731e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, dimmInterfaces,
732ac106bf6SEd Tanous         [dimmId, asyncResp{std::move(asyncResp)}](
733e99073f5SGeorge Liu             const boost::system::error_code& ec,
734b9d36b47SEd Tanous             const dbus::utility::MapperGetSubTreeResponse& subtree) {
735ac6a4445SGunnar Mills             if (ec)
736ac6a4445SGunnar Mills             {
73762598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error");
738ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
739ac6a4445SGunnar Mills 
740ac6a4445SGunnar Mills                 return;
741ac6a4445SGunnar Mills             }
742ac6a4445SGunnar Mills             bool found = false;
74376686dccSNan Zhou             for (const auto& [rawPath, object] : subtree)
744ac6a4445SGunnar Mills             {
74576686dccSNan Zhou                 sdbusplus::message::object_path path(rawPath);
746ac6a4445SGunnar Mills                 for (const auto& [service, interfaces] : object)
747ac6a4445SGunnar Mills                 {
748b9d36b47SEd Tanous                     for (const auto& interface : interfaces)
749ac6a4445SGunnar Mills                     {
750b9d36b47SEd Tanous                         if (interface ==
75176686dccSNan Zhou                                 "xyz.openbmc_project.Inventory.Item.Dimm" &&
75276686dccSNan Zhou                             path.filename() == dimmId)
753b9d36b47SEd Tanous                         {
754ac106bf6SEd Tanous                             getDimmDataByService(asyncResp, dimmId, service,
755ac106bf6SEd Tanous                                                  rawPath);
756ac6a4445SGunnar Mills                             found = true;
757ac6a4445SGunnar Mills                         }
758ac6a4445SGunnar Mills 
759b9d36b47SEd Tanous                         // partitions are separate as there can be multiple
760b9d36b47SEd Tanous                         // per
761ac6a4445SGunnar Mills                         // device, i.e.
762ac6a4445SGunnar Mills                         // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1
763ac6a4445SGunnar Mills                         // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2
764b9d36b47SEd Tanous                         if (interface ==
76576686dccSNan Zhou                                 "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition" &&
76676686dccSNan Zhou                             path.parent_path().filename() == dimmId)
767ac6a4445SGunnar Mills                         {
768ac106bf6SEd Tanous                             getDimmPartitionData(asyncResp, service, rawPath);
769ac6a4445SGunnar Mills                         }
770ac6a4445SGunnar Mills                     }
771ac6a4445SGunnar Mills                 }
772b9d36b47SEd Tanous             }
773ac6a4445SGunnar Mills             // Object not found
774ac6a4445SGunnar Mills             if (!found)
775ac6a4445SGunnar Mills             {
776ac106bf6SEd Tanous                 messages::resourceNotFound(asyncResp->res, "Memory", dimmId);
7771a1d5d6dSNan Zhou                 return;
778ac6a4445SGunnar Mills             }
7791a1d5d6dSNan Zhou             // Set @odata only if object is found
780ac106bf6SEd Tanous             asyncResp->res.jsonValue["@odata.type"] = "#Memory.v1_11_0.Memory";
781ac106bf6SEd Tanous             asyncResp->res.jsonValue["@odata.id"] =
782253f11b8SEd Tanous                 boost::urls::format("/redfish/v1/Systems/{}/Memory/{}",
783253f11b8SEd Tanous                                     BMCWEB_REDFISH_SYSTEM_URI_NAME, dimmId);
784ac6a4445SGunnar Mills             return;
785e99073f5SGeorge Liu         });
786ac6a4445SGunnar Mills }
787ac6a4445SGunnar Mills 
7887e860f15SJohn Edward Broadbent inline void requestRoutesMemoryCollection(App& app)
789ac6a4445SGunnar Mills {
790ac6a4445SGunnar Mills     /**
791ac6a4445SGunnar Mills      * Functions triggers appropriate requests on DBus
792ac6a4445SGunnar Mills      */
79322d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/")
794ed398213SEd Tanous         .privileges(redfish::privileges::getMemoryCollection)
7957e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
79645ca1b86SEd Tanous             [&app](const crow::Request& req,
79722d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
79822d268cbSEd Tanous                    const std::string& systemName) {
7993ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
80045ca1b86SEd Tanous                 {
80145ca1b86SEd Tanous                     return;
80245ca1b86SEd Tanous                 }
80325b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
8047f3e84a1SEd Tanous                 {
8057f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
8067f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
8077f3e84a1SEd Tanous                                                systemName);
8087f3e84a1SEd Tanous                     return;
8097f3e84a1SEd Tanous                 }
810253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
81122d268cbSEd Tanous                 {
81222d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
81322d268cbSEd Tanous                                                systemName);
81422d268cbSEd Tanous                     return;
81522d268cbSEd Tanous                 }
81622d268cbSEd Tanous 
8178d1b46d7Szhanghch05                 asyncResp->res.jsonValue["@odata.type"] =
8188d1b46d7Szhanghch05                     "#MemoryCollection.MemoryCollection";
8198d1b46d7Szhanghch05                 asyncResp->res.jsonValue["Name"] = "Memory Module Collection";
820bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["@odata.id"] =
821bd79bce8SPatrick Williams                     boost::urls::format("/redfish/v1/Systems/{}/Memory",
822bd79bce8SPatrick Williams                                         BMCWEB_REDFISH_SYSTEM_URI_NAME);
823ac6a4445SGunnar Mills 
8247a1dbc48SGeorge Liu                 constexpr std::array<std::string_view, 1> interfaces{
8257a1dbc48SGeorge Liu                     "xyz.openbmc_project.Inventory.Item.Dimm"};
82605030b8eSGunnar Mills                 collection_util::getCollectionMembers(
827253f11b8SEd Tanous                     asyncResp,
828253f11b8SEd Tanous                     boost::urls::format("/redfish/v1/Systems/{}/Memory",
829253f11b8SEd Tanous                                         BMCWEB_REDFISH_SYSTEM_URI_NAME),
83036b5f1edSLakshmi Yadlapati                     interfaces, "/xyz/openbmc_project/inventory");
8317e860f15SJohn Edward Broadbent             });
832ac6a4445SGunnar Mills }
833ac6a4445SGunnar Mills 
8347e860f15SJohn Edward Broadbent inline void requestRoutesMemory(App& app)
8357e860f15SJohn Edward Broadbent {
836ac6a4445SGunnar Mills     /**
837ac6a4445SGunnar Mills      * Functions triggers appropriate requests on DBus
838ac6a4445SGunnar Mills      */
83922d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/<str>/")
840ed398213SEd Tanous         .privileges(redfish::privileges::getMemory)
8417e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
84245ca1b86SEd Tanous             [&app](const crow::Request& req,
8437e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
84422d268cbSEd Tanous                    const std::string& systemName, const std::string& dimmId) {
8453ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
84645ca1b86SEd Tanous                 {
84745ca1b86SEd Tanous                     return;
84845ca1b86SEd Tanous                 }
8497f3e84a1SEd Tanous 
85025b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
8517f3e84a1SEd Tanous                 {
8527f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
8537f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
8547f3e84a1SEd Tanous                                                systemName);
8557f3e84a1SEd Tanous                     return;
8567f3e84a1SEd Tanous                 }
8577f3e84a1SEd Tanous 
858253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
85922d268cbSEd Tanous                 {
86022d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
86122d268cbSEd Tanous                                                systemName);
86222d268cbSEd Tanous                     return;
86322d268cbSEd Tanous                 }
86422d268cbSEd Tanous 
865ac6a4445SGunnar Mills                 getDimmData(asyncResp, dimmId);
8667e860f15SJohn Edward Broadbent             });
867ac6a4445SGunnar Mills }
868ac6a4445SGunnar Mills 
869ac6a4445SGunnar Mills } // namespace redfish
870