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