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