xref: /openbmc/bmcweb/features/redfish/lib/memory.hpp (revision bd79bce8c3f1deb1fb2773868b9ece25233cf27b)
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"
22539d8c6bSEd Tanous #include "generated/enums/memory.hpp"
23539d8c6bSEd Tanous #include "generated/enums/resource.hpp"
243ccb3adbSEd Tanous #include "query.hpp"
253ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
263ccb3adbSEd Tanous #include "utils/collection.hpp"
273ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
283ccb3adbSEd Tanous #include "utils/hex_utils.hpp"
293ccb3adbSEd Tanous #include "utils/json_utils.hpp"
30ac6a4445SGunnar Mills 
31e99073f5SGeorge Liu #include <boost/system/error_code.hpp>
32ef4c65b7SEd Tanous #include <boost/url/format.hpp>
33d7f04fd9SNan Zhou #include <nlohmann/json.hpp>
34c1343bf6SKrzysztof Grobelny #include <sdbusplus/asio/property.hpp>
35c1343bf6SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
36ac6a4445SGunnar Mills 
377a1dbc48SGeorge Liu #include <array>
387a1dbc48SGeorge Liu #include <string_view>
397a1dbc48SGeorge Liu 
40ac6a4445SGunnar Mills namespace redfish
41ac6a4445SGunnar Mills {
42ac6a4445SGunnar Mills 
43313efb1cSGunnar Mills inline std::string translateMemoryTypeToRedfish(const std::string& memoryType)
44313efb1cSGunnar Mills {
45313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR")
46313efb1cSGunnar Mills     {
47313efb1cSGunnar Mills         return "DDR";
48313efb1cSGunnar Mills     }
49313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2")
50313efb1cSGunnar Mills     {
51313efb1cSGunnar Mills         return "DDR2";
52313efb1cSGunnar Mills     }
53313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR3")
54313efb1cSGunnar Mills     {
55313efb1cSGunnar Mills         return "DDR3";
56313efb1cSGunnar Mills     }
57313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4")
58313efb1cSGunnar Mills     {
59313efb1cSGunnar Mills         return "DDR4";
60313efb1cSGunnar Mills     }
61313efb1cSGunnar Mills     if (memoryType ==
62313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4E_SDRAM")
63313efb1cSGunnar Mills     {
64313efb1cSGunnar Mills         return "DDR4E_SDRAM";
65313efb1cSGunnar Mills     }
6611a2f0f0SMansi Joshi     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR5")
6711a2f0f0SMansi Joshi     {
6811a2f0f0SMansi Joshi         return "DDR5";
6911a2f0f0SMansi Joshi     }
70313efb1cSGunnar Mills     if (memoryType ==
71313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR4_SDRAM")
72313efb1cSGunnar Mills     {
73313efb1cSGunnar Mills         return "LPDDR4_SDRAM";
74313efb1cSGunnar Mills     }
75313efb1cSGunnar Mills     if (memoryType ==
76313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR3_SDRAM")
77313efb1cSGunnar Mills     {
78313efb1cSGunnar Mills         return "LPDDR3_SDRAM";
79313efb1cSGunnar Mills     }
80313efb1cSGunnar Mills     if (memoryType ==
81313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM")
82313efb1cSGunnar Mills     {
83313efb1cSGunnar Mills         return "DDR2_SDRAM_FB_DIMM";
84313efb1cSGunnar Mills     }
850fda0f12SGeorge Liu     if (memoryType ==
860fda0f12SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM_PROB")
87313efb1cSGunnar Mills     {
88313efb1cSGunnar Mills         return "DDR2_SDRAM_FB_DIMM_PROBE";
89313efb1cSGunnar Mills     }
90313efb1cSGunnar Mills     if (memoryType ==
91313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR_SGRAM")
92313efb1cSGunnar Mills     {
93313efb1cSGunnar Mills         return "DDR_SGRAM";
94313efb1cSGunnar Mills     }
95313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.ROM")
96313efb1cSGunnar Mills     {
97313efb1cSGunnar Mills         return "ROM";
98313efb1cSGunnar Mills     }
99313efb1cSGunnar Mills     if (memoryType ==
100313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.SDRAM")
101313efb1cSGunnar Mills     {
102313efb1cSGunnar Mills         return "SDRAM";
103313efb1cSGunnar Mills     }
104313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.EDO")
105313efb1cSGunnar Mills     {
106313efb1cSGunnar Mills         return "EDO";
107313efb1cSGunnar Mills     }
108313efb1cSGunnar Mills     if (memoryType ==
109313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.FastPageMode")
110313efb1cSGunnar Mills     {
111313efb1cSGunnar Mills         return "FastPageMode";
112313efb1cSGunnar Mills     }
113313efb1cSGunnar Mills     if (memoryType ==
114313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.PipelinedNibble")
115313efb1cSGunnar Mills     {
116313efb1cSGunnar Mills         return "PipelinedNibble";
117313efb1cSGunnar Mills     }
118313efb1cSGunnar Mills     if (memoryType ==
119313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.Logical")
120313efb1cSGunnar Mills     {
121313efb1cSGunnar Mills         return "Logical";
122313efb1cSGunnar Mills     }
123313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM")
124313efb1cSGunnar Mills     {
125313efb1cSGunnar Mills         return "HBM";
126313efb1cSGunnar Mills     }
127313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM2")
128313efb1cSGunnar Mills     {
129313efb1cSGunnar Mills         return "HBM2";
130313efb1cSGunnar Mills     }
131ce34d514STyson Tuckerbear     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM3")
132ce34d514STyson Tuckerbear     {
133ce34d514STyson Tuckerbear         return "HBM3";
134ce34d514STyson Tuckerbear     }
135313efb1cSGunnar Mills     // This is values like Other or Unknown
136313efb1cSGunnar Mills     // Also D-Bus values:
137313efb1cSGunnar Mills     // DRAM
138313efb1cSGunnar Mills     // EDRAM
139313efb1cSGunnar Mills     // VRAM
140313efb1cSGunnar Mills     // SRAM
141313efb1cSGunnar Mills     // RAM
142313efb1cSGunnar Mills     // FLASH
143313efb1cSGunnar Mills     // EEPROM
144313efb1cSGunnar Mills     // FEPROM
145313efb1cSGunnar Mills     // EPROM
146313efb1cSGunnar Mills     // CDRAM
147313efb1cSGunnar Mills     // ThreeDRAM
148313efb1cSGunnar Mills     // RDRAM
149313efb1cSGunnar Mills     // FBD2
150313efb1cSGunnar Mills     // LPDDR_SDRAM
151313efb1cSGunnar Mills     // LPDDR2_SDRAM
15211a2f0f0SMansi Joshi     // LPDDR5_SDRAM
153313efb1cSGunnar Mills     return "";
154313efb1cSGunnar Mills }
155313efb1cSGunnar Mills 
156ac106bf6SEd Tanous inline void dimmPropToHex(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
157c1343bf6SKrzysztof Grobelny                           const char* key, const uint16_t* value,
158d7f04fd9SNan Zhou                           const nlohmann::json::json_pointer& jsonPtr)
159ac6a4445SGunnar Mills {
160ac6a4445SGunnar Mills     if (value == nullptr)
161ac6a4445SGunnar Mills     {
162ac6a4445SGunnar Mills         return;
163ac6a4445SGunnar Mills     }
164ac106bf6SEd Tanous     asyncResp->res.jsonValue[jsonPtr][key] = "0x" + intToHexString(*value, 4);
165ac6a4445SGunnar Mills }
166ac6a4445SGunnar Mills 
1678d1b46d7Szhanghch05 inline void getPersistentMemoryProperties(
168ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
169c1343bf6SKrzysztof Grobelny     const dbus::utility::DBusPropertiesMap& properties,
170d7f04fd9SNan Zhou     const nlohmann::json::json_pointer& jsonPtr)
171ac6a4445SGunnar Mills {
172c1343bf6SKrzysztof Grobelny     const uint16_t* moduleManufacturerID = nullptr;
173c1343bf6SKrzysztof Grobelny     const uint16_t* moduleProductID = nullptr;
174c1343bf6SKrzysztof Grobelny     const uint16_t* subsystemVendorID = nullptr;
175c1343bf6SKrzysztof Grobelny     const uint16_t* subsystemDeviceID = nullptr;
176c1343bf6SKrzysztof Grobelny     const uint64_t* volatileRegionSizeLimitInKiB = nullptr;
177c1343bf6SKrzysztof Grobelny     const uint64_t* pmRegionSizeLimitInKiB = nullptr;
178c1343bf6SKrzysztof Grobelny     const uint64_t* volatileSizeInKiB = nullptr;
179c1343bf6SKrzysztof Grobelny     const uint64_t* pmSizeInKiB = nullptr;
180c1343bf6SKrzysztof Grobelny     const uint64_t* cacheSizeInKB = nullptr;
181c1343bf6SKrzysztof Grobelny     const uint64_t* voltaileRegionMaxSizeInKib = nullptr;
182c1343bf6SKrzysztof Grobelny     const uint64_t* pmRegionMaxSizeInKiB = nullptr;
183c1343bf6SKrzysztof Grobelny     const uint64_t* allocationIncrementInKiB = nullptr;
184c1343bf6SKrzysztof Grobelny     const uint64_t* allocationAlignmentInKiB = nullptr;
185c1343bf6SKrzysztof Grobelny     const uint64_t* volatileRegionNumberLimit = nullptr;
186c1343bf6SKrzysztof Grobelny     const uint64_t* pmRegionNumberLimit = nullptr;
187c1343bf6SKrzysztof Grobelny     const uint64_t* spareDeviceCount = nullptr;
188c1343bf6SKrzysztof Grobelny     const bool* isSpareDeviceInUse = nullptr;
189c1343bf6SKrzysztof Grobelny     const bool* isRankSpareEnabled = nullptr;
190c1343bf6SKrzysztof Grobelny     const std::vector<uint32_t>* maxAveragePowerLimitmW = nullptr;
191c1343bf6SKrzysztof Grobelny     const bool* configurationLocked = nullptr;
192c1343bf6SKrzysztof Grobelny     const std::string* allowedMemoryModes = nullptr;
193c1343bf6SKrzysztof Grobelny     const std::string* memoryMedia = nullptr;
194c1343bf6SKrzysztof Grobelny     const bool* configurationLockCapable = nullptr;
195c1343bf6SKrzysztof Grobelny     const bool* dataLockCapable = nullptr;
196c1343bf6SKrzysztof Grobelny     const bool* passphraseCapable = nullptr;
197c1343bf6SKrzysztof Grobelny     const uint64_t* maxPassphraseCount = nullptr;
198c1343bf6SKrzysztof Grobelny     const uint64_t* passphraseLockLimit = nullptr;
199c1343bf6SKrzysztof Grobelny 
200c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
201c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "ModuleManufacturerID",
202c1343bf6SKrzysztof Grobelny         moduleManufacturerID, "ModuleProductID", moduleProductID,
203c1343bf6SKrzysztof Grobelny         "SubsystemVendorID", subsystemVendorID, "SubsystemDeviceID",
204c1343bf6SKrzysztof Grobelny         subsystemDeviceID, "VolatileRegionSizeLimitInKiB",
205c1343bf6SKrzysztof Grobelny         volatileRegionSizeLimitInKiB, "PmRegionSizeLimitInKiB",
206c1343bf6SKrzysztof Grobelny         pmRegionSizeLimitInKiB, "VolatileSizeInKiB", volatileSizeInKiB,
207c1343bf6SKrzysztof Grobelny         "PmSizeInKiB", pmSizeInKiB, "CacheSizeInKB", cacheSizeInKB,
208c1343bf6SKrzysztof Grobelny         "VoltaileRegionMaxSizeInKib", voltaileRegionMaxSizeInKib,
209c1343bf6SKrzysztof Grobelny         "PmRegionMaxSizeInKiB", pmRegionMaxSizeInKiB,
210c1343bf6SKrzysztof Grobelny         "AllocationIncrementInKiB", allocationIncrementInKiB,
211c1343bf6SKrzysztof Grobelny         "AllocationAlignmentInKiB", allocationAlignmentInKiB,
212c1343bf6SKrzysztof Grobelny         "VolatileRegionNumberLimit", volatileRegionNumberLimit,
213c1343bf6SKrzysztof Grobelny         "PmRegionNumberLimit", pmRegionNumberLimit, "SpareDeviceCount",
214c1343bf6SKrzysztof Grobelny         spareDeviceCount, "IsSpareDeviceInUse", isSpareDeviceInUse,
215c1343bf6SKrzysztof Grobelny         "IsRankSpareEnabled", isRankSpareEnabled, "MaxAveragePowerLimitmW",
216c1343bf6SKrzysztof Grobelny         maxAveragePowerLimitmW, "ConfigurationLocked", configurationLocked,
217c1343bf6SKrzysztof Grobelny         "AllowedMemoryModes", allowedMemoryModes, "MemoryMedia", memoryMedia,
218c1343bf6SKrzysztof Grobelny         "ConfigurationLockCapable", configurationLockCapable, "DataLockCapable",
219c1343bf6SKrzysztof Grobelny         dataLockCapable, "PassphraseCapable", passphraseCapable,
220c1343bf6SKrzysztof Grobelny         "MaxPassphraseCount", maxPassphraseCount, "PassphraseLockLimit",
221c1343bf6SKrzysztof Grobelny         passphraseLockLimit);
222c1343bf6SKrzysztof Grobelny 
223c1343bf6SKrzysztof Grobelny     if (!success)
224ac6a4445SGunnar Mills     {
225ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
226c1343bf6SKrzysztof Grobelny         return;
227ac6a4445SGunnar Mills     }
228c1343bf6SKrzysztof Grobelny 
229ac106bf6SEd Tanous     dimmPropToHex(asyncResp, "ModuleManufacturerID", moduleManufacturerID,
230ac106bf6SEd Tanous                   jsonPtr);
231ac106bf6SEd Tanous     dimmPropToHex(asyncResp, "ModuleProductID", moduleProductID, jsonPtr);
232ac106bf6SEd Tanous     dimmPropToHex(asyncResp, "MemorySubsystemControllerManufacturerID",
233c1343bf6SKrzysztof Grobelny                   subsystemVendorID, jsonPtr);
234ac106bf6SEd Tanous     dimmPropToHex(asyncResp, "MemorySubsystemControllerProductID",
235c1343bf6SKrzysztof Grobelny                   subsystemDeviceID, jsonPtr);
236ac6a4445SGunnar Mills 
237c1343bf6SKrzysztof Grobelny     if (volatileRegionSizeLimitInKiB != nullptr)
238ac6a4445SGunnar Mills     {
239ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["VolatileRegionSizeLimitMiB"] =
240c1343bf6SKrzysztof Grobelny             (*volatileRegionSizeLimitInKiB) >> 10;
241ac6a4445SGunnar Mills     }
242ac6a4445SGunnar Mills 
243c1343bf6SKrzysztof Grobelny     if (pmRegionSizeLimitInKiB != nullptr)
244ac6a4445SGunnar Mills     {
245ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["PersistentRegionSizeLimitMiB"] =
246c1343bf6SKrzysztof Grobelny             (*pmRegionSizeLimitInKiB) >> 10;
247ac6a4445SGunnar Mills     }
248ac6a4445SGunnar Mills 
249c1343bf6SKrzysztof Grobelny     if (volatileSizeInKiB != nullptr)
250ac6a4445SGunnar Mills     {
251ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["VolatileSizeMiB"] =
252c1343bf6SKrzysztof Grobelny             (*volatileSizeInKiB) >> 10;
253ac6a4445SGunnar Mills     }
254c1343bf6SKrzysztof Grobelny 
255c1343bf6SKrzysztof Grobelny     if (pmSizeInKiB != nullptr)
256c1343bf6SKrzysztof Grobelny     {
257ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["NonVolatileSizeMiB"] =
258ac106bf6SEd Tanous             (*pmSizeInKiB) >> 10;
259c1343bf6SKrzysztof Grobelny     }
260c1343bf6SKrzysztof Grobelny 
261c1343bf6SKrzysztof Grobelny     if (cacheSizeInKB != nullptr)
262c1343bf6SKrzysztof Grobelny     {
263ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["CacheSizeMiB"] =
264ac106bf6SEd Tanous             (*cacheSizeInKB >> 10);
265c1343bf6SKrzysztof Grobelny     }
266c1343bf6SKrzysztof Grobelny 
267c1343bf6SKrzysztof Grobelny     if (voltaileRegionMaxSizeInKib != nullptr)
268c1343bf6SKrzysztof Grobelny     {
269ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["VolatileRegionSizeMaxMiB"] =
270c1343bf6SKrzysztof Grobelny             (*voltaileRegionMaxSizeInKib) >> 10;
271ac6a4445SGunnar Mills     }
272ac6a4445SGunnar Mills 
273c1343bf6SKrzysztof Grobelny     if (pmRegionMaxSizeInKiB != nullptr)
274ac6a4445SGunnar Mills     {
275ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["PersistentRegionSizeMaxMiB"] =
276c1343bf6SKrzysztof Grobelny             (*pmRegionMaxSizeInKiB) >> 10;
277ac6a4445SGunnar Mills     }
278ac6a4445SGunnar Mills 
279c1343bf6SKrzysztof Grobelny     if (allocationIncrementInKiB != nullptr)
280ac6a4445SGunnar Mills     {
281ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["AllocationIncrementMiB"] =
282c1343bf6SKrzysztof Grobelny             (*allocationIncrementInKiB) >> 10;
283ac6a4445SGunnar Mills     }
284ac6a4445SGunnar Mills 
285c1343bf6SKrzysztof Grobelny     if (allocationAlignmentInKiB != nullptr)
286ac6a4445SGunnar Mills     {
287ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["AllocationAlignmentMiB"] =
288c1343bf6SKrzysztof Grobelny             (*allocationAlignmentInKiB) >> 10;
289ac6a4445SGunnar Mills     }
290c1343bf6SKrzysztof Grobelny 
291c1343bf6SKrzysztof Grobelny     if (volatileRegionNumberLimit != nullptr)
292ac6a4445SGunnar Mills     {
293ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["VolatileRegionNumberLimit"] =
294c1343bf6SKrzysztof Grobelny             *volatileRegionNumberLimit;
295ac6a4445SGunnar Mills     }
296c1343bf6SKrzysztof Grobelny 
297c1343bf6SKrzysztof Grobelny     if (pmRegionNumberLimit != nullptr)
298ac6a4445SGunnar Mills     {
299ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["PersistentRegionNumberLimit"] =
300c1343bf6SKrzysztof Grobelny             *pmRegionNumberLimit;
301ac6a4445SGunnar Mills     }
302c1343bf6SKrzysztof Grobelny 
303c1343bf6SKrzysztof Grobelny     if (spareDeviceCount != nullptr)
304ac6a4445SGunnar Mills     {
305ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SpareDeviceCount"] =
306ac106bf6SEd Tanous             *spareDeviceCount;
307ac6a4445SGunnar Mills     }
308c1343bf6SKrzysztof Grobelny 
309c1343bf6SKrzysztof Grobelny     if (isSpareDeviceInUse != nullptr)
310ac6a4445SGunnar Mills     {
311ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["IsSpareDeviceEnabled"] =
312c1343bf6SKrzysztof Grobelny             *isSpareDeviceInUse;
313ac6a4445SGunnar Mills     }
314c1343bf6SKrzysztof Grobelny 
315c1343bf6SKrzysztof Grobelny     if (isRankSpareEnabled != nullptr)
316ac6a4445SGunnar Mills     {
317ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["IsRankSpareEnabled"] =
318c1343bf6SKrzysztof Grobelny             *isRankSpareEnabled;
319ac6a4445SGunnar Mills     }
320c1343bf6SKrzysztof Grobelny 
321c1343bf6SKrzysztof Grobelny     if (maxAveragePowerLimitmW != nullptr)
322ac6a4445SGunnar Mills     {
323ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MaxTDPMilliWatts"] =
324c1343bf6SKrzysztof Grobelny             *maxAveragePowerLimitmW;
325ac6a4445SGunnar Mills     }
326c1343bf6SKrzysztof Grobelny 
327c1343bf6SKrzysztof Grobelny     if (configurationLocked != nullptr)
328ac6a4445SGunnar Mills     {
329ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["ConfigurationLocked"] =
330c1343bf6SKrzysztof Grobelny             *configurationLocked;
331ac6a4445SGunnar Mills     }
332c1343bf6SKrzysztof Grobelny 
333c1343bf6SKrzysztof Grobelny     if (allowedMemoryModes != nullptr)
334ac6a4445SGunnar Mills     {
33580badf7cSJiaqing Zhao         constexpr const std::array<const char*, 3> values{"Volatile", "PMEM",
33680badf7cSJiaqing Zhao                                                           "Block"};
337ac6a4445SGunnar Mills 
338ac6a4445SGunnar Mills         for (const char* v : values)
339ac6a4445SGunnar Mills         {
340c1343bf6SKrzysztof Grobelny             if (allowedMemoryModes->ends_with(v))
341ac6a4445SGunnar Mills             {
342ac106bf6SEd Tanous                 asyncResp->res.jsonValue[jsonPtr]["OperatingMemoryModes"]
343ac106bf6SEd Tanous                     .push_back(v);
344ac6a4445SGunnar Mills                 break;
345ac6a4445SGunnar Mills             }
346ac6a4445SGunnar Mills         }
347ac6a4445SGunnar Mills     }
348c1343bf6SKrzysztof Grobelny 
349c1343bf6SKrzysztof Grobelny     if (memoryMedia != nullptr)
350ac6a4445SGunnar Mills     {
351ac6a4445SGunnar Mills         constexpr const std::array<const char*, 3> values{"DRAM", "NAND",
352ac6a4445SGunnar Mills                                                           "Intel3DXPoint"};
353ac6a4445SGunnar Mills 
354ac6a4445SGunnar Mills         for (const char* v : values)
355ac6a4445SGunnar Mills         {
356c1343bf6SKrzysztof Grobelny             if (memoryMedia->ends_with(v))
357ac6a4445SGunnar Mills             {
358ac106bf6SEd Tanous                 asyncResp->res.jsonValue[jsonPtr]["MemoryMedia"].push_back(v);
359ac6a4445SGunnar Mills                 break;
360ac6a4445SGunnar Mills             }
361ac6a4445SGunnar Mills         }
362ac6a4445SGunnar Mills     }
363c1343bf6SKrzysztof Grobelny 
364c1343bf6SKrzysztof Grobelny     if (configurationLockCapable != nullptr)
365ac6a4445SGunnar Mills     {
366ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
367c1343bf6SKrzysztof Grobelny                                 ["ConfigurationLockCapable"] =
368c1343bf6SKrzysztof Grobelny             *configurationLockCapable;
369ac6a4445SGunnar Mills     }
370c1343bf6SKrzysztof Grobelny 
371c1343bf6SKrzysztof Grobelny     if (dataLockCapable != nullptr)
372ac6a4445SGunnar Mills     {
373*bd79bce8SPatrick Williams         asyncResp->res
374*bd79bce8SPatrick Williams             .jsonValue[jsonPtr]["SecurityCapabilities"]["DataLockCapable"] =
375*bd79bce8SPatrick Williams             *dataLockCapable;
376ac6a4445SGunnar Mills     }
377c1343bf6SKrzysztof Grobelny 
378c1343bf6SKrzysztof Grobelny     if (passphraseCapable != nullptr)
379c1343bf6SKrzysztof Grobelny     {
380*bd79bce8SPatrick Williams         asyncResp->res
381*bd79bce8SPatrick Williams             .jsonValue[jsonPtr]["SecurityCapabilities"]["PassphraseCapable"] =
382*bd79bce8SPatrick Williams             *passphraseCapable;
383c1343bf6SKrzysztof Grobelny     }
384c1343bf6SKrzysztof Grobelny 
385c1343bf6SKrzysztof Grobelny     if (maxPassphraseCount != nullptr)
386c1343bf6SKrzysztof Grobelny     {
387*bd79bce8SPatrick Williams         asyncResp->res
388*bd79bce8SPatrick Williams             .jsonValue[jsonPtr]["SecurityCapabilities"]["MaxPassphraseCount"] =
389*bd79bce8SPatrick Williams             *maxPassphraseCount;
390c1343bf6SKrzysztof Grobelny     }
391c1343bf6SKrzysztof Grobelny 
392c1343bf6SKrzysztof Grobelny     if (passphraseLockLimit != nullptr)
393c1343bf6SKrzysztof Grobelny     {
394*bd79bce8SPatrick Williams         asyncResp->res
395*bd79bce8SPatrick Williams             .jsonValue[jsonPtr]["SecurityCapabilities"]["PassphraseLockLimit"] =
396*bd79bce8SPatrick Williams             *passphraseLockLimit;
397ac6a4445SGunnar Mills     }
398ac6a4445SGunnar Mills }
399ac6a4445SGunnar Mills 
400*bd79bce8SPatrick Williams inline void assembleDimmProperties(
401*bd79bce8SPatrick Williams     std::string_view dimmId,
402ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
403d7f04fd9SNan Zhou     const dbus::utility::DBusPropertiesMap& properties,
404d7f04fd9SNan Zhou     const nlohmann::json::json_pointer& jsonPtr)
405ac6a4445SGunnar Mills {
406ac106bf6SEd Tanous     asyncResp->res.jsonValue[jsonPtr]["Id"] = dimmId;
407ac106bf6SEd Tanous     asyncResp->res.jsonValue[jsonPtr]["Name"] = "DIMM Slot";
408539d8c6bSEd Tanous     asyncResp->res.jsonValue[jsonPtr]["Status"]["State"] =
409539d8c6bSEd Tanous         resource::State::Enabled;
410539d8c6bSEd Tanous     asyncResp->res.jsonValue[jsonPtr]["Status"]["Health"] =
411539d8c6bSEd Tanous         resource::Health::OK;
412ac6a4445SGunnar Mills 
413c1343bf6SKrzysztof Grobelny     const uint16_t* memoryDataWidth = nullptr;
414c1343bf6SKrzysztof Grobelny     const size_t* memorySizeInKB = nullptr;
415c1343bf6SKrzysztof Grobelny     const std::string* partNumber = nullptr;
416c1343bf6SKrzysztof Grobelny     const std::string* serialNumber = nullptr;
417c1343bf6SKrzysztof Grobelny     const std::string* manufacturer = nullptr;
418c1343bf6SKrzysztof Grobelny     const uint16_t* revisionCode = nullptr;
419c1343bf6SKrzysztof Grobelny     const bool* present = nullptr;
420c1343bf6SKrzysztof Grobelny     const uint16_t* memoryTotalWidth = nullptr;
421c1343bf6SKrzysztof Grobelny     const std::string* ecc = nullptr;
422c1343bf6SKrzysztof Grobelny     const std::string* formFactor = nullptr;
423c1343bf6SKrzysztof Grobelny     const std::vector<uint16_t>* allowedSpeedsMT = nullptr;
4246995c1ceSGeorge Liu     const size_t* memoryAttributes = nullptr;
425c1343bf6SKrzysztof Grobelny     const uint16_t* memoryConfiguredSpeedInMhz = nullptr;
426c1343bf6SKrzysztof Grobelny     const std::string* memoryType = nullptr;
4276fde5971SJayaprakash Mutyala     const std::uint8_t* channel = nullptr;
4286fde5971SJayaprakash Mutyala     const std::uint8_t* memoryController = nullptr;
4296fde5971SJayaprakash Mutyala     const std::uint8_t* slot = nullptr;
4306fde5971SJayaprakash Mutyala     const std::uint8_t* socket = nullptr;
431c1343bf6SKrzysztof Grobelny     const std::string* sparePartNumber = nullptr;
432c1343bf6SKrzysztof Grobelny     const std::string* model = nullptr;
433c1343bf6SKrzysztof Grobelny     const std::string* locationCode = nullptr;
434ac6a4445SGunnar Mills 
435c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
436c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "MemoryDataWidth",
437c1343bf6SKrzysztof Grobelny         memoryDataWidth, "MemorySizeInKB", memorySizeInKB, "PartNumber",
438656472d9SNikhil Namjoshi         partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
439656472d9SNikhil Namjoshi         "RevisionCode", revisionCode, "Present", present, "MemoryTotalWidth",
440656472d9SNikhil Namjoshi         memoryTotalWidth, "ECC", ecc, "FormFactor", formFactor,
441656472d9SNikhil Namjoshi         "AllowedSpeedsMT", allowedSpeedsMT, "MemoryAttributes",
442c1343bf6SKrzysztof Grobelny         memoryAttributes, "MemoryConfiguredSpeedInMhz",
443c1343bf6SKrzysztof Grobelny         memoryConfiguredSpeedInMhz, "MemoryType", memoryType, "Channel",
444c1343bf6SKrzysztof Grobelny         channel, "MemoryController", memoryController, "Slot", slot, "Socket",
445c1343bf6SKrzysztof Grobelny         socket, "SparePartNumber", sparePartNumber, "Model", model,
446c1343bf6SKrzysztof Grobelny         "LocationCode", locationCode);
447c1343bf6SKrzysztof Grobelny 
448c1343bf6SKrzysztof Grobelny     if (!success)
449ac6a4445SGunnar Mills     {
450ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
451601af5edSChicago Duan         return;
452ac6a4445SGunnar Mills     }
453c1343bf6SKrzysztof Grobelny 
454c1343bf6SKrzysztof Grobelny     if (memoryDataWidth != nullptr)
455c1343bf6SKrzysztof Grobelny     {
456ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["DataWidthBits"] = *memoryDataWidth;
457c1343bf6SKrzysztof Grobelny     }
458c1343bf6SKrzysztof Grobelny 
459c1343bf6SKrzysztof Grobelny     if (memorySizeInKB != nullptr)
460c1343bf6SKrzysztof Grobelny     {
461ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["CapacityMiB"] =
462ac106bf6SEd Tanous             (*memorySizeInKB >> 10);
463c1343bf6SKrzysztof Grobelny     }
464c1343bf6SKrzysztof Grobelny 
465c1343bf6SKrzysztof Grobelny     if (partNumber != nullptr)
466c1343bf6SKrzysztof Grobelny     {
467ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["PartNumber"] = *partNumber;
468c1343bf6SKrzysztof Grobelny     }
469c1343bf6SKrzysztof Grobelny 
470c1343bf6SKrzysztof Grobelny     if (serialNumber != nullptr)
471c1343bf6SKrzysztof Grobelny     {
472ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SerialNumber"] = *serialNumber;
473c1343bf6SKrzysztof Grobelny     }
474c1343bf6SKrzysztof Grobelny 
475c1343bf6SKrzysztof Grobelny     if (manufacturer != nullptr)
476c1343bf6SKrzysztof Grobelny     {
477ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["Manufacturer"] = *manufacturer;
478c1343bf6SKrzysztof Grobelny     }
479c1343bf6SKrzysztof Grobelny 
480c1343bf6SKrzysztof Grobelny     if (revisionCode != nullptr)
481c1343bf6SKrzysztof Grobelny     {
482ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["FirmwareRevision"] =
483c1343bf6SKrzysztof Grobelny             std::to_string(*revisionCode);
484ac6a4445SGunnar Mills     }
485c1343bf6SKrzysztof Grobelny 
486c1343bf6SKrzysztof Grobelny     if (present != nullptr && !*present)
4879a128eb3SJoshi-Mansi     {
488539d8c6bSEd Tanous         asyncResp->res.jsonValue[jsonPtr]["Status"]["State"] =
489539d8c6bSEd Tanous             resource::State::Absent;
4909a128eb3SJoshi-Mansi     }
491c1343bf6SKrzysztof Grobelny 
492c1343bf6SKrzysztof Grobelny     if (memoryTotalWidth != nullptr)
493ac6a4445SGunnar Mills     {
494ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["BusWidthBits"] = *memoryTotalWidth;
495ac6a4445SGunnar Mills     }
496c1343bf6SKrzysztof Grobelny 
497c1343bf6SKrzysztof Grobelny     if (ecc != nullptr)
498ac6a4445SGunnar Mills     {
499ac6a4445SGunnar Mills         constexpr const std::array<const char*, 4> values{
5009a5aceacSNan Zhou             "NoECC", "SingleBitECC", "MultiBitECC", "AddressParity"};
501ac6a4445SGunnar Mills 
502ac6a4445SGunnar Mills         for (const char* v : values)
503ac6a4445SGunnar Mills         {
504c1343bf6SKrzysztof Grobelny             if (ecc->ends_with(v))
505ac6a4445SGunnar Mills             {
506ac106bf6SEd Tanous                 asyncResp->res.jsonValue[jsonPtr]["ErrorCorrection"] = v;
507ac6a4445SGunnar Mills                 break;
508ac6a4445SGunnar Mills             }
509ac6a4445SGunnar Mills         }
510ac6a4445SGunnar Mills     }
511c1343bf6SKrzysztof Grobelny 
512c1343bf6SKrzysztof Grobelny     if (formFactor != nullptr)
513ac6a4445SGunnar Mills     {
514ac6a4445SGunnar Mills         constexpr const std::array<const char*, 11> values{
5159a5aceacSNan Zhou             "RDIMM",       "UDIMM",       "SO_DIMM",      "LRDIMM",
5169a5aceacSNan Zhou             "Mini_RDIMM",  "Mini_UDIMM",  "SO_RDIMM_72b", "SO_UDIMM_72b",
5179a5aceacSNan Zhou             "SO_DIMM_16b", "SO_DIMM_32b", "Die"};
518ac6a4445SGunnar Mills 
519ac6a4445SGunnar Mills         for (const char* v : values)
520ac6a4445SGunnar Mills         {
521c1343bf6SKrzysztof Grobelny             if (formFactor->ends_with(v))
522ac6a4445SGunnar Mills             {
523ac106bf6SEd Tanous                 asyncResp->res.jsonValue[jsonPtr]["BaseModuleType"] = v;
524ac6a4445SGunnar Mills                 break;
525ac6a4445SGunnar Mills             }
526ac6a4445SGunnar Mills         }
527ac6a4445SGunnar Mills     }
528c1343bf6SKrzysztof Grobelny 
529c1343bf6SKrzysztof Grobelny     if (allowedSpeedsMT != nullptr)
530ac6a4445SGunnar Mills     {
531d7f04fd9SNan Zhou         nlohmann::json& jValue =
532ac106bf6SEd Tanous             asyncResp->res.jsonValue[jsonPtr]["AllowedSpeedsMHz"];
533ac6a4445SGunnar Mills         jValue = nlohmann::json::array();
534c1343bf6SKrzysztof Grobelny         for (uint16_t subVal : *allowedSpeedsMT)
535ac6a4445SGunnar Mills         {
536ac6a4445SGunnar Mills             jValue.push_back(subVal);
537ac6a4445SGunnar Mills         }
538ac6a4445SGunnar Mills     }
539ac6a4445SGunnar Mills 
540c1343bf6SKrzysztof Grobelny     if (memoryAttributes != nullptr)
541ac6a4445SGunnar Mills     {
5426995c1ceSGeorge Liu         asyncResp->res.jsonValue[jsonPtr]["RankCount"] = *memoryAttributes;
543ac6a4445SGunnar Mills     }
544c1343bf6SKrzysztof Grobelny 
545c1343bf6SKrzysztof Grobelny     if (memoryConfiguredSpeedInMhz != nullptr)
546ac6a4445SGunnar Mills     {
547ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["OperatingSpeedMhz"] =
548c1343bf6SKrzysztof Grobelny             *memoryConfiguredSpeedInMhz;
549ac6a4445SGunnar Mills     }
550c1343bf6SKrzysztof Grobelny 
551c1343bf6SKrzysztof Grobelny     if (memoryType != nullptr)
552ac6a4445SGunnar Mills     {
553313efb1cSGunnar Mills         std::string memoryDeviceType =
554c1343bf6SKrzysztof Grobelny             translateMemoryTypeToRedfish(*memoryType);
555313efb1cSGunnar Mills         // Values like "Unknown" or "Other" will return empty
556313efb1cSGunnar Mills         // so just leave off
557313efb1cSGunnar Mills         if (!memoryDeviceType.empty())
558ac6a4445SGunnar Mills         {
559ac106bf6SEd Tanous             asyncResp->res.jsonValue[jsonPtr]["MemoryDeviceType"] =
560d7f04fd9SNan Zhou                 memoryDeviceType;
561ac6a4445SGunnar Mills         }
562c1343bf6SKrzysztof Grobelny         if (memoryType->find("DDR") != std::string::npos)
563ac6a4445SGunnar Mills         {
564539d8c6bSEd Tanous             asyncResp->res.jsonValue[jsonPtr]["MemoryType"] =
565539d8c6bSEd Tanous                 memory::MemoryType::DRAM;
566ac6a4445SGunnar Mills         }
567c1343bf6SKrzysztof Grobelny         else if (memoryType->ends_with("Logical"))
568ac6a4445SGunnar Mills         {
569539d8c6bSEd Tanous             asyncResp->res.jsonValue[jsonPtr]["MemoryType"] =
570539d8c6bSEd Tanous                 memory::MemoryType::IntelOptane;
571ac6a4445SGunnar Mills         }
572ac6a4445SGunnar Mills     }
573c1343bf6SKrzysztof Grobelny 
574c1343bf6SKrzysztof Grobelny     if (channel != nullptr)
575ac6a4445SGunnar Mills     {
576ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Channel"] =
577ac106bf6SEd Tanous             *channel;
578c1343bf6SKrzysztof Grobelny     }
579c1343bf6SKrzysztof Grobelny 
580c1343bf6SKrzysztof Grobelny     if (memoryController != nullptr)
581ac6a4445SGunnar Mills     {
582*bd79bce8SPatrick Williams         asyncResp->res
583*bd79bce8SPatrick Williams             .jsonValue[jsonPtr]["MemoryLocation"]["MemoryController"] =
584*bd79bce8SPatrick Williams             *memoryController;
585ac6a4445SGunnar Mills     }
586c1343bf6SKrzysztof Grobelny 
587c1343bf6SKrzysztof Grobelny     if (slot != nullptr)
588ee135e24SSunnySrivastava1984     {
589ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Slot"] = *slot;
590c1343bf6SKrzysztof Grobelny     }
591c1343bf6SKrzysztof Grobelny 
592c1343bf6SKrzysztof Grobelny     if (socket != nullptr)
593ee135e24SSunnySrivastava1984     {
594ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Socket"] = *socket;
595ee135e24SSunnySrivastava1984     }
596c1343bf6SKrzysztof Grobelny 
597c1343bf6SKrzysztof Grobelny     if (sparePartNumber != nullptr)
598ee135e24SSunnySrivastava1984     {
599ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["SparePartNumber"] = *sparePartNumber;
600c1343bf6SKrzysztof Grobelny     }
601c1343bf6SKrzysztof Grobelny 
602c1343bf6SKrzysztof Grobelny     if (model != nullptr)
603ee135e24SSunnySrivastava1984     {
604ac106bf6SEd Tanous         asyncResp->res.jsonValue[jsonPtr]["Model"] = *model;
605ee135e24SSunnySrivastava1984     }
606c1343bf6SKrzysztof Grobelny 
607c1343bf6SKrzysztof Grobelny     if (locationCode != nullptr)
608ee135e24SSunnySrivastava1984     {
609*bd79bce8SPatrick Williams         asyncResp->res
610*bd79bce8SPatrick Williams             .jsonValue[jsonPtr]["Location"]["PartLocation"]["ServiceLabel"] =
611*bd79bce8SPatrick Williams             *locationCode;
612ee135e24SSunnySrivastava1984     }
613c1343bf6SKrzysztof Grobelny 
614ac106bf6SEd Tanous     getPersistentMemoryProperties(asyncResp, properties, jsonPtr);
6159a5aceacSNan Zhou }
6169a5aceacSNan Zhou 
617*bd79bce8SPatrick Williams inline void getDimmDataByService(
618*bd79bce8SPatrick Williams     std::shared_ptr<bmcweb::AsyncResp> asyncResp, const std::string& dimmId,
619*bd79bce8SPatrick Williams     const std::string& service, const std::string& objPath)
6209a5aceacSNan Zhou {
62162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get available system components.");
622c1343bf6SKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
623c1343bf6SKrzysztof Grobelny         *crow::connections::systemBus, service, objPath, "",
624ac106bf6SEd Tanous         [dimmId, asyncResp{std::move(asyncResp)}](
6255e7e2dc5SEd Tanous             const boost::system::error_code& ec,
6269a5aceacSNan Zhou             const dbus::utility::DBusPropertiesMap& properties) {
6279a5aceacSNan Zhou             if (ec)
6289a5aceacSNan Zhou             {
62962598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error");
630ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
6319a5aceacSNan Zhou                 return;
6329a5aceacSNan Zhou             }
633*bd79bce8SPatrick Williams             assembleDimmProperties(dimmId, asyncResp, properties,
634*bd79bce8SPatrick Williams                                    ""_json_pointer);
635c1343bf6SKrzysztof Grobelny         });
636ac6a4445SGunnar Mills }
637ac6a4445SGunnar Mills 
638ef00d7d4SNan Zhou inline void assembleDimmPartitionData(
639ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
640d7f04fd9SNan Zhou     const dbus::utility::DBusPropertiesMap& properties,
641d7f04fd9SNan Zhou     const nlohmann::json::json_pointer& regionPtr)
642ac6a4445SGunnar Mills {
643c1343bf6SKrzysztof Grobelny     const std::string* memoryClassification = nullptr;
644c1343bf6SKrzysztof Grobelny     const uint64_t* offsetInKiB = nullptr;
645c1343bf6SKrzysztof Grobelny     const std::string* partitionId = nullptr;
646c1343bf6SKrzysztof Grobelny     const bool* passphraseState = nullptr;
647c1343bf6SKrzysztof Grobelny     const uint64_t* sizeInKiB = nullptr;
648c1343bf6SKrzysztof Grobelny 
649c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
650c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "MemoryClassification",
651c1343bf6SKrzysztof Grobelny         memoryClassification, "OffsetInKiB", offsetInKiB, "PartitionId",
652c1343bf6SKrzysztof Grobelny         partitionId, "PassphraseState", passphraseState, "SizeInKiB",
653c1343bf6SKrzysztof Grobelny         sizeInKiB);
654c1343bf6SKrzysztof Grobelny 
655c1343bf6SKrzysztof Grobelny     if (!success)
656c1343bf6SKrzysztof Grobelny     {
657ac106bf6SEd Tanous         messages::internalError(asyncResp->res);
658c1343bf6SKrzysztof Grobelny         return;
659c1343bf6SKrzysztof Grobelny     }
660c1343bf6SKrzysztof Grobelny 
661d7f04fd9SNan Zhou     nlohmann::json::object_t partition;
662c1343bf6SKrzysztof Grobelny 
663c1343bf6SKrzysztof Grobelny     if (memoryClassification != nullptr)
664ac6a4445SGunnar Mills     {
665c1343bf6SKrzysztof Grobelny         partition["MemoryClassification"] = *memoryClassification;
666ac6a4445SGunnar Mills     }
667ac6a4445SGunnar Mills 
668c1343bf6SKrzysztof Grobelny     if (offsetInKiB != nullptr)
669ac6a4445SGunnar Mills     {
670c1343bf6SKrzysztof Grobelny         partition["OffsetMiB"] = (*offsetInKiB >> 10);
671ac6a4445SGunnar Mills     }
672ac6a4445SGunnar Mills 
673c1343bf6SKrzysztof Grobelny     if (partitionId != nullptr)
674ac6a4445SGunnar Mills     {
675c1343bf6SKrzysztof Grobelny         partition["RegionId"] = *partitionId;
676c1343bf6SKrzysztof Grobelny     }
677c1343bf6SKrzysztof Grobelny 
678c1343bf6SKrzysztof Grobelny     if (passphraseState != nullptr)
679ac6a4445SGunnar Mills     {
680c1343bf6SKrzysztof Grobelny         partition["PassphraseEnabled"] = *passphraseState;
681ac6a4445SGunnar Mills     }
682c1343bf6SKrzysztof Grobelny 
683c1343bf6SKrzysztof Grobelny     if (sizeInKiB != nullptr)
684ac6a4445SGunnar Mills     {
685c1343bf6SKrzysztof Grobelny         partition["SizeMiB"] = (*sizeInKiB >> 10);
686ac6a4445SGunnar Mills     }
687c1343bf6SKrzysztof Grobelny 
688ac106bf6SEd Tanous     asyncResp->res.jsonValue[regionPtr].emplace_back(std::move(partition));
689ef00d7d4SNan Zhou }
690ef00d7d4SNan Zhou 
691ac106bf6SEd Tanous inline void getDimmPartitionData(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
692ef00d7d4SNan Zhou                                  const std::string& service,
693ef00d7d4SNan Zhou                                  const std::string& path)
694ef00d7d4SNan Zhou {
695c1343bf6SKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
696c1343bf6SKrzysztof Grobelny         *crow::connections::systemBus, service, path,
697c1343bf6SKrzysztof Grobelny         "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition",
698ac106bf6SEd Tanous         [asyncResp{std::move(asyncResp)}](
6995e7e2dc5SEd Tanous             const boost::system::error_code& ec,
700ef00d7d4SNan Zhou             const dbus::utility::DBusPropertiesMap& properties) {
701ef00d7d4SNan Zhou             if (ec)
702ef00d7d4SNan Zhou             {
70362598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error");
704ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
705ef00d7d4SNan Zhou 
706ef00d7d4SNan Zhou                 return;
707ef00d7d4SNan Zhou             }
708d7f04fd9SNan Zhou             nlohmann::json::json_pointer regionPtr = "/Regions"_json_pointer;
709ac106bf6SEd Tanous             assembleDimmPartitionData(asyncResp, properties, regionPtr);
710c1343bf6SKrzysztof Grobelny         }
711ac6a4445SGunnar Mills 
712c1343bf6SKrzysztof Grobelny     );
713ac6a4445SGunnar Mills }
714ac6a4445SGunnar Mills 
715ac106bf6SEd Tanous inline void getDimmData(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
716ac6a4445SGunnar Mills                         const std::string& dimmId)
717ac6a4445SGunnar Mills {
71862598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get available system dimm resources.");
719e99073f5SGeorge Liu     constexpr std::array<std::string_view, 2> dimmInterfaces = {
720e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Dimm",
721e99073f5SGeorge Liu         "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"};
722e99073f5SGeorge Liu     dbus::utility::getSubTree(
723e99073f5SGeorge Liu         "/xyz/openbmc_project/inventory", 0, dimmInterfaces,
724ac106bf6SEd Tanous         [dimmId, asyncResp{std::move(asyncResp)}](
725e99073f5SGeorge Liu             const boost::system::error_code& ec,
726b9d36b47SEd Tanous             const dbus::utility::MapperGetSubTreeResponse& subtree) {
727ac6a4445SGunnar Mills             if (ec)
728ac6a4445SGunnar Mills             {
72962598e31SEd Tanous                 BMCWEB_LOG_DEBUG("DBUS response error");
730ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
731ac6a4445SGunnar Mills 
732ac6a4445SGunnar Mills                 return;
733ac6a4445SGunnar Mills             }
734ac6a4445SGunnar Mills             bool found = false;
73576686dccSNan Zhou             for (const auto& [rawPath, object] : subtree)
736ac6a4445SGunnar Mills             {
73776686dccSNan Zhou                 sdbusplus::message::object_path path(rawPath);
738ac6a4445SGunnar Mills                 for (const auto& [service, interfaces] : object)
739ac6a4445SGunnar Mills                 {
740b9d36b47SEd Tanous                     for (const auto& interface : interfaces)
741ac6a4445SGunnar Mills                     {
742b9d36b47SEd Tanous                         if (interface ==
74376686dccSNan Zhou                                 "xyz.openbmc_project.Inventory.Item.Dimm" &&
74476686dccSNan Zhou                             path.filename() == dimmId)
745b9d36b47SEd Tanous                         {
746ac106bf6SEd Tanous                             getDimmDataByService(asyncResp, dimmId, service,
747ac106bf6SEd Tanous                                                  rawPath);
748ac6a4445SGunnar Mills                             found = true;
749ac6a4445SGunnar Mills                         }
750ac6a4445SGunnar Mills 
751b9d36b47SEd Tanous                         // partitions are separate as there can be multiple
752b9d36b47SEd Tanous                         // per
753ac6a4445SGunnar Mills                         // device, i.e.
754ac6a4445SGunnar Mills                         // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1
755ac6a4445SGunnar Mills                         // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2
756b9d36b47SEd Tanous                         if (interface ==
75776686dccSNan Zhou                                 "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition" &&
75876686dccSNan Zhou                             path.parent_path().filename() == dimmId)
759ac6a4445SGunnar Mills                         {
760ac106bf6SEd Tanous                             getDimmPartitionData(asyncResp, service, rawPath);
761ac6a4445SGunnar Mills                         }
762ac6a4445SGunnar Mills                     }
763ac6a4445SGunnar Mills                 }
764b9d36b47SEd Tanous             }
765ac6a4445SGunnar Mills             // Object not found
766ac6a4445SGunnar Mills             if (!found)
767ac6a4445SGunnar Mills             {
768ac106bf6SEd Tanous                 messages::resourceNotFound(asyncResp->res, "Memory", dimmId);
7691a1d5d6dSNan Zhou                 return;
770ac6a4445SGunnar Mills             }
7711a1d5d6dSNan Zhou             // Set @odata only if object is found
772ac106bf6SEd Tanous             asyncResp->res.jsonValue["@odata.type"] = "#Memory.v1_11_0.Memory";
773ac106bf6SEd Tanous             asyncResp->res.jsonValue["@odata.id"] =
774253f11b8SEd Tanous                 boost::urls::format("/redfish/v1/Systems/{}/Memory/{}",
775253f11b8SEd Tanous                                     BMCWEB_REDFISH_SYSTEM_URI_NAME, dimmId);
776ac6a4445SGunnar Mills             return;
777e99073f5SGeorge Liu         });
778ac6a4445SGunnar Mills }
779ac6a4445SGunnar Mills 
7807e860f15SJohn Edward Broadbent inline void requestRoutesMemoryCollection(App& app)
781ac6a4445SGunnar Mills {
782ac6a4445SGunnar Mills     /**
783ac6a4445SGunnar Mills      * Functions triggers appropriate requests on DBus
784ac6a4445SGunnar Mills      */
78522d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/")
786ed398213SEd Tanous         .privileges(redfish::privileges::getMemoryCollection)
7877e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
78845ca1b86SEd Tanous             [&app](const crow::Request& req,
78922d268cbSEd Tanous                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
79022d268cbSEd Tanous                    const std::string& systemName) {
7913ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
79245ca1b86SEd Tanous                 {
79345ca1b86SEd Tanous                     return;
79445ca1b86SEd Tanous                 }
79525b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
7967f3e84a1SEd Tanous                 {
7977f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
7987f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
7997f3e84a1SEd Tanous                                                systemName);
8007f3e84a1SEd Tanous                     return;
8017f3e84a1SEd Tanous                 }
802253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
80322d268cbSEd Tanous                 {
80422d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
80522d268cbSEd Tanous                                                systemName);
80622d268cbSEd Tanous                     return;
80722d268cbSEd Tanous                 }
80822d268cbSEd Tanous 
8098d1b46d7Szhanghch05                 asyncResp->res.jsonValue["@odata.type"] =
8108d1b46d7Szhanghch05                     "#MemoryCollection.MemoryCollection";
8118d1b46d7Szhanghch05                 asyncResp->res.jsonValue["Name"] = "Memory Module Collection";
812*bd79bce8SPatrick Williams                 asyncResp->res.jsonValue["@odata.id"] =
813*bd79bce8SPatrick Williams                     boost::urls::format("/redfish/v1/Systems/{}/Memory",
814*bd79bce8SPatrick Williams                                         BMCWEB_REDFISH_SYSTEM_URI_NAME);
815ac6a4445SGunnar Mills 
8167a1dbc48SGeorge Liu                 constexpr std::array<std::string_view, 1> interfaces{
8177a1dbc48SGeorge Liu                     "xyz.openbmc_project.Inventory.Item.Dimm"};
81805030b8eSGunnar Mills                 collection_util::getCollectionMembers(
819253f11b8SEd Tanous                     asyncResp,
820253f11b8SEd Tanous                     boost::urls::format("/redfish/v1/Systems/{}/Memory",
821253f11b8SEd Tanous                                         BMCWEB_REDFISH_SYSTEM_URI_NAME),
82236b5f1edSLakshmi Yadlapati                     interfaces, "/xyz/openbmc_project/inventory");
8237e860f15SJohn Edward Broadbent             });
824ac6a4445SGunnar Mills }
825ac6a4445SGunnar Mills 
8267e860f15SJohn Edward Broadbent inline void requestRoutesMemory(App& app)
8277e860f15SJohn Edward Broadbent {
828ac6a4445SGunnar Mills     /**
829ac6a4445SGunnar Mills      * Functions triggers appropriate requests on DBus
830ac6a4445SGunnar Mills      */
83122d268cbSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/<str>/")
832ed398213SEd Tanous         .privileges(redfish::privileges::getMemory)
8337e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
83445ca1b86SEd Tanous             [&app](const crow::Request& req,
8357e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
83622d268cbSEd Tanous                    const std::string& systemName, const std::string& dimmId) {
8373ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
83845ca1b86SEd Tanous                 {
83945ca1b86SEd Tanous                     return;
84045ca1b86SEd Tanous                 }
8417f3e84a1SEd Tanous 
84225b54dbaSEd Tanous                 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
8437f3e84a1SEd Tanous                 {
8447f3e84a1SEd Tanous                     // Option currently returns no systems.  TBD
8457f3e84a1SEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
8467f3e84a1SEd Tanous                                                systemName);
8477f3e84a1SEd Tanous                     return;
8487f3e84a1SEd Tanous                 }
8497f3e84a1SEd Tanous 
850253f11b8SEd Tanous                 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
85122d268cbSEd Tanous                 {
85222d268cbSEd Tanous                     messages::resourceNotFound(asyncResp->res, "ComputerSystem",
85322d268cbSEd Tanous                                                systemName);
85422d268cbSEd Tanous                     return;
85522d268cbSEd Tanous                 }
85622d268cbSEd Tanous 
857ac6a4445SGunnar Mills                 getDimmData(asyncResp, dimmId);
8587e860f15SJohn Edward Broadbent             });
859ac6a4445SGunnar Mills }
860ac6a4445SGunnar Mills 
861ac6a4445SGunnar Mills } // namespace redfish
862