xref: /openbmc/bmcweb/features/redfish/lib/memory.hpp (revision 25b54dba775b31021a3a4677eb79e9771bcb97f7)
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"
223ccb3adbSEd Tanous #include "query.hpp"
233ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
243ccb3adbSEd Tanous #include "utils/collection.hpp"
253ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
263ccb3adbSEd Tanous #include "utils/hex_utils.hpp"
273ccb3adbSEd Tanous #include "utils/json_utils.hpp"
28ac6a4445SGunnar Mills 
29e99073f5SGeorge Liu #include <boost/system/error_code.hpp>
30ef4c65b7SEd Tanous #include <boost/url/format.hpp>
31d7f04fd9SNan Zhou #include <nlohmann/json.hpp>
32c1343bf6SKrzysztof Grobelny #include <sdbusplus/asio/property.hpp>
33c1343bf6SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
34ac6a4445SGunnar Mills 
357a1dbc48SGeorge Liu #include <array>
367a1dbc48SGeorge Liu #include <string_view>
377a1dbc48SGeorge Liu 
38ac6a4445SGunnar Mills namespace redfish
39ac6a4445SGunnar Mills {
40ac6a4445SGunnar Mills 
41313efb1cSGunnar Mills inline std::string translateMemoryTypeToRedfish(const std::string& memoryType)
42313efb1cSGunnar Mills {
43313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR")
44313efb1cSGunnar Mills     {
45313efb1cSGunnar Mills         return "DDR";
46313efb1cSGunnar Mills     }
47313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2")
48313efb1cSGunnar Mills     {
49313efb1cSGunnar Mills         return "DDR2";
50313efb1cSGunnar Mills     }
51313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR3")
52313efb1cSGunnar Mills     {
53313efb1cSGunnar Mills         return "DDR3";
54313efb1cSGunnar Mills     }
55313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4")
56313efb1cSGunnar Mills     {
57313efb1cSGunnar Mills         return "DDR4";
58313efb1cSGunnar Mills     }
59313efb1cSGunnar Mills     if (memoryType ==
60313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4E_SDRAM")
61313efb1cSGunnar Mills     {
62313efb1cSGunnar Mills         return "DDR4E_SDRAM";
63313efb1cSGunnar Mills     }
6411a2f0f0SMansi Joshi     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR5")
6511a2f0f0SMansi Joshi     {
6611a2f0f0SMansi Joshi         return "DDR5";
6711a2f0f0SMansi Joshi     }
68313efb1cSGunnar Mills     if (memoryType ==
69313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR4_SDRAM")
70313efb1cSGunnar Mills     {
71313efb1cSGunnar Mills         return "LPDDR4_SDRAM";
72313efb1cSGunnar Mills     }
73313efb1cSGunnar Mills     if (memoryType ==
74313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR3_SDRAM")
75313efb1cSGunnar Mills     {
76313efb1cSGunnar Mills         return "LPDDR3_SDRAM";
77313efb1cSGunnar Mills     }
78313efb1cSGunnar Mills     if (memoryType ==
79313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM")
80313efb1cSGunnar Mills     {
81313efb1cSGunnar Mills         return "DDR2_SDRAM_FB_DIMM";
82313efb1cSGunnar Mills     }
830fda0f12SGeorge Liu     if (memoryType ==
840fda0f12SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM_PROB")
85313efb1cSGunnar Mills     {
86313efb1cSGunnar Mills         return "DDR2_SDRAM_FB_DIMM_PROBE";
87313efb1cSGunnar Mills     }
88313efb1cSGunnar Mills     if (memoryType ==
89313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR_SGRAM")
90313efb1cSGunnar Mills     {
91313efb1cSGunnar Mills         return "DDR_SGRAM";
92313efb1cSGunnar Mills     }
93313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.ROM")
94313efb1cSGunnar Mills     {
95313efb1cSGunnar Mills         return "ROM";
96313efb1cSGunnar Mills     }
97313efb1cSGunnar Mills     if (memoryType ==
98313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.SDRAM")
99313efb1cSGunnar Mills     {
100313efb1cSGunnar Mills         return "SDRAM";
101313efb1cSGunnar Mills     }
102313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.EDO")
103313efb1cSGunnar Mills     {
104313efb1cSGunnar Mills         return "EDO";
105313efb1cSGunnar Mills     }
106313efb1cSGunnar Mills     if (memoryType ==
107313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.FastPageMode")
108313efb1cSGunnar Mills     {
109313efb1cSGunnar Mills         return "FastPageMode";
110313efb1cSGunnar Mills     }
111313efb1cSGunnar Mills     if (memoryType ==
112313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.PipelinedNibble")
113313efb1cSGunnar Mills     {
114313efb1cSGunnar Mills         return "PipelinedNibble";
115313efb1cSGunnar Mills     }
116313efb1cSGunnar Mills     if (memoryType ==
117313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.Logical")
118313efb1cSGunnar Mills     {
119313efb1cSGunnar Mills         return "Logical";
120313efb1cSGunnar Mills     }
121313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM")
122313efb1cSGunnar Mills     {
123313efb1cSGunnar Mills         return "HBM";
124313efb1cSGunnar Mills     }
125313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM2")
126313efb1cSGunnar Mills     {
127313efb1cSGunnar Mills         return "HBM2";
128313efb1cSGunnar Mills     }
129ce34d514STyson Tuckerbear     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM3")
130ce34d514STyson Tuckerbear     {
131ce34d514STyson Tuckerbear         return "HBM3";
132ce34d514STyson Tuckerbear     }
133313efb1cSGunnar Mills     // This is values like Other or Unknown
134313efb1cSGunnar Mills     // Also D-Bus values:
135313efb1cSGunnar Mills     // DRAM
136313efb1cSGunnar Mills     // EDRAM
137313efb1cSGunnar Mills     // VRAM
138313efb1cSGunnar Mills     // SRAM
139313efb1cSGunnar Mills     // RAM
140313efb1cSGunnar Mills     // FLASH
141313efb1cSGunnar Mills     // EEPROM
142313efb1cSGunnar Mills     // FEPROM
143313efb1cSGunnar Mills     // EPROM
144313efb1cSGunnar Mills     // CDRAM
145313efb1cSGunnar Mills     // ThreeDRAM
146313efb1cSGunnar Mills     // RDRAM
147313efb1cSGunnar Mills     // FBD2
148313efb1cSGunnar Mills     // LPDDR_SDRAM
149313efb1cSGunnar Mills     // LPDDR2_SDRAM
15011a2f0f0SMansi Joshi     // LPDDR5_SDRAM
151313efb1cSGunnar Mills     return "";
152313efb1cSGunnar Mills }
153313efb1cSGunnar Mills 
154ac106bf6SEd Tanous inline void dimmPropToHex(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
155c1343bf6SKrzysztof Grobelny                           const char* key, const uint16_t* value,
156d7f04fd9SNan Zhou                           const nlohmann::json::json_pointer& jsonPtr)
157ac6a4445SGunnar Mills {
158ac6a4445SGunnar Mills     if (value == nullptr)
159ac6a4445SGunnar Mills     {
160ac6a4445SGunnar Mills         return;
161ac6a4445SGunnar Mills     }
162ac106bf6SEd Tanous     asyncResp->res.jsonValue[jsonPtr][key] = "0x" + intToHexString(*value, 4);
163ac6a4445SGunnar Mills }
164ac6a4445SGunnar Mills 
1658d1b46d7Szhanghch05 inline void getPersistentMemoryProperties(
166ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
167c1343bf6SKrzysztof Grobelny     const dbus::utility::DBusPropertiesMap& properties,
168d7f04fd9SNan Zhou     const nlohmann::json::json_pointer& jsonPtr)
169ac6a4445SGunnar Mills {
170c1343bf6SKrzysztof Grobelny     const uint16_t* moduleManufacturerID = nullptr;
171c1343bf6SKrzysztof Grobelny     const uint16_t* moduleProductID = nullptr;
172c1343bf6SKrzysztof Grobelny     const uint16_t* subsystemVendorID = nullptr;
173c1343bf6SKrzysztof Grobelny     const uint16_t* subsystemDeviceID = nullptr;
174c1343bf6SKrzysztof Grobelny     const uint64_t* volatileRegionSizeLimitInKiB = nullptr;
175c1343bf6SKrzysztof Grobelny     const uint64_t* pmRegionSizeLimitInKiB = nullptr;
176c1343bf6SKrzysztof Grobelny     const uint64_t* volatileSizeInKiB = nullptr;
177c1343bf6SKrzysztof Grobelny     const uint64_t* pmSizeInKiB = nullptr;
178c1343bf6SKrzysztof Grobelny     const uint64_t* cacheSizeInKB = nullptr;
179c1343bf6SKrzysztof Grobelny     const uint64_t* voltaileRegionMaxSizeInKib = nullptr;
180c1343bf6SKrzysztof Grobelny     const uint64_t* pmRegionMaxSizeInKiB = nullptr;
181c1343bf6SKrzysztof Grobelny     const uint64_t* allocationIncrementInKiB = nullptr;
182c1343bf6SKrzysztof Grobelny     const uint64_t* allocationAlignmentInKiB = nullptr;
183c1343bf6SKrzysztof Grobelny     const uint64_t* volatileRegionNumberLimit = nullptr;
184c1343bf6SKrzysztof Grobelny     const uint64_t* pmRegionNumberLimit = nullptr;
185c1343bf6SKrzysztof Grobelny     const uint64_t* spareDeviceCount = nullptr;
186c1343bf6SKrzysztof Grobelny     const bool* isSpareDeviceInUse = nullptr;
187c1343bf6SKrzysztof Grobelny     const bool* isRankSpareEnabled = nullptr;
188c1343bf6SKrzysztof Grobelny     const std::vector<uint32_t>* maxAveragePowerLimitmW = nullptr;
189c1343bf6SKrzysztof Grobelny     const bool* configurationLocked = nullptr;
190c1343bf6SKrzysztof Grobelny     const std::string* allowedMemoryModes = nullptr;
191c1343bf6SKrzysztof Grobelny     const std::string* memoryMedia = nullptr;
192c1343bf6SKrzysztof Grobelny     const bool* configurationLockCapable = nullptr;
193c1343bf6SKrzysztof Grobelny     const bool* dataLockCapable = nullptr;
194c1343bf6SKrzysztof Grobelny     const bool* passphraseCapable = nullptr;
195c1343bf6SKrzysztof Grobelny     const uint64_t* maxPassphraseCount = nullptr;
196c1343bf6SKrzysztof Grobelny     const uint64_t* passphraseLockLimit = nullptr;
197c1343bf6SKrzysztof Grobelny 
198c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
199c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "ModuleManufacturerID",
200c1343bf6SKrzysztof Grobelny         moduleManufacturerID, "ModuleProductID", moduleProductID,
201c1343bf6SKrzysztof Grobelny         "SubsystemVendorID", subsystemVendorID, "SubsystemDeviceID",
202c1343bf6SKrzysztof Grobelny         subsystemDeviceID, "VolatileRegionSizeLimitInKiB",
203c1343bf6SKrzysztof Grobelny         volatileRegionSizeLimitInKiB, "PmRegionSizeLimitInKiB",
204c1343bf6SKrzysztof Grobelny         pmRegionSizeLimitInKiB, "VolatileSizeInKiB", volatileSizeInKiB,
205c1343bf6SKrzysztof Grobelny         "PmSizeInKiB", pmSizeInKiB, "CacheSizeInKB", cacheSizeInKB,
206c1343bf6SKrzysztof Grobelny         "VoltaileRegionMaxSizeInKib", voltaileRegionMaxSizeInKib,
207c1343bf6SKrzysztof Grobelny         "PmRegionMaxSizeInKiB", pmRegionMaxSizeInKiB,
208c1343bf6SKrzysztof Grobelny         "AllocationIncrementInKiB", allocationIncrementInKiB,
209c1343bf6SKrzysztof Grobelny         "AllocationAlignmentInKiB", allocationAlignmentInKiB,
210c1343bf6SKrzysztof Grobelny         "VolatileRegionNumberLimit", volatileRegionNumberLimit,
211c1343bf6SKrzysztof Grobelny         "PmRegionNumberLimit", pmRegionNumberLimit, "SpareDeviceCount",
212c1343bf6SKrzysztof Grobelny         spareDeviceCount, "IsSpareDeviceInUse", isSpareDeviceInUse,
213c1343bf6SKrzysztof Grobelny         "IsRankSpareEnabled", isRankSpareEnabled, "MaxAveragePowerLimitmW",
214c1343bf6SKrzysztof Grobelny         maxAveragePowerLimitmW, "ConfigurationLocked", configurationLocked,
215c1343bf6SKrzysztof Grobelny         "AllowedMemoryModes", allowedMemoryModes, "MemoryMedia", memoryMedia,
216c1343bf6SKrzysztof Grobelny         "ConfigurationLockCapable", configurationLockCapable, "DataLockCapable",
217c1343bf6SKrzysztof Grobelny         dataLockCapable, "PassphraseCapable", passphraseCapable,
218c1343bf6SKrzysztof Grobelny         "MaxPassphraseCount", maxPassphraseCount, "PassphraseLockLimit",
219c1343bf6SKrzysztof Grobelny         passphraseLockLimit);
220c1343bf6SKrzysztof Grobelny 
221c1343bf6SKrzysztof Grobelny     if (!success)
222ac6a4445SGunnar Mills     {
223ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
224c1343bf6SKrzysztof Grobelny         return;
225ac6a4445SGunnar Mills     }
226c1343bf6SKrzysztof Grobelny 
227ac106bf6SEd Tanous     dimmPropToHex(asyncResp, "ModuleManufacturerID", moduleManufacturerID,
228ac106bf6SEd Tanous                   jsonPtr);
229ac106bf6SEd Tanous     dimmPropToHex(asyncResp, "ModuleProductID", moduleProductID, jsonPtr);
230ac106bf6SEd Tanous     dimmPropToHex(asyncResp, "MemorySubsystemControllerManufacturerID",
231c1343bf6SKrzysztof Grobelny                   subsystemVendorID, jsonPtr);
232ac106bf6SEd Tanous     dimmPropToHex(asyncResp, "MemorySubsystemControllerProductID",
233c1343bf6SKrzysztof Grobelny                   subsystemDeviceID, jsonPtr);
234ac6a4445SGunnar Mills 
235c1343bf6SKrzysztof Grobelny     if (volatileRegionSizeLimitInKiB != nullptr)
236ac6a4445SGunnar Mills     {
237ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["VolatileRegionSizeLimitMiB"] =
238c1343bf6SKrzysztof Grobelny             (*volatileRegionSizeLimitInKiB) >> 10;
239ac6a4445SGunnar Mills     }
240ac6a4445SGunnar Mills 
241c1343bf6SKrzysztof Grobelny     if (pmRegionSizeLimitInKiB != nullptr)
242ac6a4445SGunnar Mills     {
243ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["PersistentRegionSizeLimitMiB"] =
244c1343bf6SKrzysztof Grobelny             (*pmRegionSizeLimitInKiB) >> 10;
245ac6a4445SGunnar Mills     }
246ac6a4445SGunnar Mills 
247c1343bf6SKrzysztof Grobelny     if (volatileSizeInKiB != nullptr)
248ac6a4445SGunnar Mills     {
249ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["VolatileSizeMiB"] =
250c1343bf6SKrzysztof Grobelny             (*volatileSizeInKiB) >> 10;
251ac6a4445SGunnar Mills     }
252c1343bf6SKrzysztof Grobelny 
253c1343bf6SKrzysztof Grobelny     if (pmSizeInKiB != nullptr)
254c1343bf6SKrzysztof Grobelny     {
255ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["NonVolatileSizeMiB"] =
256ac106bf6SEd Tanous             (*pmSizeInKiB) >> 10;
257c1343bf6SKrzysztof Grobelny     }
258c1343bf6SKrzysztof Grobelny 
259c1343bf6SKrzysztof Grobelny     if (cacheSizeInKB != nullptr)
260c1343bf6SKrzysztof Grobelny     {
261ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["CacheSizeMiB"] =
262ac106bf6SEd Tanous             (*cacheSizeInKB >> 10);
263c1343bf6SKrzysztof Grobelny     }
264c1343bf6SKrzysztof Grobelny 
265c1343bf6SKrzysztof Grobelny     if (voltaileRegionMaxSizeInKib != nullptr)
266c1343bf6SKrzysztof Grobelny     {
267ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["VolatileRegionSizeMaxMiB"] =
268c1343bf6SKrzysztof Grobelny             (*voltaileRegionMaxSizeInKib) >> 10;
269ac6a4445SGunnar Mills     }
270ac6a4445SGunnar Mills 
271c1343bf6SKrzysztof Grobelny     if (pmRegionMaxSizeInKiB != nullptr)
272ac6a4445SGunnar Mills     {
273ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["PersistentRegionSizeMaxMiB"] =
274c1343bf6SKrzysztof Grobelny             (*pmRegionMaxSizeInKiB) >> 10;
275ac6a4445SGunnar Mills     }
276ac6a4445SGunnar Mills 
277c1343bf6SKrzysztof Grobelny     if (allocationIncrementInKiB != nullptr)
278ac6a4445SGunnar Mills     {
279ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["AllocationIncrementMiB"] =
280c1343bf6SKrzysztof Grobelny             (*allocationIncrementInKiB) >> 10;
281ac6a4445SGunnar Mills     }
282ac6a4445SGunnar Mills 
283c1343bf6SKrzysztof Grobelny     if (allocationAlignmentInKiB != nullptr)
284ac6a4445SGunnar Mills     {
285ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["AllocationAlignmentMiB"] =
286c1343bf6SKrzysztof Grobelny             (*allocationAlignmentInKiB) >> 10;
287ac6a4445SGunnar Mills     }
288c1343bf6SKrzysztof Grobelny 
289c1343bf6SKrzysztof Grobelny     if (volatileRegionNumberLimit != nullptr)
290ac6a4445SGunnar Mills     {
291ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["VolatileRegionNumberLimit"] =
292c1343bf6SKrzysztof Grobelny             *volatileRegionNumberLimit;
293ac6a4445SGunnar Mills     }
294c1343bf6SKrzysztof Grobelny 
295c1343bf6SKrzysztof Grobelny     if (pmRegionNumberLimit != nullptr)
296ac6a4445SGunnar Mills     {
297ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["PersistentRegionNumberLimit"] =
298c1343bf6SKrzysztof Grobelny             *pmRegionNumberLimit;
299ac6a4445SGunnar Mills     }
300c1343bf6SKrzysztof Grobelny 
301c1343bf6SKrzysztof Grobelny     if (spareDeviceCount != nullptr)
302ac6a4445SGunnar Mills     {
303ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SpareDeviceCount"] =
304ac106bf6SEd Tanous             *spareDeviceCount;
305ac6a4445SGunnar Mills     }
306c1343bf6SKrzysztof Grobelny 
307c1343bf6SKrzysztof Grobelny     if (isSpareDeviceInUse != nullptr)
308ac6a4445SGunnar Mills     {
309ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["IsSpareDeviceEnabled"] =
310c1343bf6SKrzysztof Grobelny             *isSpareDeviceInUse;
311ac6a4445SGunnar Mills     }
312c1343bf6SKrzysztof Grobelny 
313c1343bf6SKrzysztof Grobelny     if (isRankSpareEnabled != nullptr)
314ac6a4445SGunnar Mills     {
315ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["IsRankSpareEnabled"] =
316c1343bf6SKrzysztof Grobelny             *isRankSpareEnabled;
317ac6a4445SGunnar Mills     }
318c1343bf6SKrzysztof Grobelny 
319c1343bf6SKrzysztof Grobelny     if (maxAveragePowerLimitmW != nullptr)
320ac6a4445SGunnar Mills     {
321ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MaxTDPMilliWatts"] =
322c1343bf6SKrzysztof Grobelny             *maxAveragePowerLimitmW;
323ac6a4445SGunnar Mills     }
324c1343bf6SKrzysztof Grobelny 
325c1343bf6SKrzysztof Grobelny     if (configurationLocked != nullptr)
326ac6a4445SGunnar Mills     {
327ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["ConfigurationLocked"] =
328c1343bf6SKrzysztof Grobelny             *configurationLocked;
329ac6a4445SGunnar Mills     }
330c1343bf6SKrzysztof Grobelny 
331c1343bf6SKrzysztof Grobelny     if (allowedMemoryModes != nullptr)
332ac6a4445SGunnar Mills     {
33380badf7cSJiaqing Zhao         constexpr const std::array<const char*, 3> values{"Volatile", "PMEM",
33480badf7cSJiaqing Zhao                                                           "Block"};
335ac6a4445SGunnar Mills 
336ac6a4445SGunnar Mills         for (const char* v : values)
337ac6a4445SGunnar Mills         {
338c1343bf6SKrzysztof Grobelny             if (allowedMemoryModes->ends_with(v))
339ac6a4445SGunnar Mills             {
340ac106bf6SEd Tanous                 asyncResp->res.jsonValue[jsonPtr]["OperatingMemoryModes"]
341ac106bf6SEd Tanous                     .push_back(v);
342ac6a4445SGunnar Mills                 break;
343ac6a4445SGunnar Mills             }
344ac6a4445SGunnar Mills         }
345ac6a4445SGunnar Mills     }
346c1343bf6SKrzysztof Grobelny 
347c1343bf6SKrzysztof Grobelny     if (memoryMedia != nullptr)
348ac6a4445SGunnar Mills     {
349ac6a4445SGunnar Mills         constexpr const std::array<const char*, 3> values{"DRAM", "NAND",
350ac6a4445SGunnar Mills                                                           "Intel3DXPoint"};
351ac6a4445SGunnar Mills 
352ac6a4445SGunnar Mills         for (const char* v : values)
353ac6a4445SGunnar Mills         {
354c1343bf6SKrzysztof Grobelny             if (memoryMedia->ends_with(v))
355ac6a4445SGunnar Mills             {
356ac106bf6SEd Tanous                 asyncResp->res.jsonValue[jsonPtr]["MemoryMedia"].push_back(v);
357ac6a4445SGunnar Mills                 break;
358ac6a4445SGunnar Mills             }
359ac6a4445SGunnar Mills         }
360ac6a4445SGunnar Mills     }
361c1343bf6SKrzysztof Grobelny 
362c1343bf6SKrzysztof Grobelny     if (configurationLockCapable != nullptr)
363ac6a4445SGunnar Mills     {
364ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
365c1343bf6SKrzysztof Grobelny                                 ["ConfigurationLockCapable"] =
366c1343bf6SKrzysztof Grobelny             *configurationLockCapable;
367ac6a4445SGunnar Mills     }
368c1343bf6SKrzysztof Grobelny 
369c1343bf6SKrzysztof Grobelny     if (dataLockCapable != nullptr)
370ac6a4445SGunnar Mills     {
371ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
37289492a15SPatrick Williams                                 ["DataLockCapable"] = *dataLockCapable;
373ac6a4445SGunnar Mills     }
374c1343bf6SKrzysztof Grobelny 
375c1343bf6SKrzysztof Grobelny     if (passphraseCapable != nullptr)
376c1343bf6SKrzysztof Grobelny     {
377ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
37889492a15SPatrick Williams                                 ["PassphraseCapable"] = *passphraseCapable;
379c1343bf6SKrzysztof Grobelny     }
380c1343bf6SKrzysztof Grobelny 
381c1343bf6SKrzysztof Grobelny     if (maxPassphraseCount != nullptr)
382c1343bf6SKrzysztof Grobelny     {
383ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
38489492a15SPatrick Williams                                 ["MaxPassphraseCount"] = *maxPassphraseCount;
385c1343bf6SKrzysztof Grobelny     }
386c1343bf6SKrzysztof Grobelny 
387c1343bf6SKrzysztof Grobelny     if (passphraseLockLimit != nullptr)
388c1343bf6SKrzysztof Grobelny     {
389ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
39089492a15SPatrick Williams                                 ["PassphraseLockLimit"] = *passphraseLockLimit;
391ac6a4445SGunnar Mills     }
392ac6a4445SGunnar Mills }
393ac6a4445SGunnar Mills 
3949a5aceacSNan Zhou inline void
3959a5aceacSNan Zhou     assembleDimmProperties(std::string_view dimmId,
396ac106bf6SEd Tanous                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
397d7f04fd9SNan Zhou                            const dbus::utility::DBusPropertiesMap& properties,
398d7f04fd9SNan Zhou                            const nlohmann::json::json_pointer& jsonPtr)
399ac6a4445SGunnar Mills {
400ac106bf6SEd Tanous     asyncResp->res.jsonValue[jsonPtr]["Id"] = dimmId;
401ac106bf6SEd Tanous     asyncResp->res.jsonValue[jsonPtr]["Name"] = "DIMM Slot";
402ac106bf6SEd Tanous     asyncResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Enabled";
403ac106bf6SEd Tanous     asyncResp->res.jsonValue[jsonPtr]["Status"]["Health"] = "OK";
404ac6a4445SGunnar Mills 
405c1343bf6SKrzysztof Grobelny     const uint16_t* memoryDataWidth = nullptr;
406c1343bf6SKrzysztof Grobelny     const size_t* memorySizeInKB = nullptr;
407c1343bf6SKrzysztof Grobelny     const std::string* partNumber = nullptr;
408c1343bf6SKrzysztof Grobelny     const std::string* serialNumber = nullptr;
409c1343bf6SKrzysztof Grobelny     const std::string* manufacturer = nullptr;
410c1343bf6SKrzysztof Grobelny     const uint16_t* revisionCode = nullptr;
411c1343bf6SKrzysztof Grobelny     const bool* present = nullptr;
412c1343bf6SKrzysztof Grobelny     const uint16_t* memoryTotalWidth = nullptr;
413c1343bf6SKrzysztof Grobelny     const std::string* ecc = nullptr;
414c1343bf6SKrzysztof Grobelny     const std::string* formFactor = nullptr;
415c1343bf6SKrzysztof Grobelny     const std::vector<uint16_t>* allowedSpeedsMT = nullptr;
4166995c1ceSGeorge Liu     const size_t* memoryAttributes = nullptr;
417c1343bf6SKrzysztof Grobelny     const uint16_t* memoryConfiguredSpeedInMhz = nullptr;
418c1343bf6SKrzysztof Grobelny     const std::string* memoryType = nullptr;
4196fde5971SJayaprakash Mutyala     const std::uint8_t* channel = nullptr;
4206fde5971SJayaprakash Mutyala     const std::uint8_t* memoryController = nullptr;
4216fde5971SJayaprakash Mutyala     const std::uint8_t* slot = nullptr;
4226fde5971SJayaprakash Mutyala     const std::uint8_t* socket = nullptr;
423c1343bf6SKrzysztof Grobelny     const std::string* sparePartNumber = nullptr;
424c1343bf6SKrzysztof Grobelny     const std::string* model = nullptr;
425c1343bf6SKrzysztof Grobelny     const std::string* locationCode = nullptr;
426ac6a4445SGunnar Mills 
427c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
428c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "MemoryDataWidth",
429c1343bf6SKrzysztof Grobelny         memoryDataWidth, "MemorySizeInKB", memorySizeInKB, "PartNumber",
430656472d9SNikhil Namjoshi         partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
431656472d9SNikhil Namjoshi         "RevisionCode", revisionCode, "Present", present, "MemoryTotalWidth",
432656472d9SNikhil Namjoshi         memoryTotalWidth, "ECC", ecc, "FormFactor", formFactor,
433656472d9SNikhil Namjoshi         "AllowedSpeedsMT", allowedSpeedsMT, "MemoryAttributes",
434c1343bf6SKrzysztof Grobelny         memoryAttributes, "MemoryConfiguredSpeedInMhz",
435c1343bf6SKrzysztof Grobelny         memoryConfiguredSpeedInMhz, "MemoryType", memoryType, "Channel",
436c1343bf6SKrzysztof Grobelny         channel, "MemoryController", memoryController, "Slot", slot, "Socket",
437c1343bf6SKrzysztof Grobelny         socket, "SparePartNumber", sparePartNumber, "Model", model,
438c1343bf6SKrzysztof Grobelny         "LocationCode", locationCode);
439c1343bf6SKrzysztof Grobelny 
440c1343bf6SKrzysztof Grobelny     if (!success)
441ac6a4445SGunnar Mills     {
442ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
443601af5edSChicago Duan         return;
444ac6a4445SGunnar Mills     }
445c1343bf6SKrzysztof Grobelny 
446c1343bf6SKrzysztof Grobelny     if (memoryDataWidth != nullptr)
447c1343bf6SKrzysztof Grobelny     {
448ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["DataWidthBits"] = *memoryDataWidth;
449c1343bf6SKrzysztof Grobelny     }
450c1343bf6SKrzysztof Grobelny 
451c1343bf6SKrzysztof Grobelny     if (memorySizeInKB != nullptr)
452c1343bf6SKrzysztof Grobelny     {
453ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["CapacityMiB"] =
454ac106bf6SEd Tanous             (*memorySizeInKB >> 10);
455c1343bf6SKrzysztof Grobelny     }
456c1343bf6SKrzysztof Grobelny 
457c1343bf6SKrzysztof Grobelny     if (partNumber != nullptr)
458c1343bf6SKrzysztof Grobelny     {
459ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["PartNumber"] = *partNumber;
460c1343bf6SKrzysztof Grobelny     }
461c1343bf6SKrzysztof Grobelny 
462c1343bf6SKrzysztof Grobelny     if (serialNumber != nullptr)
463c1343bf6SKrzysztof Grobelny     {
464ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SerialNumber"] = *serialNumber;
465c1343bf6SKrzysztof Grobelny     }
466c1343bf6SKrzysztof Grobelny 
467c1343bf6SKrzysztof Grobelny     if (manufacturer != nullptr)
468c1343bf6SKrzysztof Grobelny     {
469ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["Manufacturer"] = *manufacturer;
470c1343bf6SKrzysztof Grobelny     }
471c1343bf6SKrzysztof Grobelny 
472c1343bf6SKrzysztof Grobelny     if (revisionCode != nullptr)
473c1343bf6SKrzysztof Grobelny     {
474ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["FirmwareRevision"] =
475c1343bf6SKrzysztof Grobelny             std::to_string(*revisionCode);
476ac6a4445SGunnar Mills     }
477c1343bf6SKrzysztof Grobelny 
478c1343bf6SKrzysztof Grobelny     if (present != nullptr && !*present)
4799a128eb3SJoshi-Mansi     {
480ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Absent";
4819a128eb3SJoshi-Mansi     }
482c1343bf6SKrzysztof Grobelny 
483c1343bf6SKrzysztof Grobelny     if (memoryTotalWidth != nullptr)
484ac6a4445SGunnar Mills     {
485ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["BusWidthBits"] = *memoryTotalWidth;
486ac6a4445SGunnar Mills     }
487c1343bf6SKrzysztof Grobelny 
488c1343bf6SKrzysztof Grobelny     if (ecc != nullptr)
489ac6a4445SGunnar Mills     {
490ac6a4445SGunnar Mills         constexpr const std::array<const char*, 4> values{
4919a5aceacSNan Zhou             "NoECC", "SingleBitECC", "MultiBitECC", "AddressParity"};
492ac6a4445SGunnar Mills 
493ac6a4445SGunnar Mills         for (const char* v : values)
494ac6a4445SGunnar Mills         {
495c1343bf6SKrzysztof Grobelny             if (ecc->ends_with(v))
496ac6a4445SGunnar Mills             {
497ac106bf6SEd Tanous                 asyncResp->res.jsonValue[jsonPtr]["ErrorCorrection"] = v;
498ac6a4445SGunnar Mills                 break;
499ac6a4445SGunnar Mills             }
500ac6a4445SGunnar Mills         }
501ac6a4445SGunnar Mills     }
502c1343bf6SKrzysztof Grobelny 
503c1343bf6SKrzysztof Grobelny     if (formFactor != nullptr)
504ac6a4445SGunnar Mills     {
505ac6a4445SGunnar Mills         constexpr const std::array<const char*, 11> values{
5069a5aceacSNan Zhou             "RDIMM",       "UDIMM",       "SO_DIMM",      "LRDIMM",
5079a5aceacSNan Zhou             "Mini_RDIMM",  "Mini_UDIMM",  "SO_RDIMM_72b", "SO_UDIMM_72b",
5089a5aceacSNan Zhou             "SO_DIMM_16b", "SO_DIMM_32b", "Die"};
509ac6a4445SGunnar Mills 
510ac6a4445SGunnar Mills         for (const char* v : values)
511ac6a4445SGunnar Mills         {
512c1343bf6SKrzysztof Grobelny             if (formFactor->ends_with(v))
513ac6a4445SGunnar Mills             {
514ac106bf6SEd Tanous                 asyncResp->res.jsonValue[jsonPtr]["BaseModuleType"] = v;
515ac6a4445SGunnar Mills                 break;
516ac6a4445SGunnar Mills             }
517ac6a4445SGunnar Mills         }
518ac6a4445SGunnar Mills     }
519c1343bf6SKrzysztof Grobelny 
520c1343bf6SKrzysztof Grobelny     if (allowedSpeedsMT != nullptr)
521ac6a4445SGunnar Mills     {
522d7f04fd9SNan Zhou         nlohmann::json& jValue =
523ac106bf6SEd Tanous             asyncResp->res.jsonValue[jsonPtr]["AllowedSpeedsMHz"];
524ac6a4445SGunnar Mills         jValue = nlohmann::json::array();
525c1343bf6SKrzysztof Grobelny         for (uint16_t subVal : *allowedSpeedsMT)
526ac6a4445SGunnar Mills         {
527ac6a4445SGunnar Mills             jValue.push_back(subVal);
528ac6a4445SGunnar Mills         }
529ac6a4445SGunnar Mills     }
530ac6a4445SGunnar Mills 
531c1343bf6SKrzysztof Grobelny     if (memoryAttributes != nullptr)
532ac6a4445SGunnar Mills     {
5336995c1ceSGeorge Liu         asyncResp->res.jsonValue[jsonPtr]["RankCount"] = *memoryAttributes;
534ac6a4445SGunnar Mills     }
535c1343bf6SKrzysztof Grobelny 
536c1343bf6SKrzysztof Grobelny     if (memoryConfiguredSpeedInMhz != nullptr)
537ac6a4445SGunnar Mills     {
538ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["OperatingSpeedMhz"] =
539c1343bf6SKrzysztof Grobelny             *memoryConfiguredSpeedInMhz;
540ac6a4445SGunnar Mills     }
541c1343bf6SKrzysztof Grobelny 
542c1343bf6SKrzysztof Grobelny     if (memoryType != nullptr)
543ac6a4445SGunnar Mills     {
544313efb1cSGunnar Mills         std::string memoryDeviceType =
545c1343bf6SKrzysztof Grobelny             translateMemoryTypeToRedfish(*memoryType);
546313efb1cSGunnar Mills         // Values like "Unknown" or "Other" will return empty
547313efb1cSGunnar Mills         // so just leave off
548313efb1cSGunnar Mills         if (!memoryDeviceType.empty())
549ac6a4445SGunnar Mills         {
550ac106bf6SEd Tanous             asyncResp->res.jsonValue[jsonPtr]["MemoryDeviceType"] =
551d7f04fd9SNan Zhou                 memoryDeviceType;
552ac6a4445SGunnar Mills         }
553c1343bf6SKrzysztof Grobelny         if (memoryType->find("DDR") != std::string::npos)
554ac6a4445SGunnar Mills         {
555ac106bf6SEd Tanous             asyncResp->res.jsonValue[jsonPtr]["MemoryType"] = "DRAM";
556ac6a4445SGunnar Mills         }
557c1343bf6SKrzysztof Grobelny         else if (memoryType->ends_with("Logical"))
558ac6a4445SGunnar Mills         {
559ac106bf6SEd Tanous             asyncResp->res.jsonValue[jsonPtr]["MemoryType"] = "IntelOptane";
560ac6a4445SGunnar Mills         }
561ac6a4445SGunnar Mills     }
562c1343bf6SKrzysztof Grobelny 
563c1343bf6SKrzysztof Grobelny     if (channel != nullptr)
564ac6a4445SGunnar Mills     {
565ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Channel"] =
566ac106bf6SEd Tanous             *channel;
567c1343bf6SKrzysztof Grobelny     }
568c1343bf6SKrzysztof Grobelny 
569c1343bf6SKrzysztof Grobelny     if (memoryController != nullptr)
570ac6a4445SGunnar Mills     {
571ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]
572ac106bf6SEd Tanous                                 ["MemoryController"] = *memoryController;
573ac6a4445SGunnar Mills     }
574c1343bf6SKrzysztof Grobelny 
575c1343bf6SKrzysztof Grobelny     if (slot != nullptr)
576ee135e24SSunnySrivastava1984     {
577ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Slot"] = *slot;
578c1343bf6SKrzysztof Grobelny     }
579c1343bf6SKrzysztof Grobelny 
580c1343bf6SKrzysztof Grobelny     if (socket != nullptr)
581ee135e24SSunnySrivastava1984     {
582ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Socket"] = *socket;
583ee135e24SSunnySrivastava1984     }
584c1343bf6SKrzysztof Grobelny 
585c1343bf6SKrzysztof Grobelny     if (sparePartNumber != nullptr)
586ee135e24SSunnySrivastava1984     {
587ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SparePartNumber"] = *sparePartNumber;
588c1343bf6SKrzysztof Grobelny     }
589c1343bf6SKrzysztof Grobelny 
590c1343bf6SKrzysztof Grobelny     if (model != nullptr)
591ee135e24SSunnySrivastava1984     {
592ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["Model"] = *model;
593ee135e24SSunnySrivastava1984     }
594c1343bf6SKrzysztof Grobelny 
595c1343bf6SKrzysztof Grobelny     if (locationCode != nullptr)
596ee135e24SSunnySrivastava1984     {
597ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["Location"]["PartLocation"]
59889492a15SPatrick Williams                                 ["ServiceLabel"] = *locationCode;
599ee135e24SSunnySrivastava1984     }
600c1343bf6SKrzysztof Grobelny 
601ac106bf6SEd Tanous     getPersistentMemoryProperties(asyncResp, properties, jsonPtr);
6029a5aceacSNan Zhou }
6039a5aceacSNan Zhou 
604ac106bf6SEd Tanous inline void getDimmDataByService(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
6059a5aceacSNan Zhou                                  const std::string& dimmId,
6069a5aceacSNan Zhou                                  const std::string& service,
6079a5aceacSNan Zhou                                  const std::string& objPath)
6089a5aceacSNan Zhou {
60962598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get available system components.");
610c1343bf6SKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
611c1343bf6SKrzysztof Grobelny         *crow::connections::systemBus, service, objPath, "",
612ac106bf6SEd Tanous         [dimmId, asyncResp{std::move(asyncResp)}](
6135e7e2dc5SEd Tanous             const boost::system::error_code& ec,
6149a5aceacSNan Zhou             const dbus::utility::DBusPropertiesMap& properties) {
6159a5aceacSNan Zhou         if (ec)
6169a5aceacSNan Zhou         {
61762598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error");
618ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
6199a5aceacSNan Zhou             return;
6209a5aceacSNan Zhou         }
621ac106bf6SEd Tanous         assembleDimmProperties(dimmId, asyncResp, properties, ""_json_pointer);
622c1343bf6SKrzysztof Grobelny     });
623ac6a4445SGunnar Mills }
624ac6a4445SGunnar Mills 
625ef00d7d4SNan Zhou inline void assembleDimmPartitionData(
626ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
627d7f04fd9SNan Zhou     const dbus::utility::DBusPropertiesMap& properties,
628d7f04fd9SNan Zhou     const nlohmann::json::json_pointer& regionPtr)
629ac6a4445SGunnar Mills {
630c1343bf6SKrzysztof Grobelny     const std::string* memoryClassification = nullptr;
631c1343bf6SKrzysztof Grobelny     const uint64_t* offsetInKiB = nullptr;
632c1343bf6SKrzysztof Grobelny     const std::string* partitionId = nullptr;
633c1343bf6SKrzysztof Grobelny     const bool* passphraseState = nullptr;
634c1343bf6SKrzysztof Grobelny     const uint64_t* sizeInKiB = nullptr;
635c1343bf6SKrzysztof Grobelny 
636c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
637c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "MemoryClassification",
638c1343bf6SKrzysztof Grobelny         memoryClassification, "OffsetInKiB", offsetInKiB, "PartitionId",
639c1343bf6SKrzysztof Grobelny         partitionId, "PassphraseState", passphraseState, "SizeInKiB",
640c1343bf6SKrzysztof Grobelny         sizeInKiB);
641c1343bf6SKrzysztof Grobelny 
642c1343bf6SKrzysztof Grobelny     if (!success)
643c1343bf6SKrzysztof Grobelny     {
644ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
645c1343bf6SKrzysztof Grobelny         return;
646c1343bf6SKrzysztof Grobelny     }
647c1343bf6SKrzysztof Grobelny 
648d7f04fd9SNan Zhou     nlohmann::json::object_t partition;
649c1343bf6SKrzysztof Grobelny 
650c1343bf6SKrzysztof Grobelny     if (memoryClassification != nullptr)
651ac6a4445SGunnar Mills     {
652c1343bf6SKrzysztof Grobelny         partition["MemoryClassification"] = *memoryClassification;
653ac6a4445SGunnar Mills     }
654ac6a4445SGunnar Mills 
655c1343bf6SKrzysztof Grobelny     if (offsetInKiB != nullptr)
656ac6a4445SGunnar Mills     {
657c1343bf6SKrzysztof Grobelny         partition["OffsetMiB"] = (*offsetInKiB >> 10);
658ac6a4445SGunnar Mills     }
659ac6a4445SGunnar Mills 
660c1343bf6SKrzysztof Grobelny     if (partitionId != nullptr)
661ac6a4445SGunnar Mills     {
662c1343bf6SKrzysztof Grobelny         partition["RegionId"] = *partitionId;
663c1343bf6SKrzysztof Grobelny     }
664c1343bf6SKrzysztof Grobelny 
665c1343bf6SKrzysztof Grobelny     if (passphraseState != nullptr)
666ac6a4445SGunnar Mills     {
667c1343bf6SKrzysztof Grobelny         partition["PassphraseEnabled"] = *passphraseState;
668ac6a4445SGunnar Mills     }
669c1343bf6SKrzysztof Grobelny 
670c1343bf6SKrzysztof Grobelny     if (sizeInKiB != nullptr)
671ac6a4445SGunnar Mills     {
672c1343bf6SKrzysztof Grobelny         partition["SizeMiB"] = (*sizeInKiB >> 10);
673ac6a4445SGunnar Mills     }
674c1343bf6SKrzysztof Grobelny 
675ac106bf6SEd Tanous     asyncResp->res.jsonValue[regionPtr].emplace_back(std::move(partition));
676ef00d7d4SNan Zhou }
677ef00d7d4SNan Zhou 
678ac106bf6SEd Tanous inline void getDimmPartitionData(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
679ef00d7d4SNan Zhou                                  const std::string& service,
680ef00d7d4SNan Zhou                                  const std::string& path)
681ef00d7d4SNan Zhou {
682c1343bf6SKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
683c1343bf6SKrzysztof Grobelny         *crow::connections::systemBus, service, path,
684c1343bf6SKrzysztof Grobelny         "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition",
685ac106bf6SEd Tanous         [asyncResp{std::move(asyncResp)}](
6865e7e2dc5SEd Tanous             const boost::system::error_code& ec,
687ef00d7d4SNan Zhou             const dbus::utility::DBusPropertiesMap& properties) {
688ef00d7d4SNan Zhou         if (ec)
689ef00d7d4SNan Zhou         {
69062598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error");
691ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
692ef00d7d4SNan Zhou 
693ef00d7d4SNan Zhou             return;
694ef00d7d4SNan Zhou         }
695d7f04fd9SNan Zhou         nlohmann::json::json_pointer regionPtr = "/Regions"_json_pointer;
696ac106bf6SEd Tanous         assembleDimmPartitionData(asyncResp, properties, regionPtr);
697c1343bf6SKrzysztof Grobelny     }
698ac6a4445SGunnar Mills 
699c1343bf6SKrzysztof Grobelny     );
700ac6a4445SGunnar Mills }
701ac6a4445SGunnar Mills 
702ac106bf6SEd Tanous inline void getDimmData(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
703ac6a4445SGunnar Mills                         const std::string& dimmId)
704ac6a4445SGunnar Mills {
70562598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get available system dimm resources.");
706e99073f5SGeorge Liu     constexpr std::array<std::string_view, 2> dimmInterfaces = {
707e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Dimm",
708e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"};
709e99073f5SGeorge Liu     dbus::utility::getSubTree(
710e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, dimmInterfaces,
711ac106bf6SEd Tanous         [dimmId, asyncResp{std::move(asyncResp)}](
712e99073f5SGeorge Liu             const boost::system::error_code& ec,
713b9d36b47SEd Tanous             const dbus::utility::MapperGetSubTreeResponse& subtree) {
714ac6a4445SGunnar Mills         if (ec)
715ac6a4445SGunnar Mills         {
71662598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error");
717ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
718ac6a4445SGunnar Mills 
719ac6a4445SGunnar Mills             return;
720ac6a4445SGunnar Mills         }
721ac6a4445SGunnar Mills         bool found = false;
72276686dccSNan Zhou         for (const auto& [rawPath, object] : subtree)
723ac6a4445SGunnar Mills         {
72476686dccSNan Zhou             sdbusplus::message::object_path path(rawPath);
725ac6a4445SGunnar Mills             for (const auto& [service, interfaces] : object)
726ac6a4445SGunnar Mills             {
727b9d36b47SEd Tanous                 for (const auto& interface : interfaces)
728ac6a4445SGunnar Mills                 {
729b9d36b47SEd Tanous                     if (interface ==
73076686dccSNan Zhou                             "xyz.openbmc_project.Inventory.Item.Dimm" &&
73176686dccSNan Zhou                         path.filename() == dimmId)
732b9d36b47SEd Tanous                     {
733ac106bf6SEd Tanous                         getDimmDataByService(asyncResp, dimmId, service,
734ac106bf6SEd Tanous                                              rawPath);
735ac6a4445SGunnar Mills                         found = true;
736ac6a4445SGunnar Mills                     }
737ac6a4445SGunnar Mills 
738b9d36b47SEd Tanous                     // partitions are separate as there can be multiple
739b9d36b47SEd Tanous                     // per
740ac6a4445SGunnar Mills                     // device, i.e.
741ac6a4445SGunnar Mills                     // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1
742ac6a4445SGunnar Mills                     // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2
743b9d36b47SEd Tanous                     if (interface ==
74476686dccSNan Zhou                             "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition" &&
74576686dccSNan Zhou                         path.parent_path().filename() == dimmId)
746ac6a4445SGunnar Mills                     {
747ac106bf6SEd Tanous                         getDimmPartitionData(asyncResp, service, rawPath);
748ac6a4445SGunnar Mills                     }
749ac6a4445SGunnar Mills                 }
750ac6a4445SGunnar Mills             }
751b9d36b47SEd Tanous         }
752ac6a4445SGunnar Mills         // Object not found
753ac6a4445SGunnar Mills         if (!found)
754ac6a4445SGunnar Mills         {
755ac106bf6SEd Tanous             messages::resourceNotFound(asyncResp->res, "Memory", dimmId);
7561a1d5d6dSNan Zhou             return;
757ac6a4445SGunnar Mills         }
7581a1d5d6dSNan Zhou         // Set @odata only if object is found
759ac106bf6SEd Tanous         asyncResp->res.jsonValue["@odata.type"] = "#Memory.v1_11_0.Memory";
760ac106bf6SEd Tanous         asyncResp->res.jsonValue["@odata.id"] =
761ef4c65b7SEd Tanous             boost::urls::format("/redfish/v1/Systems/system/Memory/{}", dimmId);
762ac6a4445SGunnar Mills         return;
763e99073f5SGeorge Liu     });
764ac6a4445SGunnar Mills }
765ac6a4445SGunnar Mills 
7667e860f15SJohn Edward Broadbent inline void requestRoutesMemoryCollection(App& app)
767ac6a4445SGunnar Mills {
768ac6a4445SGunnar Mills     /**
769ac6a4445SGunnar Mills      * Functions triggers appropriate requests on DBus
770ac6a4445SGunnar Mills      */
77122d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/")
772ed398213SEd Tanous         .privileges(redfish::privileges::getMemoryCollection)
7737e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
77445ca1b86SEd Tanous             [&app](const crow::Request& req,
77522d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
77622d268cbSEd Tanous                    const std::string& systemName) {
7773ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
77845ca1b86SEd Tanous         {
77945ca1b86SEd Tanous             return;
78045ca1b86SEd Tanous         }
781*25b54dbaSEd Tanous         if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
7827f3e84a1SEd Tanous         {
7837f3e84a1SEd Tanous             // Option currently returns no systems.  TBD
7847f3e84a1SEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
7857f3e84a1SEd Tanous                                        systemName);
7867f3e84a1SEd Tanous             return;
7877f3e84a1SEd Tanous         }
78822d268cbSEd Tanous         if (systemName != "system")
78922d268cbSEd Tanous         {
79022d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
79122d268cbSEd Tanous                                        systemName);
79222d268cbSEd Tanous             return;
79322d268cbSEd Tanous         }
79422d268cbSEd Tanous 
7958d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.type"] =
7968d1b46d7Szhanghch05             "#MemoryCollection.MemoryCollection";
7978d1b46d7Szhanghch05         asyncResp->res.jsonValue["Name"] = "Memory Module Collection";
7988d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.id"] =
7998d1b46d7Szhanghch05             "/redfish/v1/Systems/system/Memory";
800ac6a4445SGunnar Mills 
8017a1dbc48SGeorge Liu         constexpr std::array<std::string_view, 1> interfaces{
8027a1dbc48SGeorge Liu             "xyz.openbmc_project.Inventory.Item.Dimm"};
80305030b8eSGunnar Mills         collection_util::getCollectionMembers(
804ae9031f0SWilly Tu             asyncResp, boost::urls::url("/redfish/v1/Systems/system/Memory"),
80536b5f1edSLakshmi Yadlapati             interfaces, "/xyz/openbmc_project/inventory");
8067e860f15SJohn Edward Broadbent     });
807ac6a4445SGunnar Mills }
808ac6a4445SGunnar Mills 
8097e860f15SJohn Edward Broadbent inline void requestRoutesMemory(App& app)
8107e860f15SJohn Edward Broadbent {
811ac6a4445SGunnar Mills     /**
812ac6a4445SGunnar Mills      * Functions triggers appropriate requests on DBus
813ac6a4445SGunnar Mills      */
81422d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/<str>/")
815ed398213SEd Tanous         .privileges(redfish::privileges::getMemory)
8167e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
81745ca1b86SEd Tanous             [&app](const crow::Request& req,
8187e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
81922d268cbSEd Tanous                    const std::string& systemName, const std::string& dimmId) {
8203ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
82145ca1b86SEd Tanous         {
82245ca1b86SEd Tanous             return;
82345ca1b86SEd Tanous         }
8247f3e84a1SEd Tanous 
825*25b54dbaSEd Tanous         if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
8267f3e84a1SEd Tanous         {
8277f3e84a1SEd Tanous             // Option currently returns no systems.  TBD
8287f3e84a1SEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
8297f3e84a1SEd Tanous                                        systemName);
8307f3e84a1SEd Tanous             return;
8317f3e84a1SEd Tanous         }
8327f3e84a1SEd Tanous 
83322d268cbSEd Tanous         if (systemName != "system")
83422d268cbSEd Tanous         {
83522d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
83622d268cbSEd Tanous                                        systemName);
83722d268cbSEd Tanous             return;
83822d268cbSEd Tanous         }
83922d268cbSEd Tanous 
840ac6a4445SGunnar Mills         getDimmData(asyncResp, dimmId);
8417e860f15SJohn Edward Broadbent     });
842ac6a4445SGunnar Mills }
843ac6a4445SGunnar Mills 
844ac6a4445SGunnar Mills } // namespace redfish
845