xref: /openbmc/bmcweb/features/redfish/lib/memory.hpp (revision d78572018fc2022091ff8b8eb5a7fef2172ba3d6)
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"
9*d7857201SEd Tanous #include "async_resp.hpp"
103ccb3adbSEd Tanous #include "dbus_utility.hpp"
11*d7857201SEd Tanous #include "error_messages.hpp"
12539d8c6bSEd Tanous #include "generated/enums/memory.hpp"
13539d8c6bSEd Tanous #include "generated/enums/resource.hpp"
14*d7857201SEd Tanous #include "http_request.hpp"
15*d7857201SEd 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 
22*d7857201SEd 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>
26*d7857201SEd Tanous #include <sdbusplus/message/native_types.hpp>
27c1343bf6SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
28ac6a4445SGunnar Mills 
297a1dbc48SGeorge Liu #include <array>
30*d7857201SEd Tanous #include <cstddef>
31*d7857201SEd Tanous #include <cstdint>
32*d7857201SEd Tanous #include <memory>
33*d7857201SEd Tanous #include <string>
347a1dbc48SGeorge Liu #include <string_view>
35*d7857201SEd Tanous #include <utility>
36*d7857201SEd 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;
432ac6a4445SGunnar Mills 
433c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
434c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "MemoryDataWidth",
435c1343bf6SKrzysztof Grobelny         memoryDataWidth, "MemorySizeInKB", memorySizeInKB, "PartNumber",
436656472d9SNikhil Namjoshi         partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
437656472d9SNikhil Namjoshi         "RevisionCode", revisionCode, "Present", present, "MemoryTotalWidth",
438656472d9SNikhil Namjoshi         memoryTotalWidth, "ECC", ecc, "FormFactor", formFactor,
439656472d9SNikhil Namjoshi         "AllowedSpeedsMT", allowedSpeedsMT, "MemoryAttributes",
440c1343bf6SKrzysztof Grobelny         memoryAttributes, "MemoryConfiguredSpeedInMhz",
441c1343bf6SKrzysztof Grobelny         memoryConfiguredSpeedInMhz, "MemoryType", memoryType, "Channel",
442c1343bf6SKrzysztof Grobelny         channel, "MemoryController", memoryController, "Slot", slot, "Socket",
443c1343bf6SKrzysztof Grobelny         socket, "SparePartNumber", sparePartNumber, "Model", model,
444c1343bf6SKrzysztof Grobelny         "LocationCode", locationCode);
445c1343bf6SKrzysztof Grobelny 
446c1343bf6SKrzysztof Grobelny     if (!success)
447ac6a4445SGunnar Mills     {
448ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
449601af5edSChicago Duan         return;
450ac6a4445SGunnar Mills     }
451c1343bf6SKrzysztof Grobelny 
452c1343bf6SKrzysztof Grobelny     if (memoryDataWidth != nullptr)
453c1343bf6SKrzysztof Grobelny     {
454ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["DataWidthBits"] = *memoryDataWidth;
455c1343bf6SKrzysztof Grobelny     }
456c1343bf6SKrzysztof Grobelny 
457c1343bf6SKrzysztof Grobelny     if (memorySizeInKB != nullptr)
458c1343bf6SKrzysztof Grobelny     {
459ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["CapacityMiB"] =
460ac106bf6SEd Tanous             (*memorySizeInKB >> 10);
461c1343bf6SKrzysztof Grobelny     }
462c1343bf6SKrzysztof Grobelny 
463c1343bf6SKrzysztof Grobelny     if (partNumber != nullptr)
464c1343bf6SKrzysztof Grobelny     {
465ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["PartNumber"] = *partNumber;
466c1343bf6SKrzysztof Grobelny     }
467c1343bf6SKrzysztof Grobelny 
468c1343bf6SKrzysztof Grobelny     if (serialNumber != nullptr)
469c1343bf6SKrzysztof Grobelny     {
470ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SerialNumber"] = *serialNumber;
471c1343bf6SKrzysztof Grobelny     }
472c1343bf6SKrzysztof Grobelny 
473c1343bf6SKrzysztof Grobelny     if (manufacturer != nullptr)
474c1343bf6SKrzysztof Grobelny     {
475ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["Manufacturer"] = *manufacturer;
476c1343bf6SKrzysztof Grobelny     }
477c1343bf6SKrzysztof Grobelny 
478c1343bf6SKrzysztof Grobelny     if (revisionCode != nullptr)
479c1343bf6SKrzysztof Grobelny     {
480ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["FirmwareRevision"] =
481c1343bf6SKrzysztof Grobelny             std::to_string(*revisionCode);
482ac6a4445SGunnar Mills     }
483c1343bf6SKrzysztof Grobelny 
484c1343bf6SKrzysztof Grobelny     if (present != nullptr && !*present)
4859a128eb3SJoshi-Mansi     {
486539d8c6bSEd Tanous         asyncResp->res.jsonValue[jsonPtr]["Status"]["State"] =
487539d8c6bSEd Tanous             resource::State::Absent;
4889a128eb3SJoshi-Mansi     }
489c1343bf6SKrzysztof Grobelny 
490c1343bf6SKrzysztof Grobelny     if (memoryTotalWidth != nullptr)
491ac6a4445SGunnar Mills     {
492ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["BusWidthBits"] = *memoryTotalWidth;
493ac6a4445SGunnar Mills     }
494c1343bf6SKrzysztof Grobelny 
495c1343bf6SKrzysztof Grobelny     if (ecc != nullptr)
496ac6a4445SGunnar Mills     {
497ac6a4445SGunnar Mills         constexpr const std::array<const char*, 4> values{
4989a5aceacSNan Zhou             "NoECC", "SingleBitECC", "MultiBitECC", "AddressParity"};
499ac6a4445SGunnar Mills 
500ac6a4445SGunnar Mills         for (const char* v : values)
501ac6a4445SGunnar Mills         {
502c1343bf6SKrzysztof Grobelny             if (ecc->ends_with(v))
503ac6a4445SGunnar Mills             {
504ac106bf6SEd Tanous                 asyncResp->res.jsonValue[jsonPtr]["ErrorCorrection"] = v;
505ac6a4445SGunnar Mills                 break;
506ac6a4445SGunnar Mills             }
507ac6a4445SGunnar Mills         }
508ac6a4445SGunnar Mills     }
509c1343bf6SKrzysztof Grobelny 
510c1343bf6SKrzysztof Grobelny     if (formFactor != nullptr)
511ac6a4445SGunnar Mills     {
512ac6a4445SGunnar Mills         constexpr const std::array<const char*, 11> values{
5139a5aceacSNan Zhou             "RDIMM",       "UDIMM",       "SO_DIMM",      "LRDIMM",
5149a5aceacSNan Zhou             "Mini_RDIMM",  "Mini_UDIMM",  "SO_RDIMM_72b", "SO_UDIMM_72b",
5159a5aceacSNan Zhou             "SO_DIMM_16b", "SO_DIMM_32b", "Die"};
516ac6a4445SGunnar Mills 
517ac6a4445SGunnar Mills         for (const char* v : values)
518ac6a4445SGunnar Mills         {
519c1343bf6SKrzysztof Grobelny             if (formFactor->ends_with(v))
520ac6a4445SGunnar Mills             {
521ac106bf6SEd Tanous                 asyncResp->res.jsonValue[jsonPtr]["BaseModuleType"] = v;
522ac6a4445SGunnar Mills                 break;
523ac6a4445SGunnar Mills             }
524ac6a4445SGunnar Mills         }
525ac6a4445SGunnar Mills     }
526c1343bf6SKrzysztof Grobelny 
527c1343bf6SKrzysztof Grobelny     if (allowedSpeedsMT != nullptr)
528ac6a4445SGunnar Mills     {
529d7f04fd9SNan Zhou         nlohmann::json& jValue =
530ac106bf6SEd Tanous             asyncResp->res.jsonValue[jsonPtr]["AllowedSpeedsMHz"];
531ac6a4445SGunnar Mills         jValue = nlohmann::json::array();
532c1343bf6SKrzysztof Grobelny         for (uint16_t subVal : *allowedSpeedsMT)
533ac6a4445SGunnar Mills         {
534ac6a4445SGunnar Mills             jValue.push_back(subVal);
535ac6a4445SGunnar Mills         }
536ac6a4445SGunnar Mills     }
537ac6a4445SGunnar Mills 
538c1343bf6SKrzysztof Grobelny     if (memoryAttributes != nullptr)
539ac6a4445SGunnar Mills     {
5406995c1ceSGeorge Liu         asyncResp->res.jsonValue[jsonPtr]["RankCount"] = *memoryAttributes;
541ac6a4445SGunnar Mills     }
542c1343bf6SKrzysztof Grobelny 
543c1343bf6SKrzysztof Grobelny     if (memoryConfiguredSpeedInMhz != nullptr)
544ac6a4445SGunnar Mills     {
545ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["OperatingSpeedMhz"] =
546c1343bf6SKrzysztof Grobelny             *memoryConfiguredSpeedInMhz;
547ac6a4445SGunnar Mills     }
548c1343bf6SKrzysztof Grobelny 
549c1343bf6SKrzysztof Grobelny     if (memoryType != nullptr)
550ac6a4445SGunnar Mills     {
551313efb1cSGunnar Mills         std::string memoryDeviceType =
552c1343bf6SKrzysztof Grobelny             translateMemoryTypeToRedfish(*memoryType);
553313efb1cSGunnar Mills         // Values like "Unknown" or "Other" will return empty
554313efb1cSGunnar Mills         // so just leave off
555313efb1cSGunnar Mills         if (!memoryDeviceType.empty())
556ac6a4445SGunnar Mills         {
557ac106bf6SEd Tanous             asyncResp->res.jsonValue[jsonPtr]["MemoryDeviceType"] =
558d7f04fd9SNan Zhou                 memoryDeviceType;
559ac6a4445SGunnar Mills         }
560c1343bf6SKrzysztof Grobelny         if (memoryType->find("DDR") != std::string::npos)
561ac6a4445SGunnar Mills         {
562539d8c6bSEd Tanous             asyncResp->res.jsonValue[jsonPtr]["MemoryType"] =
563539d8c6bSEd Tanous                 memory::MemoryType::DRAM;
564ac6a4445SGunnar Mills         }
565c1343bf6SKrzysztof Grobelny         else if (memoryType->ends_with("Logical"))
566ac6a4445SGunnar Mills         {
567539d8c6bSEd Tanous             asyncResp->res.jsonValue[jsonPtr]["MemoryType"] =
568539d8c6bSEd Tanous                 memory::MemoryType::IntelOptane;
569ac6a4445SGunnar Mills         }
570ac6a4445SGunnar Mills     }
571c1343bf6SKrzysztof Grobelny 
572c1343bf6SKrzysztof Grobelny     if (channel != nullptr)
573ac6a4445SGunnar Mills     {
574ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Channel"] =
575ac106bf6SEd Tanous             *channel;
576c1343bf6SKrzysztof Grobelny     }
577c1343bf6SKrzysztof Grobelny 
578c1343bf6SKrzysztof Grobelny     if (memoryController != nullptr)
579ac6a4445SGunnar Mills     {
580bd79bce8SPatrick Williams         asyncResp->res
581bd79bce8SPatrick Williams             .jsonValue[jsonPtr]["MemoryLocation"]["MemoryController"] =
582bd79bce8SPatrick Williams             *memoryController;
583ac6a4445SGunnar Mills     }
584c1343bf6SKrzysztof Grobelny 
585c1343bf6SKrzysztof Grobelny     if (slot != nullptr)
586ee135e24SSunnySrivastava1984     {
587ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Slot"] = *slot;
588c1343bf6SKrzysztof Grobelny     }
589c1343bf6SKrzysztof Grobelny 
590c1343bf6SKrzysztof Grobelny     if (socket != nullptr)
591ee135e24SSunnySrivastava1984     {
592ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Socket"] = *socket;
593ee135e24SSunnySrivastava1984     }
594c1343bf6SKrzysztof Grobelny 
595c1343bf6SKrzysztof Grobelny     if (sparePartNumber != nullptr)
596ee135e24SSunnySrivastava1984     {
597ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SparePartNumber"] = *sparePartNumber;
598c1343bf6SKrzysztof Grobelny     }
599c1343bf6SKrzysztof Grobelny 
600c1343bf6SKrzysztof Grobelny     if (model != nullptr)
601ee135e24SSunnySrivastava1984     {
602ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["Model"] = *model;
603ee135e24SSunnySrivastava1984     }
604c1343bf6SKrzysztof Grobelny 
605c1343bf6SKrzysztof Grobelny     if (locationCode != nullptr)
606ee135e24SSunnySrivastava1984     {
607bd79bce8SPatrick Williams         asyncResp->res
608bd79bce8SPatrick Williams             .jsonValue[jsonPtr]["Location"]["PartLocation"]["ServiceLabel"] =
609bd79bce8SPatrick Williams             *locationCode;
610ee135e24SSunnySrivastava1984     }
611c1343bf6SKrzysztof Grobelny 
612ac106bf6SEd Tanous     getPersistentMemoryProperties(asyncResp, properties, jsonPtr);
6139a5aceacSNan Zhou }
6149a5aceacSNan Zhou 
615bd79bce8SPatrick Williams inline void getDimmDataByService(
616bd79bce8SPatrick Williams     std::shared_ptr<bmcweb::AsyncResp> asyncResp, const std::string& dimmId,
617bd79bce8SPatrick Williams     const std::string& service, const std::string& objPath)
6189a5aceacSNan Zhou {
61962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get available system components.");
620deae6a78SEd Tanous     dbus::utility::getAllProperties(
621deae6a78SEd Tanous         service, objPath, "",
622ac106bf6SEd Tanous         [dimmId, asyncResp{std::move(asyncResp)}](
6235e7e2dc5SEd Tanous             const boost::system::error_code& ec,
6249a5aceacSNan Zhou             const dbus::utility::DBusPropertiesMap& properties) {
6259a5aceacSNan Zhou             if (ec)
6269a5aceacSNan Zhou             {
62762598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error");
628ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
6299a5aceacSNan Zhou                 return;
6309a5aceacSNan Zhou             }
631bd79bce8SPatrick Williams             assembleDimmProperties(dimmId, asyncResp, properties,
632bd79bce8SPatrick Williams                                    ""_json_pointer);
633c1343bf6SKrzysztof Grobelny         });
634ac6a4445SGunnar Mills }
635ac6a4445SGunnar Mills 
636ef00d7d4SNan Zhou inline void assembleDimmPartitionData(
637ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
638d7f04fd9SNan Zhou     const dbus::utility::DBusPropertiesMap& properties,
639d7f04fd9SNan Zhou     const nlohmann::json::json_pointer& regionPtr)
640ac6a4445SGunnar Mills {
641c1343bf6SKrzysztof Grobelny     const std::string* memoryClassification = nullptr;
642c1343bf6SKrzysztof Grobelny     const uint64_t* offsetInKiB = nullptr;
643c1343bf6SKrzysztof Grobelny     const std::string* partitionId = nullptr;
644c1343bf6SKrzysztof Grobelny     const bool* passphraseState = nullptr;
645c1343bf6SKrzysztof Grobelny     const uint64_t* sizeInKiB = nullptr;
646c1343bf6SKrzysztof Grobelny 
647c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
648c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "MemoryClassification",
649c1343bf6SKrzysztof Grobelny         memoryClassification, "OffsetInKiB", offsetInKiB, "PartitionId",
650c1343bf6SKrzysztof Grobelny         partitionId, "PassphraseState", passphraseState, "SizeInKiB",
651c1343bf6SKrzysztof Grobelny         sizeInKiB);
652c1343bf6SKrzysztof Grobelny 
653c1343bf6SKrzysztof Grobelny     if (!success)
654c1343bf6SKrzysztof Grobelny     {
655ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
656c1343bf6SKrzysztof Grobelny         return;
657c1343bf6SKrzysztof Grobelny     }
658c1343bf6SKrzysztof Grobelny 
659d7f04fd9SNan Zhou     nlohmann::json::object_t partition;
660c1343bf6SKrzysztof Grobelny 
661c1343bf6SKrzysztof Grobelny     if (memoryClassification != nullptr)
662ac6a4445SGunnar Mills     {
663c1343bf6SKrzysztof Grobelny         partition["MemoryClassification"] = *memoryClassification;
664ac6a4445SGunnar Mills     }
665ac6a4445SGunnar Mills 
666c1343bf6SKrzysztof Grobelny     if (offsetInKiB != nullptr)
667ac6a4445SGunnar Mills     {
668c1343bf6SKrzysztof Grobelny         partition["OffsetMiB"] = (*offsetInKiB >> 10);
669ac6a4445SGunnar Mills     }
670ac6a4445SGunnar Mills 
671c1343bf6SKrzysztof Grobelny     if (partitionId != nullptr)
672ac6a4445SGunnar Mills     {
673c1343bf6SKrzysztof Grobelny         partition["RegionId"] = *partitionId;
674c1343bf6SKrzysztof Grobelny     }
675c1343bf6SKrzysztof Grobelny 
676c1343bf6SKrzysztof Grobelny     if (passphraseState != nullptr)
677ac6a4445SGunnar Mills     {
678c1343bf6SKrzysztof Grobelny         partition["PassphraseEnabled"] = *passphraseState;
679ac6a4445SGunnar Mills     }
680c1343bf6SKrzysztof Grobelny 
681c1343bf6SKrzysztof Grobelny     if (sizeInKiB != nullptr)
682ac6a4445SGunnar Mills     {
683c1343bf6SKrzysztof Grobelny         partition["SizeMiB"] = (*sizeInKiB >> 10);
684ac6a4445SGunnar Mills     }
685c1343bf6SKrzysztof Grobelny 
686ac106bf6SEd Tanous     asyncResp->res.jsonValue[regionPtr].emplace_back(std::move(partition));
687ef00d7d4SNan Zhou }
688ef00d7d4SNan Zhou 
689ac106bf6SEd Tanous inline void getDimmPartitionData(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
690ef00d7d4SNan Zhou                                  const std::string& service,
691ef00d7d4SNan Zhou                                  const std::string& path)
692ef00d7d4SNan Zhou {
693deae6a78SEd Tanous     dbus::utility::getAllProperties(
694deae6a78SEd Tanous         service, path,
695c1343bf6SKrzysztof Grobelny         "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition",
696ac106bf6SEd Tanous         [asyncResp{std::move(asyncResp)}](
6975e7e2dc5SEd Tanous             const boost::system::error_code& ec,
698ef00d7d4SNan Zhou             const dbus::utility::DBusPropertiesMap& properties) {
699ef00d7d4SNan Zhou             if (ec)
700ef00d7d4SNan Zhou             {
70162598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error");
702ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
703ef00d7d4SNan Zhou 
704ef00d7d4SNan Zhou                 return;
705ef00d7d4SNan Zhou             }
706d7f04fd9SNan Zhou             nlohmann::json::json_pointer regionPtr = "/Regions"_json_pointer;
707ac106bf6SEd Tanous             assembleDimmPartitionData(asyncResp, properties, regionPtr);
708c1343bf6SKrzysztof Grobelny         }
709ac6a4445SGunnar Mills 
710c1343bf6SKrzysztof Grobelny     );
711ac6a4445SGunnar Mills }
712ac6a4445SGunnar Mills 
713ac106bf6SEd Tanous inline void getDimmData(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
714ac6a4445SGunnar Mills                         const std::string& dimmId)
715ac6a4445SGunnar Mills {
71662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get available system dimm resources.");
717e99073f5SGeorge Liu     constexpr std::array<std::string_view, 2> dimmInterfaces = {
718e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Dimm",
719e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"};
720e99073f5SGeorge Liu     dbus::utility::getSubTree(
721e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, dimmInterfaces,
722ac106bf6SEd Tanous         [dimmId, asyncResp{std::move(asyncResp)}](
723e99073f5SGeorge Liu             const boost::system::error_code& ec,
724b9d36b47SEd Tanous             const dbus::utility::MapperGetSubTreeResponse& subtree) {
725ac6a4445SGunnar Mills             if (ec)
726ac6a4445SGunnar Mills             {
72762598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error");
728ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
729ac6a4445SGunnar Mills 
730ac6a4445SGunnar Mills                 return;
731ac6a4445SGunnar Mills             }
732ac6a4445SGunnar Mills             bool found = false;
73376686dccSNan Zhou             for (const auto& [rawPath, object] : subtree)
734ac6a4445SGunnar Mills             {
73576686dccSNan Zhou                 sdbusplus::message::object_path path(rawPath);
736ac6a4445SGunnar Mills                 for (const auto& [service, interfaces] : object)
737ac6a4445SGunnar Mills                 {
738b9d36b47SEd Tanous                     for (const auto& interface : interfaces)
739ac6a4445SGunnar Mills                     {
740b9d36b47SEd Tanous                         if (interface ==
74176686dccSNan Zhou                                 "xyz.openbmc_project.Inventory.Item.Dimm" &&
74276686dccSNan Zhou                             path.filename() == dimmId)
743b9d36b47SEd Tanous                         {
744ac106bf6SEd Tanous                             getDimmDataByService(asyncResp, dimmId, service,
745ac106bf6SEd Tanous                                                  rawPath);
746ac6a4445SGunnar Mills                             found = true;
747ac6a4445SGunnar Mills                         }
748ac6a4445SGunnar Mills 
749b9d36b47SEd Tanous                         // partitions are separate as there can be multiple
750b9d36b47SEd Tanous                         // per
751ac6a4445SGunnar Mills                         // device, i.e.
752ac6a4445SGunnar Mills                         // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1
753ac6a4445SGunnar Mills                         // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2
754b9d36b47SEd Tanous                         if (interface ==
75576686dccSNan Zhou                                 "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition" &&
75676686dccSNan Zhou                             path.parent_path().filename() == dimmId)
757ac6a4445SGunnar Mills                         {
758ac106bf6SEd Tanous                             getDimmPartitionData(asyncResp, service, rawPath);
759ac6a4445SGunnar Mills                         }
760ac6a4445SGunnar Mills                     }
761ac6a4445SGunnar Mills                 }
762b9d36b47SEd Tanous             }
763ac6a4445SGunnar Mills             // Object not found
764ac6a4445SGunnar Mills             if (!found)
765ac6a4445SGunnar Mills             {
766ac106bf6SEd Tanous                 messages::resourceNotFound(asyncResp->res, "Memory", dimmId);
7671a1d5d6dSNan Zhou                 return;
768ac6a4445SGunnar Mills             }
7691a1d5d6dSNan Zhou             // Set @odata only if object is found
770ac106bf6SEd Tanous             asyncResp->res.jsonValue["@odata.type"] = "#Memory.v1_11_0.Memory";
771ac106bf6SEd Tanous             asyncResp->res.jsonValue["@odata.id"] =
772253f11b8SEd Tanous                 boost::urls::format("/redfish/v1/Systems/{}/Memory/{}",
773253f11b8SEd Tanous                                     BMCWEB_REDFISH_SYSTEM_URI_NAME, dimmId);
774ac6a4445SGunnar Mills             return;
775e99073f5SGeorge Liu         });
776ac6a4445SGunnar Mills }
777ac6a4445SGunnar Mills 
7787e860f15SJohn Edward Broadbent inline void requestRoutesMemoryCollection(App& app)
779ac6a4445SGunnar Mills {
780ac6a4445SGunnar Mills     /**
781ac6a4445SGunnar Mills      * Functions triggers appropriate requests on DBus
782ac6a4445SGunnar Mills      */
78322d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/")
784ed398213SEd Tanous         .privileges(redfish::privileges::getMemoryCollection)
7857e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
78645ca1b86SEd Tanous             [&app](const crow::Request& req,
78722d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
78822d268cbSEd Tanous                    const std::string& systemName) {
7893ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
79045ca1b86SEd Tanous                 {
79145ca1b86SEd Tanous                     return;
79245ca1b86SEd Tanous                 }
79325b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
7947f3e84a1SEd Tanous                 {
7957f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
7967f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
7977f3e84a1SEd Tanous                                                systemName);
7987f3e84a1SEd Tanous                     return;
7997f3e84a1SEd Tanous                 }
800253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
80122d268cbSEd Tanous                 {
80222d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
80322d268cbSEd Tanous                                                systemName);
80422d268cbSEd Tanous                     return;
80522d268cbSEd Tanous                 }
80622d268cbSEd Tanous 
8078d1b46d7Szhanghch05                 asyncResp->res.jsonValue["@odata.type"] =
8088d1b46d7Szhanghch05                     "#MemoryCollection.MemoryCollection";
8098d1b46d7Szhanghch05                 asyncResp->res.jsonValue["Name"] = "Memory Module Collection";
810bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["@odata.id"] =
811bd79bce8SPatrick Williams                     boost::urls::format("/redfish/v1/Systems/{}/Memory",
812bd79bce8SPatrick Williams                                         BMCWEB_REDFISH_SYSTEM_URI_NAME);
813ac6a4445SGunnar Mills 
8147a1dbc48SGeorge Liu                 constexpr std::array<std::string_view, 1> interfaces{
8157a1dbc48SGeorge Liu                     "xyz.openbmc_project.Inventory.Item.Dimm"};
81605030b8eSGunnar Mills                 collection_util::getCollectionMembers(
817253f11b8SEd Tanous                     asyncResp,
818253f11b8SEd Tanous                     boost::urls::format("/redfish/v1/Systems/{}/Memory",
819253f11b8SEd Tanous                                         BMCWEB_REDFISH_SYSTEM_URI_NAME),
82036b5f1edSLakshmi Yadlapati                     interfaces, "/xyz/openbmc_project/inventory");
8217e860f15SJohn Edward Broadbent             });
822ac6a4445SGunnar Mills }
823ac6a4445SGunnar Mills 
8247e860f15SJohn Edward Broadbent inline void requestRoutesMemory(App& app)
8257e860f15SJohn Edward Broadbent {
826ac6a4445SGunnar Mills     /**
827ac6a4445SGunnar Mills      * Functions triggers appropriate requests on DBus
828ac6a4445SGunnar Mills      */
82922d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/<str>/")
830ed398213SEd Tanous         .privileges(redfish::privileges::getMemory)
8317e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
83245ca1b86SEd Tanous             [&app](const crow::Request& req,
8337e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
83422d268cbSEd Tanous                    const std::string& systemName, const std::string& dimmId) {
8353ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
83645ca1b86SEd Tanous                 {
83745ca1b86SEd Tanous                     return;
83845ca1b86SEd Tanous                 }
8397f3e84a1SEd Tanous 
84025b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
8417f3e84a1SEd Tanous                 {
8427f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
8437f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
8447f3e84a1SEd Tanous                                                systemName);
8457f3e84a1SEd Tanous                     return;
8467f3e84a1SEd Tanous                 }
8477f3e84a1SEd Tanous 
848253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
84922d268cbSEd Tanous                 {
85022d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
85122d268cbSEd Tanous                                                systemName);
85222d268cbSEd Tanous                     return;
85322d268cbSEd Tanous                 }
85422d268cbSEd Tanous 
855ac6a4445SGunnar Mills                 getDimmData(asyncResp, dimmId);
8567e860f15SJohn Edward Broadbent             });
857ac6a4445SGunnar Mills }
858ac6a4445SGunnar Mills 
859ac6a4445SGunnar Mills } // namespace redfish
860