xref: /openbmc/bmcweb/features/redfish/lib/memory.hpp (revision 62598e31d0988d589506d5091bd38f72d61faf5e)
1ac6a4445SGunnar Mills /*
2ac6a4445SGunnar Mills // Copyright (c) 2018 Intel Corporation
3ac6a4445SGunnar Mills //
4ac6a4445SGunnar Mills // Licensed under the Apache License, Version 2.0 (the "License");
5ac6a4445SGunnar Mills // you may not use this file except in compliance with the License.
6ac6a4445SGunnar Mills // You may obtain a copy of the License at
7ac6a4445SGunnar Mills //
8ac6a4445SGunnar Mills //      http://www.apache.org/licenses/LICENSE-2.0
9ac6a4445SGunnar Mills //
10ac6a4445SGunnar Mills // Unless required by applicable law or agreed to in writing, software
11ac6a4445SGunnar Mills // distributed under the License is distributed on an "AS IS" BASIS,
12ac6a4445SGunnar Mills // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ac6a4445SGunnar Mills // See the License for the specific language governing permissions and
14ac6a4445SGunnar Mills // limitations under the License.
15ac6a4445SGunnar Mills */
16ac6a4445SGunnar Mills #pragma once
17ac6a4445SGunnar Mills 
1813451e39SWilly Tu #include "bmcweb_config.h"
1913451e39SWilly Tu 
203ccb3adbSEd Tanous #include "app.hpp"
213ccb3adbSEd Tanous #include "dbus_utility.hpp"
22ac6a4445SGunnar Mills #include "health.hpp"
233ccb3adbSEd Tanous #include "query.hpp"
243ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
253ccb3adbSEd Tanous #include "utils/collection.hpp"
263ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
273ccb3adbSEd Tanous #include "utils/hex_utils.hpp"
283ccb3adbSEd Tanous #include "utils/json_utils.hpp"
29ac6a4445SGunnar Mills 
30e99073f5SGeorge Liu #include <boost/system/error_code.hpp>
31ef4c65b7SEd Tanous #include <boost/url/format.hpp>
32d7f04fd9SNan Zhou #include <nlohmann/json.hpp>
33c1343bf6SKrzysztof Grobelny #include <sdbusplus/asio/property.hpp>
34c1343bf6SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
35ac6a4445SGunnar Mills 
367a1dbc48SGeorge Liu #include <array>
377a1dbc48SGeorge Liu #include <string_view>
387a1dbc48SGeorge Liu 
39ac6a4445SGunnar Mills namespace redfish
40ac6a4445SGunnar Mills {
41ac6a4445SGunnar Mills 
42313efb1cSGunnar Mills inline std::string translateMemoryTypeToRedfish(const std::string& memoryType)
43313efb1cSGunnar Mills {
44313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR")
45313efb1cSGunnar Mills     {
46313efb1cSGunnar Mills         return "DDR";
47313efb1cSGunnar Mills     }
48313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2")
49313efb1cSGunnar Mills     {
50313efb1cSGunnar Mills         return "DDR2";
51313efb1cSGunnar Mills     }
52313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR3")
53313efb1cSGunnar Mills     {
54313efb1cSGunnar Mills         return "DDR3";
55313efb1cSGunnar Mills     }
56313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4")
57313efb1cSGunnar Mills     {
58313efb1cSGunnar Mills         return "DDR4";
59313efb1cSGunnar Mills     }
60313efb1cSGunnar Mills     if (memoryType ==
61313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4E_SDRAM")
62313efb1cSGunnar Mills     {
63313efb1cSGunnar Mills         return "DDR4E_SDRAM";
64313efb1cSGunnar Mills     }
6511a2f0f0SMansi Joshi     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR5")
6611a2f0f0SMansi Joshi     {
6711a2f0f0SMansi Joshi         return "DDR5";
6811a2f0f0SMansi Joshi     }
69313efb1cSGunnar Mills     if (memoryType ==
70313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR4_SDRAM")
71313efb1cSGunnar Mills     {
72313efb1cSGunnar Mills         return "LPDDR4_SDRAM";
73313efb1cSGunnar Mills     }
74313efb1cSGunnar Mills     if (memoryType ==
75313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR3_SDRAM")
76313efb1cSGunnar Mills     {
77313efb1cSGunnar Mills         return "LPDDR3_SDRAM";
78313efb1cSGunnar Mills     }
79313efb1cSGunnar Mills     if (memoryType ==
80313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM")
81313efb1cSGunnar Mills     {
82313efb1cSGunnar Mills         return "DDR2_SDRAM_FB_DIMM";
83313efb1cSGunnar Mills     }
840fda0f12SGeorge Liu     if (memoryType ==
850fda0f12SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM_PROB")
86313efb1cSGunnar Mills     {
87313efb1cSGunnar Mills         return "DDR2_SDRAM_FB_DIMM_PROBE";
88313efb1cSGunnar Mills     }
89313efb1cSGunnar Mills     if (memoryType ==
90313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR_SGRAM")
91313efb1cSGunnar Mills     {
92313efb1cSGunnar Mills         return "DDR_SGRAM";
93313efb1cSGunnar Mills     }
94313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.ROM")
95313efb1cSGunnar Mills     {
96313efb1cSGunnar Mills         return "ROM";
97313efb1cSGunnar Mills     }
98313efb1cSGunnar Mills     if (memoryType ==
99313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.SDRAM")
100313efb1cSGunnar Mills     {
101313efb1cSGunnar Mills         return "SDRAM";
102313efb1cSGunnar Mills     }
103313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.EDO")
104313efb1cSGunnar Mills     {
105313efb1cSGunnar Mills         return "EDO";
106313efb1cSGunnar Mills     }
107313efb1cSGunnar Mills     if (memoryType ==
108313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.FastPageMode")
109313efb1cSGunnar Mills     {
110313efb1cSGunnar Mills         return "FastPageMode";
111313efb1cSGunnar Mills     }
112313efb1cSGunnar Mills     if (memoryType ==
113313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.PipelinedNibble")
114313efb1cSGunnar Mills     {
115313efb1cSGunnar Mills         return "PipelinedNibble";
116313efb1cSGunnar Mills     }
117313efb1cSGunnar Mills     if (memoryType ==
118313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.Logical")
119313efb1cSGunnar Mills     {
120313efb1cSGunnar Mills         return "Logical";
121313efb1cSGunnar Mills     }
122313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM")
123313efb1cSGunnar Mills     {
124313efb1cSGunnar Mills         return "HBM";
125313efb1cSGunnar Mills     }
126313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM2")
127313efb1cSGunnar Mills     {
128313efb1cSGunnar Mills         return "HBM2";
129313efb1cSGunnar Mills     }
130ce34d514STyson Tuckerbear     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM3")
131ce34d514STyson Tuckerbear     {
132ce34d514STyson Tuckerbear         return "HBM3";
133ce34d514STyson Tuckerbear     }
134313efb1cSGunnar Mills     // This is values like Other or Unknown
135313efb1cSGunnar Mills     // Also D-Bus values:
136313efb1cSGunnar Mills     // DRAM
137313efb1cSGunnar Mills     // EDRAM
138313efb1cSGunnar Mills     // VRAM
139313efb1cSGunnar Mills     // SRAM
140313efb1cSGunnar Mills     // RAM
141313efb1cSGunnar Mills     // FLASH
142313efb1cSGunnar Mills     // EEPROM
143313efb1cSGunnar Mills     // FEPROM
144313efb1cSGunnar Mills     // EPROM
145313efb1cSGunnar Mills     // CDRAM
146313efb1cSGunnar Mills     // ThreeDRAM
147313efb1cSGunnar Mills     // RDRAM
148313efb1cSGunnar Mills     // FBD2
149313efb1cSGunnar Mills     // LPDDR_SDRAM
150313efb1cSGunnar Mills     // LPDDR2_SDRAM
15111a2f0f0SMansi Joshi     // LPDDR5_SDRAM
152313efb1cSGunnar Mills     return "";
153313efb1cSGunnar Mills }
154313efb1cSGunnar Mills 
155ac106bf6SEd Tanous inline void dimmPropToHex(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
156c1343bf6SKrzysztof Grobelny                           const char* key, const uint16_t* value,
157d7f04fd9SNan Zhou                           const nlohmann::json::json_pointer& jsonPtr)
158ac6a4445SGunnar Mills {
159ac6a4445SGunnar Mills     if (value == nullptr)
160ac6a4445SGunnar Mills     {
161ac6a4445SGunnar Mills         return;
162ac6a4445SGunnar Mills     }
163ac106bf6SEd Tanous     asyncResp->res.jsonValue[jsonPtr][key] = "0x" + intToHexString(*value, 4);
164ac6a4445SGunnar Mills }
165ac6a4445SGunnar Mills 
1668d1b46d7Szhanghch05 inline void getPersistentMemoryProperties(
167ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
168c1343bf6SKrzysztof Grobelny     const dbus::utility::DBusPropertiesMap& properties,
169d7f04fd9SNan Zhou     const nlohmann::json::json_pointer& jsonPtr)
170ac6a4445SGunnar Mills {
171c1343bf6SKrzysztof Grobelny     const uint16_t* moduleManufacturerID = nullptr;
172c1343bf6SKrzysztof Grobelny     const uint16_t* moduleProductID = nullptr;
173c1343bf6SKrzysztof Grobelny     const uint16_t* subsystemVendorID = nullptr;
174c1343bf6SKrzysztof Grobelny     const uint16_t* subsystemDeviceID = nullptr;
175c1343bf6SKrzysztof Grobelny     const uint64_t* volatileRegionSizeLimitInKiB = nullptr;
176c1343bf6SKrzysztof Grobelny     const uint64_t* pmRegionSizeLimitInKiB = nullptr;
177c1343bf6SKrzysztof Grobelny     const uint64_t* volatileSizeInKiB = nullptr;
178c1343bf6SKrzysztof Grobelny     const uint64_t* pmSizeInKiB = nullptr;
179c1343bf6SKrzysztof Grobelny     const uint64_t* cacheSizeInKB = nullptr;
180c1343bf6SKrzysztof Grobelny     const uint64_t* voltaileRegionMaxSizeInKib = nullptr;
181c1343bf6SKrzysztof Grobelny     const uint64_t* pmRegionMaxSizeInKiB = nullptr;
182c1343bf6SKrzysztof Grobelny     const uint64_t* allocationIncrementInKiB = nullptr;
183c1343bf6SKrzysztof Grobelny     const uint64_t* allocationAlignmentInKiB = nullptr;
184c1343bf6SKrzysztof Grobelny     const uint64_t* volatileRegionNumberLimit = nullptr;
185c1343bf6SKrzysztof Grobelny     const uint64_t* pmRegionNumberLimit = nullptr;
186c1343bf6SKrzysztof Grobelny     const uint64_t* spareDeviceCount = nullptr;
187c1343bf6SKrzysztof Grobelny     const bool* isSpareDeviceInUse = nullptr;
188c1343bf6SKrzysztof Grobelny     const bool* isRankSpareEnabled = nullptr;
189c1343bf6SKrzysztof Grobelny     const std::vector<uint32_t>* maxAveragePowerLimitmW = nullptr;
190c1343bf6SKrzysztof Grobelny     const bool* configurationLocked = nullptr;
191c1343bf6SKrzysztof Grobelny     const std::string* allowedMemoryModes = nullptr;
192c1343bf6SKrzysztof Grobelny     const std::string* memoryMedia = nullptr;
193c1343bf6SKrzysztof Grobelny     const bool* configurationLockCapable = nullptr;
194c1343bf6SKrzysztof Grobelny     const bool* dataLockCapable = nullptr;
195c1343bf6SKrzysztof Grobelny     const bool* passphraseCapable = nullptr;
196c1343bf6SKrzysztof Grobelny     const uint64_t* maxPassphraseCount = nullptr;
197c1343bf6SKrzysztof Grobelny     const uint64_t* passphraseLockLimit = nullptr;
198c1343bf6SKrzysztof Grobelny 
199c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
200c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "ModuleManufacturerID",
201c1343bf6SKrzysztof Grobelny         moduleManufacturerID, "ModuleProductID", moduleProductID,
202c1343bf6SKrzysztof Grobelny         "SubsystemVendorID", subsystemVendorID, "SubsystemDeviceID",
203c1343bf6SKrzysztof Grobelny         subsystemDeviceID, "VolatileRegionSizeLimitInKiB",
204c1343bf6SKrzysztof Grobelny         volatileRegionSizeLimitInKiB, "PmRegionSizeLimitInKiB",
205c1343bf6SKrzysztof Grobelny         pmRegionSizeLimitInKiB, "VolatileSizeInKiB", volatileSizeInKiB,
206c1343bf6SKrzysztof Grobelny         "PmSizeInKiB", pmSizeInKiB, "CacheSizeInKB", cacheSizeInKB,
207c1343bf6SKrzysztof Grobelny         "VoltaileRegionMaxSizeInKib", voltaileRegionMaxSizeInKib,
208c1343bf6SKrzysztof Grobelny         "PmRegionMaxSizeInKiB", pmRegionMaxSizeInKiB,
209c1343bf6SKrzysztof Grobelny         "AllocationIncrementInKiB", allocationIncrementInKiB,
210c1343bf6SKrzysztof Grobelny         "AllocationAlignmentInKiB", allocationAlignmentInKiB,
211c1343bf6SKrzysztof Grobelny         "VolatileRegionNumberLimit", volatileRegionNumberLimit,
212c1343bf6SKrzysztof Grobelny         "PmRegionNumberLimit", pmRegionNumberLimit, "SpareDeviceCount",
213c1343bf6SKrzysztof Grobelny         spareDeviceCount, "IsSpareDeviceInUse", isSpareDeviceInUse,
214c1343bf6SKrzysztof Grobelny         "IsRankSpareEnabled", isRankSpareEnabled, "MaxAveragePowerLimitmW",
215c1343bf6SKrzysztof Grobelny         maxAveragePowerLimitmW, "ConfigurationLocked", configurationLocked,
216c1343bf6SKrzysztof Grobelny         "AllowedMemoryModes", allowedMemoryModes, "MemoryMedia", memoryMedia,
217c1343bf6SKrzysztof Grobelny         "ConfigurationLockCapable", configurationLockCapable, "DataLockCapable",
218c1343bf6SKrzysztof Grobelny         dataLockCapable, "PassphraseCapable", passphraseCapable,
219c1343bf6SKrzysztof Grobelny         "MaxPassphraseCount", maxPassphraseCount, "PassphraseLockLimit",
220c1343bf6SKrzysztof Grobelny         passphraseLockLimit);
221c1343bf6SKrzysztof Grobelny 
222c1343bf6SKrzysztof Grobelny     if (!success)
223ac6a4445SGunnar Mills     {
224ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
225c1343bf6SKrzysztof Grobelny         return;
226ac6a4445SGunnar Mills     }
227c1343bf6SKrzysztof Grobelny 
228ac106bf6SEd Tanous     dimmPropToHex(asyncResp, "ModuleManufacturerID", moduleManufacturerID,
229ac106bf6SEd Tanous                   jsonPtr);
230ac106bf6SEd Tanous     dimmPropToHex(asyncResp, "ModuleProductID", moduleProductID, jsonPtr);
231ac106bf6SEd Tanous     dimmPropToHex(asyncResp, "MemorySubsystemControllerManufacturerID",
232c1343bf6SKrzysztof Grobelny                   subsystemVendorID, jsonPtr);
233ac106bf6SEd Tanous     dimmPropToHex(asyncResp, "MemorySubsystemControllerProductID",
234c1343bf6SKrzysztof Grobelny                   subsystemDeviceID, jsonPtr);
235ac6a4445SGunnar Mills 
236c1343bf6SKrzysztof Grobelny     if (volatileRegionSizeLimitInKiB != nullptr)
237ac6a4445SGunnar Mills     {
238ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["VolatileRegionSizeLimitMiB"] =
239c1343bf6SKrzysztof Grobelny             (*volatileRegionSizeLimitInKiB) >> 10;
240ac6a4445SGunnar Mills     }
241ac6a4445SGunnar Mills 
242c1343bf6SKrzysztof Grobelny     if (pmRegionSizeLimitInKiB != nullptr)
243ac6a4445SGunnar Mills     {
244ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["PersistentRegionSizeLimitMiB"] =
245c1343bf6SKrzysztof Grobelny             (*pmRegionSizeLimitInKiB) >> 10;
246ac6a4445SGunnar Mills     }
247ac6a4445SGunnar Mills 
248c1343bf6SKrzysztof Grobelny     if (volatileSizeInKiB != nullptr)
249ac6a4445SGunnar Mills     {
250ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["VolatileSizeMiB"] =
251c1343bf6SKrzysztof Grobelny             (*volatileSizeInKiB) >> 10;
252ac6a4445SGunnar Mills     }
253c1343bf6SKrzysztof Grobelny 
254c1343bf6SKrzysztof Grobelny     if (pmSizeInKiB != nullptr)
255c1343bf6SKrzysztof Grobelny     {
256ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["NonVolatileSizeMiB"] =
257ac106bf6SEd Tanous             (*pmSizeInKiB) >> 10;
258c1343bf6SKrzysztof Grobelny     }
259c1343bf6SKrzysztof Grobelny 
260c1343bf6SKrzysztof Grobelny     if (cacheSizeInKB != nullptr)
261c1343bf6SKrzysztof Grobelny     {
262ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["CacheSizeMiB"] =
263ac106bf6SEd Tanous             (*cacheSizeInKB >> 10);
264c1343bf6SKrzysztof Grobelny     }
265c1343bf6SKrzysztof Grobelny 
266c1343bf6SKrzysztof Grobelny     if (voltaileRegionMaxSizeInKib != nullptr)
267c1343bf6SKrzysztof Grobelny     {
268ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["VolatileRegionSizeMaxMiB"] =
269c1343bf6SKrzysztof Grobelny             (*voltaileRegionMaxSizeInKib) >> 10;
270ac6a4445SGunnar Mills     }
271ac6a4445SGunnar Mills 
272c1343bf6SKrzysztof Grobelny     if (pmRegionMaxSizeInKiB != nullptr)
273ac6a4445SGunnar Mills     {
274ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["PersistentRegionSizeMaxMiB"] =
275c1343bf6SKrzysztof Grobelny             (*pmRegionMaxSizeInKiB) >> 10;
276ac6a4445SGunnar Mills     }
277ac6a4445SGunnar Mills 
278c1343bf6SKrzysztof Grobelny     if (allocationIncrementInKiB != nullptr)
279ac6a4445SGunnar Mills     {
280ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["AllocationIncrementMiB"] =
281c1343bf6SKrzysztof Grobelny             (*allocationIncrementInKiB) >> 10;
282ac6a4445SGunnar Mills     }
283ac6a4445SGunnar Mills 
284c1343bf6SKrzysztof Grobelny     if (allocationAlignmentInKiB != nullptr)
285ac6a4445SGunnar Mills     {
286ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["AllocationAlignmentMiB"] =
287c1343bf6SKrzysztof Grobelny             (*allocationAlignmentInKiB) >> 10;
288ac6a4445SGunnar Mills     }
289c1343bf6SKrzysztof Grobelny 
290c1343bf6SKrzysztof Grobelny     if (volatileRegionNumberLimit != nullptr)
291ac6a4445SGunnar Mills     {
292ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["VolatileRegionNumberLimit"] =
293c1343bf6SKrzysztof Grobelny             *volatileRegionNumberLimit;
294ac6a4445SGunnar Mills     }
295c1343bf6SKrzysztof Grobelny 
296c1343bf6SKrzysztof Grobelny     if (pmRegionNumberLimit != nullptr)
297ac6a4445SGunnar Mills     {
298ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["PersistentRegionNumberLimit"] =
299c1343bf6SKrzysztof Grobelny             *pmRegionNumberLimit;
300ac6a4445SGunnar Mills     }
301c1343bf6SKrzysztof Grobelny 
302c1343bf6SKrzysztof Grobelny     if (spareDeviceCount != nullptr)
303ac6a4445SGunnar Mills     {
304ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SpareDeviceCount"] =
305ac106bf6SEd Tanous             *spareDeviceCount;
306ac6a4445SGunnar Mills     }
307c1343bf6SKrzysztof Grobelny 
308c1343bf6SKrzysztof Grobelny     if (isSpareDeviceInUse != nullptr)
309ac6a4445SGunnar Mills     {
310ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["IsSpareDeviceEnabled"] =
311c1343bf6SKrzysztof Grobelny             *isSpareDeviceInUse;
312ac6a4445SGunnar Mills     }
313c1343bf6SKrzysztof Grobelny 
314c1343bf6SKrzysztof Grobelny     if (isRankSpareEnabled != nullptr)
315ac6a4445SGunnar Mills     {
316ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["IsRankSpareEnabled"] =
317c1343bf6SKrzysztof Grobelny             *isRankSpareEnabled;
318ac6a4445SGunnar Mills     }
319c1343bf6SKrzysztof Grobelny 
320c1343bf6SKrzysztof Grobelny     if (maxAveragePowerLimitmW != nullptr)
321ac6a4445SGunnar Mills     {
322ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MaxTDPMilliWatts"] =
323c1343bf6SKrzysztof Grobelny             *maxAveragePowerLimitmW;
324ac6a4445SGunnar Mills     }
325c1343bf6SKrzysztof Grobelny 
326c1343bf6SKrzysztof Grobelny     if (configurationLocked != nullptr)
327ac6a4445SGunnar Mills     {
328ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["ConfigurationLocked"] =
329c1343bf6SKrzysztof Grobelny             *configurationLocked;
330ac6a4445SGunnar Mills     }
331c1343bf6SKrzysztof Grobelny 
332c1343bf6SKrzysztof Grobelny     if (allowedMemoryModes != nullptr)
333ac6a4445SGunnar Mills     {
33480badf7cSJiaqing Zhao         constexpr const std::array<const char*, 3> values{"Volatile", "PMEM",
33580badf7cSJiaqing Zhao                                                           "Block"};
336ac6a4445SGunnar Mills 
337ac6a4445SGunnar Mills         for (const char* v : values)
338ac6a4445SGunnar Mills         {
339c1343bf6SKrzysztof Grobelny             if (allowedMemoryModes->ends_with(v))
340ac6a4445SGunnar Mills             {
341ac106bf6SEd Tanous                 asyncResp->res.jsonValue[jsonPtr]["OperatingMemoryModes"]
342ac106bf6SEd Tanous                     .push_back(v);
343ac6a4445SGunnar Mills                 break;
344ac6a4445SGunnar Mills             }
345ac6a4445SGunnar Mills         }
346ac6a4445SGunnar Mills     }
347c1343bf6SKrzysztof Grobelny 
348c1343bf6SKrzysztof Grobelny     if (memoryMedia != nullptr)
349ac6a4445SGunnar Mills     {
350ac6a4445SGunnar Mills         constexpr const std::array<const char*, 3> values{"DRAM", "NAND",
351ac6a4445SGunnar Mills                                                           "Intel3DXPoint"};
352ac6a4445SGunnar Mills 
353ac6a4445SGunnar Mills         for (const char* v : values)
354ac6a4445SGunnar Mills         {
355c1343bf6SKrzysztof Grobelny             if (memoryMedia->ends_with(v))
356ac6a4445SGunnar Mills             {
357ac106bf6SEd Tanous                 asyncResp->res.jsonValue[jsonPtr]["MemoryMedia"].push_back(v);
358ac6a4445SGunnar Mills                 break;
359ac6a4445SGunnar Mills             }
360ac6a4445SGunnar Mills         }
361ac6a4445SGunnar Mills     }
362c1343bf6SKrzysztof Grobelny 
363c1343bf6SKrzysztof Grobelny     if (configurationLockCapable != nullptr)
364ac6a4445SGunnar Mills     {
365ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
366c1343bf6SKrzysztof Grobelny                                 ["ConfigurationLockCapable"] =
367c1343bf6SKrzysztof Grobelny             *configurationLockCapable;
368ac6a4445SGunnar Mills     }
369c1343bf6SKrzysztof Grobelny 
370c1343bf6SKrzysztof Grobelny     if (dataLockCapable != nullptr)
371ac6a4445SGunnar Mills     {
372ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
37389492a15SPatrick Williams                                 ["DataLockCapable"] = *dataLockCapable;
374ac6a4445SGunnar Mills     }
375c1343bf6SKrzysztof Grobelny 
376c1343bf6SKrzysztof Grobelny     if (passphraseCapable != nullptr)
377c1343bf6SKrzysztof Grobelny     {
378ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
37989492a15SPatrick Williams                                 ["PassphraseCapable"] = *passphraseCapable;
380c1343bf6SKrzysztof Grobelny     }
381c1343bf6SKrzysztof Grobelny 
382c1343bf6SKrzysztof Grobelny     if (maxPassphraseCount != nullptr)
383c1343bf6SKrzysztof Grobelny     {
384ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
38589492a15SPatrick Williams                                 ["MaxPassphraseCount"] = *maxPassphraseCount;
386c1343bf6SKrzysztof Grobelny     }
387c1343bf6SKrzysztof Grobelny 
388c1343bf6SKrzysztof Grobelny     if (passphraseLockLimit != nullptr)
389c1343bf6SKrzysztof Grobelny     {
390ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
39189492a15SPatrick Williams                                 ["PassphraseLockLimit"] = *passphraseLockLimit;
392ac6a4445SGunnar Mills     }
393ac6a4445SGunnar Mills }
394ac6a4445SGunnar Mills 
3959a5aceacSNan Zhou inline void
3969a5aceacSNan Zhou     assembleDimmProperties(std::string_view dimmId,
397ac106bf6SEd Tanous                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
398d7f04fd9SNan Zhou                            const dbus::utility::DBusPropertiesMap& properties,
399d7f04fd9SNan Zhou                            const nlohmann::json::json_pointer& jsonPtr)
400ac6a4445SGunnar Mills {
401ac106bf6SEd Tanous     asyncResp->res.jsonValue[jsonPtr]["Id"] = dimmId;
402ac106bf6SEd Tanous     asyncResp->res.jsonValue[jsonPtr]["Name"] = "DIMM Slot";
403ac106bf6SEd Tanous     asyncResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Enabled";
404ac106bf6SEd Tanous     asyncResp->res.jsonValue[jsonPtr]["Status"]["Health"] = "OK";
405ac6a4445SGunnar Mills 
406c1343bf6SKrzysztof Grobelny     const uint16_t* memoryDataWidth = nullptr;
407c1343bf6SKrzysztof Grobelny     const size_t* memorySizeInKB = nullptr;
408c1343bf6SKrzysztof Grobelny     const std::string* partNumber = nullptr;
409c1343bf6SKrzysztof Grobelny     const std::string* serialNumber = nullptr;
410c1343bf6SKrzysztof Grobelny     const std::string* manufacturer = nullptr;
411c1343bf6SKrzysztof Grobelny     const uint16_t* revisionCode = nullptr;
412c1343bf6SKrzysztof Grobelny     const bool* present = nullptr;
413c1343bf6SKrzysztof Grobelny     const uint16_t* memoryTotalWidth = nullptr;
414c1343bf6SKrzysztof Grobelny     const std::string* ecc = nullptr;
415c1343bf6SKrzysztof Grobelny     const std::string* formFactor = nullptr;
416c1343bf6SKrzysztof Grobelny     const std::vector<uint16_t>* allowedSpeedsMT = nullptr;
4176995c1ceSGeorge Liu     const size_t* memoryAttributes = nullptr;
418c1343bf6SKrzysztof Grobelny     const uint16_t* memoryConfiguredSpeedInMhz = nullptr;
419c1343bf6SKrzysztof Grobelny     const std::string* memoryType = nullptr;
4206fde5971SJayaprakash Mutyala     const std::uint8_t* channel = nullptr;
4216fde5971SJayaprakash Mutyala     const std::uint8_t* memoryController = nullptr;
4226fde5971SJayaprakash Mutyala     const std::uint8_t* slot = nullptr;
4236fde5971SJayaprakash Mutyala     const std::uint8_t* socket = nullptr;
424c1343bf6SKrzysztof Grobelny     const std::string* sparePartNumber = nullptr;
425c1343bf6SKrzysztof Grobelny     const std::string* model = nullptr;
426c1343bf6SKrzysztof Grobelny     const std::string* locationCode = nullptr;
427ac6a4445SGunnar Mills 
428c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
429c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "MemoryDataWidth",
430c1343bf6SKrzysztof Grobelny         memoryDataWidth, "MemorySizeInKB", memorySizeInKB, "PartNumber",
431656472d9SNikhil Namjoshi         partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
432656472d9SNikhil Namjoshi         "RevisionCode", revisionCode, "Present", present, "MemoryTotalWidth",
433656472d9SNikhil Namjoshi         memoryTotalWidth, "ECC", ecc, "FormFactor", formFactor,
434656472d9SNikhil Namjoshi         "AllowedSpeedsMT", allowedSpeedsMT, "MemoryAttributes",
435c1343bf6SKrzysztof Grobelny         memoryAttributes, "MemoryConfiguredSpeedInMhz",
436c1343bf6SKrzysztof Grobelny         memoryConfiguredSpeedInMhz, "MemoryType", memoryType, "Channel",
437c1343bf6SKrzysztof Grobelny         channel, "MemoryController", memoryController, "Slot", slot, "Socket",
438c1343bf6SKrzysztof Grobelny         socket, "SparePartNumber", sparePartNumber, "Model", model,
439c1343bf6SKrzysztof Grobelny         "LocationCode", locationCode);
440c1343bf6SKrzysztof Grobelny 
441c1343bf6SKrzysztof Grobelny     if (!success)
442ac6a4445SGunnar Mills     {
443ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
444601af5edSChicago Duan         return;
445ac6a4445SGunnar Mills     }
446c1343bf6SKrzysztof Grobelny 
447c1343bf6SKrzysztof Grobelny     if (memoryDataWidth != nullptr)
448c1343bf6SKrzysztof Grobelny     {
449ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["DataWidthBits"] = *memoryDataWidth;
450c1343bf6SKrzysztof Grobelny     }
451c1343bf6SKrzysztof Grobelny 
452c1343bf6SKrzysztof Grobelny     if (memorySizeInKB != nullptr)
453c1343bf6SKrzysztof Grobelny     {
454ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["CapacityMiB"] =
455ac106bf6SEd Tanous             (*memorySizeInKB >> 10);
456c1343bf6SKrzysztof Grobelny     }
457c1343bf6SKrzysztof Grobelny 
458c1343bf6SKrzysztof Grobelny     if (partNumber != nullptr)
459c1343bf6SKrzysztof Grobelny     {
460ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["PartNumber"] = *partNumber;
461c1343bf6SKrzysztof Grobelny     }
462c1343bf6SKrzysztof Grobelny 
463c1343bf6SKrzysztof Grobelny     if (serialNumber != nullptr)
464c1343bf6SKrzysztof Grobelny     {
465ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SerialNumber"] = *serialNumber;
466c1343bf6SKrzysztof Grobelny     }
467c1343bf6SKrzysztof Grobelny 
468c1343bf6SKrzysztof Grobelny     if (manufacturer != nullptr)
469c1343bf6SKrzysztof Grobelny     {
470ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["Manufacturer"] = *manufacturer;
471c1343bf6SKrzysztof Grobelny     }
472c1343bf6SKrzysztof Grobelny 
473c1343bf6SKrzysztof Grobelny     if (revisionCode != nullptr)
474c1343bf6SKrzysztof Grobelny     {
475ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["FirmwareRevision"] =
476c1343bf6SKrzysztof Grobelny             std::to_string(*revisionCode);
477ac6a4445SGunnar Mills     }
478c1343bf6SKrzysztof Grobelny 
479c1343bf6SKrzysztof Grobelny     if (present != nullptr && !*present)
4809a128eb3SJoshi-Mansi     {
481ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Absent";
4829a128eb3SJoshi-Mansi     }
483c1343bf6SKrzysztof Grobelny 
484c1343bf6SKrzysztof Grobelny     if (memoryTotalWidth != nullptr)
485ac6a4445SGunnar Mills     {
486ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["BusWidthBits"] = *memoryTotalWidth;
487ac6a4445SGunnar Mills     }
488c1343bf6SKrzysztof Grobelny 
489c1343bf6SKrzysztof Grobelny     if (ecc != nullptr)
490ac6a4445SGunnar Mills     {
491ac6a4445SGunnar Mills         constexpr const std::array<const char*, 4> values{
4929a5aceacSNan Zhou             "NoECC", "SingleBitECC", "MultiBitECC", "AddressParity"};
493ac6a4445SGunnar Mills 
494ac6a4445SGunnar Mills         for (const char* v : values)
495ac6a4445SGunnar Mills         {
496c1343bf6SKrzysztof Grobelny             if (ecc->ends_with(v))
497ac6a4445SGunnar Mills             {
498ac106bf6SEd Tanous                 asyncResp->res.jsonValue[jsonPtr]["ErrorCorrection"] = v;
499ac6a4445SGunnar Mills                 break;
500ac6a4445SGunnar Mills             }
501ac6a4445SGunnar Mills         }
502ac6a4445SGunnar Mills     }
503c1343bf6SKrzysztof Grobelny 
504c1343bf6SKrzysztof Grobelny     if (formFactor != nullptr)
505ac6a4445SGunnar Mills     {
506ac6a4445SGunnar Mills         constexpr const std::array<const char*, 11> values{
5079a5aceacSNan Zhou             "RDIMM",       "UDIMM",       "SO_DIMM",      "LRDIMM",
5089a5aceacSNan Zhou             "Mini_RDIMM",  "Mini_UDIMM",  "SO_RDIMM_72b", "SO_UDIMM_72b",
5099a5aceacSNan Zhou             "SO_DIMM_16b", "SO_DIMM_32b", "Die"};
510ac6a4445SGunnar Mills 
511ac6a4445SGunnar Mills         for (const char* v : values)
512ac6a4445SGunnar Mills         {
513c1343bf6SKrzysztof Grobelny             if (formFactor->ends_with(v))
514ac6a4445SGunnar Mills             {
515ac106bf6SEd Tanous                 asyncResp->res.jsonValue[jsonPtr]["BaseModuleType"] = v;
516ac6a4445SGunnar Mills                 break;
517ac6a4445SGunnar Mills             }
518ac6a4445SGunnar Mills         }
519ac6a4445SGunnar Mills     }
520c1343bf6SKrzysztof Grobelny 
521c1343bf6SKrzysztof Grobelny     if (allowedSpeedsMT != nullptr)
522ac6a4445SGunnar Mills     {
523d7f04fd9SNan Zhou         nlohmann::json& jValue =
524ac106bf6SEd Tanous             asyncResp->res.jsonValue[jsonPtr]["AllowedSpeedsMHz"];
525ac6a4445SGunnar Mills         jValue = nlohmann::json::array();
526c1343bf6SKrzysztof Grobelny         for (uint16_t subVal : *allowedSpeedsMT)
527ac6a4445SGunnar Mills         {
528ac6a4445SGunnar Mills             jValue.push_back(subVal);
529ac6a4445SGunnar Mills         }
530ac6a4445SGunnar Mills     }
531ac6a4445SGunnar Mills 
532c1343bf6SKrzysztof Grobelny     if (memoryAttributes != nullptr)
533ac6a4445SGunnar Mills     {
5346995c1ceSGeorge Liu         asyncResp->res.jsonValue[jsonPtr]["RankCount"] = *memoryAttributes;
535ac6a4445SGunnar Mills     }
536c1343bf6SKrzysztof Grobelny 
537c1343bf6SKrzysztof Grobelny     if (memoryConfiguredSpeedInMhz != nullptr)
538ac6a4445SGunnar Mills     {
539ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["OperatingSpeedMhz"] =
540c1343bf6SKrzysztof Grobelny             *memoryConfiguredSpeedInMhz;
541ac6a4445SGunnar Mills     }
542c1343bf6SKrzysztof Grobelny 
543c1343bf6SKrzysztof Grobelny     if (memoryType != nullptr)
544ac6a4445SGunnar Mills     {
545313efb1cSGunnar Mills         std::string memoryDeviceType =
546c1343bf6SKrzysztof Grobelny             translateMemoryTypeToRedfish(*memoryType);
547313efb1cSGunnar Mills         // Values like "Unknown" or "Other" will return empty
548313efb1cSGunnar Mills         // so just leave off
549313efb1cSGunnar Mills         if (!memoryDeviceType.empty())
550ac6a4445SGunnar Mills         {
551ac106bf6SEd Tanous             asyncResp->res.jsonValue[jsonPtr]["MemoryDeviceType"] =
552d7f04fd9SNan Zhou                 memoryDeviceType;
553ac6a4445SGunnar Mills         }
554c1343bf6SKrzysztof Grobelny         if (memoryType->find("DDR") != std::string::npos)
555ac6a4445SGunnar Mills         {
556ac106bf6SEd Tanous             asyncResp->res.jsonValue[jsonPtr]["MemoryType"] = "DRAM";
557ac6a4445SGunnar Mills         }
558c1343bf6SKrzysztof Grobelny         else if (memoryType->ends_with("Logical"))
559ac6a4445SGunnar Mills         {
560ac106bf6SEd Tanous             asyncResp->res.jsonValue[jsonPtr]["MemoryType"] = "IntelOptane";
561ac6a4445SGunnar Mills         }
562ac6a4445SGunnar Mills     }
563c1343bf6SKrzysztof Grobelny 
564c1343bf6SKrzysztof Grobelny     if (channel != nullptr)
565ac6a4445SGunnar Mills     {
566ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Channel"] =
567ac106bf6SEd Tanous             *channel;
568c1343bf6SKrzysztof Grobelny     }
569c1343bf6SKrzysztof Grobelny 
570c1343bf6SKrzysztof Grobelny     if (memoryController != nullptr)
571ac6a4445SGunnar Mills     {
572ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]
573ac106bf6SEd Tanous                                 ["MemoryController"] = *memoryController;
574ac6a4445SGunnar Mills     }
575c1343bf6SKrzysztof Grobelny 
576c1343bf6SKrzysztof Grobelny     if (slot != nullptr)
577ee135e24SSunnySrivastava1984     {
578ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Slot"] = *slot;
579c1343bf6SKrzysztof Grobelny     }
580c1343bf6SKrzysztof Grobelny 
581c1343bf6SKrzysztof Grobelny     if (socket != nullptr)
582ee135e24SSunnySrivastava1984     {
583ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Socket"] = *socket;
584ee135e24SSunnySrivastava1984     }
585c1343bf6SKrzysztof Grobelny 
586c1343bf6SKrzysztof Grobelny     if (sparePartNumber != nullptr)
587ee135e24SSunnySrivastava1984     {
588ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SparePartNumber"] = *sparePartNumber;
589c1343bf6SKrzysztof Grobelny     }
590c1343bf6SKrzysztof Grobelny 
591c1343bf6SKrzysztof Grobelny     if (model != nullptr)
592ee135e24SSunnySrivastava1984     {
593ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["Model"] = *model;
594ee135e24SSunnySrivastava1984     }
595c1343bf6SKrzysztof Grobelny 
596c1343bf6SKrzysztof Grobelny     if (locationCode != nullptr)
597ee135e24SSunnySrivastava1984     {
598ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["Location"]["PartLocation"]
59989492a15SPatrick Williams                                 ["ServiceLabel"] = *locationCode;
600ee135e24SSunnySrivastava1984     }
601c1343bf6SKrzysztof Grobelny 
602ac106bf6SEd Tanous     getPersistentMemoryProperties(asyncResp, properties, jsonPtr);
6039a5aceacSNan Zhou }
6049a5aceacSNan Zhou 
605ac106bf6SEd Tanous inline void getDimmDataByService(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
6069a5aceacSNan Zhou                                  const std::string& dimmId,
6079a5aceacSNan Zhou                                  const std::string& service,
6089a5aceacSNan Zhou                                  const std::string& objPath)
6099a5aceacSNan Zhou {
61013451e39SWilly Tu     if constexpr (bmcwebEnableHealthPopulate)
61113451e39SWilly Tu     {
612ac106bf6SEd Tanous         auto health = std::make_shared<HealthPopulate>(asyncResp);
6139a5aceacSNan Zhou         health->selfPath = objPath;
6149a5aceacSNan Zhou         health->populate();
61513451e39SWilly Tu     }
6169a5aceacSNan Zhou 
617*62598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get available system components.");
618c1343bf6SKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
619c1343bf6SKrzysztof Grobelny         *crow::connections::systemBus, service, objPath, "",
620ac106bf6SEd Tanous         [dimmId, asyncResp{std::move(asyncResp)}](
6215e7e2dc5SEd Tanous             const boost::system::error_code& ec,
6229a5aceacSNan Zhou             const dbus::utility::DBusPropertiesMap& properties) {
6239a5aceacSNan Zhou         if (ec)
6249a5aceacSNan Zhou         {
625*62598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error");
626ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
6279a5aceacSNan Zhou             return;
6289a5aceacSNan Zhou         }
629ac106bf6SEd Tanous         assembleDimmProperties(dimmId, asyncResp, properties, ""_json_pointer);
630c1343bf6SKrzysztof Grobelny         });
631ac6a4445SGunnar Mills }
632ac6a4445SGunnar Mills 
633ef00d7d4SNan Zhou inline void assembleDimmPartitionData(
634ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
635d7f04fd9SNan Zhou     const dbus::utility::DBusPropertiesMap& properties,
636d7f04fd9SNan Zhou     const nlohmann::json::json_pointer& regionPtr)
637ac6a4445SGunnar Mills {
638c1343bf6SKrzysztof Grobelny     const std::string* memoryClassification = nullptr;
639c1343bf6SKrzysztof Grobelny     const uint64_t* offsetInKiB = nullptr;
640c1343bf6SKrzysztof Grobelny     const std::string* partitionId = nullptr;
641c1343bf6SKrzysztof Grobelny     const bool* passphraseState = nullptr;
642c1343bf6SKrzysztof Grobelny     const uint64_t* sizeInKiB = nullptr;
643c1343bf6SKrzysztof Grobelny 
644c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
645c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "MemoryClassification",
646c1343bf6SKrzysztof Grobelny         memoryClassification, "OffsetInKiB", offsetInKiB, "PartitionId",
647c1343bf6SKrzysztof Grobelny         partitionId, "PassphraseState", passphraseState, "SizeInKiB",
648c1343bf6SKrzysztof Grobelny         sizeInKiB);
649c1343bf6SKrzysztof Grobelny 
650c1343bf6SKrzysztof Grobelny     if (!success)
651c1343bf6SKrzysztof Grobelny     {
652ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
653c1343bf6SKrzysztof Grobelny         return;
654c1343bf6SKrzysztof Grobelny     }
655c1343bf6SKrzysztof Grobelny 
656d7f04fd9SNan Zhou     nlohmann::json::object_t partition;
657c1343bf6SKrzysztof Grobelny 
658c1343bf6SKrzysztof Grobelny     if (memoryClassification != nullptr)
659ac6a4445SGunnar Mills     {
660c1343bf6SKrzysztof Grobelny         partition["MemoryClassification"] = *memoryClassification;
661ac6a4445SGunnar Mills     }
662ac6a4445SGunnar Mills 
663c1343bf6SKrzysztof Grobelny     if (offsetInKiB != nullptr)
664ac6a4445SGunnar Mills     {
665c1343bf6SKrzysztof Grobelny         partition["OffsetMiB"] = (*offsetInKiB >> 10);
666ac6a4445SGunnar Mills     }
667ac6a4445SGunnar Mills 
668c1343bf6SKrzysztof Grobelny     if (partitionId != nullptr)
669ac6a4445SGunnar Mills     {
670c1343bf6SKrzysztof Grobelny         partition["RegionId"] = *partitionId;
671c1343bf6SKrzysztof Grobelny     }
672c1343bf6SKrzysztof Grobelny 
673c1343bf6SKrzysztof Grobelny     if (passphraseState != nullptr)
674ac6a4445SGunnar Mills     {
675c1343bf6SKrzysztof Grobelny         partition["PassphraseEnabled"] = *passphraseState;
676ac6a4445SGunnar Mills     }
677c1343bf6SKrzysztof Grobelny 
678c1343bf6SKrzysztof Grobelny     if (sizeInKiB != nullptr)
679ac6a4445SGunnar Mills     {
680c1343bf6SKrzysztof Grobelny         partition["SizeMiB"] = (*sizeInKiB >> 10);
681ac6a4445SGunnar Mills     }
682c1343bf6SKrzysztof Grobelny 
683ac106bf6SEd Tanous     asyncResp->res.jsonValue[regionPtr].emplace_back(std::move(partition));
684ef00d7d4SNan Zhou }
685ef00d7d4SNan Zhou 
686ac106bf6SEd Tanous inline void getDimmPartitionData(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
687ef00d7d4SNan Zhou                                  const std::string& service,
688ef00d7d4SNan Zhou                                  const std::string& path)
689ef00d7d4SNan Zhou {
690c1343bf6SKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
691c1343bf6SKrzysztof Grobelny         *crow::connections::systemBus, service, path,
692c1343bf6SKrzysztof Grobelny         "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition",
693ac106bf6SEd Tanous         [asyncResp{std::move(asyncResp)}](
6945e7e2dc5SEd Tanous             const boost::system::error_code& ec,
695ef00d7d4SNan Zhou             const dbus::utility::DBusPropertiesMap& properties) {
696ef00d7d4SNan Zhou         if (ec)
697ef00d7d4SNan Zhou         {
698*62598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error");
699ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
700ef00d7d4SNan Zhou 
701ef00d7d4SNan Zhou             return;
702ef00d7d4SNan Zhou         }
703d7f04fd9SNan Zhou         nlohmann::json::json_pointer regionPtr = "/Regions"_json_pointer;
704ac106bf6SEd Tanous         assembleDimmPartitionData(asyncResp, properties, regionPtr);
705c1343bf6SKrzysztof Grobelny         }
706ac6a4445SGunnar Mills 
707c1343bf6SKrzysztof Grobelny     );
708ac6a4445SGunnar Mills }
709ac6a4445SGunnar Mills 
710ac106bf6SEd Tanous inline void getDimmData(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
711ac6a4445SGunnar Mills                         const std::string& dimmId)
712ac6a4445SGunnar Mills {
713*62598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get available system dimm resources.");
714e99073f5SGeorge Liu     constexpr std::array<std::string_view, 2> dimmInterfaces = {
715e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Dimm",
716e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"};
717e99073f5SGeorge Liu     dbus::utility::getSubTree(
718e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, dimmInterfaces,
719ac106bf6SEd Tanous         [dimmId, asyncResp{std::move(asyncResp)}](
720e99073f5SGeorge Liu             const boost::system::error_code& ec,
721b9d36b47SEd Tanous             const dbus::utility::MapperGetSubTreeResponse& subtree) {
722ac6a4445SGunnar Mills         if (ec)
723ac6a4445SGunnar Mills         {
724*62598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error");
725ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
726ac6a4445SGunnar Mills 
727ac6a4445SGunnar Mills             return;
728ac6a4445SGunnar Mills         }
729ac6a4445SGunnar Mills         bool found = false;
73076686dccSNan Zhou         for (const auto& [rawPath, object] : subtree)
731ac6a4445SGunnar Mills         {
73276686dccSNan Zhou             sdbusplus::message::object_path path(rawPath);
733ac6a4445SGunnar Mills             for (const auto& [service, interfaces] : object)
734ac6a4445SGunnar Mills             {
735b9d36b47SEd Tanous                 for (const auto& interface : interfaces)
736ac6a4445SGunnar Mills                 {
737b9d36b47SEd Tanous                     if (interface ==
73876686dccSNan Zhou                             "xyz.openbmc_project.Inventory.Item.Dimm" &&
73976686dccSNan Zhou                         path.filename() == dimmId)
740b9d36b47SEd Tanous                     {
741ac106bf6SEd Tanous                         getDimmDataByService(asyncResp, dimmId, service,
742ac106bf6SEd Tanous                                              rawPath);
743ac6a4445SGunnar Mills                         found = true;
744ac6a4445SGunnar Mills                     }
745ac6a4445SGunnar Mills 
746b9d36b47SEd Tanous                     // partitions are separate as there can be multiple
747b9d36b47SEd Tanous                     // per
748ac6a4445SGunnar Mills                     // device, i.e.
749ac6a4445SGunnar Mills                     // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1
750ac6a4445SGunnar Mills                     // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2
751b9d36b47SEd Tanous                     if (interface ==
75276686dccSNan Zhou                             "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition" &&
75376686dccSNan Zhou                         path.parent_path().filename() == dimmId)
754ac6a4445SGunnar Mills                     {
755ac106bf6SEd Tanous                         getDimmPartitionData(asyncResp, service, rawPath);
756ac6a4445SGunnar Mills                     }
757ac6a4445SGunnar Mills                 }
758ac6a4445SGunnar Mills             }
759b9d36b47SEd Tanous         }
760ac6a4445SGunnar Mills         // Object not found
761ac6a4445SGunnar Mills         if (!found)
762ac6a4445SGunnar Mills         {
763ac106bf6SEd Tanous             messages::resourceNotFound(asyncResp->res, "Memory", dimmId);
7641a1d5d6dSNan Zhou             return;
765ac6a4445SGunnar Mills         }
7661a1d5d6dSNan Zhou         // Set @odata only if object is found
767ac106bf6SEd Tanous         asyncResp->res.jsonValue["@odata.type"] = "#Memory.v1_11_0.Memory";
768ac106bf6SEd Tanous         asyncResp->res.jsonValue["@odata.id"] =
769ef4c65b7SEd Tanous             boost::urls::format("/redfish/v1/Systems/system/Memory/{}", dimmId);
770ac6a4445SGunnar Mills         return;
771e99073f5SGeorge Liu         });
772ac6a4445SGunnar Mills }
773ac6a4445SGunnar Mills 
7747e860f15SJohn Edward Broadbent inline void requestRoutesMemoryCollection(App& app)
775ac6a4445SGunnar Mills {
776ac6a4445SGunnar Mills     /**
777ac6a4445SGunnar Mills      * Functions triggers appropriate requests on DBus
778ac6a4445SGunnar Mills      */
77922d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/")
780ed398213SEd Tanous         .privileges(redfish::privileges::getMemoryCollection)
7817e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
78245ca1b86SEd Tanous             [&app](const crow::Request& req,
78322d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
78422d268cbSEd Tanous                    const std::string& systemName) {
7853ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
78645ca1b86SEd Tanous         {
78745ca1b86SEd Tanous             return;
78845ca1b86SEd Tanous         }
7897f3e84a1SEd Tanous         if constexpr (bmcwebEnableMultiHost)
7907f3e84a1SEd Tanous         {
7917f3e84a1SEd Tanous             // Option currently returns no systems.  TBD
7927f3e84a1SEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
7937f3e84a1SEd Tanous                                        systemName);
7947f3e84a1SEd Tanous             return;
7957f3e84a1SEd Tanous         }
79622d268cbSEd Tanous         if (systemName != "system")
79722d268cbSEd Tanous         {
79822d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
79922d268cbSEd Tanous                                        systemName);
80022d268cbSEd Tanous             return;
80122d268cbSEd Tanous         }
80222d268cbSEd Tanous 
8038d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.type"] =
8048d1b46d7Szhanghch05             "#MemoryCollection.MemoryCollection";
8058d1b46d7Szhanghch05         asyncResp->res.jsonValue["Name"] = "Memory Module Collection";
8068d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.id"] =
8078d1b46d7Szhanghch05             "/redfish/v1/Systems/system/Memory";
808ac6a4445SGunnar Mills 
8097a1dbc48SGeorge Liu         constexpr std::array<std::string_view, 1> interfaces{
8107a1dbc48SGeorge Liu             "xyz.openbmc_project.Inventory.Item.Dimm"};
81105030b8eSGunnar Mills         collection_util::getCollectionMembers(
812ae9031f0SWilly Tu             asyncResp, boost::urls::url("/redfish/v1/Systems/system/Memory"),
8137a1dbc48SGeorge Liu             interfaces);
8147e860f15SJohn Edward Broadbent         });
815ac6a4445SGunnar Mills }
816ac6a4445SGunnar Mills 
8177e860f15SJohn Edward Broadbent inline void requestRoutesMemory(App& app)
8187e860f15SJohn Edward Broadbent {
819ac6a4445SGunnar Mills     /**
820ac6a4445SGunnar Mills      * Functions triggers appropriate requests on DBus
821ac6a4445SGunnar Mills      */
82222d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/<str>/")
823ed398213SEd Tanous         .privileges(redfish::privileges::getMemory)
8247e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
82545ca1b86SEd Tanous             [&app](const crow::Request& req,
8267e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
82722d268cbSEd Tanous                    const std::string& systemName, const std::string& dimmId) {
8283ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
82945ca1b86SEd Tanous         {
83045ca1b86SEd Tanous             return;
83145ca1b86SEd Tanous         }
8327f3e84a1SEd Tanous 
8337f3e84a1SEd Tanous         if constexpr (bmcwebEnableMultiHost)
8347f3e84a1SEd Tanous         {
8357f3e84a1SEd Tanous             // Option currently returns no systems.  TBD
8367f3e84a1SEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
8377f3e84a1SEd Tanous                                        systemName);
8387f3e84a1SEd Tanous             return;
8397f3e84a1SEd Tanous         }
8407f3e84a1SEd Tanous 
84122d268cbSEd Tanous         if (systemName != "system")
84222d268cbSEd Tanous         {
84322d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
84422d268cbSEd Tanous                                        systemName);
84522d268cbSEd Tanous             return;
84622d268cbSEd Tanous         }
84722d268cbSEd Tanous 
848ac6a4445SGunnar Mills         getDimmData(asyncResp, dimmId);
8497e860f15SJohn Edward Broadbent         });
850ac6a4445SGunnar Mills }
851ac6a4445SGunnar Mills 
852ac6a4445SGunnar Mills } // namespace redfish
853