xref: /openbmc/bmcweb/features/redfish/lib/memory.hpp (revision 539d8c6bc399e516d39bcaa18262cf206f4c1035)
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"
22*539d8c6bSEd Tanous #include "generated/enums/memory.hpp"
23*539d8c6bSEd Tanous #include "generated/enums/resource.hpp"
243ccb3adbSEd Tanous #include "query.hpp"
253ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
263ccb3adbSEd Tanous #include "utils/collection.hpp"
273ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
283ccb3adbSEd Tanous #include "utils/hex_utils.hpp"
293ccb3adbSEd Tanous #include "utils/json_utils.hpp"
30ac6a4445SGunnar Mills 
31e99073f5SGeorge Liu #include <boost/system/error_code.hpp>
32ef4c65b7SEd Tanous #include <boost/url/format.hpp>
33d7f04fd9SNan Zhou #include <nlohmann/json.hpp>
34c1343bf6SKrzysztof Grobelny #include <sdbusplus/asio/property.hpp>
35c1343bf6SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
36ac6a4445SGunnar Mills 
377a1dbc48SGeorge Liu #include <array>
387a1dbc48SGeorge Liu #include <string_view>
397a1dbc48SGeorge Liu 
40ac6a4445SGunnar Mills namespace redfish
41ac6a4445SGunnar Mills {
42ac6a4445SGunnar Mills 
43313efb1cSGunnar Mills inline std::string translateMemoryTypeToRedfish(const std::string& memoryType)
44313efb1cSGunnar Mills {
45313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR")
46313efb1cSGunnar Mills     {
47313efb1cSGunnar Mills         return "DDR";
48313efb1cSGunnar Mills     }
49313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2")
50313efb1cSGunnar Mills     {
51313efb1cSGunnar Mills         return "DDR2";
52313efb1cSGunnar Mills     }
53313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR3")
54313efb1cSGunnar Mills     {
55313efb1cSGunnar Mills         return "DDR3";
56313efb1cSGunnar Mills     }
57313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4")
58313efb1cSGunnar Mills     {
59313efb1cSGunnar Mills         return "DDR4";
60313efb1cSGunnar Mills     }
61313efb1cSGunnar Mills     if (memoryType ==
62313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4E_SDRAM")
63313efb1cSGunnar Mills     {
64313efb1cSGunnar Mills         return "DDR4E_SDRAM";
65313efb1cSGunnar Mills     }
6611a2f0f0SMansi Joshi     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR5")
6711a2f0f0SMansi Joshi     {
6811a2f0f0SMansi Joshi         return "DDR5";
6911a2f0f0SMansi Joshi     }
70313efb1cSGunnar Mills     if (memoryType ==
71313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR4_SDRAM")
72313efb1cSGunnar Mills     {
73313efb1cSGunnar Mills         return "LPDDR4_SDRAM";
74313efb1cSGunnar Mills     }
75313efb1cSGunnar Mills     if (memoryType ==
76313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR3_SDRAM")
77313efb1cSGunnar Mills     {
78313efb1cSGunnar Mills         return "LPDDR3_SDRAM";
79313efb1cSGunnar Mills     }
80313efb1cSGunnar Mills     if (memoryType ==
81313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM")
82313efb1cSGunnar Mills     {
83313efb1cSGunnar Mills         return "DDR2_SDRAM_FB_DIMM";
84313efb1cSGunnar Mills     }
850fda0f12SGeorge Liu     if (memoryType ==
860fda0f12SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM_PROB")
87313efb1cSGunnar Mills     {
88313efb1cSGunnar Mills         return "DDR2_SDRAM_FB_DIMM_PROBE";
89313efb1cSGunnar Mills     }
90313efb1cSGunnar Mills     if (memoryType ==
91313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR_SGRAM")
92313efb1cSGunnar Mills     {
93313efb1cSGunnar Mills         return "DDR_SGRAM";
94313efb1cSGunnar Mills     }
95313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.ROM")
96313efb1cSGunnar Mills     {
97313efb1cSGunnar Mills         return "ROM";
98313efb1cSGunnar Mills     }
99313efb1cSGunnar Mills     if (memoryType ==
100313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.SDRAM")
101313efb1cSGunnar Mills     {
102313efb1cSGunnar Mills         return "SDRAM";
103313efb1cSGunnar Mills     }
104313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.EDO")
105313efb1cSGunnar Mills     {
106313efb1cSGunnar Mills         return "EDO";
107313efb1cSGunnar Mills     }
108313efb1cSGunnar Mills     if (memoryType ==
109313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.FastPageMode")
110313efb1cSGunnar Mills     {
111313efb1cSGunnar Mills         return "FastPageMode";
112313efb1cSGunnar Mills     }
113313efb1cSGunnar Mills     if (memoryType ==
114313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.PipelinedNibble")
115313efb1cSGunnar Mills     {
116313efb1cSGunnar Mills         return "PipelinedNibble";
117313efb1cSGunnar Mills     }
118313efb1cSGunnar Mills     if (memoryType ==
119313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.Logical")
120313efb1cSGunnar Mills     {
121313efb1cSGunnar Mills         return "Logical";
122313efb1cSGunnar Mills     }
123313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM")
124313efb1cSGunnar Mills     {
125313efb1cSGunnar Mills         return "HBM";
126313efb1cSGunnar Mills     }
127313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM2")
128313efb1cSGunnar Mills     {
129313efb1cSGunnar Mills         return "HBM2";
130313efb1cSGunnar Mills     }
131ce34d514STyson Tuckerbear     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM3")
132ce34d514STyson Tuckerbear     {
133ce34d514STyson Tuckerbear         return "HBM3";
134ce34d514STyson Tuckerbear     }
135313efb1cSGunnar Mills     // This is values like Other or Unknown
136313efb1cSGunnar Mills     // Also D-Bus values:
137313efb1cSGunnar Mills     // DRAM
138313efb1cSGunnar Mills     // EDRAM
139313efb1cSGunnar Mills     // VRAM
140313efb1cSGunnar Mills     // SRAM
141313efb1cSGunnar Mills     // RAM
142313efb1cSGunnar Mills     // FLASH
143313efb1cSGunnar Mills     // EEPROM
144313efb1cSGunnar Mills     // FEPROM
145313efb1cSGunnar Mills     // EPROM
146313efb1cSGunnar Mills     // CDRAM
147313efb1cSGunnar Mills     // ThreeDRAM
148313efb1cSGunnar Mills     // RDRAM
149313efb1cSGunnar Mills     // FBD2
150313efb1cSGunnar Mills     // LPDDR_SDRAM
151313efb1cSGunnar Mills     // LPDDR2_SDRAM
15211a2f0f0SMansi Joshi     // LPDDR5_SDRAM
153313efb1cSGunnar Mills     return "";
154313efb1cSGunnar Mills }
155313efb1cSGunnar Mills 
156ac106bf6SEd Tanous inline void dimmPropToHex(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
157c1343bf6SKrzysztof Grobelny                           const char* key, const uint16_t* value,
158d7f04fd9SNan Zhou                           const nlohmann::json::json_pointer& jsonPtr)
159ac6a4445SGunnar Mills {
160ac6a4445SGunnar Mills     if (value == nullptr)
161ac6a4445SGunnar Mills     {
162ac6a4445SGunnar Mills         return;
163ac6a4445SGunnar Mills     }
164ac106bf6SEd Tanous     asyncResp->res.jsonValue[jsonPtr][key] = "0x" + intToHexString(*value, 4);
165ac6a4445SGunnar Mills }
166ac6a4445SGunnar Mills 
1678d1b46d7Szhanghch05 inline void getPersistentMemoryProperties(
168ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
169c1343bf6SKrzysztof Grobelny     const dbus::utility::DBusPropertiesMap& properties,
170d7f04fd9SNan Zhou     const nlohmann::json::json_pointer& jsonPtr)
171ac6a4445SGunnar Mills {
172c1343bf6SKrzysztof Grobelny     const uint16_t* moduleManufacturerID = nullptr;
173c1343bf6SKrzysztof Grobelny     const uint16_t* moduleProductID = nullptr;
174c1343bf6SKrzysztof Grobelny     const uint16_t* subsystemVendorID = nullptr;
175c1343bf6SKrzysztof Grobelny     const uint16_t* subsystemDeviceID = nullptr;
176c1343bf6SKrzysztof Grobelny     const uint64_t* volatileRegionSizeLimitInKiB = nullptr;
177c1343bf6SKrzysztof Grobelny     const uint64_t* pmRegionSizeLimitInKiB = nullptr;
178c1343bf6SKrzysztof Grobelny     const uint64_t* volatileSizeInKiB = nullptr;
179c1343bf6SKrzysztof Grobelny     const uint64_t* pmSizeInKiB = nullptr;
180c1343bf6SKrzysztof Grobelny     const uint64_t* cacheSizeInKB = nullptr;
181c1343bf6SKrzysztof Grobelny     const uint64_t* voltaileRegionMaxSizeInKib = nullptr;
182c1343bf6SKrzysztof Grobelny     const uint64_t* pmRegionMaxSizeInKiB = nullptr;
183c1343bf6SKrzysztof Grobelny     const uint64_t* allocationIncrementInKiB = nullptr;
184c1343bf6SKrzysztof Grobelny     const uint64_t* allocationAlignmentInKiB = nullptr;
185c1343bf6SKrzysztof Grobelny     const uint64_t* volatileRegionNumberLimit = nullptr;
186c1343bf6SKrzysztof Grobelny     const uint64_t* pmRegionNumberLimit = nullptr;
187c1343bf6SKrzysztof Grobelny     const uint64_t* spareDeviceCount = nullptr;
188c1343bf6SKrzysztof Grobelny     const bool* isSpareDeviceInUse = nullptr;
189c1343bf6SKrzysztof Grobelny     const bool* isRankSpareEnabled = nullptr;
190c1343bf6SKrzysztof Grobelny     const std::vector<uint32_t>* maxAveragePowerLimitmW = nullptr;
191c1343bf6SKrzysztof Grobelny     const bool* configurationLocked = nullptr;
192c1343bf6SKrzysztof Grobelny     const std::string* allowedMemoryModes = nullptr;
193c1343bf6SKrzysztof Grobelny     const std::string* memoryMedia = nullptr;
194c1343bf6SKrzysztof Grobelny     const bool* configurationLockCapable = nullptr;
195c1343bf6SKrzysztof Grobelny     const bool* dataLockCapable = nullptr;
196c1343bf6SKrzysztof Grobelny     const bool* passphraseCapable = nullptr;
197c1343bf6SKrzysztof Grobelny     const uint64_t* maxPassphraseCount = nullptr;
198c1343bf6SKrzysztof Grobelny     const uint64_t* passphraseLockLimit = nullptr;
199c1343bf6SKrzysztof Grobelny 
200c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
201c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "ModuleManufacturerID",
202c1343bf6SKrzysztof Grobelny         moduleManufacturerID, "ModuleProductID", moduleProductID,
203c1343bf6SKrzysztof Grobelny         "SubsystemVendorID", subsystemVendorID, "SubsystemDeviceID",
204c1343bf6SKrzysztof Grobelny         subsystemDeviceID, "VolatileRegionSizeLimitInKiB",
205c1343bf6SKrzysztof Grobelny         volatileRegionSizeLimitInKiB, "PmRegionSizeLimitInKiB",
206c1343bf6SKrzysztof Grobelny         pmRegionSizeLimitInKiB, "VolatileSizeInKiB", volatileSizeInKiB,
207c1343bf6SKrzysztof Grobelny         "PmSizeInKiB", pmSizeInKiB, "CacheSizeInKB", cacheSizeInKB,
208c1343bf6SKrzysztof Grobelny         "VoltaileRegionMaxSizeInKib", voltaileRegionMaxSizeInKib,
209c1343bf6SKrzysztof Grobelny         "PmRegionMaxSizeInKiB", pmRegionMaxSizeInKiB,
210c1343bf6SKrzysztof Grobelny         "AllocationIncrementInKiB", allocationIncrementInKiB,
211c1343bf6SKrzysztof Grobelny         "AllocationAlignmentInKiB", allocationAlignmentInKiB,
212c1343bf6SKrzysztof Grobelny         "VolatileRegionNumberLimit", volatileRegionNumberLimit,
213c1343bf6SKrzysztof Grobelny         "PmRegionNumberLimit", pmRegionNumberLimit, "SpareDeviceCount",
214c1343bf6SKrzysztof Grobelny         spareDeviceCount, "IsSpareDeviceInUse", isSpareDeviceInUse,
215c1343bf6SKrzysztof Grobelny         "IsRankSpareEnabled", isRankSpareEnabled, "MaxAveragePowerLimitmW",
216c1343bf6SKrzysztof Grobelny         maxAveragePowerLimitmW, "ConfigurationLocked", configurationLocked,
217c1343bf6SKrzysztof Grobelny         "AllowedMemoryModes", allowedMemoryModes, "MemoryMedia", memoryMedia,
218c1343bf6SKrzysztof Grobelny         "ConfigurationLockCapable", configurationLockCapable, "DataLockCapable",
219c1343bf6SKrzysztof Grobelny         dataLockCapable, "PassphraseCapable", passphraseCapable,
220c1343bf6SKrzysztof Grobelny         "MaxPassphraseCount", maxPassphraseCount, "PassphraseLockLimit",
221c1343bf6SKrzysztof Grobelny         passphraseLockLimit);
222c1343bf6SKrzysztof Grobelny 
223c1343bf6SKrzysztof Grobelny     if (!success)
224ac6a4445SGunnar Mills     {
225ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
226c1343bf6SKrzysztof Grobelny         return;
227ac6a4445SGunnar Mills     }
228c1343bf6SKrzysztof Grobelny 
229ac106bf6SEd Tanous     dimmPropToHex(asyncResp, "ModuleManufacturerID", moduleManufacturerID,
230ac106bf6SEd Tanous                   jsonPtr);
231ac106bf6SEd Tanous     dimmPropToHex(asyncResp, "ModuleProductID", moduleProductID, jsonPtr);
232ac106bf6SEd Tanous     dimmPropToHex(asyncResp, "MemorySubsystemControllerManufacturerID",
233c1343bf6SKrzysztof Grobelny                   subsystemVendorID, jsonPtr);
234ac106bf6SEd Tanous     dimmPropToHex(asyncResp, "MemorySubsystemControllerProductID",
235c1343bf6SKrzysztof Grobelny                   subsystemDeviceID, jsonPtr);
236ac6a4445SGunnar Mills 
237c1343bf6SKrzysztof Grobelny     if (volatileRegionSizeLimitInKiB != nullptr)
238ac6a4445SGunnar Mills     {
239ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["VolatileRegionSizeLimitMiB"] =
240c1343bf6SKrzysztof Grobelny             (*volatileRegionSizeLimitInKiB) >> 10;
241ac6a4445SGunnar Mills     }
242ac6a4445SGunnar Mills 
243c1343bf6SKrzysztof Grobelny     if (pmRegionSizeLimitInKiB != nullptr)
244ac6a4445SGunnar Mills     {
245ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["PersistentRegionSizeLimitMiB"] =
246c1343bf6SKrzysztof Grobelny             (*pmRegionSizeLimitInKiB) >> 10;
247ac6a4445SGunnar Mills     }
248ac6a4445SGunnar Mills 
249c1343bf6SKrzysztof Grobelny     if (volatileSizeInKiB != nullptr)
250ac6a4445SGunnar Mills     {
251ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["VolatileSizeMiB"] =
252c1343bf6SKrzysztof Grobelny             (*volatileSizeInKiB) >> 10;
253ac6a4445SGunnar Mills     }
254c1343bf6SKrzysztof Grobelny 
255c1343bf6SKrzysztof Grobelny     if (pmSizeInKiB != nullptr)
256c1343bf6SKrzysztof Grobelny     {
257ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["NonVolatileSizeMiB"] =
258ac106bf6SEd Tanous             (*pmSizeInKiB) >> 10;
259c1343bf6SKrzysztof Grobelny     }
260c1343bf6SKrzysztof Grobelny 
261c1343bf6SKrzysztof Grobelny     if (cacheSizeInKB != nullptr)
262c1343bf6SKrzysztof Grobelny     {
263ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["CacheSizeMiB"] =
264ac106bf6SEd Tanous             (*cacheSizeInKB >> 10);
265c1343bf6SKrzysztof Grobelny     }
266c1343bf6SKrzysztof Grobelny 
267c1343bf6SKrzysztof Grobelny     if (voltaileRegionMaxSizeInKib != nullptr)
268c1343bf6SKrzysztof Grobelny     {
269ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["VolatileRegionSizeMaxMiB"] =
270c1343bf6SKrzysztof Grobelny             (*voltaileRegionMaxSizeInKib) >> 10;
271ac6a4445SGunnar Mills     }
272ac6a4445SGunnar Mills 
273c1343bf6SKrzysztof Grobelny     if (pmRegionMaxSizeInKiB != nullptr)
274ac6a4445SGunnar Mills     {
275ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["PersistentRegionSizeMaxMiB"] =
276c1343bf6SKrzysztof Grobelny             (*pmRegionMaxSizeInKiB) >> 10;
277ac6a4445SGunnar Mills     }
278ac6a4445SGunnar Mills 
279c1343bf6SKrzysztof Grobelny     if (allocationIncrementInKiB != nullptr)
280ac6a4445SGunnar Mills     {
281ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["AllocationIncrementMiB"] =
282c1343bf6SKrzysztof Grobelny             (*allocationIncrementInKiB) >> 10;
283ac6a4445SGunnar Mills     }
284ac6a4445SGunnar Mills 
285c1343bf6SKrzysztof Grobelny     if (allocationAlignmentInKiB != nullptr)
286ac6a4445SGunnar Mills     {
287ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["AllocationAlignmentMiB"] =
288c1343bf6SKrzysztof Grobelny             (*allocationAlignmentInKiB) >> 10;
289ac6a4445SGunnar Mills     }
290c1343bf6SKrzysztof Grobelny 
291c1343bf6SKrzysztof Grobelny     if (volatileRegionNumberLimit != nullptr)
292ac6a4445SGunnar Mills     {
293ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["VolatileRegionNumberLimit"] =
294c1343bf6SKrzysztof Grobelny             *volatileRegionNumberLimit;
295ac6a4445SGunnar Mills     }
296c1343bf6SKrzysztof Grobelny 
297c1343bf6SKrzysztof Grobelny     if (pmRegionNumberLimit != nullptr)
298ac6a4445SGunnar Mills     {
299ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["PersistentRegionNumberLimit"] =
300c1343bf6SKrzysztof Grobelny             *pmRegionNumberLimit;
301ac6a4445SGunnar Mills     }
302c1343bf6SKrzysztof Grobelny 
303c1343bf6SKrzysztof Grobelny     if (spareDeviceCount != nullptr)
304ac6a4445SGunnar Mills     {
305ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SpareDeviceCount"] =
306ac106bf6SEd Tanous             *spareDeviceCount;
307ac6a4445SGunnar Mills     }
308c1343bf6SKrzysztof Grobelny 
309c1343bf6SKrzysztof Grobelny     if (isSpareDeviceInUse != nullptr)
310ac6a4445SGunnar Mills     {
311ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["IsSpareDeviceEnabled"] =
312c1343bf6SKrzysztof Grobelny             *isSpareDeviceInUse;
313ac6a4445SGunnar Mills     }
314c1343bf6SKrzysztof Grobelny 
315c1343bf6SKrzysztof Grobelny     if (isRankSpareEnabled != nullptr)
316ac6a4445SGunnar Mills     {
317ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["IsRankSpareEnabled"] =
318c1343bf6SKrzysztof Grobelny             *isRankSpareEnabled;
319ac6a4445SGunnar Mills     }
320c1343bf6SKrzysztof Grobelny 
321c1343bf6SKrzysztof Grobelny     if (maxAveragePowerLimitmW != nullptr)
322ac6a4445SGunnar Mills     {
323ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MaxTDPMilliWatts"] =
324c1343bf6SKrzysztof Grobelny             *maxAveragePowerLimitmW;
325ac6a4445SGunnar Mills     }
326c1343bf6SKrzysztof Grobelny 
327c1343bf6SKrzysztof Grobelny     if (configurationLocked != nullptr)
328ac6a4445SGunnar Mills     {
329ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["ConfigurationLocked"] =
330c1343bf6SKrzysztof Grobelny             *configurationLocked;
331ac6a4445SGunnar Mills     }
332c1343bf6SKrzysztof Grobelny 
333c1343bf6SKrzysztof Grobelny     if (allowedMemoryModes != nullptr)
334ac6a4445SGunnar Mills     {
33580badf7cSJiaqing Zhao         constexpr const std::array<const char*, 3> values{"Volatile", "PMEM",
33680badf7cSJiaqing Zhao                                                           "Block"};
337ac6a4445SGunnar Mills 
338ac6a4445SGunnar Mills         for (const char* v : values)
339ac6a4445SGunnar Mills         {
340c1343bf6SKrzysztof Grobelny             if (allowedMemoryModes->ends_with(v))
341ac6a4445SGunnar Mills             {
342ac106bf6SEd Tanous                 asyncResp->res.jsonValue[jsonPtr]["OperatingMemoryModes"]
343ac106bf6SEd Tanous                     .push_back(v);
344ac6a4445SGunnar Mills                 break;
345ac6a4445SGunnar Mills             }
346ac6a4445SGunnar Mills         }
347ac6a4445SGunnar Mills     }
348c1343bf6SKrzysztof Grobelny 
349c1343bf6SKrzysztof Grobelny     if (memoryMedia != nullptr)
350ac6a4445SGunnar Mills     {
351ac6a4445SGunnar Mills         constexpr const std::array<const char*, 3> values{"DRAM", "NAND",
352ac6a4445SGunnar Mills                                                           "Intel3DXPoint"};
353ac6a4445SGunnar Mills 
354ac6a4445SGunnar Mills         for (const char* v : values)
355ac6a4445SGunnar Mills         {
356c1343bf6SKrzysztof Grobelny             if (memoryMedia->ends_with(v))
357ac6a4445SGunnar Mills             {
358ac106bf6SEd Tanous                 asyncResp->res.jsonValue[jsonPtr]["MemoryMedia"].push_back(v);
359ac6a4445SGunnar Mills                 break;
360ac6a4445SGunnar Mills             }
361ac6a4445SGunnar Mills         }
362ac6a4445SGunnar Mills     }
363c1343bf6SKrzysztof Grobelny 
364c1343bf6SKrzysztof Grobelny     if (configurationLockCapable != nullptr)
365ac6a4445SGunnar Mills     {
366ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
367c1343bf6SKrzysztof Grobelny                                 ["ConfigurationLockCapable"] =
368c1343bf6SKrzysztof Grobelny             *configurationLockCapable;
369ac6a4445SGunnar Mills     }
370c1343bf6SKrzysztof Grobelny 
371c1343bf6SKrzysztof Grobelny     if (dataLockCapable != nullptr)
372ac6a4445SGunnar Mills     {
373ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
37489492a15SPatrick Williams                                 ["DataLockCapable"] = *dataLockCapable;
375ac6a4445SGunnar Mills     }
376c1343bf6SKrzysztof Grobelny 
377c1343bf6SKrzysztof Grobelny     if (passphraseCapable != nullptr)
378c1343bf6SKrzysztof Grobelny     {
379ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
38089492a15SPatrick Williams                                 ["PassphraseCapable"] = *passphraseCapable;
381c1343bf6SKrzysztof Grobelny     }
382c1343bf6SKrzysztof Grobelny 
383c1343bf6SKrzysztof Grobelny     if (maxPassphraseCount != nullptr)
384c1343bf6SKrzysztof Grobelny     {
385ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
38689492a15SPatrick Williams                                 ["MaxPassphraseCount"] = *maxPassphraseCount;
387c1343bf6SKrzysztof Grobelny     }
388c1343bf6SKrzysztof Grobelny 
389c1343bf6SKrzysztof Grobelny     if (passphraseLockLimit != nullptr)
390c1343bf6SKrzysztof Grobelny     {
391ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
39289492a15SPatrick Williams                                 ["PassphraseLockLimit"] = *passphraseLockLimit;
393ac6a4445SGunnar Mills     }
394ac6a4445SGunnar Mills }
395ac6a4445SGunnar Mills 
3969a5aceacSNan Zhou inline void
3979a5aceacSNan Zhou     assembleDimmProperties(std::string_view dimmId,
398ac106bf6SEd Tanous                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
399d7f04fd9SNan Zhou                            const dbus::utility::DBusPropertiesMap& properties,
400d7f04fd9SNan Zhou                            const nlohmann::json::json_pointer& jsonPtr)
401ac6a4445SGunnar Mills {
402ac106bf6SEd Tanous     asyncResp->res.jsonValue[jsonPtr]["Id"] = dimmId;
403ac106bf6SEd Tanous     asyncResp->res.jsonValue[jsonPtr]["Name"] = "DIMM Slot";
404*539d8c6bSEd Tanous     asyncResp->res.jsonValue[jsonPtr]["Status"]["State"] =
405*539d8c6bSEd Tanous         resource::State::Enabled;
406*539d8c6bSEd Tanous     asyncResp->res.jsonValue[jsonPtr]["Status"]["Health"] =
407*539d8c6bSEd Tanous         resource::Health::OK;
408ac6a4445SGunnar Mills 
409c1343bf6SKrzysztof Grobelny     const uint16_t* memoryDataWidth = nullptr;
410c1343bf6SKrzysztof Grobelny     const size_t* memorySizeInKB = nullptr;
411c1343bf6SKrzysztof Grobelny     const std::string* partNumber = nullptr;
412c1343bf6SKrzysztof Grobelny     const std::string* serialNumber = nullptr;
413c1343bf6SKrzysztof Grobelny     const std::string* manufacturer = nullptr;
414c1343bf6SKrzysztof Grobelny     const uint16_t* revisionCode = nullptr;
415c1343bf6SKrzysztof Grobelny     const bool* present = nullptr;
416c1343bf6SKrzysztof Grobelny     const uint16_t* memoryTotalWidth = nullptr;
417c1343bf6SKrzysztof Grobelny     const std::string* ecc = nullptr;
418c1343bf6SKrzysztof Grobelny     const std::string* formFactor = nullptr;
419c1343bf6SKrzysztof Grobelny     const std::vector<uint16_t>* allowedSpeedsMT = nullptr;
4206995c1ceSGeorge Liu     const size_t* memoryAttributes = nullptr;
421c1343bf6SKrzysztof Grobelny     const uint16_t* memoryConfiguredSpeedInMhz = nullptr;
422c1343bf6SKrzysztof Grobelny     const std::string* memoryType = nullptr;
4236fde5971SJayaprakash Mutyala     const std::uint8_t* channel = nullptr;
4246fde5971SJayaprakash Mutyala     const std::uint8_t* memoryController = nullptr;
4256fde5971SJayaprakash Mutyala     const std::uint8_t* slot = nullptr;
4266fde5971SJayaprakash Mutyala     const std::uint8_t* socket = nullptr;
427c1343bf6SKrzysztof Grobelny     const std::string* sparePartNumber = nullptr;
428c1343bf6SKrzysztof Grobelny     const std::string* model = nullptr;
429c1343bf6SKrzysztof Grobelny     const std::string* locationCode = nullptr;
430ac6a4445SGunnar Mills 
431c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
432c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "MemoryDataWidth",
433c1343bf6SKrzysztof Grobelny         memoryDataWidth, "MemorySizeInKB", memorySizeInKB, "PartNumber",
434656472d9SNikhil Namjoshi         partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
435656472d9SNikhil Namjoshi         "RevisionCode", revisionCode, "Present", present, "MemoryTotalWidth",
436656472d9SNikhil Namjoshi         memoryTotalWidth, "ECC", ecc, "FormFactor", formFactor,
437656472d9SNikhil Namjoshi         "AllowedSpeedsMT", allowedSpeedsMT, "MemoryAttributes",
438c1343bf6SKrzysztof Grobelny         memoryAttributes, "MemoryConfiguredSpeedInMhz",
439c1343bf6SKrzysztof Grobelny         memoryConfiguredSpeedInMhz, "MemoryType", memoryType, "Channel",
440c1343bf6SKrzysztof Grobelny         channel, "MemoryController", memoryController, "Slot", slot, "Socket",
441c1343bf6SKrzysztof Grobelny         socket, "SparePartNumber", sparePartNumber, "Model", model,
442c1343bf6SKrzysztof Grobelny         "LocationCode", locationCode);
443c1343bf6SKrzysztof Grobelny 
444c1343bf6SKrzysztof Grobelny     if (!success)
445ac6a4445SGunnar Mills     {
446ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
447601af5edSChicago Duan         return;
448ac6a4445SGunnar Mills     }
449c1343bf6SKrzysztof Grobelny 
450c1343bf6SKrzysztof Grobelny     if (memoryDataWidth != nullptr)
451c1343bf6SKrzysztof Grobelny     {
452ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["DataWidthBits"] = *memoryDataWidth;
453c1343bf6SKrzysztof Grobelny     }
454c1343bf6SKrzysztof Grobelny 
455c1343bf6SKrzysztof Grobelny     if (memorySizeInKB != nullptr)
456c1343bf6SKrzysztof Grobelny     {
457ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["CapacityMiB"] =
458ac106bf6SEd Tanous             (*memorySizeInKB >> 10);
459c1343bf6SKrzysztof Grobelny     }
460c1343bf6SKrzysztof Grobelny 
461c1343bf6SKrzysztof Grobelny     if (partNumber != nullptr)
462c1343bf6SKrzysztof Grobelny     {
463ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["PartNumber"] = *partNumber;
464c1343bf6SKrzysztof Grobelny     }
465c1343bf6SKrzysztof Grobelny 
466c1343bf6SKrzysztof Grobelny     if (serialNumber != nullptr)
467c1343bf6SKrzysztof Grobelny     {
468ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SerialNumber"] = *serialNumber;
469c1343bf6SKrzysztof Grobelny     }
470c1343bf6SKrzysztof Grobelny 
471c1343bf6SKrzysztof Grobelny     if (manufacturer != nullptr)
472c1343bf6SKrzysztof Grobelny     {
473ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["Manufacturer"] = *manufacturer;
474c1343bf6SKrzysztof Grobelny     }
475c1343bf6SKrzysztof Grobelny 
476c1343bf6SKrzysztof Grobelny     if (revisionCode != nullptr)
477c1343bf6SKrzysztof Grobelny     {
478ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["FirmwareRevision"] =
479c1343bf6SKrzysztof Grobelny             std::to_string(*revisionCode);
480ac6a4445SGunnar Mills     }
481c1343bf6SKrzysztof Grobelny 
482c1343bf6SKrzysztof Grobelny     if (present != nullptr && !*present)
4839a128eb3SJoshi-Mansi     {
484*539d8c6bSEd Tanous         asyncResp->res.jsonValue[jsonPtr]["Status"]["State"] =
485*539d8c6bSEd Tanous             resource::State::Absent;
4869a128eb3SJoshi-Mansi     }
487c1343bf6SKrzysztof Grobelny 
488c1343bf6SKrzysztof Grobelny     if (memoryTotalWidth != nullptr)
489ac6a4445SGunnar Mills     {
490ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["BusWidthBits"] = *memoryTotalWidth;
491ac6a4445SGunnar Mills     }
492c1343bf6SKrzysztof Grobelny 
493c1343bf6SKrzysztof Grobelny     if (ecc != nullptr)
494ac6a4445SGunnar Mills     {
495ac6a4445SGunnar Mills         constexpr const std::array<const char*, 4> values{
4969a5aceacSNan Zhou             "NoECC", "SingleBitECC", "MultiBitECC", "AddressParity"};
497ac6a4445SGunnar Mills 
498ac6a4445SGunnar Mills         for (const char* v : values)
499ac6a4445SGunnar Mills         {
500c1343bf6SKrzysztof Grobelny             if (ecc->ends_with(v))
501ac6a4445SGunnar Mills             {
502ac106bf6SEd Tanous                 asyncResp->res.jsonValue[jsonPtr]["ErrorCorrection"] = v;
503ac6a4445SGunnar Mills                 break;
504ac6a4445SGunnar Mills             }
505ac6a4445SGunnar Mills         }
506ac6a4445SGunnar Mills     }
507c1343bf6SKrzysztof Grobelny 
508c1343bf6SKrzysztof Grobelny     if (formFactor != nullptr)
509ac6a4445SGunnar Mills     {
510ac6a4445SGunnar Mills         constexpr const std::array<const char*, 11> values{
5119a5aceacSNan Zhou             "RDIMM",       "UDIMM",       "SO_DIMM",      "LRDIMM",
5129a5aceacSNan Zhou             "Mini_RDIMM",  "Mini_UDIMM",  "SO_RDIMM_72b", "SO_UDIMM_72b",
5139a5aceacSNan Zhou             "SO_DIMM_16b", "SO_DIMM_32b", "Die"};
514ac6a4445SGunnar Mills 
515ac6a4445SGunnar Mills         for (const char* v : values)
516ac6a4445SGunnar Mills         {
517c1343bf6SKrzysztof Grobelny             if (formFactor->ends_with(v))
518ac6a4445SGunnar Mills             {
519ac106bf6SEd Tanous                 asyncResp->res.jsonValue[jsonPtr]["BaseModuleType"] = v;
520ac6a4445SGunnar Mills                 break;
521ac6a4445SGunnar Mills             }
522ac6a4445SGunnar Mills         }
523ac6a4445SGunnar Mills     }
524c1343bf6SKrzysztof Grobelny 
525c1343bf6SKrzysztof Grobelny     if (allowedSpeedsMT != nullptr)
526ac6a4445SGunnar Mills     {
527d7f04fd9SNan Zhou         nlohmann::json& jValue =
528ac106bf6SEd Tanous             asyncResp->res.jsonValue[jsonPtr]["AllowedSpeedsMHz"];
529ac6a4445SGunnar Mills         jValue = nlohmann::json::array();
530c1343bf6SKrzysztof Grobelny         for (uint16_t subVal : *allowedSpeedsMT)
531ac6a4445SGunnar Mills         {
532ac6a4445SGunnar Mills             jValue.push_back(subVal);
533ac6a4445SGunnar Mills         }
534ac6a4445SGunnar Mills     }
535ac6a4445SGunnar Mills 
536c1343bf6SKrzysztof Grobelny     if (memoryAttributes != nullptr)
537ac6a4445SGunnar Mills     {
5386995c1ceSGeorge Liu         asyncResp->res.jsonValue[jsonPtr]["RankCount"] = *memoryAttributes;
539ac6a4445SGunnar Mills     }
540c1343bf6SKrzysztof Grobelny 
541c1343bf6SKrzysztof Grobelny     if (memoryConfiguredSpeedInMhz != nullptr)
542ac6a4445SGunnar Mills     {
543ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["OperatingSpeedMhz"] =
544c1343bf6SKrzysztof Grobelny             *memoryConfiguredSpeedInMhz;
545ac6a4445SGunnar Mills     }
546c1343bf6SKrzysztof Grobelny 
547c1343bf6SKrzysztof Grobelny     if (memoryType != nullptr)
548ac6a4445SGunnar Mills     {
549313efb1cSGunnar Mills         std::string memoryDeviceType =
550c1343bf6SKrzysztof Grobelny             translateMemoryTypeToRedfish(*memoryType);
551313efb1cSGunnar Mills         // Values like "Unknown" or "Other" will return empty
552313efb1cSGunnar Mills         // so just leave off
553313efb1cSGunnar Mills         if (!memoryDeviceType.empty())
554ac6a4445SGunnar Mills         {
555ac106bf6SEd Tanous             asyncResp->res.jsonValue[jsonPtr]["MemoryDeviceType"] =
556d7f04fd9SNan Zhou                 memoryDeviceType;
557ac6a4445SGunnar Mills         }
558c1343bf6SKrzysztof Grobelny         if (memoryType->find("DDR") != std::string::npos)
559ac6a4445SGunnar Mills         {
560*539d8c6bSEd Tanous             asyncResp->res.jsonValue[jsonPtr]["MemoryType"] =
561*539d8c6bSEd Tanous                 memory::MemoryType::DRAM;
562ac6a4445SGunnar Mills         }
563c1343bf6SKrzysztof Grobelny         else if (memoryType->ends_with("Logical"))
564ac6a4445SGunnar Mills         {
565*539d8c6bSEd Tanous             asyncResp->res.jsonValue[jsonPtr]["MemoryType"] =
566*539d8c6bSEd Tanous                 memory::MemoryType::IntelOptane;
567ac6a4445SGunnar Mills         }
568ac6a4445SGunnar Mills     }
569c1343bf6SKrzysztof Grobelny 
570c1343bf6SKrzysztof Grobelny     if (channel != nullptr)
571ac6a4445SGunnar Mills     {
572ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Channel"] =
573ac106bf6SEd Tanous             *channel;
574c1343bf6SKrzysztof Grobelny     }
575c1343bf6SKrzysztof Grobelny 
576c1343bf6SKrzysztof Grobelny     if (memoryController != nullptr)
577ac6a4445SGunnar Mills     {
578ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]
579ac106bf6SEd Tanous                                 ["MemoryController"] = *memoryController;
580ac6a4445SGunnar Mills     }
581c1343bf6SKrzysztof Grobelny 
582c1343bf6SKrzysztof Grobelny     if (slot != nullptr)
583ee135e24SSunnySrivastava1984     {
584ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Slot"] = *slot;
585c1343bf6SKrzysztof Grobelny     }
586c1343bf6SKrzysztof Grobelny 
587c1343bf6SKrzysztof Grobelny     if (socket != nullptr)
588ee135e24SSunnySrivastava1984     {
589ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Socket"] = *socket;
590ee135e24SSunnySrivastava1984     }
591c1343bf6SKrzysztof Grobelny 
592c1343bf6SKrzysztof Grobelny     if (sparePartNumber != nullptr)
593ee135e24SSunnySrivastava1984     {
594ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SparePartNumber"] = *sparePartNumber;
595c1343bf6SKrzysztof Grobelny     }
596c1343bf6SKrzysztof Grobelny 
597c1343bf6SKrzysztof Grobelny     if (model != nullptr)
598ee135e24SSunnySrivastava1984     {
599ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["Model"] = *model;
600ee135e24SSunnySrivastava1984     }
601c1343bf6SKrzysztof Grobelny 
602c1343bf6SKrzysztof Grobelny     if (locationCode != nullptr)
603ee135e24SSunnySrivastava1984     {
604ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["Location"]["PartLocation"]
60589492a15SPatrick Williams                                 ["ServiceLabel"] = *locationCode;
606ee135e24SSunnySrivastava1984     }
607c1343bf6SKrzysztof Grobelny 
608ac106bf6SEd Tanous     getPersistentMemoryProperties(asyncResp, properties, jsonPtr);
6099a5aceacSNan Zhou }
6109a5aceacSNan Zhou 
611ac106bf6SEd Tanous inline void getDimmDataByService(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
6129a5aceacSNan Zhou                                  const std::string& dimmId,
6139a5aceacSNan Zhou                                  const std::string& service,
6149a5aceacSNan Zhou                                  const std::string& objPath)
6159a5aceacSNan Zhou {
61662598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get available system components.");
617c1343bf6SKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
618c1343bf6SKrzysztof Grobelny         *crow::connections::systemBus, service, objPath, "",
619ac106bf6SEd Tanous         [dimmId, asyncResp{std::move(asyncResp)}](
6205e7e2dc5SEd Tanous             const boost::system::error_code& ec,
6219a5aceacSNan Zhou             const dbus::utility::DBusPropertiesMap& properties) {
6229a5aceacSNan Zhou         if (ec)
6239a5aceacSNan Zhou         {
62462598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error");
625ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
6269a5aceacSNan Zhou             return;
6279a5aceacSNan Zhou         }
628ac106bf6SEd Tanous         assembleDimmProperties(dimmId, asyncResp, properties, ""_json_pointer);
629c1343bf6SKrzysztof Grobelny     });
630ac6a4445SGunnar Mills }
631ac6a4445SGunnar Mills 
632ef00d7d4SNan Zhou inline void assembleDimmPartitionData(
633ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
634d7f04fd9SNan Zhou     const dbus::utility::DBusPropertiesMap& properties,
635d7f04fd9SNan Zhou     const nlohmann::json::json_pointer& regionPtr)
636ac6a4445SGunnar Mills {
637c1343bf6SKrzysztof Grobelny     const std::string* memoryClassification = nullptr;
638c1343bf6SKrzysztof Grobelny     const uint64_t* offsetInKiB = nullptr;
639c1343bf6SKrzysztof Grobelny     const std::string* partitionId = nullptr;
640c1343bf6SKrzysztof Grobelny     const bool* passphraseState = nullptr;
641c1343bf6SKrzysztof Grobelny     const uint64_t* sizeInKiB = nullptr;
642c1343bf6SKrzysztof Grobelny 
643c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
644c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "MemoryClassification",
645c1343bf6SKrzysztof Grobelny         memoryClassification, "OffsetInKiB", offsetInKiB, "PartitionId",
646c1343bf6SKrzysztof Grobelny         partitionId, "PassphraseState", passphraseState, "SizeInKiB",
647c1343bf6SKrzysztof Grobelny         sizeInKiB);
648c1343bf6SKrzysztof Grobelny 
649c1343bf6SKrzysztof Grobelny     if (!success)
650c1343bf6SKrzysztof Grobelny     {
651ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
652c1343bf6SKrzysztof Grobelny         return;
653c1343bf6SKrzysztof Grobelny     }
654c1343bf6SKrzysztof Grobelny 
655d7f04fd9SNan Zhou     nlohmann::json::object_t partition;
656c1343bf6SKrzysztof Grobelny 
657c1343bf6SKrzysztof Grobelny     if (memoryClassification != nullptr)
658ac6a4445SGunnar Mills     {
659c1343bf6SKrzysztof Grobelny         partition["MemoryClassification"] = *memoryClassification;
660ac6a4445SGunnar Mills     }
661ac6a4445SGunnar Mills 
662c1343bf6SKrzysztof Grobelny     if (offsetInKiB != nullptr)
663ac6a4445SGunnar Mills     {
664c1343bf6SKrzysztof Grobelny         partition["OffsetMiB"] = (*offsetInKiB >> 10);
665ac6a4445SGunnar Mills     }
666ac6a4445SGunnar Mills 
667c1343bf6SKrzysztof Grobelny     if (partitionId != nullptr)
668ac6a4445SGunnar Mills     {
669c1343bf6SKrzysztof Grobelny         partition["RegionId"] = *partitionId;
670c1343bf6SKrzysztof Grobelny     }
671c1343bf6SKrzysztof Grobelny 
672c1343bf6SKrzysztof Grobelny     if (passphraseState != nullptr)
673ac6a4445SGunnar Mills     {
674c1343bf6SKrzysztof Grobelny         partition["PassphraseEnabled"] = *passphraseState;
675ac6a4445SGunnar Mills     }
676c1343bf6SKrzysztof Grobelny 
677c1343bf6SKrzysztof Grobelny     if (sizeInKiB != nullptr)
678ac6a4445SGunnar Mills     {
679c1343bf6SKrzysztof Grobelny         partition["SizeMiB"] = (*sizeInKiB >> 10);
680ac6a4445SGunnar Mills     }
681c1343bf6SKrzysztof Grobelny 
682ac106bf6SEd Tanous     asyncResp->res.jsonValue[regionPtr].emplace_back(std::move(partition));
683ef00d7d4SNan Zhou }
684ef00d7d4SNan Zhou 
685ac106bf6SEd Tanous inline void getDimmPartitionData(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
686ef00d7d4SNan Zhou                                  const std::string& service,
687ef00d7d4SNan Zhou                                  const std::string& path)
688ef00d7d4SNan Zhou {
689c1343bf6SKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
690c1343bf6SKrzysztof Grobelny         *crow::connections::systemBus, service, path,
691c1343bf6SKrzysztof Grobelny         "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition",
692ac106bf6SEd Tanous         [asyncResp{std::move(asyncResp)}](
6935e7e2dc5SEd Tanous             const boost::system::error_code& ec,
694ef00d7d4SNan Zhou             const dbus::utility::DBusPropertiesMap& properties) {
695ef00d7d4SNan Zhou         if (ec)
696ef00d7d4SNan Zhou         {
69762598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error");
698ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
699ef00d7d4SNan Zhou 
700ef00d7d4SNan Zhou             return;
701ef00d7d4SNan Zhou         }
702d7f04fd9SNan Zhou         nlohmann::json::json_pointer regionPtr = "/Regions"_json_pointer;
703ac106bf6SEd Tanous         assembleDimmPartitionData(asyncResp, properties, regionPtr);
704c1343bf6SKrzysztof Grobelny     }
705ac6a4445SGunnar Mills 
706c1343bf6SKrzysztof Grobelny     );
707ac6a4445SGunnar Mills }
708ac6a4445SGunnar Mills 
709ac106bf6SEd Tanous inline void getDimmData(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
710ac6a4445SGunnar Mills                         const std::string& dimmId)
711ac6a4445SGunnar Mills {
71262598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get available system dimm resources.");
713e99073f5SGeorge Liu     constexpr std::array<std::string_view, 2> dimmInterfaces = {
714e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Dimm",
715e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"};
716e99073f5SGeorge Liu     dbus::utility::getSubTree(
717e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, dimmInterfaces,
718ac106bf6SEd Tanous         [dimmId, asyncResp{std::move(asyncResp)}](
719e99073f5SGeorge Liu             const boost::system::error_code& ec,
720b9d36b47SEd Tanous             const dbus::utility::MapperGetSubTreeResponse& subtree) {
721ac6a4445SGunnar Mills         if (ec)
722ac6a4445SGunnar Mills         {
72362598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error");
724ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
725ac6a4445SGunnar Mills 
726ac6a4445SGunnar Mills             return;
727ac6a4445SGunnar Mills         }
728ac6a4445SGunnar Mills         bool found = false;
72976686dccSNan Zhou         for (const auto& [rawPath, object] : subtree)
730ac6a4445SGunnar Mills         {
73176686dccSNan Zhou             sdbusplus::message::object_path path(rawPath);
732ac6a4445SGunnar Mills             for (const auto& [service, interfaces] : object)
733ac6a4445SGunnar Mills             {
734b9d36b47SEd Tanous                 for (const auto& interface : interfaces)
735ac6a4445SGunnar Mills                 {
736b9d36b47SEd Tanous                     if (interface ==
73776686dccSNan Zhou                             "xyz.openbmc_project.Inventory.Item.Dimm" &&
73876686dccSNan Zhou                         path.filename() == dimmId)
739b9d36b47SEd Tanous                     {
740ac106bf6SEd Tanous                         getDimmDataByService(asyncResp, dimmId, service,
741ac106bf6SEd Tanous                                              rawPath);
742ac6a4445SGunnar Mills                         found = true;
743ac6a4445SGunnar Mills                     }
744ac6a4445SGunnar Mills 
745b9d36b47SEd Tanous                     // partitions are separate as there can be multiple
746b9d36b47SEd Tanous                     // per
747ac6a4445SGunnar Mills                     // device, i.e.
748ac6a4445SGunnar Mills                     // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1
749ac6a4445SGunnar Mills                     // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2
750b9d36b47SEd Tanous                     if (interface ==
75176686dccSNan Zhou                             "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition" &&
75276686dccSNan Zhou                         path.parent_path().filename() == dimmId)
753ac6a4445SGunnar Mills                     {
754ac106bf6SEd Tanous                         getDimmPartitionData(asyncResp, service, rawPath);
755ac6a4445SGunnar Mills                     }
756ac6a4445SGunnar Mills                 }
757ac6a4445SGunnar Mills             }
758b9d36b47SEd Tanous         }
759ac6a4445SGunnar Mills         // Object not found
760ac6a4445SGunnar Mills         if (!found)
761ac6a4445SGunnar Mills         {
762ac106bf6SEd Tanous             messages::resourceNotFound(asyncResp->res, "Memory", dimmId);
7631a1d5d6dSNan Zhou             return;
764ac6a4445SGunnar Mills         }
7651a1d5d6dSNan Zhou         // Set @odata only if object is found
766ac106bf6SEd Tanous         asyncResp->res.jsonValue["@odata.type"] = "#Memory.v1_11_0.Memory";
767ac106bf6SEd Tanous         asyncResp->res.jsonValue["@odata.id"] =
768253f11b8SEd Tanous             boost::urls::format("/redfish/v1/Systems/{}/Memory/{}",
769253f11b8SEd Tanous                                 BMCWEB_REDFISH_SYSTEM_URI_NAME, 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         }
78925b54dbaSEd Tanous         if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
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         }
796253f11b8SEd Tanous         if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
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";
806253f11b8SEd Tanous         asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
807253f11b8SEd Tanous             "/redfish/v1/Systems/{}/Memory", BMCWEB_REDFISH_SYSTEM_URI_NAME);
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(
812253f11b8SEd Tanous             asyncResp,
813253f11b8SEd Tanous             boost::urls::format("/redfish/v1/Systems/{}/Memory",
814253f11b8SEd Tanous                                 BMCWEB_REDFISH_SYSTEM_URI_NAME),
81536b5f1edSLakshmi Yadlapati             interfaces, "/xyz/openbmc_project/inventory");
8167e860f15SJohn Edward Broadbent     });
817ac6a4445SGunnar Mills }
818ac6a4445SGunnar Mills 
8197e860f15SJohn Edward Broadbent inline void requestRoutesMemory(App& app)
8207e860f15SJohn Edward Broadbent {
821ac6a4445SGunnar Mills     /**
822ac6a4445SGunnar Mills      * Functions triggers appropriate requests on DBus
823ac6a4445SGunnar Mills      */
82422d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/<str>/")
825ed398213SEd Tanous         .privileges(redfish::privileges::getMemory)
8267e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
82745ca1b86SEd Tanous             [&app](const crow::Request& req,
8287e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
82922d268cbSEd Tanous                    const std::string& systemName, const std::string& dimmId) {
8303ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
83145ca1b86SEd Tanous         {
83245ca1b86SEd Tanous             return;
83345ca1b86SEd Tanous         }
8347f3e84a1SEd Tanous 
83525b54dbaSEd Tanous         if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
8367f3e84a1SEd Tanous         {
8377f3e84a1SEd Tanous             // Option currently returns no systems.  TBD
8387f3e84a1SEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
8397f3e84a1SEd Tanous                                        systemName);
8407f3e84a1SEd Tanous             return;
8417f3e84a1SEd Tanous         }
8427f3e84a1SEd Tanous 
843253f11b8SEd Tanous         if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
84422d268cbSEd Tanous         {
84522d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
84622d268cbSEd Tanous                                        systemName);
84722d268cbSEd Tanous             return;
84822d268cbSEd Tanous         }
84922d268cbSEd Tanous 
850ac6a4445SGunnar Mills         getDimmData(asyncResp, dimmId);
8517e860f15SJohn Edward Broadbent     });
852ac6a4445SGunnar Mills }
853ac6a4445SGunnar Mills 
854ac6a4445SGunnar Mills } // namespace redfish
855