xref: /openbmc/bmcweb/features/redfish/lib/memory.hpp (revision 13451e3913c29bb380ef6778f11749d337ddd442)
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 
18*13451e39SWilly Tu #include "bmcweb_config.h"
19*13451e39SWilly 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 
155c1343bf6SKrzysztof Grobelny inline void dimmPropToHex(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
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     }
163d7f04fd9SNan Zhou     aResp->res.jsonValue[jsonPtr][key] = "0x" + intToHexString(*value, 4);
164ac6a4445SGunnar Mills }
165ac6a4445SGunnar Mills 
1668d1b46d7Szhanghch05 inline void getPersistentMemoryProperties(
1678d1b46d7Szhanghch05     const std::shared_ptr<bmcweb::AsyncResp>& aResp,
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     {
224c1343bf6SKrzysztof Grobelny         messages::internalError(aResp->res);
225c1343bf6SKrzysztof Grobelny         return;
226ac6a4445SGunnar Mills     }
227c1343bf6SKrzysztof Grobelny 
228c1343bf6SKrzysztof Grobelny     dimmPropToHex(aResp, "ModuleManufacturerID", moduleManufacturerID, jsonPtr);
229c1343bf6SKrzysztof Grobelny     dimmPropToHex(aResp, "ModuleProductID", moduleProductID, jsonPtr);
230ac6a4445SGunnar Mills     dimmPropToHex(aResp, "MemorySubsystemControllerManufacturerID",
231c1343bf6SKrzysztof Grobelny                   subsystemVendorID, jsonPtr);
232c1343bf6SKrzysztof Grobelny     dimmPropToHex(aResp, "MemorySubsystemControllerProductID",
233c1343bf6SKrzysztof Grobelny                   subsystemDeviceID, jsonPtr);
234ac6a4445SGunnar Mills 
235c1343bf6SKrzysztof Grobelny     if (volatileRegionSizeLimitInKiB != nullptr)
236ac6a4445SGunnar Mills     {
237d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["VolatileRegionSizeLimitMiB"] =
238c1343bf6SKrzysztof Grobelny             (*volatileRegionSizeLimitInKiB) >> 10;
239ac6a4445SGunnar Mills     }
240ac6a4445SGunnar Mills 
241c1343bf6SKrzysztof Grobelny     if (pmRegionSizeLimitInKiB != nullptr)
242ac6a4445SGunnar Mills     {
243d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["PersistentRegionSizeLimitMiB"] =
244c1343bf6SKrzysztof Grobelny             (*pmRegionSizeLimitInKiB) >> 10;
245ac6a4445SGunnar Mills     }
246ac6a4445SGunnar Mills 
247c1343bf6SKrzysztof Grobelny     if (volatileSizeInKiB != nullptr)
248ac6a4445SGunnar Mills     {
249c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["VolatileSizeMiB"] =
250c1343bf6SKrzysztof Grobelny             (*volatileSizeInKiB) >> 10;
251ac6a4445SGunnar Mills     }
252c1343bf6SKrzysztof Grobelny 
253c1343bf6SKrzysztof Grobelny     if (pmSizeInKiB != nullptr)
254c1343bf6SKrzysztof Grobelny     {
25589492a15SPatrick Williams         aResp->res.jsonValue[jsonPtr]["NonVolatileSizeMiB"] = (*pmSizeInKiB) >>
25689492a15SPatrick Williams                                                               10;
257c1343bf6SKrzysztof Grobelny     }
258c1343bf6SKrzysztof Grobelny 
259c1343bf6SKrzysztof Grobelny     if (cacheSizeInKB != nullptr)
260c1343bf6SKrzysztof Grobelny     {
261c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["CacheSizeMiB"] = (*cacheSizeInKB >> 10);
262c1343bf6SKrzysztof Grobelny     }
263c1343bf6SKrzysztof Grobelny 
264c1343bf6SKrzysztof Grobelny     if (voltaileRegionMaxSizeInKib != nullptr)
265c1343bf6SKrzysztof Grobelny     {
266d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["VolatileRegionSizeMaxMiB"] =
267c1343bf6SKrzysztof Grobelny             (*voltaileRegionMaxSizeInKib) >> 10;
268ac6a4445SGunnar Mills     }
269ac6a4445SGunnar Mills 
270c1343bf6SKrzysztof Grobelny     if (pmRegionMaxSizeInKiB != nullptr)
271ac6a4445SGunnar Mills     {
272d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["PersistentRegionSizeMaxMiB"] =
273c1343bf6SKrzysztof Grobelny             (*pmRegionMaxSizeInKiB) >> 10;
274ac6a4445SGunnar Mills     }
275ac6a4445SGunnar Mills 
276c1343bf6SKrzysztof Grobelny     if (allocationIncrementInKiB != nullptr)
277ac6a4445SGunnar Mills     {
278d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["AllocationIncrementMiB"] =
279c1343bf6SKrzysztof Grobelny             (*allocationIncrementInKiB) >> 10;
280ac6a4445SGunnar Mills     }
281ac6a4445SGunnar Mills 
282c1343bf6SKrzysztof Grobelny     if (allocationAlignmentInKiB != nullptr)
283ac6a4445SGunnar Mills     {
284d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["AllocationAlignmentMiB"] =
285c1343bf6SKrzysztof Grobelny             (*allocationAlignmentInKiB) >> 10;
286ac6a4445SGunnar Mills     }
287c1343bf6SKrzysztof Grobelny 
288c1343bf6SKrzysztof Grobelny     if (volatileRegionNumberLimit != nullptr)
289ac6a4445SGunnar Mills     {
290c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["VolatileRegionNumberLimit"] =
291c1343bf6SKrzysztof Grobelny             *volatileRegionNumberLimit;
292ac6a4445SGunnar Mills     }
293c1343bf6SKrzysztof Grobelny 
294c1343bf6SKrzysztof Grobelny     if (pmRegionNumberLimit != nullptr)
295ac6a4445SGunnar Mills     {
296c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["PersistentRegionNumberLimit"] =
297c1343bf6SKrzysztof Grobelny             *pmRegionNumberLimit;
298ac6a4445SGunnar Mills     }
299c1343bf6SKrzysztof Grobelny 
300c1343bf6SKrzysztof Grobelny     if (spareDeviceCount != nullptr)
301ac6a4445SGunnar Mills     {
302c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["SpareDeviceCount"] = *spareDeviceCount;
303ac6a4445SGunnar Mills     }
304c1343bf6SKrzysztof Grobelny 
305c1343bf6SKrzysztof Grobelny     if (isSpareDeviceInUse != nullptr)
306ac6a4445SGunnar Mills     {
307c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["IsSpareDeviceEnabled"] =
308c1343bf6SKrzysztof Grobelny             *isSpareDeviceInUse;
309ac6a4445SGunnar Mills     }
310c1343bf6SKrzysztof Grobelny 
311c1343bf6SKrzysztof Grobelny     if (isRankSpareEnabled != nullptr)
312ac6a4445SGunnar Mills     {
313c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["IsRankSpareEnabled"] =
314c1343bf6SKrzysztof Grobelny             *isRankSpareEnabled;
315ac6a4445SGunnar Mills     }
316c1343bf6SKrzysztof Grobelny 
317c1343bf6SKrzysztof Grobelny     if (maxAveragePowerLimitmW != nullptr)
318ac6a4445SGunnar Mills     {
319c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["MaxTDPMilliWatts"] =
320c1343bf6SKrzysztof Grobelny             *maxAveragePowerLimitmW;
321ac6a4445SGunnar Mills     }
322c1343bf6SKrzysztof Grobelny 
323c1343bf6SKrzysztof Grobelny     if (configurationLocked != nullptr)
324ac6a4445SGunnar Mills     {
325c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["ConfigurationLocked"] =
326c1343bf6SKrzysztof Grobelny             *configurationLocked;
327ac6a4445SGunnar Mills     }
328c1343bf6SKrzysztof Grobelny 
329c1343bf6SKrzysztof Grobelny     if (allowedMemoryModes != nullptr)
330ac6a4445SGunnar Mills     {
33180badf7cSJiaqing Zhao         constexpr const std::array<const char*, 3> values{"Volatile", "PMEM",
33280badf7cSJiaqing Zhao                                                           "Block"};
333ac6a4445SGunnar Mills 
334ac6a4445SGunnar Mills         for (const char* v : values)
335ac6a4445SGunnar Mills         {
336c1343bf6SKrzysztof Grobelny             if (allowedMemoryModes->ends_with(v))
337ac6a4445SGunnar Mills             {
338d7f04fd9SNan Zhou                 aResp->res.jsonValue[jsonPtr]["OperatingMemoryModes"].push_back(
339d7f04fd9SNan Zhou                     v);
340ac6a4445SGunnar Mills                 break;
341ac6a4445SGunnar Mills             }
342ac6a4445SGunnar Mills         }
343ac6a4445SGunnar Mills     }
344c1343bf6SKrzysztof Grobelny 
345c1343bf6SKrzysztof Grobelny     if (memoryMedia != nullptr)
346ac6a4445SGunnar Mills     {
347ac6a4445SGunnar Mills         constexpr const std::array<const char*, 3> values{"DRAM", "NAND",
348ac6a4445SGunnar Mills                                                           "Intel3DXPoint"};
349ac6a4445SGunnar Mills 
350ac6a4445SGunnar Mills         for (const char* v : values)
351ac6a4445SGunnar Mills         {
352c1343bf6SKrzysztof Grobelny             if (memoryMedia->ends_with(v))
353ac6a4445SGunnar Mills             {
354d7f04fd9SNan Zhou                 aResp->res.jsonValue[jsonPtr]["MemoryMedia"].push_back(v);
355ac6a4445SGunnar Mills                 break;
356ac6a4445SGunnar Mills             }
357ac6a4445SGunnar Mills         }
358ac6a4445SGunnar Mills     }
359c1343bf6SKrzysztof Grobelny 
360c1343bf6SKrzysztof Grobelny     if (configurationLockCapable != nullptr)
361ac6a4445SGunnar Mills     {
362c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
363c1343bf6SKrzysztof Grobelny                             ["ConfigurationLockCapable"] =
364c1343bf6SKrzysztof Grobelny             *configurationLockCapable;
365ac6a4445SGunnar Mills     }
366c1343bf6SKrzysztof Grobelny 
367c1343bf6SKrzysztof Grobelny     if (dataLockCapable != nullptr)
368ac6a4445SGunnar Mills     {
36989492a15SPatrick Williams         aResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
37089492a15SPatrick Williams                             ["DataLockCapable"] = *dataLockCapable;
371ac6a4445SGunnar Mills     }
372c1343bf6SKrzysztof Grobelny 
373c1343bf6SKrzysztof Grobelny     if (passphraseCapable != nullptr)
374c1343bf6SKrzysztof Grobelny     {
37589492a15SPatrick Williams         aResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
37689492a15SPatrick Williams                             ["PassphraseCapable"] = *passphraseCapable;
377c1343bf6SKrzysztof Grobelny     }
378c1343bf6SKrzysztof Grobelny 
379c1343bf6SKrzysztof Grobelny     if (maxPassphraseCount != nullptr)
380c1343bf6SKrzysztof Grobelny     {
38189492a15SPatrick Williams         aResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
38289492a15SPatrick Williams                             ["MaxPassphraseCount"] = *maxPassphraseCount;
383c1343bf6SKrzysztof Grobelny     }
384c1343bf6SKrzysztof Grobelny 
385c1343bf6SKrzysztof Grobelny     if (passphraseLockLimit != nullptr)
386c1343bf6SKrzysztof Grobelny     {
38789492a15SPatrick Williams         aResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
38889492a15SPatrick Williams                             ["PassphraseLockLimit"] = *passphraseLockLimit;
389ac6a4445SGunnar Mills     }
390ac6a4445SGunnar Mills }
391ac6a4445SGunnar Mills 
3929a5aceacSNan Zhou inline void
3939a5aceacSNan Zhou     assembleDimmProperties(std::string_view dimmId,
3949a5aceacSNan Zhou                            const std::shared_ptr<bmcweb::AsyncResp>& aResp,
395d7f04fd9SNan Zhou                            const dbus::utility::DBusPropertiesMap& properties,
396d7f04fd9SNan Zhou                            const nlohmann::json::json_pointer& jsonPtr)
397ac6a4445SGunnar Mills {
398d7f04fd9SNan Zhou     aResp->res.jsonValue[jsonPtr]["Id"] = dimmId;
399d7f04fd9SNan Zhou     aResp->res.jsonValue[jsonPtr]["Name"] = "DIMM Slot";
400d7f04fd9SNan Zhou     aResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Enabled";
401d7f04fd9SNan Zhou     aResp->res.jsonValue[jsonPtr]["Status"]["Health"] = "OK";
402ac6a4445SGunnar Mills 
403c1343bf6SKrzysztof Grobelny     const uint16_t* memoryDataWidth = nullptr;
404c1343bf6SKrzysztof Grobelny     const size_t* memorySizeInKB = nullptr;
405c1343bf6SKrzysztof Grobelny     const std::string* partNumber = nullptr;
406c1343bf6SKrzysztof Grobelny     const std::string* serialNumber = nullptr;
407c1343bf6SKrzysztof Grobelny     const std::string* manufacturer = nullptr;
408c1343bf6SKrzysztof Grobelny     const uint16_t* revisionCode = nullptr;
409c1343bf6SKrzysztof Grobelny     const bool* present = nullptr;
410c1343bf6SKrzysztof Grobelny     const uint16_t* memoryTotalWidth = nullptr;
411c1343bf6SKrzysztof Grobelny     const std::string* ecc = nullptr;
412c1343bf6SKrzysztof Grobelny     const std::string* formFactor = nullptr;
413c1343bf6SKrzysztof Grobelny     const std::vector<uint16_t>* allowedSpeedsMT = nullptr;
414c1343bf6SKrzysztof Grobelny     const uint8_t* memoryAttributes = nullptr;
415c1343bf6SKrzysztof Grobelny     const uint16_t* memoryConfiguredSpeedInMhz = nullptr;
416c1343bf6SKrzysztof Grobelny     const std::string* memoryType = nullptr;
417c1343bf6SKrzysztof Grobelny     const std::string* channel = nullptr;
418c1343bf6SKrzysztof Grobelny     const std::string* memoryController = nullptr;
419c1343bf6SKrzysztof Grobelny     const std::string* slot = nullptr;
420c1343bf6SKrzysztof Grobelny     const std::string* socket = nullptr;
421c1343bf6SKrzysztof Grobelny     const std::string* sparePartNumber = nullptr;
422c1343bf6SKrzysztof Grobelny     const std::string* model = nullptr;
423c1343bf6SKrzysztof Grobelny     const std::string* locationCode = nullptr;
424ac6a4445SGunnar Mills 
425c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
426c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "MemoryDataWidth",
427c1343bf6SKrzysztof Grobelny         memoryDataWidth, "MemorySizeInKB", memorySizeInKB, "PartNumber",
428656472d9SNikhil Namjoshi         partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
429656472d9SNikhil Namjoshi         "RevisionCode", revisionCode, "Present", present, "MemoryTotalWidth",
430656472d9SNikhil Namjoshi         memoryTotalWidth, "ECC", ecc, "FormFactor", formFactor,
431656472d9SNikhil Namjoshi         "AllowedSpeedsMT", allowedSpeedsMT, "MemoryAttributes",
432c1343bf6SKrzysztof Grobelny         memoryAttributes, "MemoryConfiguredSpeedInMhz",
433c1343bf6SKrzysztof Grobelny         memoryConfiguredSpeedInMhz, "MemoryType", memoryType, "Channel",
434c1343bf6SKrzysztof Grobelny         channel, "MemoryController", memoryController, "Slot", slot, "Socket",
435c1343bf6SKrzysztof Grobelny         socket, "SparePartNumber", sparePartNumber, "Model", model,
436c1343bf6SKrzysztof Grobelny         "LocationCode", locationCode);
437c1343bf6SKrzysztof Grobelny 
438c1343bf6SKrzysztof Grobelny     if (!success)
439ac6a4445SGunnar Mills     {
440ac6a4445SGunnar Mills         messages::internalError(aResp->res);
441601af5edSChicago Duan         return;
442ac6a4445SGunnar Mills     }
443c1343bf6SKrzysztof Grobelny 
444c1343bf6SKrzysztof Grobelny     if (memoryDataWidth != nullptr)
445c1343bf6SKrzysztof Grobelny     {
446c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["DataWidthBits"] = *memoryDataWidth;
447c1343bf6SKrzysztof Grobelny     }
448c1343bf6SKrzysztof Grobelny 
449c1343bf6SKrzysztof Grobelny     if (memorySizeInKB != nullptr)
450c1343bf6SKrzysztof Grobelny     {
451c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["CapacityMiB"] = (*memorySizeInKB >> 10);
452c1343bf6SKrzysztof Grobelny     }
453c1343bf6SKrzysztof Grobelny 
454c1343bf6SKrzysztof Grobelny     if (partNumber != nullptr)
455c1343bf6SKrzysztof Grobelny     {
456c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["PartNumber"] = *partNumber;
457c1343bf6SKrzysztof Grobelny     }
458c1343bf6SKrzysztof Grobelny 
459c1343bf6SKrzysztof Grobelny     if (serialNumber != nullptr)
460c1343bf6SKrzysztof Grobelny     {
461c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["SerialNumber"] = *serialNumber;
462c1343bf6SKrzysztof Grobelny     }
463c1343bf6SKrzysztof Grobelny 
464c1343bf6SKrzysztof Grobelny     if (manufacturer != nullptr)
465c1343bf6SKrzysztof Grobelny     {
466c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["Manufacturer"] = *manufacturer;
467c1343bf6SKrzysztof Grobelny     }
468c1343bf6SKrzysztof Grobelny 
469c1343bf6SKrzysztof Grobelny     if (revisionCode != nullptr)
470c1343bf6SKrzysztof Grobelny     {
471d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["FirmwareRevision"] =
472c1343bf6SKrzysztof Grobelny             std::to_string(*revisionCode);
473ac6a4445SGunnar Mills     }
474c1343bf6SKrzysztof Grobelny 
475c1343bf6SKrzysztof Grobelny     if (present != nullptr && !*present)
4769a128eb3SJoshi-Mansi     {
477d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Absent";
4789a128eb3SJoshi-Mansi     }
479c1343bf6SKrzysztof Grobelny 
480c1343bf6SKrzysztof Grobelny     if (memoryTotalWidth != nullptr)
481ac6a4445SGunnar Mills     {
482c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["BusWidthBits"] = *memoryTotalWidth;
483ac6a4445SGunnar Mills     }
484c1343bf6SKrzysztof Grobelny 
485c1343bf6SKrzysztof Grobelny     if (ecc != nullptr)
486ac6a4445SGunnar Mills     {
487ac6a4445SGunnar Mills         constexpr const std::array<const char*, 4> values{
4889a5aceacSNan Zhou             "NoECC", "SingleBitECC", "MultiBitECC", "AddressParity"};
489ac6a4445SGunnar Mills 
490ac6a4445SGunnar Mills         for (const char* v : values)
491ac6a4445SGunnar Mills         {
492c1343bf6SKrzysztof Grobelny             if (ecc->ends_with(v))
493ac6a4445SGunnar Mills             {
494d7f04fd9SNan Zhou                 aResp->res.jsonValue[jsonPtr]["ErrorCorrection"] = v;
495ac6a4445SGunnar Mills                 break;
496ac6a4445SGunnar Mills             }
497ac6a4445SGunnar Mills         }
498ac6a4445SGunnar Mills     }
499c1343bf6SKrzysztof Grobelny 
500c1343bf6SKrzysztof Grobelny     if (formFactor != nullptr)
501ac6a4445SGunnar Mills     {
502ac6a4445SGunnar Mills         constexpr const std::array<const char*, 11> values{
5039a5aceacSNan Zhou             "RDIMM",       "UDIMM",       "SO_DIMM",      "LRDIMM",
5049a5aceacSNan Zhou             "Mini_RDIMM",  "Mini_UDIMM",  "SO_RDIMM_72b", "SO_UDIMM_72b",
5059a5aceacSNan Zhou             "SO_DIMM_16b", "SO_DIMM_32b", "Die"};
506ac6a4445SGunnar Mills 
507ac6a4445SGunnar Mills         for (const char* v : values)
508ac6a4445SGunnar Mills         {
509c1343bf6SKrzysztof Grobelny             if (formFactor->ends_with(v))
510ac6a4445SGunnar Mills             {
511d7f04fd9SNan Zhou                 aResp->res.jsonValue[jsonPtr]["BaseModuleType"] = v;
512ac6a4445SGunnar Mills                 break;
513ac6a4445SGunnar Mills             }
514ac6a4445SGunnar Mills         }
515ac6a4445SGunnar Mills     }
516c1343bf6SKrzysztof Grobelny 
517c1343bf6SKrzysztof Grobelny     if (allowedSpeedsMT != nullptr)
518ac6a4445SGunnar Mills     {
519d7f04fd9SNan Zhou         nlohmann::json& jValue =
520d7f04fd9SNan Zhou             aResp->res.jsonValue[jsonPtr]["AllowedSpeedsMHz"];
521ac6a4445SGunnar Mills         jValue = nlohmann::json::array();
522c1343bf6SKrzysztof Grobelny         for (uint16_t subVal : *allowedSpeedsMT)
523ac6a4445SGunnar Mills         {
524ac6a4445SGunnar Mills             jValue.push_back(subVal);
525ac6a4445SGunnar Mills         }
526ac6a4445SGunnar Mills     }
527ac6a4445SGunnar Mills 
528c1343bf6SKrzysztof Grobelny     if (memoryAttributes != nullptr)
529ac6a4445SGunnar Mills     {
530d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["RankCount"] =
531c1343bf6SKrzysztof Grobelny             static_cast<uint64_t>(*memoryAttributes);
532ac6a4445SGunnar Mills     }
533c1343bf6SKrzysztof Grobelny 
534c1343bf6SKrzysztof Grobelny     if (memoryConfiguredSpeedInMhz != nullptr)
535ac6a4445SGunnar Mills     {
536c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["OperatingSpeedMhz"] =
537c1343bf6SKrzysztof Grobelny             *memoryConfiguredSpeedInMhz;
538ac6a4445SGunnar Mills     }
539c1343bf6SKrzysztof Grobelny 
540c1343bf6SKrzysztof Grobelny     if (memoryType != nullptr)
541ac6a4445SGunnar Mills     {
542313efb1cSGunnar Mills         std::string memoryDeviceType =
543c1343bf6SKrzysztof Grobelny             translateMemoryTypeToRedfish(*memoryType);
544313efb1cSGunnar Mills         // Values like "Unknown" or "Other" will return empty
545313efb1cSGunnar Mills         // so just leave off
546313efb1cSGunnar Mills         if (!memoryDeviceType.empty())
547ac6a4445SGunnar Mills         {
548d7f04fd9SNan Zhou             aResp->res.jsonValue[jsonPtr]["MemoryDeviceType"] =
549d7f04fd9SNan Zhou                 memoryDeviceType;
550ac6a4445SGunnar Mills         }
551c1343bf6SKrzysztof Grobelny         if (memoryType->find("DDR") != std::string::npos)
552ac6a4445SGunnar Mills         {
553d7f04fd9SNan Zhou             aResp->res.jsonValue[jsonPtr]["MemoryType"] = "DRAM";
554ac6a4445SGunnar Mills         }
555c1343bf6SKrzysztof Grobelny         else if (memoryType->ends_with("Logical"))
556ac6a4445SGunnar Mills         {
557d7f04fd9SNan Zhou             aResp->res.jsonValue[jsonPtr]["MemoryType"] = "IntelOptane";
558ac6a4445SGunnar Mills         }
559ac6a4445SGunnar Mills     }
560c1343bf6SKrzysztof Grobelny 
561c1343bf6SKrzysztof Grobelny     if (channel != nullptr)
562ac6a4445SGunnar Mills     {
563c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Channel"] = *channel;
564c1343bf6SKrzysztof Grobelny     }
565c1343bf6SKrzysztof Grobelny 
566c1343bf6SKrzysztof Grobelny     if (memoryController != nullptr)
567ac6a4445SGunnar Mills     {
568c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["MemoryLocation"]["MemoryController"] =
569c1343bf6SKrzysztof Grobelny             *memoryController;
570ac6a4445SGunnar Mills     }
571c1343bf6SKrzysztof Grobelny 
572c1343bf6SKrzysztof Grobelny     if (slot != nullptr)
573ee135e24SSunnySrivastava1984     {
574c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Slot"] = *slot;
575c1343bf6SKrzysztof Grobelny     }
576c1343bf6SKrzysztof Grobelny 
577c1343bf6SKrzysztof Grobelny     if (socket != nullptr)
578ee135e24SSunnySrivastava1984     {
579c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Socket"] = *socket;
580ee135e24SSunnySrivastava1984     }
581c1343bf6SKrzysztof Grobelny 
582c1343bf6SKrzysztof Grobelny     if (sparePartNumber != nullptr)
583ee135e24SSunnySrivastava1984     {
584c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["SparePartNumber"] = *sparePartNumber;
585c1343bf6SKrzysztof Grobelny     }
586c1343bf6SKrzysztof Grobelny 
587c1343bf6SKrzysztof Grobelny     if (model != nullptr)
588ee135e24SSunnySrivastava1984     {
589c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["Model"] = *model;
590ee135e24SSunnySrivastava1984     }
591c1343bf6SKrzysztof Grobelny 
592c1343bf6SKrzysztof Grobelny     if (locationCode != nullptr)
593ee135e24SSunnySrivastava1984     {
59489492a15SPatrick Williams         aResp->res.jsonValue[jsonPtr]["Location"]["PartLocation"]
59589492a15SPatrick Williams                             ["ServiceLabel"] = *locationCode;
596ee135e24SSunnySrivastava1984     }
597c1343bf6SKrzysztof Grobelny 
598c1343bf6SKrzysztof Grobelny     getPersistentMemoryProperties(aResp, properties, jsonPtr);
5999a5aceacSNan Zhou }
6009a5aceacSNan Zhou 
6019a5aceacSNan Zhou inline void getDimmDataByService(std::shared_ptr<bmcweb::AsyncResp> aResp,
6029a5aceacSNan Zhou                                  const std::string& dimmId,
6039a5aceacSNan Zhou                                  const std::string& service,
6049a5aceacSNan Zhou                                  const std::string& objPath)
6059a5aceacSNan Zhou {
606*13451e39SWilly Tu     if constexpr (bmcwebEnableHealthPopulate)
607*13451e39SWilly Tu     {
6089a5aceacSNan Zhou         auto health = std::make_shared<HealthPopulate>(aResp);
6099a5aceacSNan Zhou         health->selfPath = objPath;
6109a5aceacSNan Zhou         health->populate();
611*13451e39SWilly Tu     }
6129a5aceacSNan Zhou 
6139a5aceacSNan Zhou     BMCWEB_LOG_DEBUG << "Get available system components.";
614c1343bf6SKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
615c1343bf6SKrzysztof Grobelny         *crow::connections::systemBus, service, objPath, "",
6169a5aceacSNan Zhou         [dimmId, aResp{std::move(aResp)}](
6175e7e2dc5SEd Tanous             const boost::system::error_code& ec,
6189a5aceacSNan Zhou             const dbus::utility::DBusPropertiesMap& properties) {
6199a5aceacSNan Zhou         if (ec)
6209a5aceacSNan Zhou         {
6219a5aceacSNan Zhou             BMCWEB_LOG_DEBUG << "DBUS response error";
6229a5aceacSNan Zhou             messages::internalError(aResp->res);
6239a5aceacSNan Zhou             return;
6249a5aceacSNan Zhou         }
625d7f04fd9SNan Zhou         assembleDimmProperties(dimmId, aResp, properties, ""_json_pointer);
626c1343bf6SKrzysztof Grobelny         });
627ac6a4445SGunnar Mills }
628ac6a4445SGunnar Mills 
629ef00d7d4SNan Zhou inline void assembleDimmPartitionData(
630ef00d7d4SNan Zhou     const std::shared_ptr<bmcweb::AsyncResp>& aResp,
631d7f04fd9SNan Zhou     const dbus::utility::DBusPropertiesMap& properties,
632d7f04fd9SNan Zhou     const nlohmann::json::json_pointer& regionPtr)
633ac6a4445SGunnar Mills {
634c1343bf6SKrzysztof Grobelny     const std::string* memoryClassification = nullptr;
635c1343bf6SKrzysztof Grobelny     const uint64_t* offsetInKiB = nullptr;
636c1343bf6SKrzysztof Grobelny     const std::string* partitionId = nullptr;
637c1343bf6SKrzysztof Grobelny     const bool* passphraseState = nullptr;
638c1343bf6SKrzysztof Grobelny     const uint64_t* sizeInKiB = nullptr;
639c1343bf6SKrzysztof Grobelny 
640c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
641c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "MemoryClassification",
642c1343bf6SKrzysztof Grobelny         memoryClassification, "OffsetInKiB", offsetInKiB, "PartitionId",
643c1343bf6SKrzysztof Grobelny         partitionId, "PassphraseState", passphraseState, "SizeInKiB",
644c1343bf6SKrzysztof Grobelny         sizeInKiB);
645c1343bf6SKrzysztof Grobelny 
646c1343bf6SKrzysztof Grobelny     if (!success)
647c1343bf6SKrzysztof Grobelny     {
648c1343bf6SKrzysztof Grobelny         messages::internalError(aResp->res);
649c1343bf6SKrzysztof Grobelny         return;
650c1343bf6SKrzysztof Grobelny     }
651c1343bf6SKrzysztof Grobelny 
652d7f04fd9SNan Zhou     nlohmann::json::object_t partition;
653c1343bf6SKrzysztof Grobelny 
654c1343bf6SKrzysztof Grobelny     if (memoryClassification != nullptr)
655ac6a4445SGunnar Mills     {
656c1343bf6SKrzysztof Grobelny         partition["MemoryClassification"] = *memoryClassification;
657ac6a4445SGunnar Mills     }
658ac6a4445SGunnar Mills 
659c1343bf6SKrzysztof Grobelny     if (offsetInKiB != nullptr)
660ac6a4445SGunnar Mills     {
661c1343bf6SKrzysztof Grobelny         partition["OffsetMiB"] = (*offsetInKiB >> 10);
662ac6a4445SGunnar Mills     }
663ac6a4445SGunnar Mills 
664c1343bf6SKrzysztof Grobelny     if (partitionId != nullptr)
665ac6a4445SGunnar Mills     {
666c1343bf6SKrzysztof Grobelny         partition["RegionId"] = *partitionId;
667c1343bf6SKrzysztof Grobelny     }
668c1343bf6SKrzysztof Grobelny 
669c1343bf6SKrzysztof Grobelny     if (passphraseState != nullptr)
670ac6a4445SGunnar Mills     {
671c1343bf6SKrzysztof Grobelny         partition["PassphraseEnabled"] = *passphraseState;
672ac6a4445SGunnar Mills     }
673c1343bf6SKrzysztof Grobelny 
674c1343bf6SKrzysztof Grobelny     if (sizeInKiB != nullptr)
675ac6a4445SGunnar Mills     {
676c1343bf6SKrzysztof Grobelny         partition["SizeMiB"] = (*sizeInKiB >> 10);
677ac6a4445SGunnar Mills     }
678c1343bf6SKrzysztof Grobelny 
679d7f04fd9SNan Zhou     aResp->res.jsonValue[regionPtr].emplace_back(std::move(partition));
680ef00d7d4SNan Zhou }
681ef00d7d4SNan Zhou 
682ef00d7d4SNan Zhou inline void getDimmPartitionData(std::shared_ptr<bmcweb::AsyncResp> aResp,
683ef00d7d4SNan Zhou                                  const std::string& service,
684ef00d7d4SNan Zhou                                  const std::string& path)
685ef00d7d4SNan Zhou {
686c1343bf6SKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
687c1343bf6SKrzysztof Grobelny         *crow::connections::systemBus, service, path,
688c1343bf6SKrzysztof Grobelny         "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition",
689ef00d7d4SNan Zhou         [aResp{std::move(aResp)}](
6905e7e2dc5SEd Tanous             const boost::system::error_code& ec,
691ef00d7d4SNan Zhou             const dbus::utility::DBusPropertiesMap& properties) {
692ef00d7d4SNan Zhou         if (ec)
693ef00d7d4SNan Zhou         {
694ef00d7d4SNan Zhou             BMCWEB_LOG_DEBUG << "DBUS response error";
695ef00d7d4SNan Zhou             messages::internalError(aResp->res);
696ef00d7d4SNan Zhou 
697ef00d7d4SNan Zhou             return;
698ef00d7d4SNan Zhou         }
699d7f04fd9SNan Zhou         nlohmann::json::json_pointer regionPtr = "/Regions"_json_pointer;
700d7f04fd9SNan Zhou         assembleDimmPartitionData(aResp, properties, regionPtr);
701c1343bf6SKrzysztof Grobelny         }
702ac6a4445SGunnar Mills 
703c1343bf6SKrzysztof Grobelny     );
704ac6a4445SGunnar Mills }
705ac6a4445SGunnar Mills 
7068d1b46d7Szhanghch05 inline void getDimmData(std::shared_ptr<bmcweb::AsyncResp> aResp,
707ac6a4445SGunnar Mills                         const std::string& dimmId)
708ac6a4445SGunnar Mills {
709ac6a4445SGunnar Mills     BMCWEB_LOG_DEBUG << "Get available system dimm resources.";
710e99073f5SGeorge Liu     constexpr std::array<std::string_view, 2> dimmInterfaces = {
711e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Dimm",
712e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"};
713e99073f5SGeorge Liu     dbus::utility::getSubTree(
714e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, dimmInterfaces,
715ac6a4445SGunnar Mills         [dimmId, aResp{std::move(aResp)}](
716e99073f5SGeorge Liu             const boost::system::error_code& ec,
717b9d36b47SEd Tanous             const dbus::utility::MapperGetSubTreeResponse& subtree) {
718ac6a4445SGunnar Mills         if (ec)
719ac6a4445SGunnar Mills         {
720ac6a4445SGunnar Mills             BMCWEB_LOG_DEBUG << "DBUS response error";
721ac6a4445SGunnar Mills             messages::internalError(aResp->res);
722ac6a4445SGunnar Mills 
723ac6a4445SGunnar Mills             return;
724ac6a4445SGunnar Mills         }
725ac6a4445SGunnar Mills         bool found = false;
72676686dccSNan Zhou         for (const auto& [rawPath, object] : subtree)
727ac6a4445SGunnar Mills         {
72876686dccSNan Zhou             sdbusplus::message::object_path path(rawPath);
729ac6a4445SGunnar Mills             for (const auto& [service, interfaces] : object)
730ac6a4445SGunnar Mills             {
731b9d36b47SEd Tanous                 for (const auto& interface : interfaces)
732ac6a4445SGunnar Mills                 {
733b9d36b47SEd Tanous                     if (interface ==
73476686dccSNan Zhou                             "xyz.openbmc_project.Inventory.Item.Dimm" &&
73576686dccSNan Zhou                         path.filename() == dimmId)
736b9d36b47SEd Tanous                     {
73776686dccSNan Zhou                         getDimmDataByService(aResp, dimmId, service, rawPath);
738ac6a4445SGunnar Mills                         found = true;
739ac6a4445SGunnar Mills                     }
740ac6a4445SGunnar Mills 
741b9d36b47SEd Tanous                     // partitions are separate as there can be multiple
742b9d36b47SEd Tanous                     // per
743ac6a4445SGunnar Mills                     // device, i.e.
744ac6a4445SGunnar Mills                     // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1
745ac6a4445SGunnar Mills                     // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2
746b9d36b47SEd Tanous                     if (interface ==
74776686dccSNan Zhou                             "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition" &&
74876686dccSNan Zhou                         path.parent_path().filename() == dimmId)
749ac6a4445SGunnar Mills                     {
75076686dccSNan Zhou                         getDimmPartitionData(aResp, service, rawPath);
751ac6a4445SGunnar Mills                     }
752ac6a4445SGunnar Mills                 }
753ac6a4445SGunnar Mills             }
754b9d36b47SEd Tanous         }
755ac6a4445SGunnar Mills         // Object not found
756ac6a4445SGunnar Mills         if (!found)
757ac6a4445SGunnar Mills         {
758ac6a4445SGunnar Mills             messages::resourceNotFound(aResp->res, "Memory", dimmId);
7591a1d5d6dSNan Zhou             return;
760ac6a4445SGunnar Mills         }
7611a1d5d6dSNan Zhou         // Set @odata only if object is found
7621a1d5d6dSNan Zhou         aResp->res.jsonValue["@odata.type"] = "#Memory.v1_11_0.Memory";
763ef4c65b7SEd Tanous         aResp->res.jsonValue["@odata.id"] =
764ef4c65b7SEd Tanous             boost::urls::format("/redfish/v1/Systems/system/Memory/{}", dimmId);
765ac6a4445SGunnar Mills         return;
766e99073f5SGeorge Liu         });
767ac6a4445SGunnar Mills }
768ac6a4445SGunnar Mills 
7697e860f15SJohn Edward Broadbent inline void requestRoutesMemoryCollection(App& app)
770ac6a4445SGunnar Mills {
771ac6a4445SGunnar Mills     /**
772ac6a4445SGunnar Mills      * Functions triggers appropriate requests on DBus
773ac6a4445SGunnar Mills      */
77422d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/")
775ed398213SEd Tanous         .privileges(redfish::privileges::getMemoryCollection)
7767e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
77745ca1b86SEd Tanous             [&app](const crow::Request& req,
77822d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
77922d268cbSEd Tanous                    const std::string& systemName) {
7803ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
78145ca1b86SEd Tanous         {
78245ca1b86SEd Tanous             return;
78345ca1b86SEd Tanous         }
78422d268cbSEd Tanous         if (systemName != "system")
78522d268cbSEd Tanous         {
78622d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
78722d268cbSEd Tanous                                        systemName);
78822d268cbSEd Tanous             return;
78922d268cbSEd Tanous         }
79022d268cbSEd Tanous 
7918d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.type"] =
7928d1b46d7Szhanghch05             "#MemoryCollection.MemoryCollection";
7938d1b46d7Szhanghch05         asyncResp->res.jsonValue["Name"] = "Memory Module Collection";
7948d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.id"] =
7958d1b46d7Szhanghch05             "/redfish/v1/Systems/system/Memory";
796ac6a4445SGunnar Mills 
7977a1dbc48SGeorge Liu         constexpr std::array<std::string_view, 1> interfaces{
7987a1dbc48SGeorge Liu             "xyz.openbmc_project.Inventory.Item.Dimm"};
79905030b8eSGunnar Mills         collection_util::getCollectionMembers(
800ae9031f0SWilly Tu             asyncResp, boost::urls::url("/redfish/v1/Systems/system/Memory"),
8017a1dbc48SGeorge Liu             interfaces);
8027e860f15SJohn Edward Broadbent         });
803ac6a4445SGunnar Mills }
804ac6a4445SGunnar Mills 
8057e860f15SJohn Edward Broadbent inline void requestRoutesMemory(App& app)
8067e860f15SJohn Edward Broadbent {
807ac6a4445SGunnar Mills     /**
808ac6a4445SGunnar Mills      * Functions triggers appropriate requests on DBus
809ac6a4445SGunnar Mills      */
81022d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/<str>/")
811ed398213SEd Tanous         .privileges(redfish::privileges::getMemory)
8127e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
81345ca1b86SEd Tanous             [&app](const crow::Request& req,
8147e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
81522d268cbSEd Tanous                    const std::string& systemName, const std::string& dimmId) {
8163ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
81745ca1b86SEd Tanous         {
81845ca1b86SEd Tanous             return;
81945ca1b86SEd Tanous         }
82022d268cbSEd Tanous         if (systemName != "system")
82122d268cbSEd Tanous         {
82222d268cbSEd Tanous             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
82322d268cbSEd Tanous                                        systemName);
82422d268cbSEd Tanous             return;
82522d268cbSEd Tanous         }
82622d268cbSEd Tanous 
827ac6a4445SGunnar Mills         getDimmData(asyncResp, dimmId);
8287e860f15SJohn Edward Broadbent         });
829ac6a4445SGunnar Mills }
830ac6a4445SGunnar Mills 
831ac6a4445SGunnar Mills } // namespace redfish
832