xref: /openbmc/bmcweb/features/redfish/lib/memory.hpp (revision ef4c65b741724d724452a3a0efe8dff0d450514a)
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 
183ccb3adbSEd Tanous #include "app.hpp"
193ccb3adbSEd Tanous #include "dbus_utility.hpp"
20ac6a4445SGunnar Mills #include "health.hpp"
213ccb3adbSEd Tanous #include "query.hpp"
223ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
233ccb3adbSEd Tanous #include "utils/collection.hpp"
243ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
253ccb3adbSEd Tanous #include "utils/hex_utils.hpp"
263ccb3adbSEd Tanous #include "utils/json_utils.hpp"
27ac6a4445SGunnar Mills 
28e99073f5SGeorge Liu #include <boost/system/error_code.hpp>
29*ef4c65b7SEd Tanous #include <boost/url/format.hpp>
30d7f04fd9SNan Zhou #include <nlohmann/json.hpp>
31c1343bf6SKrzysztof Grobelny #include <sdbusplus/asio/property.hpp>
32c1343bf6SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
33ac6a4445SGunnar Mills 
347a1dbc48SGeorge Liu #include <array>
357a1dbc48SGeorge Liu #include <string_view>
367a1dbc48SGeorge Liu 
37ac6a4445SGunnar Mills namespace redfish
38ac6a4445SGunnar Mills {
39ac6a4445SGunnar Mills 
40313efb1cSGunnar Mills inline std::string translateMemoryTypeToRedfish(const std::string& memoryType)
41313efb1cSGunnar Mills {
42313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR")
43313efb1cSGunnar Mills     {
44313efb1cSGunnar Mills         return "DDR";
45313efb1cSGunnar Mills     }
46313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2")
47313efb1cSGunnar Mills     {
48313efb1cSGunnar Mills         return "DDR2";
49313efb1cSGunnar Mills     }
50313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR3")
51313efb1cSGunnar Mills     {
52313efb1cSGunnar Mills         return "DDR3";
53313efb1cSGunnar Mills     }
54313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4")
55313efb1cSGunnar Mills     {
56313efb1cSGunnar Mills         return "DDR4";
57313efb1cSGunnar Mills     }
58313efb1cSGunnar Mills     if (memoryType ==
59313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4E_SDRAM")
60313efb1cSGunnar Mills     {
61313efb1cSGunnar Mills         return "DDR4E_SDRAM";
62313efb1cSGunnar Mills     }
6311a2f0f0SMansi Joshi     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR5")
6411a2f0f0SMansi Joshi     {
6511a2f0f0SMansi Joshi         return "DDR5";
6611a2f0f0SMansi Joshi     }
67313efb1cSGunnar Mills     if (memoryType ==
68313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR4_SDRAM")
69313efb1cSGunnar Mills     {
70313efb1cSGunnar Mills         return "LPDDR4_SDRAM";
71313efb1cSGunnar Mills     }
72313efb1cSGunnar Mills     if (memoryType ==
73313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR3_SDRAM")
74313efb1cSGunnar Mills     {
75313efb1cSGunnar Mills         return "LPDDR3_SDRAM";
76313efb1cSGunnar Mills     }
77313efb1cSGunnar Mills     if (memoryType ==
78313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM")
79313efb1cSGunnar Mills     {
80313efb1cSGunnar Mills         return "DDR2_SDRAM_FB_DIMM";
81313efb1cSGunnar Mills     }
820fda0f12SGeorge Liu     if (memoryType ==
830fda0f12SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM_PROB")
84313efb1cSGunnar Mills     {
85313efb1cSGunnar Mills         return "DDR2_SDRAM_FB_DIMM_PROBE";
86313efb1cSGunnar Mills     }
87313efb1cSGunnar Mills     if (memoryType ==
88313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR_SGRAM")
89313efb1cSGunnar Mills     {
90313efb1cSGunnar Mills         return "DDR_SGRAM";
91313efb1cSGunnar Mills     }
92313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.ROM")
93313efb1cSGunnar Mills     {
94313efb1cSGunnar Mills         return "ROM";
95313efb1cSGunnar Mills     }
96313efb1cSGunnar Mills     if (memoryType ==
97313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.SDRAM")
98313efb1cSGunnar Mills     {
99313efb1cSGunnar Mills         return "SDRAM";
100313efb1cSGunnar Mills     }
101313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.EDO")
102313efb1cSGunnar Mills     {
103313efb1cSGunnar Mills         return "EDO";
104313efb1cSGunnar Mills     }
105313efb1cSGunnar Mills     if (memoryType ==
106313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.FastPageMode")
107313efb1cSGunnar Mills     {
108313efb1cSGunnar Mills         return "FastPageMode";
109313efb1cSGunnar Mills     }
110313efb1cSGunnar Mills     if (memoryType ==
111313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.PipelinedNibble")
112313efb1cSGunnar Mills     {
113313efb1cSGunnar Mills         return "PipelinedNibble";
114313efb1cSGunnar Mills     }
115313efb1cSGunnar Mills     if (memoryType ==
116313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.Logical")
117313efb1cSGunnar Mills     {
118313efb1cSGunnar Mills         return "Logical";
119313efb1cSGunnar Mills     }
120313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM")
121313efb1cSGunnar Mills     {
122313efb1cSGunnar Mills         return "HBM";
123313efb1cSGunnar Mills     }
124313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM2")
125313efb1cSGunnar Mills     {
126313efb1cSGunnar Mills         return "HBM2";
127313efb1cSGunnar Mills     }
128ce34d514STyson Tuckerbear     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM3")
129ce34d514STyson Tuckerbear     {
130ce34d514STyson Tuckerbear         return "HBM3";
131ce34d514STyson Tuckerbear     }
132313efb1cSGunnar Mills     // This is values like Other or Unknown
133313efb1cSGunnar Mills     // Also D-Bus values:
134313efb1cSGunnar Mills     // DRAM
135313efb1cSGunnar Mills     // EDRAM
136313efb1cSGunnar Mills     // VRAM
137313efb1cSGunnar Mills     // SRAM
138313efb1cSGunnar Mills     // RAM
139313efb1cSGunnar Mills     // FLASH
140313efb1cSGunnar Mills     // EEPROM
141313efb1cSGunnar Mills     // FEPROM
142313efb1cSGunnar Mills     // EPROM
143313efb1cSGunnar Mills     // CDRAM
144313efb1cSGunnar Mills     // ThreeDRAM
145313efb1cSGunnar Mills     // RDRAM
146313efb1cSGunnar Mills     // FBD2
147313efb1cSGunnar Mills     // LPDDR_SDRAM
148313efb1cSGunnar Mills     // LPDDR2_SDRAM
14911a2f0f0SMansi Joshi     // LPDDR5_SDRAM
150313efb1cSGunnar Mills     return "";
151313efb1cSGunnar Mills }
152313efb1cSGunnar Mills 
153c1343bf6SKrzysztof Grobelny inline void dimmPropToHex(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
154c1343bf6SKrzysztof Grobelny                           const char* key, const uint16_t* value,
155d7f04fd9SNan Zhou                           const nlohmann::json::json_pointer& jsonPtr)
156ac6a4445SGunnar Mills {
157ac6a4445SGunnar Mills     if (value == nullptr)
158ac6a4445SGunnar Mills     {
159ac6a4445SGunnar Mills         return;
160ac6a4445SGunnar Mills     }
161d7f04fd9SNan Zhou     aResp->res.jsonValue[jsonPtr][key] = "0x" + intToHexString(*value, 4);
162ac6a4445SGunnar Mills }
163ac6a4445SGunnar Mills 
1648d1b46d7Szhanghch05 inline void getPersistentMemoryProperties(
1658d1b46d7Szhanghch05     const std::shared_ptr<bmcweb::AsyncResp>& aResp,
166c1343bf6SKrzysztof Grobelny     const dbus::utility::DBusPropertiesMap& properties,
167d7f04fd9SNan Zhou     const nlohmann::json::json_pointer& jsonPtr)
168ac6a4445SGunnar Mills {
169c1343bf6SKrzysztof Grobelny     const uint16_t* moduleManufacturerID = nullptr;
170c1343bf6SKrzysztof Grobelny     const uint16_t* moduleProductID = nullptr;
171c1343bf6SKrzysztof Grobelny     const uint16_t* subsystemVendorID = nullptr;
172c1343bf6SKrzysztof Grobelny     const uint16_t* subsystemDeviceID = nullptr;
173c1343bf6SKrzysztof Grobelny     const uint64_t* volatileRegionSizeLimitInKiB = nullptr;
174c1343bf6SKrzysztof Grobelny     const uint64_t* pmRegionSizeLimitInKiB = nullptr;
175c1343bf6SKrzysztof Grobelny     const uint64_t* volatileSizeInKiB = nullptr;
176c1343bf6SKrzysztof Grobelny     const uint64_t* pmSizeInKiB = nullptr;
177c1343bf6SKrzysztof Grobelny     const uint64_t* cacheSizeInKB = nullptr;
178c1343bf6SKrzysztof Grobelny     const uint64_t* voltaileRegionMaxSizeInKib = nullptr;
179c1343bf6SKrzysztof Grobelny     const uint64_t* pmRegionMaxSizeInKiB = nullptr;
180c1343bf6SKrzysztof Grobelny     const uint64_t* allocationIncrementInKiB = nullptr;
181c1343bf6SKrzysztof Grobelny     const uint64_t* allocationAlignmentInKiB = nullptr;
182c1343bf6SKrzysztof Grobelny     const uint64_t* volatileRegionNumberLimit = nullptr;
183c1343bf6SKrzysztof Grobelny     const uint64_t* pmRegionNumberLimit = nullptr;
184c1343bf6SKrzysztof Grobelny     const uint64_t* spareDeviceCount = nullptr;
185c1343bf6SKrzysztof Grobelny     const bool* isSpareDeviceInUse = nullptr;
186c1343bf6SKrzysztof Grobelny     const bool* isRankSpareEnabled = nullptr;
187c1343bf6SKrzysztof Grobelny     const std::vector<uint32_t>* maxAveragePowerLimitmW = nullptr;
188c1343bf6SKrzysztof Grobelny     const bool* configurationLocked = nullptr;
189c1343bf6SKrzysztof Grobelny     const std::string* allowedMemoryModes = nullptr;
190c1343bf6SKrzysztof Grobelny     const std::string* memoryMedia = nullptr;
191c1343bf6SKrzysztof Grobelny     const bool* configurationLockCapable = nullptr;
192c1343bf6SKrzysztof Grobelny     const bool* dataLockCapable = nullptr;
193c1343bf6SKrzysztof Grobelny     const bool* passphraseCapable = nullptr;
194c1343bf6SKrzysztof Grobelny     const uint64_t* maxPassphraseCount = nullptr;
195c1343bf6SKrzysztof Grobelny     const uint64_t* passphraseLockLimit = nullptr;
196c1343bf6SKrzysztof Grobelny 
197c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
198c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "ModuleManufacturerID",
199c1343bf6SKrzysztof Grobelny         moduleManufacturerID, "ModuleProductID", moduleProductID,
200c1343bf6SKrzysztof Grobelny         "SubsystemVendorID", subsystemVendorID, "SubsystemDeviceID",
201c1343bf6SKrzysztof Grobelny         subsystemDeviceID, "VolatileRegionSizeLimitInKiB",
202c1343bf6SKrzysztof Grobelny         volatileRegionSizeLimitInKiB, "PmRegionSizeLimitInKiB",
203c1343bf6SKrzysztof Grobelny         pmRegionSizeLimitInKiB, "VolatileSizeInKiB", volatileSizeInKiB,
204c1343bf6SKrzysztof Grobelny         "PmSizeInKiB", pmSizeInKiB, "CacheSizeInKB", cacheSizeInKB,
205c1343bf6SKrzysztof Grobelny         "VoltaileRegionMaxSizeInKib", voltaileRegionMaxSizeInKib,
206c1343bf6SKrzysztof Grobelny         "PmRegionMaxSizeInKiB", pmRegionMaxSizeInKiB,
207c1343bf6SKrzysztof Grobelny         "AllocationIncrementInKiB", allocationIncrementInKiB,
208c1343bf6SKrzysztof Grobelny         "AllocationAlignmentInKiB", allocationAlignmentInKiB,
209c1343bf6SKrzysztof Grobelny         "VolatileRegionNumberLimit", volatileRegionNumberLimit,
210c1343bf6SKrzysztof Grobelny         "PmRegionNumberLimit", pmRegionNumberLimit, "SpareDeviceCount",
211c1343bf6SKrzysztof Grobelny         spareDeviceCount, "IsSpareDeviceInUse", isSpareDeviceInUse,
212c1343bf6SKrzysztof Grobelny         "IsRankSpareEnabled", isRankSpareEnabled, "MaxAveragePowerLimitmW",
213c1343bf6SKrzysztof Grobelny         maxAveragePowerLimitmW, "ConfigurationLocked", configurationLocked,
214c1343bf6SKrzysztof Grobelny         "AllowedMemoryModes", allowedMemoryModes, "MemoryMedia", memoryMedia,
215c1343bf6SKrzysztof Grobelny         "ConfigurationLockCapable", configurationLockCapable, "DataLockCapable",
216c1343bf6SKrzysztof Grobelny         dataLockCapable, "PassphraseCapable", passphraseCapable,
217c1343bf6SKrzysztof Grobelny         "MaxPassphraseCount", maxPassphraseCount, "PassphraseLockLimit",
218c1343bf6SKrzysztof Grobelny         passphraseLockLimit);
219c1343bf6SKrzysztof Grobelny 
220c1343bf6SKrzysztof Grobelny     if (!success)
221ac6a4445SGunnar Mills     {
222c1343bf6SKrzysztof Grobelny         messages::internalError(aResp->res);
223c1343bf6SKrzysztof Grobelny         return;
224ac6a4445SGunnar Mills     }
225c1343bf6SKrzysztof Grobelny 
226c1343bf6SKrzysztof Grobelny     dimmPropToHex(aResp, "ModuleManufacturerID", moduleManufacturerID, jsonPtr);
227c1343bf6SKrzysztof Grobelny     dimmPropToHex(aResp, "ModuleProductID", moduleProductID, jsonPtr);
228ac6a4445SGunnar Mills     dimmPropToHex(aResp, "MemorySubsystemControllerManufacturerID",
229c1343bf6SKrzysztof Grobelny                   subsystemVendorID, jsonPtr);
230c1343bf6SKrzysztof Grobelny     dimmPropToHex(aResp, "MemorySubsystemControllerProductID",
231c1343bf6SKrzysztof Grobelny                   subsystemDeviceID, jsonPtr);
232ac6a4445SGunnar Mills 
233c1343bf6SKrzysztof Grobelny     if (volatileRegionSizeLimitInKiB != nullptr)
234ac6a4445SGunnar Mills     {
235d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["VolatileRegionSizeLimitMiB"] =
236c1343bf6SKrzysztof Grobelny             (*volatileRegionSizeLimitInKiB) >> 10;
237ac6a4445SGunnar Mills     }
238ac6a4445SGunnar Mills 
239c1343bf6SKrzysztof Grobelny     if (pmRegionSizeLimitInKiB != nullptr)
240ac6a4445SGunnar Mills     {
241d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["PersistentRegionSizeLimitMiB"] =
242c1343bf6SKrzysztof Grobelny             (*pmRegionSizeLimitInKiB) >> 10;
243ac6a4445SGunnar Mills     }
244ac6a4445SGunnar Mills 
245c1343bf6SKrzysztof Grobelny     if (volatileSizeInKiB != nullptr)
246ac6a4445SGunnar Mills     {
247c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["VolatileSizeMiB"] =
248c1343bf6SKrzysztof Grobelny             (*volatileSizeInKiB) >> 10;
249ac6a4445SGunnar Mills     }
250c1343bf6SKrzysztof Grobelny 
251c1343bf6SKrzysztof Grobelny     if (pmSizeInKiB != nullptr)
252c1343bf6SKrzysztof Grobelny     {
25389492a15SPatrick Williams         aResp->res.jsonValue[jsonPtr]["NonVolatileSizeMiB"] = (*pmSizeInKiB) >>
25489492a15SPatrick Williams                                                               10;
255c1343bf6SKrzysztof Grobelny     }
256c1343bf6SKrzysztof Grobelny 
257c1343bf6SKrzysztof Grobelny     if (cacheSizeInKB != nullptr)
258c1343bf6SKrzysztof Grobelny     {
259c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["CacheSizeMiB"] = (*cacheSizeInKB >> 10);
260c1343bf6SKrzysztof Grobelny     }
261c1343bf6SKrzysztof Grobelny 
262c1343bf6SKrzysztof Grobelny     if (voltaileRegionMaxSizeInKib != nullptr)
263c1343bf6SKrzysztof Grobelny     {
264d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["VolatileRegionSizeMaxMiB"] =
265c1343bf6SKrzysztof Grobelny             (*voltaileRegionMaxSizeInKib) >> 10;
266ac6a4445SGunnar Mills     }
267ac6a4445SGunnar Mills 
268c1343bf6SKrzysztof Grobelny     if (pmRegionMaxSizeInKiB != nullptr)
269ac6a4445SGunnar Mills     {
270d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["PersistentRegionSizeMaxMiB"] =
271c1343bf6SKrzysztof Grobelny             (*pmRegionMaxSizeInKiB) >> 10;
272ac6a4445SGunnar Mills     }
273ac6a4445SGunnar Mills 
274c1343bf6SKrzysztof Grobelny     if (allocationIncrementInKiB != nullptr)
275ac6a4445SGunnar Mills     {
276d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["AllocationIncrementMiB"] =
277c1343bf6SKrzysztof Grobelny             (*allocationIncrementInKiB) >> 10;
278ac6a4445SGunnar Mills     }
279ac6a4445SGunnar Mills 
280c1343bf6SKrzysztof Grobelny     if (allocationAlignmentInKiB != nullptr)
281ac6a4445SGunnar Mills     {
282d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["AllocationAlignmentMiB"] =
283c1343bf6SKrzysztof Grobelny             (*allocationAlignmentInKiB) >> 10;
284ac6a4445SGunnar Mills     }
285c1343bf6SKrzysztof Grobelny 
286c1343bf6SKrzysztof Grobelny     if (volatileRegionNumberLimit != nullptr)
287ac6a4445SGunnar Mills     {
288c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["VolatileRegionNumberLimit"] =
289c1343bf6SKrzysztof Grobelny             *volatileRegionNumberLimit;
290ac6a4445SGunnar Mills     }
291c1343bf6SKrzysztof Grobelny 
292c1343bf6SKrzysztof Grobelny     if (pmRegionNumberLimit != nullptr)
293ac6a4445SGunnar Mills     {
294c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["PersistentRegionNumberLimit"] =
295c1343bf6SKrzysztof Grobelny             *pmRegionNumberLimit;
296ac6a4445SGunnar Mills     }
297c1343bf6SKrzysztof Grobelny 
298c1343bf6SKrzysztof Grobelny     if (spareDeviceCount != nullptr)
299ac6a4445SGunnar Mills     {
300c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["SpareDeviceCount"] = *spareDeviceCount;
301ac6a4445SGunnar Mills     }
302c1343bf6SKrzysztof Grobelny 
303c1343bf6SKrzysztof Grobelny     if (isSpareDeviceInUse != nullptr)
304ac6a4445SGunnar Mills     {
305c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["IsSpareDeviceEnabled"] =
306c1343bf6SKrzysztof Grobelny             *isSpareDeviceInUse;
307ac6a4445SGunnar Mills     }
308c1343bf6SKrzysztof Grobelny 
309c1343bf6SKrzysztof Grobelny     if (isRankSpareEnabled != nullptr)
310ac6a4445SGunnar Mills     {
311c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["IsRankSpareEnabled"] =
312c1343bf6SKrzysztof Grobelny             *isRankSpareEnabled;
313ac6a4445SGunnar Mills     }
314c1343bf6SKrzysztof Grobelny 
315c1343bf6SKrzysztof Grobelny     if (maxAveragePowerLimitmW != nullptr)
316ac6a4445SGunnar Mills     {
317c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["MaxTDPMilliWatts"] =
318c1343bf6SKrzysztof Grobelny             *maxAveragePowerLimitmW;
319ac6a4445SGunnar Mills     }
320c1343bf6SKrzysztof Grobelny 
321c1343bf6SKrzysztof Grobelny     if (configurationLocked != nullptr)
322ac6a4445SGunnar Mills     {
323c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["ConfigurationLocked"] =
324c1343bf6SKrzysztof Grobelny             *configurationLocked;
325ac6a4445SGunnar Mills     }
326c1343bf6SKrzysztof Grobelny 
327c1343bf6SKrzysztof Grobelny     if (allowedMemoryModes != nullptr)
328ac6a4445SGunnar Mills     {
32980badf7cSJiaqing Zhao         constexpr const std::array<const char*, 3> values{"Volatile", "PMEM",
33080badf7cSJiaqing Zhao                                                           "Block"};
331ac6a4445SGunnar Mills 
332ac6a4445SGunnar Mills         for (const char* v : values)
333ac6a4445SGunnar Mills         {
334c1343bf6SKrzysztof Grobelny             if (allowedMemoryModes->ends_with(v))
335ac6a4445SGunnar Mills             {
336d7f04fd9SNan Zhou                 aResp->res.jsonValue[jsonPtr]["OperatingMemoryModes"].push_back(
337d7f04fd9SNan Zhou                     v);
338ac6a4445SGunnar Mills                 break;
339ac6a4445SGunnar Mills             }
340ac6a4445SGunnar Mills         }
341ac6a4445SGunnar Mills     }
342c1343bf6SKrzysztof Grobelny 
343c1343bf6SKrzysztof Grobelny     if (memoryMedia != nullptr)
344ac6a4445SGunnar Mills     {
345ac6a4445SGunnar Mills         constexpr const std::array<const char*, 3> values{"DRAM", "NAND",
346ac6a4445SGunnar Mills                                                           "Intel3DXPoint"};
347ac6a4445SGunnar Mills 
348ac6a4445SGunnar Mills         for (const char* v : values)
349ac6a4445SGunnar Mills         {
350c1343bf6SKrzysztof Grobelny             if (memoryMedia->ends_with(v))
351ac6a4445SGunnar Mills             {
352d7f04fd9SNan Zhou                 aResp->res.jsonValue[jsonPtr]["MemoryMedia"].push_back(v);
353ac6a4445SGunnar Mills                 break;
354ac6a4445SGunnar Mills             }
355ac6a4445SGunnar Mills         }
356ac6a4445SGunnar Mills     }
357c1343bf6SKrzysztof Grobelny 
358c1343bf6SKrzysztof Grobelny     if (configurationLockCapable != nullptr)
359ac6a4445SGunnar Mills     {
360c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
361c1343bf6SKrzysztof Grobelny                             ["ConfigurationLockCapable"] =
362c1343bf6SKrzysztof Grobelny             *configurationLockCapable;
363ac6a4445SGunnar Mills     }
364c1343bf6SKrzysztof Grobelny 
365c1343bf6SKrzysztof Grobelny     if (dataLockCapable != nullptr)
366ac6a4445SGunnar Mills     {
36789492a15SPatrick Williams         aResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
36889492a15SPatrick Williams                             ["DataLockCapable"] = *dataLockCapable;
369ac6a4445SGunnar Mills     }
370c1343bf6SKrzysztof Grobelny 
371c1343bf6SKrzysztof Grobelny     if (passphraseCapable != nullptr)
372c1343bf6SKrzysztof Grobelny     {
37389492a15SPatrick Williams         aResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
37489492a15SPatrick Williams                             ["PassphraseCapable"] = *passphraseCapable;
375c1343bf6SKrzysztof Grobelny     }
376c1343bf6SKrzysztof Grobelny 
377c1343bf6SKrzysztof Grobelny     if (maxPassphraseCount != nullptr)
378c1343bf6SKrzysztof Grobelny     {
37989492a15SPatrick Williams         aResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
38089492a15SPatrick Williams                             ["MaxPassphraseCount"] = *maxPassphraseCount;
381c1343bf6SKrzysztof Grobelny     }
382c1343bf6SKrzysztof Grobelny 
383c1343bf6SKrzysztof Grobelny     if (passphraseLockLimit != nullptr)
384c1343bf6SKrzysztof Grobelny     {
38589492a15SPatrick Williams         aResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
38689492a15SPatrick Williams                             ["PassphraseLockLimit"] = *passphraseLockLimit;
387ac6a4445SGunnar Mills     }
388ac6a4445SGunnar Mills }
389ac6a4445SGunnar Mills 
3909a5aceacSNan Zhou inline void
3919a5aceacSNan Zhou     assembleDimmProperties(std::string_view dimmId,
3929a5aceacSNan Zhou                            const std::shared_ptr<bmcweb::AsyncResp>& aResp,
393d7f04fd9SNan Zhou                            const dbus::utility::DBusPropertiesMap& properties,
394d7f04fd9SNan Zhou                            const nlohmann::json::json_pointer& jsonPtr)
395ac6a4445SGunnar Mills {
396d7f04fd9SNan Zhou     aResp->res.jsonValue[jsonPtr]["Id"] = dimmId;
397d7f04fd9SNan Zhou     aResp->res.jsonValue[jsonPtr]["Name"] = "DIMM Slot";
398d7f04fd9SNan Zhou     aResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Enabled";
399d7f04fd9SNan Zhou     aResp->res.jsonValue[jsonPtr]["Status"]["Health"] = "OK";
400ac6a4445SGunnar Mills 
401c1343bf6SKrzysztof Grobelny     const uint16_t* memoryDataWidth = nullptr;
402c1343bf6SKrzysztof Grobelny     const size_t* memorySizeInKB = nullptr;
403c1343bf6SKrzysztof Grobelny     const std::string* partNumber = nullptr;
404c1343bf6SKrzysztof Grobelny     const std::string* serialNumber = nullptr;
405c1343bf6SKrzysztof Grobelny     const std::string* manufacturer = nullptr;
406c1343bf6SKrzysztof Grobelny     const uint16_t* revisionCode = nullptr;
407c1343bf6SKrzysztof Grobelny     const bool* present = nullptr;
408c1343bf6SKrzysztof Grobelny     const uint16_t* memoryTotalWidth = nullptr;
409c1343bf6SKrzysztof Grobelny     const std::string* ecc = nullptr;
410c1343bf6SKrzysztof Grobelny     const std::string* formFactor = nullptr;
411c1343bf6SKrzysztof Grobelny     const std::vector<uint16_t>* allowedSpeedsMT = nullptr;
412c1343bf6SKrzysztof Grobelny     const uint8_t* memoryAttributes = nullptr;
413c1343bf6SKrzysztof Grobelny     const uint16_t* memoryConfiguredSpeedInMhz = nullptr;
414c1343bf6SKrzysztof Grobelny     const std::string* memoryType = nullptr;
415c1343bf6SKrzysztof Grobelny     const std::string* channel = nullptr;
416c1343bf6SKrzysztof Grobelny     const std::string* memoryController = nullptr;
417c1343bf6SKrzysztof Grobelny     const std::string* slot = nullptr;
418c1343bf6SKrzysztof Grobelny     const std::string* socket = nullptr;
419c1343bf6SKrzysztof Grobelny     const std::string* sparePartNumber = nullptr;
420c1343bf6SKrzysztof Grobelny     const std::string* model = nullptr;
421c1343bf6SKrzysztof Grobelny     const std::string* locationCode = nullptr;
422ac6a4445SGunnar Mills 
423c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
424c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "MemoryDataWidth",
425c1343bf6SKrzysztof Grobelny         memoryDataWidth, "MemorySizeInKB", memorySizeInKB, "PartNumber",
426656472d9SNikhil Namjoshi         partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
427656472d9SNikhil Namjoshi         "RevisionCode", revisionCode, "Present", present, "MemoryTotalWidth",
428656472d9SNikhil Namjoshi         memoryTotalWidth, "ECC", ecc, "FormFactor", formFactor,
429656472d9SNikhil Namjoshi         "AllowedSpeedsMT", allowedSpeedsMT, "MemoryAttributes",
430c1343bf6SKrzysztof Grobelny         memoryAttributes, "MemoryConfiguredSpeedInMhz",
431c1343bf6SKrzysztof Grobelny         memoryConfiguredSpeedInMhz, "MemoryType", memoryType, "Channel",
432c1343bf6SKrzysztof Grobelny         channel, "MemoryController", memoryController, "Slot", slot, "Socket",
433c1343bf6SKrzysztof Grobelny         socket, "SparePartNumber", sparePartNumber, "Model", model,
434c1343bf6SKrzysztof Grobelny         "LocationCode", locationCode);
435c1343bf6SKrzysztof Grobelny 
436c1343bf6SKrzysztof Grobelny     if (!success)
437ac6a4445SGunnar Mills     {
438ac6a4445SGunnar Mills         messages::internalError(aResp->res);
439601af5edSChicago Duan         return;
440ac6a4445SGunnar Mills     }
441c1343bf6SKrzysztof Grobelny 
442c1343bf6SKrzysztof Grobelny     if (memoryDataWidth != nullptr)
443c1343bf6SKrzysztof Grobelny     {
444c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["DataWidthBits"] = *memoryDataWidth;
445c1343bf6SKrzysztof Grobelny     }
446c1343bf6SKrzysztof Grobelny 
447c1343bf6SKrzysztof Grobelny     if (memorySizeInKB != nullptr)
448c1343bf6SKrzysztof Grobelny     {
449c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["CapacityMiB"] = (*memorySizeInKB >> 10);
450c1343bf6SKrzysztof Grobelny     }
451c1343bf6SKrzysztof Grobelny 
452c1343bf6SKrzysztof Grobelny     if (partNumber != nullptr)
453c1343bf6SKrzysztof Grobelny     {
454c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["PartNumber"] = *partNumber;
455c1343bf6SKrzysztof Grobelny     }
456c1343bf6SKrzysztof Grobelny 
457c1343bf6SKrzysztof Grobelny     if (serialNumber != nullptr)
458c1343bf6SKrzysztof Grobelny     {
459c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["SerialNumber"] = *serialNumber;
460c1343bf6SKrzysztof Grobelny     }
461c1343bf6SKrzysztof Grobelny 
462c1343bf6SKrzysztof Grobelny     if (manufacturer != nullptr)
463c1343bf6SKrzysztof Grobelny     {
464c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["Manufacturer"] = *manufacturer;
465c1343bf6SKrzysztof Grobelny     }
466c1343bf6SKrzysztof Grobelny 
467c1343bf6SKrzysztof Grobelny     if (revisionCode != nullptr)
468c1343bf6SKrzysztof Grobelny     {
469d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["FirmwareRevision"] =
470c1343bf6SKrzysztof Grobelny             std::to_string(*revisionCode);
471ac6a4445SGunnar Mills     }
472c1343bf6SKrzysztof Grobelny 
473c1343bf6SKrzysztof Grobelny     if (present != nullptr && !*present)
4749a128eb3SJoshi-Mansi     {
475d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Absent";
4769a128eb3SJoshi-Mansi     }
477c1343bf6SKrzysztof Grobelny 
478c1343bf6SKrzysztof Grobelny     if (memoryTotalWidth != nullptr)
479ac6a4445SGunnar Mills     {
480c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["BusWidthBits"] = *memoryTotalWidth;
481ac6a4445SGunnar Mills     }
482c1343bf6SKrzysztof Grobelny 
483c1343bf6SKrzysztof Grobelny     if (ecc != nullptr)
484ac6a4445SGunnar Mills     {
485ac6a4445SGunnar Mills         constexpr const std::array<const char*, 4> values{
4869a5aceacSNan Zhou             "NoECC", "SingleBitECC", "MultiBitECC", "AddressParity"};
487ac6a4445SGunnar Mills 
488ac6a4445SGunnar Mills         for (const char* v : values)
489ac6a4445SGunnar Mills         {
490c1343bf6SKrzysztof Grobelny             if (ecc->ends_with(v))
491ac6a4445SGunnar Mills             {
492d7f04fd9SNan Zhou                 aResp->res.jsonValue[jsonPtr]["ErrorCorrection"] = v;
493ac6a4445SGunnar Mills                 break;
494ac6a4445SGunnar Mills             }
495ac6a4445SGunnar Mills         }
496ac6a4445SGunnar Mills     }
497c1343bf6SKrzysztof Grobelny 
498c1343bf6SKrzysztof Grobelny     if (formFactor != nullptr)
499ac6a4445SGunnar Mills     {
500ac6a4445SGunnar Mills         constexpr const std::array<const char*, 11> values{
5019a5aceacSNan Zhou             "RDIMM",       "UDIMM",       "SO_DIMM",      "LRDIMM",
5029a5aceacSNan Zhou             "Mini_RDIMM",  "Mini_UDIMM",  "SO_RDIMM_72b", "SO_UDIMM_72b",
5039a5aceacSNan Zhou             "SO_DIMM_16b", "SO_DIMM_32b", "Die"};
504ac6a4445SGunnar Mills 
505ac6a4445SGunnar Mills         for (const char* v : values)
506ac6a4445SGunnar Mills         {
507c1343bf6SKrzysztof Grobelny             if (formFactor->ends_with(v))
508ac6a4445SGunnar Mills             {
509d7f04fd9SNan Zhou                 aResp->res.jsonValue[jsonPtr]["BaseModuleType"] = v;
510ac6a4445SGunnar Mills                 break;
511ac6a4445SGunnar Mills             }
512ac6a4445SGunnar Mills         }
513ac6a4445SGunnar Mills     }
514c1343bf6SKrzysztof Grobelny 
515c1343bf6SKrzysztof Grobelny     if (allowedSpeedsMT != nullptr)
516ac6a4445SGunnar Mills     {
517d7f04fd9SNan Zhou         nlohmann::json& jValue =
518d7f04fd9SNan Zhou             aResp->res.jsonValue[jsonPtr]["AllowedSpeedsMHz"];
519ac6a4445SGunnar Mills         jValue = nlohmann::json::array();
520c1343bf6SKrzysztof Grobelny         for (uint16_t subVal : *allowedSpeedsMT)
521ac6a4445SGunnar Mills         {
522ac6a4445SGunnar Mills             jValue.push_back(subVal);
523ac6a4445SGunnar Mills         }
524ac6a4445SGunnar Mills     }
525ac6a4445SGunnar Mills 
526c1343bf6SKrzysztof Grobelny     if (memoryAttributes != nullptr)
527ac6a4445SGunnar Mills     {
528d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["RankCount"] =
529c1343bf6SKrzysztof Grobelny             static_cast<uint64_t>(*memoryAttributes);
530ac6a4445SGunnar Mills     }
531c1343bf6SKrzysztof Grobelny 
532c1343bf6SKrzysztof Grobelny     if (memoryConfiguredSpeedInMhz != nullptr)
533ac6a4445SGunnar Mills     {
534c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["OperatingSpeedMhz"] =
535c1343bf6SKrzysztof Grobelny             *memoryConfiguredSpeedInMhz;
536ac6a4445SGunnar Mills     }
537c1343bf6SKrzysztof Grobelny 
538c1343bf6SKrzysztof Grobelny     if (memoryType != nullptr)
539ac6a4445SGunnar Mills     {
540313efb1cSGunnar Mills         std::string memoryDeviceType =
541c1343bf6SKrzysztof Grobelny             translateMemoryTypeToRedfish(*memoryType);
542313efb1cSGunnar Mills         // Values like "Unknown" or "Other" will return empty
543313efb1cSGunnar Mills         // so just leave off
544313efb1cSGunnar Mills         if (!memoryDeviceType.empty())
545ac6a4445SGunnar Mills         {
546d7f04fd9SNan Zhou             aResp->res.jsonValue[jsonPtr]["MemoryDeviceType"] =
547d7f04fd9SNan Zhou                 memoryDeviceType;
548ac6a4445SGunnar Mills         }
549c1343bf6SKrzysztof Grobelny         if (memoryType->find("DDR") != std::string::npos)
550ac6a4445SGunnar Mills         {
551d7f04fd9SNan Zhou             aResp->res.jsonValue[jsonPtr]["MemoryType"] = "DRAM";
552ac6a4445SGunnar Mills         }
553c1343bf6SKrzysztof Grobelny         else if (memoryType->ends_with("Logical"))
554ac6a4445SGunnar Mills         {
555d7f04fd9SNan Zhou             aResp->res.jsonValue[jsonPtr]["MemoryType"] = "IntelOptane";
556ac6a4445SGunnar Mills         }
557ac6a4445SGunnar Mills     }
558c1343bf6SKrzysztof Grobelny 
559c1343bf6SKrzysztof Grobelny     if (channel != nullptr)
560ac6a4445SGunnar Mills     {
561c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Channel"] = *channel;
562c1343bf6SKrzysztof Grobelny     }
563c1343bf6SKrzysztof Grobelny 
564c1343bf6SKrzysztof Grobelny     if (memoryController != nullptr)
565ac6a4445SGunnar Mills     {
566c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["MemoryLocation"]["MemoryController"] =
567c1343bf6SKrzysztof Grobelny             *memoryController;
568ac6a4445SGunnar Mills     }
569c1343bf6SKrzysztof Grobelny 
570c1343bf6SKrzysztof Grobelny     if (slot != nullptr)
571ee135e24SSunnySrivastava1984     {
572c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Slot"] = *slot;
573c1343bf6SKrzysztof Grobelny     }
574c1343bf6SKrzysztof Grobelny 
575c1343bf6SKrzysztof Grobelny     if (socket != nullptr)
576ee135e24SSunnySrivastava1984     {
577c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Socket"] = *socket;
578ee135e24SSunnySrivastava1984     }
579c1343bf6SKrzysztof Grobelny 
580c1343bf6SKrzysztof Grobelny     if (sparePartNumber != nullptr)
581ee135e24SSunnySrivastava1984     {
582c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["SparePartNumber"] = *sparePartNumber;
583c1343bf6SKrzysztof Grobelny     }
584c1343bf6SKrzysztof Grobelny 
585c1343bf6SKrzysztof Grobelny     if (model != nullptr)
586ee135e24SSunnySrivastava1984     {
587c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["Model"] = *model;
588ee135e24SSunnySrivastava1984     }
589c1343bf6SKrzysztof Grobelny 
590c1343bf6SKrzysztof Grobelny     if (locationCode != nullptr)
591ee135e24SSunnySrivastava1984     {
59289492a15SPatrick Williams         aResp->res.jsonValue[jsonPtr]["Location"]["PartLocation"]
59389492a15SPatrick Williams                             ["ServiceLabel"] = *locationCode;
594ee135e24SSunnySrivastava1984     }
595c1343bf6SKrzysztof Grobelny 
596c1343bf6SKrzysztof Grobelny     getPersistentMemoryProperties(aResp, properties, jsonPtr);
5979a5aceacSNan Zhou }
5989a5aceacSNan Zhou 
5999a5aceacSNan Zhou inline void getDimmDataByService(std::shared_ptr<bmcweb::AsyncResp> aResp,
6009a5aceacSNan Zhou                                  const std::string& dimmId,
6019a5aceacSNan Zhou                                  const std::string& service,
6029a5aceacSNan Zhou                                  const std::string& objPath)
6039a5aceacSNan Zhou {
6049a5aceacSNan Zhou     auto health = std::make_shared<HealthPopulate>(aResp);
6059a5aceacSNan Zhou     health->selfPath = objPath;
6069a5aceacSNan Zhou     health->populate();
6079a5aceacSNan Zhou 
6089a5aceacSNan Zhou     BMCWEB_LOG_DEBUG << "Get available system components.";
609c1343bf6SKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
610c1343bf6SKrzysztof Grobelny         *crow::connections::systemBus, service, objPath, "",
6119a5aceacSNan Zhou         [dimmId, aResp{std::move(aResp)}](
6125e7e2dc5SEd Tanous             const boost::system::error_code& ec,
6139a5aceacSNan Zhou             const dbus::utility::DBusPropertiesMap& properties) {
6149a5aceacSNan Zhou         if (ec)
6159a5aceacSNan Zhou         {
6169a5aceacSNan Zhou             BMCWEB_LOG_DEBUG << "DBUS response error";
6179a5aceacSNan Zhou             messages::internalError(aResp->res);
6189a5aceacSNan Zhou             return;
6199a5aceacSNan Zhou         }
620d7f04fd9SNan Zhou         assembleDimmProperties(dimmId, aResp, properties, ""_json_pointer);
621c1343bf6SKrzysztof Grobelny         });
622ac6a4445SGunnar Mills }
623ac6a4445SGunnar Mills 
624ef00d7d4SNan Zhou inline void assembleDimmPartitionData(
625ef00d7d4SNan Zhou     const std::shared_ptr<bmcweb::AsyncResp>& aResp,
626d7f04fd9SNan Zhou     const dbus::utility::DBusPropertiesMap& properties,
627d7f04fd9SNan Zhou     const nlohmann::json::json_pointer& regionPtr)
628ac6a4445SGunnar Mills {
629c1343bf6SKrzysztof Grobelny     const std::string* memoryClassification = nullptr;
630c1343bf6SKrzysztof Grobelny     const uint64_t* offsetInKiB = nullptr;
631c1343bf6SKrzysztof Grobelny     const std::string* partitionId = nullptr;
632c1343bf6SKrzysztof Grobelny     const bool* passphraseState = nullptr;
633c1343bf6SKrzysztof Grobelny     const uint64_t* sizeInKiB = nullptr;
634c1343bf6SKrzysztof Grobelny 
635c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
636c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "MemoryClassification",
637c1343bf6SKrzysztof Grobelny         memoryClassification, "OffsetInKiB", offsetInKiB, "PartitionId",
638c1343bf6SKrzysztof Grobelny         partitionId, "PassphraseState", passphraseState, "SizeInKiB",
639c1343bf6SKrzysztof Grobelny         sizeInKiB);
640c1343bf6SKrzysztof Grobelny 
641c1343bf6SKrzysztof Grobelny     if (!success)
642c1343bf6SKrzysztof Grobelny     {
643c1343bf6SKrzysztof Grobelny         messages::internalError(aResp->res);
644c1343bf6SKrzysztof Grobelny         return;
645c1343bf6SKrzysztof Grobelny     }
646c1343bf6SKrzysztof Grobelny 
647d7f04fd9SNan Zhou     nlohmann::json::object_t partition;
648c1343bf6SKrzysztof Grobelny 
649c1343bf6SKrzysztof Grobelny     if (memoryClassification != nullptr)
650ac6a4445SGunnar Mills     {
651c1343bf6SKrzysztof Grobelny         partition["MemoryClassification"] = *memoryClassification;
652ac6a4445SGunnar Mills     }
653ac6a4445SGunnar Mills 
654c1343bf6SKrzysztof Grobelny     if (offsetInKiB != nullptr)
655ac6a4445SGunnar Mills     {
656c1343bf6SKrzysztof Grobelny         partition["OffsetMiB"] = (*offsetInKiB >> 10);
657ac6a4445SGunnar Mills     }
658ac6a4445SGunnar Mills 
659c1343bf6SKrzysztof Grobelny     if (partitionId != nullptr)
660ac6a4445SGunnar Mills     {
661c1343bf6SKrzysztof Grobelny         partition["RegionId"] = *partitionId;
662c1343bf6SKrzysztof Grobelny     }
663c1343bf6SKrzysztof Grobelny 
664c1343bf6SKrzysztof Grobelny     if (passphraseState != nullptr)
665ac6a4445SGunnar Mills     {
666c1343bf6SKrzysztof Grobelny         partition["PassphraseEnabled"] = *passphraseState;
667ac6a4445SGunnar Mills     }
668c1343bf6SKrzysztof Grobelny 
669c1343bf6SKrzysztof Grobelny     if (sizeInKiB != nullptr)
670ac6a4445SGunnar Mills     {
671c1343bf6SKrzysztof Grobelny         partition["SizeMiB"] = (*sizeInKiB >> 10);
672ac6a4445SGunnar Mills     }
673c1343bf6SKrzysztof Grobelny 
674d7f04fd9SNan Zhou     aResp->res.jsonValue[regionPtr].emplace_back(std::move(partition));
675ef00d7d4SNan Zhou }
676ef00d7d4SNan Zhou 
677ef00d7d4SNan Zhou inline void getDimmPartitionData(std::shared_ptr<bmcweb::AsyncResp> aResp,
678ef00d7d4SNan Zhou                                  const std::string& service,
679ef00d7d4SNan Zhou                                  const std::string& path)
680ef00d7d4SNan Zhou {
681c1343bf6SKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
682c1343bf6SKrzysztof Grobelny         *crow::connections::systemBus, service, path,
683c1343bf6SKrzysztof Grobelny         "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition",
684ef00d7d4SNan Zhou         [aResp{std::move(aResp)}](
6855e7e2dc5SEd Tanous             const boost::system::error_code& ec,
686ef00d7d4SNan Zhou             const dbus::utility::DBusPropertiesMap& properties) {
687ef00d7d4SNan Zhou         if (ec)
688ef00d7d4SNan Zhou         {
689ef00d7d4SNan Zhou             BMCWEB_LOG_DEBUG << "DBUS response error";
690ef00d7d4SNan Zhou             messages::internalError(aResp->res);
691ef00d7d4SNan Zhou 
692ef00d7d4SNan Zhou             return;
693ef00d7d4SNan Zhou         }
694d7f04fd9SNan Zhou         nlohmann::json::json_pointer regionPtr = "/Regions"_json_pointer;
695d7f04fd9SNan Zhou         assembleDimmPartitionData(aResp, properties, regionPtr);
696c1343bf6SKrzysztof Grobelny         }
697ac6a4445SGunnar Mills 
698c1343bf6SKrzysztof Grobelny     );
699ac6a4445SGunnar Mills }
700ac6a4445SGunnar Mills 
7018d1b46d7Szhanghch05 inline void getDimmData(std::shared_ptr<bmcweb::AsyncResp> aResp,
702ac6a4445SGunnar Mills                         const std::string& dimmId)
703ac6a4445SGunnar Mills {
704ac6a4445SGunnar Mills     BMCWEB_LOG_DEBUG << "Get available system dimm resources.";
705e99073f5SGeorge Liu     constexpr std::array<std::string_view, 2> dimmInterfaces = {
706e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Dimm",
707e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"};
708e99073f5SGeorge Liu     dbus::utility::getSubTree(
709e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, dimmInterfaces,
710ac6a4445SGunnar Mills         [dimmId, aResp{std::move(aResp)}](
711e99073f5SGeorge Liu             const boost::system::error_code& ec,
712b9d36b47SEd Tanous             const dbus::utility::MapperGetSubTreeResponse& subtree) {
713ac6a4445SGunnar Mills         if (ec)
714ac6a4445SGunnar Mills         {
715ac6a4445SGunnar Mills             BMCWEB_LOG_DEBUG << "DBUS response error";
716ac6a4445SGunnar Mills             messages::internalError(aResp->res);
717ac6a4445SGunnar Mills 
718ac6a4445SGunnar Mills             return;
719ac6a4445SGunnar Mills         }
720ac6a4445SGunnar Mills         bool found = false;
72176686dccSNan Zhou         for (const auto& [rawPath, object] : subtree)
722ac6a4445SGunnar Mills         {
72376686dccSNan Zhou             sdbusplus::message::object_path path(rawPath);
724ac6a4445SGunnar Mills             for (const auto& [service, interfaces] : object)
725ac6a4445SGunnar Mills             {
726b9d36b47SEd Tanous                 for (const auto& interface : interfaces)
727ac6a4445SGunnar Mills                 {
728b9d36b47SEd Tanous                     if (interface ==
72976686dccSNan Zhou                             "xyz.openbmc_project.Inventory.Item.Dimm" &&
73076686dccSNan Zhou                         path.filename() == dimmId)
731b9d36b47SEd Tanous                     {
73276686dccSNan Zhou                         getDimmDataByService(aResp, dimmId, service, rawPath);
733ac6a4445SGunnar Mills                         found = true;
734ac6a4445SGunnar Mills                     }
735ac6a4445SGunnar Mills 
736b9d36b47SEd Tanous                     // partitions are separate as there can be multiple
737b9d36b47SEd Tanous                     // per
738ac6a4445SGunnar Mills                     // device, i.e.
739ac6a4445SGunnar Mills                     // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1
740ac6a4445SGunnar Mills                     // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2
741b9d36b47SEd Tanous                     if (interface ==
74276686dccSNan Zhou                             "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition" &&
74376686dccSNan Zhou                         path.parent_path().filename() == dimmId)
744ac6a4445SGunnar Mills                     {
74576686dccSNan Zhou                         getDimmPartitionData(aResp, service, rawPath);
746ac6a4445SGunnar Mills                     }
747ac6a4445SGunnar Mills                 }
748ac6a4445SGunnar Mills             }
749b9d36b47SEd Tanous         }
750ac6a4445SGunnar Mills         // Object not found
751ac6a4445SGunnar Mills         if (!found)
752ac6a4445SGunnar Mills         {
753ac6a4445SGunnar Mills             messages::resourceNotFound(aResp->res, "Memory", dimmId);
7541a1d5d6dSNan Zhou             return;
755ac6a4445SGunnar Mills         }
7561a1d5d6dSNan Zhou         // Set @odata only if object is found
7571a1d5d6dSNan Zhou         aResp->res.jsonValue["@odata.type"] = "#Memory.v1_11_0.Memory";
758*ef4c65b7SEd Tanous         aResp->res.jsonValue["@odata.id"] =
759*ef4c65b7SEd Tanous             boost::urls::format("/redfish/v1/Systems/system/Memory/{}", dimmId);
760ac6a4445SGunnar Mills         return;
761e99073f5SGeorge Liu         });
762ac6a4445SGunnar Mills }
763ac6a4445SGunnar Mills 
7647e860f15SJohn Edward Broadbent inline void requestRoutesMemoryCollection(App& app)
765ac6a4445SGunnar Mills {
766ac6a4445SGunnar Mills     /**
767ac6a4445SGunnar Mills      * Functions triggers appropriate requests on DBus
768ac6a4445SGunnar Mills      */
76922d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/")
770ed398213SEd Tanous         .privileges(redfish::privileges::getMemoryCollection)
7717e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
77245ca1b86SEd Tanous             [&app](const crow::Request& req,
77322d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
77422d268cbSEd Tanous                    const std::string& systemName) {
7753ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
77645ca1b86SEd Tanous         {
77745ca1b86SEd Tanous             return;
77845ca1b86SEd Tanous         }
77922d268cbSEd Tanous         if (systemName != "system")
78022d268cbSEd Tanous         {
78122d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
78222d268cbSEd Tanous                                        systemName);
78322d268cbSEd Tanous             return;
78422d268cbSEd Tanous         }
78522d268cbSEd Tanous 
7868d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.type"] =
7878d1b46d7Szhanghch05             "#MemoryCollection.MemoryCollection";
7888d1b46d7Szhanghch05         asyncResp->res.jsonValue["Name"] = "Memory Module Collection";
7898d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.id"] =
7908d1b46d7Szhanghch05             "/redfish/v1/Systems/system/Memory";
791ac6a4445SGunnar Mills 
7927a1dbc48SGeorge Liu         constexpr std::array<std::string_view, 1> interfaces{
7937a1dbc48SGeorge Liu             "xyz.openbmc_project.Inventory.Item.Dimm"};
79405030b8eSGunnar Mills         collection_util::getCollectionMembers(
795ae9031f0SWilly Tu             asyncResp, boost::urls::url("/redfish/v1/Systems/system/Memory"),
7967a1dbc48SGeorge Liu             interfaces);
7977e860f15SJohn Edward Broadbent         });
798ac6a4445SGunnar Mills }
799ac6a4445SGunnar Mills 
8007e860f15SJohn Edward Broadbent inline void requestRoutesMemory(App& app)
8017e860f15SJohn Edward Broadbent {
802ac6a4445SGunnar Mills     /**
803ac6a4445SGunnar Mills      * Functions triggers appropriate requests on DBus
804ac6a4445SGunnar Mills      */
80522d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/<str>/")
806ed398213SEd Tanous         .privileges(redfish::privileges::getMemory)
8077e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
80845ca1b86SEd Tanous             [&app](const crow::Request& req,
8097e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
81022d268cbSEd Tanous                    const std::string& systemName, const std::string& dimmId) {
8113ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
81245ca1b86SEd Tanous         {
81345ca1b86SEd Tanous             return;
81445ca1b86SEd Tanous         }
81522d268cbSEd Tanous         if (systemName != "system")
81622d268cbSEd Tanous         {
81722d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
81822d268cbSEd Tanous                                        systemName);
81922d268cbSEd Tanous             return;
82022d268cbSEd Tanous         }
82122d268cbSEd Tanous 
822ac6a4445SGunnar Mills         getDimmData(asyncResp, dimmId);
8237e860f15SJohn Edward Broadbent         });
824ac6a4445SGunnar Mills }
825ac6a4445SGunnar Mills 
826ac6a4445SGunnar Mills } // namespace redfish
827