xref: /openbmc/bmcweb/features/redfish/lib/memory.hpp (revision c1343bf6a51b22b85a0521050948ad6026027fc8)
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 
18ac6a4445SGunnar Mills #include "health.hpp"
19ac6a4445SGunnar Mills 
207e860f15SJohn Edward Broadbent #include <app.hpp>
21168e20c1SEd Tanous #include <dbus_utility.hpp>
22d7f04fd9SNan Zhou #include <nlohmann/json.hpp>
2345ca1b86SEd Tanous #include <query.hpp>
24ed398213SEd Tanous #include <registries/privilege_registry.hpp>
25*c1343bf6SKrzysztof Grobelny #include <sdbusplus/asio/property.hpp>
26*c1343bf6SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
27ac6a4445SGunnar Mills #include <utils/collection.hpp>
28f201ffb4SEd Tanous #include <utils/hex_utils.hpp>
29ac6a4445SGunnar Mills #include <utils/json_utils.hpp>
30ac6a4445SGunnar Mills 
31ac6a4445SGunnar Mills namespace redfish
32ac6a4445SGunnar Mills {
33ac6a4445SGunnar Mills 
34313efb1cSGunnar Mills inline std::string translateMemoryTypeToRedfish(const std::string& memoryType)
35313efb1cSGunnar Mills {
36313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR")
37313efb1cSGunnar Mills     {
38313efb1cSGunnar Mills         return "DDR";
39313efb1cSGunnar Mills     }
40313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2")
41313efb1cSGunnar Mills     {
42313efb1cSGunnar Mills         return "DDR2";
43313efb1cSGunnar Mills     }
44313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR3")
45313efb1cSGunnar Mills     {
46313efb1cSGunnar Mills         return "DDR3";
47313efb1cSGunnar Mills     }
48313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4")
49313efb1cSGunnar Mills     {
50313efb1cSGunnar Mills         return "DDR4";
51313efb1cSGunnar Mills     }
52313efb1cSGunnar Mills     if (memoryType ==
53313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4E_SDRAM")
54313efb1cSGunnar Mills     {
55313efb1cSGunnar Mills         return "DDR4E_SDRAM";
56313efb1cSGunnar Mills     }
5711a2f0f0SMansi Joshi     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR5")
5811a2f0f0SMansi Joshi     {
5911a2f0f0SMansi Joshi         return "DDR5";
6011a2f0f0SMansi Joshi     }
61313efb1cSGunnar Mills     if (memoryType ==
62313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR4_SDRAM")
63313efb1cSGunnar Mills     {
64313efb1cSGunnar Mills         return "LPDDR4_SDRAM";
65313efb1cSGunnar Mills     }
66313efb1cSGunnar Mills     if (memoryType ==
67313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR3_SDRAM")
68313efb1cSGunnar Mills     {
69313efb1cSGunnar Mills         return "LPDDR3_SDRAM";
70313efb1cSGunnar Mills     }
71313efb1cSGunnar Mills     if (memoryType ==
72313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM")
73313efb1cSGunnar Mills     {
74313efb1cSGunnar Mills         return "DDR2_SDRAM_FB_DIMM";
75313efb1cSGunnar Mills     }
760fda0f12SGeorge Liu     if (memoryType ==
770fda0f12SGeorge Liu         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM_PROB")
78313efb1cSGunnar Mills     {
79313efb1cSGunnar Mills         return "DDR2_SDRAM_FB_DIMM_PROBE";
80313efb1cSGunnar Mills     }
81313efb1cSGunnar Mills     if (memoryType ==
82313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR_SGRAM")
83313efb1cSGunnar Mills     {
84313efb1cSGunnar Mills         return "DDR_SGRAM";
85313efb1cSGunnar Mills     }
86313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.ROM")
87313efb1cSGunnar Mills     {
88313efb1cSGunnar Mills         return "ROM";
89313efb1cSGunnar Mills     }
90313efb1cSGunnar Mills     if (memoryType ==
91313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.SDRAM")
92313efb1cSGunnar Mills     {
93313efb1cSGunnar Mills         return "SDRAM";
94313efb1cSGunnar Mills     }
95313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.EDO")
96313efb1cSGunnar Mills     {
97313efb1cSGunnar Mills         return "EDO";
98313efb1cSGunnar Mills     }
99313efb1cSGunnar Mills     if (memoryType ==
100313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.FastPageMode")
101313efb1cSGunnar Mills     {
102313efb1cSGunnar Mills         return "FastPageMode";
103313efb1cSGunnar Mills     }
104313efb1cSGunnar Mills     if (memoryType ==
105313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.PipelinedNibble")
106313efb1cSGunnar Mills     {
107313efb1cSGunnar Mills         return "PipelinedNibble";
108313efb1cSGunnar Mills     }
109313efb1cSGunnar Mills     if (memoryType ==
110313efb1cSGunnar Mills         "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.Logical")
111313efb1cSGunnar Mills     {
112313efb1cSGunnar Mills         return "Logical";
113313efb1cSGunnar Mills     }
114313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM")
115313efb1cSGunnar Mills     {
116313efb1cSGunnar Mills         return "HBM";
117313efb1cSGunnar Mills     }
118313efb1cSGunnar Mills     if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM2")
119313efb1cSGunnar Mills     {
120313efb1cSGunnar Mills         return "HBM2";
121313efb1cSGunnar Mills     }
122313efb1cSGunnar Mills     // This is values like Other or Unknown
123313efb1cSGunnar Mills     // Also D-Bus values:
124313efb1cSGunnar Mills     // DRAM
125313efb1cSGunnar Mills     // EDRAM
126313efb1cSGunnar Mills     // VRAM
127313efb1cSGunnar Mills     // SRAM
128313efb1cSGunnar Mills     // RAM
129313efb1cSGunnar Mills     // FLASH
130313efb1cSGunnar Mills     // EEPROM
131313efb1cSGunnar Mills     // FEPROM
132313efb1cSGunnar Mills     // EPROM
133313efb1cSGunnar Mills     // CDRAM
134313efb1cSGunnar Mills     // ThreeDRAM
135313efb1cSGunnar Mills     // RDRAM
136313efb1cSGunnar Mills     // FBD2
137313efb1cSGunnar Mills     // LPDDR_SDRAM
138313efb1cSGunnar Mills     // LPDDR2_SDRAM
13911a2f0f0SMansi Joshi     // LPDDR5_SDRAM
140313efb1cSGunnar Mills     return "";
141313efb1cSGunnar Mills }
142313efb1cSGunnar Mills 
143*c1343bf6SKrzysztof Grobelny inline void dimmPropToHex(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
144*c1343bf6SKrzysztof Grobelny                           const char* key, const uint16_t* value,
145d7f04fd9SNan Zhou                           const nlohmann::json::json_pointer& jsonPtr)
146ac6a4445SGunnar Mills {
147ac6a4445SGunnar Mills     if (value == nullptr)
148ac6a4445SGunnar Mills     {
149ac6a4445SGunnar Mills         return;
150ac6a4445SGunnar Mills     }
151d7f04fd9SNan Zhou     aResp->res.jsonValue[jsonPtr][key] = "0x" + intToHexString(*value, 4);
152ac6a4445SGunnar Mills }
153ac6a4445SGunnar Mills 
1548d1b46d7Szhanghch05 inline void getPersistentMemoryProperties(
1558d1b46d7Szhanghch05     const std::shared_ptr<bmcweb::AsyncResp>& aResp,
156*c1343bf6SKrzysztof Grobelny     const dbus::utility::DBusPropertiesMap& properties,
157d7f04fd9SNan Zhou     const nlohmann::json::json_pointer& jsonPtr)
158ac6a4445SGunnar Mills {
159*c1343bf6SKrzysztof Grobelny     const uint16_t* moduleManufacturerID = nullptr;
160*c1343bf6SKrzysztof Grobelny     const uint16_t* moduleProductID = nullptr;
161*c1343bf6SKrzysztof Grobelny     const uint16_t* subsystemVendorID = nullptr;
162*c1343bf6SKrzysztof Grobelny     const uint16_t* subsystemDeviceID = nullptr;
163*c1343bf6SKrzysztof Grobelny     const uint64_t* volatileRegionSizeLimitInKiB = nullptr;
164*c1343bf6SKrzysztof Grobelny     const uint64_t* pmRegionSizeLimitInKiB = nullptr;
165*c1343bf6SKrzysztof Grobelny     const uint64_t* volatileSizeInKiB = nullptr;
166*c1343bf6SKrzysztof Grobelny     const uint64_t* pmSizeInKiB = nullptr;
167*c1343bf6SKrzysztof Grobelny     const uint64_t* cacheSizeInKB = nullptr;
168*c1343bf6SKrzysztof Grobelny     const uint64_t* voltaileRegionMaxSizeInKib = nullptr;
169*c1343bf6SKrzysztof Grobelny     const uint64_t* pmRegionMaxSizeInKiB = nullptr;
170*c1343bf6SKrzysztof Grobelny     const uint64_t* allocationIncrementInKiB = nullptr;
171*c1343bf6SKrzysztof Grobelny     const uint64_t* allocationAlignmentInKiB = nullptr;
172*c1343bf6SKrzysztof Grobelny     const uint64_t* volatileRegionNumberLimit = nullptr;
173*c1343bf6SKrzysztof Grobelny     const uint64_t* pmRegionNumberLimit = nullptr;
174*c1343bf6SKrzysztof Grobelny     const uint64_t* spareDeviceCount = nullptr;
175*c1343bf6SKrzysztof Grobelny     const bool* isSpareDeviceInUse = nullptr;
176*c1343bf6SKrzysztof Grobelny     const bool* isRankSpareEnabled = nullptr;
177*c1343bf6SKrzysztof Grobelny     const std::vector<uint32_t>* maxAveragePowerLimitmW = nullptr;
178*c1343bf6SKrzysztof Grobelny     const bool* configurationLocked = nullptr;
179*c1343bf6SKrzysztof Grobelny     const std::string* allowedMemoryModes = nullptr;
180*c1343bf6SKrzysztof Grobelny     const std::string* memoryMedia = nullptr;
181*c1343bf6SKrzysztof Grobelny     const bool* configurationLockCapable = nullptr;
182*c1343bf6SKrzysztof Grobelny     const bool* dataLockCapable = nullptr;
183*c1343bf6SKrzysztof Grobelny     const bool* passphraseCapable = nullptr;
184*c1343bf6SKrzysztof Grobelny     const uint64_t* maxPassphraseCount = nullptr;
185*c1343bf6SKrzysztof Grobelny     const uint64_t* passphraseLockLimit = nullptr;
186*c1343bf6SKrzysztof Grobelny 
187*c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
188*c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "ModuleManufacturerID",
189*c1343bf6SKrzysztof Grobelny         moduleManufacturerID, "ModuleProductID", moduleProductID,
190*c1343bf6SKrzysztof Grobelny         "SubsystemVendorID", subsystemVendorID, "SubsystemDeviceID",
191*c1343bf6SKrzysztof Grobelny         subsystemDeviceID, "VolatileRegionSizeLimitInKiB",
192*c1343bf6SKrzysztof Grobelny         volatileRegionSizeLimitInKiB, "PmRegionSizeLimitInKiB",
193*c1343bf6SKrzysztof Grobelny         pmRegionSizeLimitInKiB, "VolatileSizeInKiB", volatileSizeInKiB,
194*c1343bf6SKrzysztof Grobelny         "PmSizeInKiB", pmSizeInKiB, "CacheSizeInKB", cacheSizeInKB,
195*c1343bf6SKrzysztof Grobelny         "VoltaileRegionMaxSizeInKib", voltaileRegionMaxSizeInKib,
196*c1343bf6SKrzysztof Grobelny         "PmRegionMaxSizeInKiB", pmRegionMaxSizeInKiB,
197*c1343bf6SKrzysztof Grobelny         "AllocationIncrementInKiB", allocationIncrementInKiB,
198*c1343bf6SKrzysztof Grobelny         "AllocationAlignmentInKiB", allocationAlignmentInKiB,
199*c1343bf6SKrzysztof Grobelny         "VolatileRegionNumberLimit", volatileRegionNumberLimit,
200*c1343bf6SKrzysztof Grobelny         "PmRegionNumberLimit", pmRegionNumberLimit, "SpareDeviceCount",
201*c1343bf6SKrzysztof Grobelny         spareDeviceCount, "IsSpareDeviceInUse", isSpareDeviceInUse,
202*c1343bf6SKrzysztof Grobelny         "IsRankSpareEnabled", isRankSpareEnabled, "MaxAveragePowerLimitmW",
203*c1343bf6SKrzysztof Grobelny         maxAveragePowerLimitmW, "ConfigurationLocked", configurationLocked,
204*c1343bf6SKrzysztof Grobelny         "AllowedMemoryModes", allowedMemoryModes, "MemoryMedia", memoryMedia,
205*c1343bf6SKrzysztof Grobelny         "ConfigurationLockCapable", configurationLockCapable, "DataLockCapable",
206*c1343bf6SKrzysztof Grobelny         dataLockCapable, "PassphraseCapable", passphraseCapable,
207*c1343bf6SKrzysztof Grobelny         "MaxPassphraseCount", maxPassphraseCount, "PassphraseLockLimit",
208*c1343bf6SKrzysztof Grobelny         passphraseLockLimit);
209*c1343bf6SKrzysztof Grobelny 
210*c1343bf6SKrzysztof Grobelny     if (!success)
211ac6a4445SGunnar Mills     {
212*c1343bf6SKrzysztof Grobelny         messages::internalError(aResp->res);
213*c1343bf6SKrzysztof Grobelny         return;
214ac6a4445SGunnar Mills     }
215*c1343bf6SKrzysztof Grobelny 
216*c1343bf6SKrzysztof Grobelny     dimmPropToHex(aResp, "ModuleManufacturerID", moduleManufacturerID, jsonPtr);
217*c1343bf6SKrzysztof Grobelny     dimmPropToHex(aResp, "ModuleProductID", moduleProductID, jsonPtr);
218ac6a4445SGunnar Mills     dimmPropToHex(aResp, "MemorySubsystemControllerManufacturerID",
219*c1343bf6SKrzysztof Grobelny                   subsystemVendorID, jsonPtr);
220*c1343bf6SKrzysztof Grobelny     dimmPropToHex(aResp, "MemorySubsystemControllerProductID",
221*c1343bf6SKrzysztof Grobelny                   subsystemDeviceID, jsonPtr);
222ac6a4445SGunnar Mills 
223*c1343bf6SKrzysztof Grobelny     if (volatileRegionSizeLimitInKiB != nullptr)
224ac6a4445SGunnar Mills     {
225d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["VolatileRegionSizeLimitMiB"] =
226*c1343bf6SKrzysztof Grobelny             (*volatileRegionSizeLimitInKiB) >> 10;
227ac6a4445SGunnar Mills     }
228ac6a4445SGunnar Mills 
229*c1343bf6SKrzysztof Grobelny     if (pmRegionSizeLimitInKiB != nullptr)
230ac6a4445SGunnar Mills     {
231d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["PersistentRegionSizeLimitMiB"] =
232*c1343bf6SKrzysztof Grobelny             (*pmRegionSizeLimitInKiB) >> 10;
233ac6a4445SGunnar Mills     }
234ac6a4445SGunnar Mills 
235*c1343bf6SKrzysztof Grobelny     if (volatileSizeInKiB != nullptr)
236ac6a4445SGunnar Mills     {
237ac6a4445SGunnar Mills 
238*c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["VolatileSizeMiB"] =
239*c1343bf6SKrzysztof Grobelny             (*volatileSizeInKiB) >> 10;
240ac6a4445SGunnar Mills     }
241*c1343bf6SKrzysztof Grobelny 
242*c1343bf6SKrzysztof Grobelny     if (pmSizeInKiB != nullptr)
243*c1343bf6SKrzysztof Grobelny     {
244*c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["NonVolatileSizeMiB"] =
245*c1343bf6SKrzysztof Grobelny             (*pmSizeInKiB) >> 10;
246*c1343bf6SKrzysztof Grobelny     }
247*c1343bf6SKrzysztof Grobelny 
248*c1343bf6SKrzysztof Grobelny     if (cacheSizeInKB != nullptr)
249*c1343bf6SKrzysztof Grobelny     {
250*c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["CacheSizeMiB"] = (*cacheSizeInKB >> 10);
251*c1343bf6SKrzysztof Grobelny     }
252*c1343bf6SKrzysztof Grobelny 
253*c1343bf6SKrzysztof Grobelny     if (voltaileRegionMaxSizeInKib != nullptr)
254*c1343bf6SKrzysztof Grobelny     {
255d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["VolatileRegionSizeMaxMiB"] =
256*c1343bf6SKrzysztof Grobelny             (*voltaileRegionMaxSizeInKib) >> 10;
257ac6a4445SGunnar Mills     }
258ac6a4445SGunnar Mills 
259*c1343bf6SKrzysztof Grobelny     if (pmRegionMaxSizeInKiB != nullptr)
260ac6a4445SGunnar Mills     {
261d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["PersistentRegionSizeMaxMiB"] =
262*c1343bf6SKrzysztof Grobelny             (*pmRegionMaxSizeInKiB) >> 10;
263ac6a4445SGunnar Mills     }
264ac6a4445SGunnar Mills 
265*c1343bf6SKrzysztof Grobelny     if (allocationIncrementInKiB != nullptr)
266ac6a4445SGunnar Mills     {
267d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["AllocationIncrementMiB"] =
268*c1343bf6SKrzysztof Grobelny             (*allocationIncrementInKiB) >> 10;
269ac6a4445SGunnar Mills     }
270ac6a4445SGunnar Mills 
271*c1343bf6SKrzysztof Grobelny     if (allocationAlignmentInKiB != nullptr)
272ac6a4445SGunnar Mills     {
273d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["AllocationAlignmentMiB"] =
274*c1343bf6SKrzysztof Grobelny             (*allocationAlignmentInKiB) >> 10;
275ac6a4445SGunnar Mills     }
276*c1343bf6SKrzysztof Grobelny 
277*c1343bf6SKrzysztof Grobelny     if (volatileRegionNumberLimit != nullptr)
278ac6a4445SGunnar Mills     {
279*c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["VolatileRegionNumberLimit"] =
280*c1343bf6SKrzysztof Grobelny             *volatileRegionNumberLimit;
281ac6a4445SGunnar Mills     }
282*c1343bf6SKrzysztof Grobelny 
283*c1343bf6SKrzysztof Grobelny     if (pmRegionNumberLimit != nullptr)
284ac6a4445SGunnar Mills     {
285*c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["PersistentRegionNumberLimit"] =
286*c1343bf6SKrzysztof Grobelny             *pmRegionNumberLimit;
287ac6a4445SGunnar Mills     }
288*c1343bf6SKrzysztof Grobelny 
289*c1343bf6SKrzysztof Grobelny     if (spareDeviceCount != nullptr)
290ac6a4445SGunnar Mills     {
291*c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["SpareDeviceCount"] = *spareDeviceCount;
292ac6a4445SGunnar Mills     }
293*c1343bf6SKrzysztof Grobelny 
294*c1343bf6SKrzysztof Grobelny     if (isSpareDeviceInUse != nullptr)
295ac6a4445SGunnar Mills     {
296*c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["IsSpareDeviceEnabled"] =
297*c1343bf6SKrzysztof Grobelny             *isSpareDeviceInUse;
298ac6a4445SGunnar Mills     }
299*c1343bf6SKrzysztof Grobelny 
300*c1343bf6SKrzysztof Grobelny     if (isRankSpareEnabled != nullptr)
301ac6a4445SGunnar Mills     {
302*c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["IsRankSpareEnabled"] =
303*c1343bf6SKrzysztof Grobelny             *isRankSpareEnabled;
304ac6a4445SGunnar Mills     }
305*c1343bf6SKrzysztof Grobelny 
306*c1343bf6SKrzysztof Grobelny     if (maxAveragePowerLimitmW != nullptr)
307ac6a4445SGunnar Mills     {
308*c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["MaxTDPMilliWatts"] =
309*c1343bf6SKrzysztof Grobelny             *maxAveragePowerLimitmW;
310ac6a4445SGunnar Mills     }
311*c1343bf6SKrzysztof Grobelny 
312*c1343bf6SKrzysztof Grobelny     if (configurationLocked != nullptr)
313ac6a4445SGunnar Mills     {
314*c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["ConfigurationLocked"] =
315*c1343bf6SKrzysztof Grobelny             *configurationLocked;
316ac6a4445SGunnar Mills     }
317*c1343bf6SKrzysztof Grobelny 
318*c1343bf6SKrzysztof Grobelny     if (allowedMemoryModes != nullptr)
319ac6a4445SGunnar Mills     {
32080badf7cSJiaqing Zhao         constexpr const std::array<const char*, 3> values{"Volatile", "PMEM",
32180badf7cSJiaqing Zhao                                                           "Block"};
322ac6a4445SGunnar Mills 
323ac6a4445SGunnar Mills         for (const char* v : values)
324ac6a4445SGunnar Mills         {
325*c1343bf6SKrzysztof Grobelny             if (allowedMemoryModes->ends_with(v))
326ac6a4445SGunnar Mills             {
327d7f04fd9SNan Zhou                 aResp->res.jsonValue[jsonPtr]["OperatingMemoryModes"].push_back(
328d7f04fd9SNan Zhou                     v);
329ac6a4445SGunnar Mills                 break;
330ac6a4445SGunnar Mills             }
331ac6a4445SGunnar Mills         }
332ac6a4445SGunnar Mills     }
333*c1343bf6SKrzysztof Grobelny 
334*c1343bf6SKrzysztof Grobelny     if (memoryMedia != nullptr)
335ac6a4445SGunnar Mills     {
336ac6a4445SGunnar Mills         constexpr const std::array<const char*, 3> values{"DRAM", "NAND",
337ac6a4445SGunnar Mills                                                           "Intel3DXPoint"};
338ac6a4445SGunnar Mills 
339ac6a4445SGunnar Mills         for (const char* v : values)
340ac6a4445SGunnar Mills         {
341*c1343bf6SKrzysztof Grobelny             if (memoryMedia->ends_with(v))
342ac6a4445SGunnar Mills             {
343d7f04fd9SNan Zhou                 aResp->res.jsonValue[jsonPtr]["MemoryMedia"].push_back(v);
344ac6a4445SGunnar Mills                 break;
345ac6a4445SGunnar Mills             }
346ac6a4445SGunnar Mills         }
347ac6a4445SGunnar Mills     }
348*c1343bf6SKrzysztof Grobelny 
349*c1343bf6SKrzysztof Grobelny     if (configurationLockCapable != nullptr)
350ac6a4445SGunnar Mills     {
351*c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["SecurityCapabilities"]
352*c1343bf6SKrzysztof Grobelny                             ["ConfigurationLockCapable"] =
353*c1343bf6SKrzysztof Grobelny             *configurationLockCapable;
354ac6a4445SGunnar Mills     }
355*c1343bf6SKrzysztof Grobelny 
356*c1343bf6SKrzysztof Grobelny     if (dataLockCapable != nullptr)
357ac6a4445SGunnar Mills     {
358*c1343bf6SKrzysztof Grobelny         aResp->res
359*c1343bf6SKrzysztof Grobelny             .jsonValue[jsonPtr]["SecurityCapabilities"]["DataLockCapable"] =
360*c1343bf6SKrzysztof Grobelny             *dataLockCapable;
361ac6a4445SGunnar Mills     }
362*c1343bf6SKrzysztof Grobelny 
363*c1343bf6SKrzysztof Grobelny     if (passphraseCapable != nullptr)
364*c1343bf6SKrzysztof Grobelny     {
365*c1343bf6SKrzysztof Grobelny         aResp->res
366*c1343bf6SKrzysztof Grobelny             .jsonValue[jsonPtr]["SecurityCapabilities"]["PassphraseCapable"] =
367*c1343bf6SKrzysztof Grobelny             *passphraseCapable;
368*c1343bf6SKrzysztof Grobelny     }
369*c1343bf6SKrzysztof Grobelny 
370*c1343bf6SKrzysztof Grobelny     if (maxPassphraseCount != nullptr)
371*c1343bf6SKrzysztof Grobelny     {
372*c1343bf6SKrzysztof Grobelny         aResp->res
373*c1343bf6SKrzysztof Grobelny             .jsonValue[jsonPtr]["SecurityCapabilities"]["MaxPassphraseCount"] =
374*c1343bf6SKrzysztof Grobelny             *maxPassphraseCount;
375*c1343bf6SKrzysztof Grobelny     }
376*c1343bf6SKrzysztof Grobelny 
377*c1343bf6SKrzysztof Grobelny     if (passphraseLockLimit != nullptr)
378*c1343bf6SKrzysztof Grobelny     {
379*c1343bf6SKrzysztof Grobelny         aResp->res
380*c1343bf6SKrzysztof Grobelny             .jsonValue[jsonPtr]["SecurityCapabilities"]["PassphraseLockLimit"] =
381*c1343bf6SKrzysztof Grobelny             *passphraseLockLimit;
382ac6a4445SGunnar Mills     }
383ac6a4445SGunnar Mills }
384ac6a4445SGunnar Mills 
3859a5aceacSNan Zhou inline void
3869a5aceacSNan Zhou     assembleDimmProperties(std::string_view dimmId,
3879a5aceacSNan Zhou                            const std::shared_ptr<bmcweb::AsyncResp>& aResp,
388d7f04fd9SNan Zhou                            const dbus::utility::DBusPropertiesMap& properties,
389d7f04fd9SNan Zhou                            const nlohmann::json::json_pointer& jsonPtr)
390ac6a4445SGunnar Mills {
391d7f04fd9SNan Zhou     aResp->res.jsonValue[jsonPtr]["Id"] = dimmId;
392d7f04fd9SNan Zhou     aResp->res.jsonValue[jsonPtr]["Name"] = "DIMM Slot";
393d7f04fd9SNan Zhou     aResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Enabled";
394d7f04fd9SNan Zhou     aResp->res.jsonValue[jsonPtr]["Status"]["Health"] = "OK";
395ac6a4445SGunnar Mills 
396*c1343bf6SKrzysztof Grobelny     const uint16_t* memoryDataWidth = nullptr;
397*c1343bf6SKrzysztof Grobelny     const size_t* memorySizeInKB = nullptr;
398*c1343bf6SKrzysztof Grobelny     const std::string* partNumber = nullptr;
399*c1343bf6SKrzysztof Grobelny     const std::string* serialNumber = nullptr;
400*c1343bf6SKrzysztof Grobelny     const std::string* manufacturer = nullptr;
401*c1343bf6SKrzysztof Grobelny     const uint16_t* revisionCode = nullptr;
402*c1343bf6SKrzysztof Grobelny     const bool* present = nullptr;
403*c1343bf6SKrzysztof Grobelny     const uint16_t* memoryTotalWidth = nullptr;
404*c1343bf6SKrzysztof Grobelny     const std::string* ecc = nullptr;
405*c1343bf6SKrzysztof Grobelny     const std::string* formFactor = nullptr;
406*c1343bf6SKrzysztof Grobelny     const std::vector<uint16_t>* allowedSpeedsMT = nullptr;
407*c1343bf6SKrzysztof Grobelny     const uint8_t* memoryAttributes = nullptr;
408*c1343bf6SKrzysztof Grobelny     const uint16_t* memoryConfiguredSpeedInMhz = nullptr;
409*c1343bf6SKrzysztof Grobelny     const std::string* memoryType = nullptr;
410*c1343bf6SKrzysztof Grobelny     const std::string* channel = nullptr;
411*c1343bf6SKrzysztof Grobelny     const std::string* memoryController = nullptr;
412*c1343bf6SKrzysztof Grobelny     const std::string* slot = nullptr;
413*c1343bf6SKrzysztof Grobelny     const std::string* socket = nullptr;
414*c1343bf6SKrzysztof Grobelny     const std::string* sparePartNumber = nullptr;
415*c1343bf6SKrzysztof Grobelny     const std::string* model = nullptr;
416*c1343bf6SKrzysztof Grobelny     const std::string* locationCode = nullptr;
417ac6a4445SGunnar Mills 
418*c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
419*c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "MemoryDataWidth",
420*c1343bf6SKrzysztof Grobelny         memoryDataWidth, "MemorySizeInKB", memorySizeInKB, "PartNumber",
421*c1343bf6SKrzysztof Grobelny         partNumber, "SerialNumber", serialNumber, "Present", present,
422*c1343bf6SKrzysztof Grobelny         "MemoryTotalWidth", memoryTotalWidth, "ECC", ecc, "FormFactor",
423*c1343bf6SKrzysztof Grobelny         formFactor, "AllowedSpeedsMT", allowedSpeedsMT, "MemoryAttributes",
424*c1343bf6SKrzysztof Grobelny         memoryAttributes, "MemoryConfiguredSpeedInMhz",
425*c1343bf6SKrzysztof Grobelny         memoryConfiguredSpeedInMhz, "MemoryType", memoryType, "Channel",
426*c1343bf6SKrzysztof Grobelny         channel, "MemoryController", memoryController, "Slot", slot, "Socket",
427*c1343bf6SKrzysztof Grobelny         socket, "SparePartNumber", sparePartNumber, "Model", model,
428*c1343bf6SKrzysztof Grobelny         "LocationCode", locationCode);
429*c1343bf6SKrzysztof Grobelny 
430*c1343bf6SKrzysztof Grobelny     if (!success)
431ac6a4445SGunnar Mills     {
432ac6a4445SGunnar Mills         messages::internalError(aResp->res);
433601af5edSChicago Duan         return;
434ac6a4445SGunnar Mills     }
435*c1343bf6SKrzysztof Grobelny 
436*c1343bf6SKrzysztof Grobelny     if (memoryDataWidth != nullptr)
437*c1343bf6SKrzysztof Grobelny     {
438*c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["DataWidthBits"] = *memoryDataWidth;
439*c1343bf6SKrzysztof Grobelny     }
440*c1343bf6SKrzysztof Grobelny 
441*c1343bf6SKrzysztof Grobelny     if (memorySizeInKB != nullptr)
442*c1343bf6SKrzysztof Grobelny     {
443*c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["CapacityMiB"] = (*memorySizeInKB >> 10);
444*c1343bf6SKrzysztof Grobelny     }
445*c1343bf6SKrzysztof Grobelny 
446*c1343bf6SKrzysztof Grobelny     if (partNumber != nullptr)
447*c1343bf6SKrzysztof Grobelny     {
448*c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["PartNumber"] = *partNumber;
449*c1343bf6SKrzysztof Grobelny     }
450*c1343bf6SKrzysztof Grobelny 
451*c1343bf6SKrzysztof Grobelny     if (serialNumber != nullptr)
452*c1343bf6SKrzysztof Grobelny     {
453*c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["SerialNumber"] = *serialNumber;
454*c1343bf6SKrzysztof Grobelny     }
455*c1343bf6SKrzysztof Grobelny 
456*c1343bf6SKrzysztof Grobelny     if (manufacturer != nullptr)
457*c1343bf6SKrzysztof Grobelny     {
458*c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["Manufacturer"] = *manufacturer;
459*c1343bf6SKrzysztof Grobelny     }
460*c1343bf6SKrzysztof Grobelny 
461*c1343bf6SKrzysztof Grobelny     if (revisionCode != nullptr)
462*c1343bf6SKrzysztof Grobelny     {
463d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["FirmwareRevision"] =
464*c1343bf6SKrzysztof Grobelny             std::to_string(*revisionCode);
465ac6a4445SGunnar Mills     }
466*c1343bf6SKrzysztof Grobelny 
467*c1343bf6SKrzysztof Grobelny     if (present != nullptr && !*present)
4689a128eb3SJoshi-Mansi     {
469d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Absent";
4709a128eb3SJoshi-Mansi     }
471*c1343bf6SKrzysztof Grobelny 
472*c1343bf6SKrzysztof Grobelny     if (memoryTotalWidth != nullptr)
473ac6a4445SGunnar Mills     {
474*c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["BusWidthBits"] = *memoryTotalWidth;
475ac6a4445SGunnar Mills     }
476*c1343bf6SKrzysztof Grobelny 
477*c1343bf6SKrzysztof Grobelny     if (ecc != nullptr)
478ac6a4445SGunnar Mills     {
479ac6a4445SGunnar Mills         constexpr const std::array<const char*, 4> values{
4809a5aceacSNan Zhou             "NoECC", "SingleBitECC", "MultiBitECC", "AddressParity"};
481ac6a4445SGunnar Mills 
482ac6a4445SGunnar Mills         for (const char* v : values)
483ac6a4445SGunnar Mills         {
484*c1343bf6SKrzysztof Grobelny             if (ecc->ends_with(v))
485ac6a4445SGunnar Mills             {
486d7f04fd9SNan Zhou                 aResp->res.jsonValue[jsonPtr]["ErrorCorrection"] = v;
487ac6a4445SGunnar Mills                 break;
488ac6a4445SGunnar Mills             }
489ac6a4445SGunnar Mills         }
490ac6a4445SGunnar Mills     }
491*c1343bf6SKrzysztof Grobelny 
492*c1343bf6SKrzysztof Grobelny     if (formFactor != nullptr)
493ac6a4445SGunnar Mills     {
494ac6a4445SGunnar Mills         constexpr const std::array<const char*, 11> values{
4959a5aceacSNan Zhou             "RDIMM",       "UDIMM",       "SO_DIMM",      "LRDIMM",
4969a5aceacSNan Zhou             "Mini_RDIMM",  "Mini_UDIMM",  "SO_RDIMM_72b", "SO_UDIMM_72b",
4979a5aceacSNan Zhou             "SO_DIMM_16b", "SO_DIMM_32b", "Die"};
498ac6a4445SGunnar Mills 
499ac6a4445SGunnar Mills         for (const char* v : values)
500ac6a4445SGunnar Mills         {
501*c1343bf6SKrzysztof Grobelny             if (formFactor->ends_with(v))
502ac6a4445SGunnar Mills             {
503d7f04fd9SNan Zhou                 aResp->res.jsonValue[jsonPtr]["BaseModuleType"] = v;
504ac6a4445SGunnar Mills                 break;
505ac6a4445SGunnar Mills             }
506ac6a4445SGunnar Mills         }
507ac6a4445SGunnar Mills     }
508*c1343bf6SKrzysztof Grobelny 
509*c1343bf6SKrzysztof Grobelny     if (allowedSpeedsMT != nullptr)
510ac6a4445SGunnar Mills     {
511d7f04fd9SNan Zhou         nlohmann::json& jValue =
512d7f04fd9SNan Zhou             aResp->res.jsonValue[jsonPtr]["AllowedSpeedsMHz"];
513ac6a4445SGunnar Mills         jValue = nlohmann::json::array();
514*c1343bf6SKrzysztof Grobelny         for (uint16_t subVal : *allowedSpeedsMT)
515ac6a4445SGunnar Mills         {
516ac6a4445SGunnar Mills             jValue.push_back(subVal);
517ac6a4445SGunnar Mills         }
518ac6a4445SGunnar Mills     }
519ac6a4445SGunnar Mills 
520*c1343bf6SKrzysztof Grobelny     if (memoryAttributes != nullptr)
521ac6a4445SGunnar Mills     {
522d7f04fd9SNan Zhou         aResp->res.jsonValue[jsonPtr]["RankCount"] =
523*c1343bf6SKrzysztof Grobelny             static_cast<uint64_t>(*memoryAttributes);
524ac6a4445SGunnar Mills     }
525*c1343bf6SKrzysztof Grobelny 
526*c1343bf6SKrzysztof Grobelny     if (memoryConfiguredSpeedInMhz != nullptr)
527ac6a4445SGunnar Mills     {
528*c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["OperatingSpeedMhz"] =
529*c1343bf6SKrzysztof Grobelny             *memoryConfiguredSpeedInMhz;
530ac6a4445SGunnar Mills     }
531*c1343bf6SKrzysztof Grobelny 
532*c1343bf6SKrzysztof Grobelny     if (memoryType != nullptr)
533ac6a4445SGunnar Mills     {
534313efb1cSGunnar Mills         std::string memoryDeviceType =
535*c1343bf6SKrzysztof Grobelny             translateMemoryTypeToRedfish(*memoryType);
536313efb1cSGunnar Mills         // Values like "Unknown" or "Other" will return empty
537313efb1cSGunnar Mills         // so just leave off
538313efb1cSGunnar Mills         if (!memoryDeviceType.empty())
539ac6a4445SGunnar Mills         {
540d7f04fd9SNan Zhou             aResp->res.jsonValue[jsonPtr]["MemoryDeviceType"] =
541d7f04fd9SNan Zhou                 memoryDeviceType;
542ac6a4445SGunnar Mills         }
543*c1343bf6SKrzysztof Grobelny         if (memoryType->find("DDR") != std::string::npos)
544ac6a4445SGunnar Mills         {
545d7f04fd9SNan Zhou             aResp->res.jsonValue[jsonPtr]["MemoryType"] = "DRAM";
546ac6a4445SGunnar Mills         }
547*c1343bf6SKrzysztof Grobelny         else if (memoryType->ends_with("Logical"))
548ac6a4445SGunnar Mills         {
549d7f04fd9SNan Zhou             aResp->res.jsonValue[jsonPtr]["MemoryType"] = "IntelOptane";
550ac6a4445SGunnar Mills         }
551ac6a4445SGunnar Mills     }
552*c1343bf6SKrzysztof Grobelny 
553*c1343bf6SKrzysztof Grobelny     if (channel != nullptr)
554ac6a4445SGunnar Mills     {
555*c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Channel"] = *channel;
556*c1343bf6SKrzysztof Grobelny     }
557*c1343bf6SKrzysztof Grobelny 
558*c1343bf6SKrzysztof Grobelny     if (memoryController != nullptr)
559ac6a4445SGunnar Mills     {
560*c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["MemoryLocation"]["MemoryController"] =
561*c1343bf6SKrzysztof Grobelny             *memoryController;
562ac6a4445SGunnar Mills     }
563*c1343bf6SKrzysztof Grobelny 
564*c1343bf6SKrzysztof Grobelny     if (slot != nullptr)
565ee135e24SSunnySrivastava1984     {
566*c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Slot"] = *slot;
567*c1343bf6SKrzysztof Grobelny     }
568*c1343bf6SKrzysztof Grobelny 
569*c1343bf6SKrzysztof Grobelny     if (socket != nullptr)
570ee135e24SSunnySrivastava1984     {
571*c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Socket"] = *socket;
572ee135e24SSunnySrivastava1984     }
573*c1343bf6SKrzysztof Grobelny 
574*c1343bf6SKrzysztof Grobelny     if (sparePartNumber != nullptr)
575ee135e24SSunnySrivastava1984     {
576*c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["SparePartNumber"] = *sparePartNumber;
577*c1343bf6SKrzysztof Grobelny     }
578*c1343bf6SKrzysztof Grobelny 
579*c1343bf6SKrzysztof Grobelny     if (model != nullptr)
580ee135e24SSunnySrivastava1984     {
581*c1343bf6SKrzysztof Grobelny         aResp->res.jsonValue[jsonPtr]["Model"] = *model;
582ee135e24SSunnySrivastava1984     }
583*c1343bf6SKrzysztof Grobelny 
584*c1343bf6SKrzysztof Grobelny     if (locationCode != nullptr)
585ee135e24SSunnySrivastava1984     {
586*c1343bf6SKrzysztof Grobelny         aResp->res
587*c1343bf6SKrzysztof Grobelny             .jsonValue[jsonPtr]["Location"]["PartLocation"]["ServiceLabel"] =
588*c1343bf6SKrzysztof Grobelny             *locationCode;
589ee135e24SSunnySrivastava1984     }
590*c1343bf6SKrzysztof Grobelny 
591*c1343bf6SKrzysztof Grobelny     getPersistentMemoryProperties(aResp, properties, jsonPtr);
5929a5aceacSNan Zhou }
5939a5aceacSNan Zhou 
5949a5aceacSNan Zhou inline void getDimmDataByService(std::shared_ptr<bmcweb::AsyncResp> aResp,
5959a5aceacSNan Zhou                                  const std::string& dimmId,
5969a5aceacSNan Zhou                                  const std::string& service,
5979a5aceacSNan Zhou                                  const std::string& objPath)
5989a5aceacSNan Zhou {
5999a5aceacSNan Zhou     auto health = std::make_shared<HealthPopulate>(aResp);
6009a5aceacSNan Zhou     health->selfPath = objPath;
6019a5aceacSNan Zhou     health->populate();
6029a5aceacSNan Zhou 
6039a5aceacSNan Zhou     BMCWEB_LOG_DEBUG << "Get available system components.";
604*c1343bf6SKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
605*c1343bf6SKrzysztof Grobelny         *crow::connections::systemBus, service, objPath, "",
6069a5aceacSNan Zhou         [dimmId, aResp{std::move(aResp)}](
6079a5aceacSNan Zhou             const boost::system::error_code ec,
6089a5aceacSNan Zhou             const dbus::utility::DBusPropertiesMap& properties) {
6099a5aceacSNan Zhou         if (ec)
6109a5aceacSNan Zhou         {
6119a5aceacSNan Zhou             BMCWEB_LOG_DEBUG << "DBUS response error";
6129a5aceacSNan Zhou             messages::internalError(aResp->res);
6139a5aceacSNan Zhou             return;
6149a5aceacSNan Zhou         }
615d7f04fd9SNan Zhou         assembleDimmProperties(dimmId, aResp, properties, ""_json_pointer);
616*c1343bf6SKrzysztof Grobelny         });
617ac6a4445SGunnar Mills }
618ac6a4445SGunnar Mills 
619ef00d7d4SNan Zhou inline void assembleDimmPartitionData(
620ef00d7d4SNan Zhou     const std::shared_ptr<bmcweb::AsyncResp>& aResp,
621d7f04fd9SNan Zhou     const dbus::utility::DBusPropertiesMap& properties,
622d7f04fd9SNan Zhou     const nlohmann::json::json_pointer& regionPtr)
623ac6a4445SGunnar Mills {
624*c1343bf6SKrzysztof Grobelny     const std::string* memoryClassification = nullptr;
625*c1343bf6SKrzysztof Grobelny     const uint64_t* offsetInKiB = nullptr;
626*c1343bf6SKrzysztof Grobelny     const std::string* partitionId = nullptr;
627*c1343bf6SKrzysztof Grobelny     const bool* passphraseState = nullptr;
628*c1343bf6SKrzysztof Grobelny     const uint64_t* sizeInKiB = nullptr;
629*c1343bf6SKrzysztof Grobelny 
630*c1343bf6SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
631*c1343bf6SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "MemoryClassification",
632*c1343bf6SKrzysztof Grobelny         memoryClassification, "OffsetInKiB", offsetInKiB, "PartitionId",
633*c1343bf6SKrzysztof Grobelny         partitionId, "PassphraseState", passphraseState, "SizeInKiB",
634*c1343bf6SKrzysztof Grobelny         sizeInKiB);
635*c1343bf6SKrzysztof Grobelny 
636*c1343bf6SKrzysztof Grobelny     if (!success)
637*c1343bf6SKrzysztof Grobelny     {
638*c1343bf6SKrzysztof Grobelny         messages::internalError(aResp->res);
639*c1343bf6SKrzysztof Grobelny         return;
640*c1343bf6SKrzysztof Grobelny     }
641*c1343bf6SKrzysztof Grobelny 
642d7f04fd9SNan Zhou     nlohmann::json::object_t partition;
643*c1343bf6SKrzysztof Grobelny 
644*c1343bf6SKrzysztof Grobelny     if (memoryClassification != nullptr)
645ac6a4445SGunnar Mills     {
646*c1343bf6SKrzysztof Grobelny         partition["MemoryClassification"] = *memoryClassification;
647ac6a4445SGunnar Mills     }
648ac6a4445SGunnar Mills 
649*c1343bf6SKrzysztof Grobelny     if (offsetInKiB != nullptr)
650ac6a4445SGunnar Mills     {
651*c1343bf6SKrzysztof Grobelny         partition["OffsetMiB"] = (*offsetInKiB >> 10);
652ac6a4445SGunnar Mills     }
653ac6a4445SGunnar Mills 
654*c1343bf6SKrzysztof Grobelny     if (partitionId != nullptr)
655ac6a4445SGunnar Mills     {
656*c1343bf6SKrzysztof Grobelny         partition["RegionId"] = *partitionId;
657*c1343bf6SKrzysztof Grobelny     }
658*c1343bf6SKrzysztof Grobelny 
659*c1343bf6SKrzysztof Grobelny     if (passphraseState != nullptr)
660ac6a4445SGunnar Mills     {
661*c1343bf6SKrzysztof Grobelny         partition["PassphraseEnabled"] = *passphraseState;
662ac6a4445SGunnar Mills     }
663*c1343bf6SKrzysztof Grobelny 
664*c1343bf6SKrzysztof Grobelny     if (sizeInKiB != nullptr)
665ac6a4445SGunnar Mills     {
666*c1343bf6SKrzysztof Grobelny         partition["SizeMiB"] = (*sizeInKiB >> 10);
667ac6a4445SGunnar Mills     }
668*c1343bf6SKrzysztof Grobelny 
669d7f04fd9SNan Zhou     aResp->res.jsonValue[regionPtr].emplace_back(std::move(partition));
670ef00d7d4SNan Zhou }
671ef00d7d4SNan Zhou 
672ef00d7d4SNan Zhou inline void getDimmPartitionData(std::shared_ptr<bmcweb::AsyncResp> aResp,
673ef00d7d4SNan Zhou                                  const std::string& service,
674ef00d7d4SNan Zhou                                  const std::string& path)
675ef00d7d4SNan Zhou {
676*c1343bf6SKrzysztof Grobelny     sdbusplus::asio::getAllProperties(
677*c1343bf6SKrzysztof Grobelny         *crow::connections::systemBus, service, path,
678*c1343bf6SKrzysztof Grobelny         "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition",
679ef00d7d4SNan Zhou         [aResp{std::move(aResp)}](
680ef00d7d4SNan Zhou             const boost::system::error_code ec,
681ef00d7d4SNan Zhou             const dbus::utility::DBusPropertiesMap& properties) {
682ef00d7d4SNan Zhou         if (ec)
683ef00d7d4SNan Zhou         {
684ef00d7d4SNan Zhou             BMCWEB_LOG_DEBUG << "DBUS response error";
685ef00d7d4SNan Zhou             messages::internalError(aResp->res);
686ef00d7d4SNan Zhou 
687ef00d7d4SNan Zhou             return;
688ef00d7d4SNan Zhou         }
689d7f04fd9SNan Zhou         nlohmann::json::json_pointer regionPtr = "/Regions"_json_pointer;
690d7f04fd9SNan Zhou         assembleDimmPartitionData(aResp, properties, regionPtr);
691*c1343bf6SKrzysztof Grobelny         }
692ac6a4445SGunnar Mills 
693*c1343bf6SKrzysztof Grobelny     );
694ac6a4445SGunnar Mills }
695ac6a4445SGunnar Mills 
6968d1b46d7Szhanghch05 inline void getDimmData(std::shared_ptr<bmcweb::AsyncResp> aResp,
697ac6a4445SGunnar Mills                         const std::string& dimmId)
698ac6a4445SGunnar Mills {
699ac6a4445SGunnar Mills     BMCWEB_LOG_DEBUG << "Get available system dimm resources.";
700ac6a4445SGunnar Mills     crow::connections::systemBus->async_method_call(
701ac6a4445SGunnar Mills         [dimmId, aResp{std::move(aResp)}](
702ac6a4445SGunnar Mills             const boost::system::error_code ec,
703b9d36b47SEd Tanous             const dbus::utility::MapperGetSubTreeResponse& subtree) {
704ac6a4445SGunnar Mills         if (ec)
705ac6a4445SGunnar Mills         {
706ac6a4445SGunnar Mills             BMCWEB_LOG_DEBUG << "DBUS response error";
707ac6a4445SGunnar Mills             messages::internalError(aResp->res);
708ac6a4445SGunnar Mills 
709ac6a4445SGunnar Mills             return;
710ac6a4445SGunnar Mills         }
711ac6a4445SGunnar Mills         bool found = false;
71276686dccSNan Zhou         for (const auto& [rawPath, object] : subtree)
713ac6a4445SGunnar Mills         {
71476686dccSNan Zhou             sdbusplus::message::object_path path(rawPath);
715ac6a4445SGunnar Mills             for (const auto& [service, interfaces] : object)
716ac6a4445SGunnar Mills             {
717b9d36b47SEd Tanous                 for (const auto& interface : interfaces)
718ac6a4445SGunnar Mills                 {
719b9d36b47SEd Tanous                     if (interface ==
72076686dccSNan Zhou                             "xyz.openbmc_project.Inventory.Item.Dimm" &&
72176686dccSNan Zhou                         path.filename() == dimmId)
722b9d36b47SEd Tanous                     {
72376686dccSNan Zhou                         getDimmDataByService(aResp, dimmId, service, rawPath);
724ac6a4445SGunnar Mills                         found = true;
725ac6a4445SGunnar Mills                     }
726ac6a4445SGunnar Mills 
727b9d36b47SEd Tanous                     // partitions are separate as there can be multiple
728b9d36b47SEd Tanous                     // per
729ac6a4445SGunnar Mills                     // device, i.e.
730ac6a4445SGunnar Mills                     // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1
731ac6a4445SGunnar Mills                     // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2
732b9d36b47SEd Tanous                     if (interface ==
73376686dccSNan Zhou                             "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition" &&
73476686dccSNan Zhou                         path.parent_path().filename() == dimmId)
735ac6a4445SGunnar Mills                     {
73676686dccSNan Zhou                         getDimmPartitionData(aResp, service, rawPath);
737ac6a4445SGunnar Mills                     }
738ac6a4445SGunnar Mills                 }
739ac6a4445SGunnar Mills             }
740b9d36b47SEd Tanous         }
741ac6a4445SGunnar Mills         // Object not found
742ac6a4445SGunnar Mills         if (!found)
743ac6a4445SGunnar Mills         {
744ac6a4445SGunnar Mills             messages::resourceNotFound(aResp->res, "Memory", dimmId);
7451a1d5d6dSNan Zhou             return;
746ac6a4445SGunnar Mills         }
7471a1d5d6dSNan Zhou         // Set @odata only if object is found
7481a1d5d6dSNan Zhou         aResp->res.jsonValue["@odata.type"] = "#Memory.v1_11_0.Memory";
7491a1d5d6dSNan Zhou         aResp->res.jsonValue["@odata.id"] =
7501a1d5d6dSNan Zhou             "/redfish/v1/Systems/system/Memory/" + dimmId;
751ac6a4445SGunnar Mills         return;
752ac6a4445SGunnar Mills         },
753ac6a4445SGunnar Mills         "xyz.openbmc_project.ObjectMapper",
754ac6a4445SGunnar Mills         "/xyz/openbmc_project/object_mapper",
755ac6a4445SGunnar Mills         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
756ac6a4445SGunnar Mills         "/xyz/openbmc_project/inventory", 0,
757ac6a4445SGunnar Mills         std::array<const char*, 2>{
758ac6a4445SGunnar Mills             "xyz.openbmc_project.Inventory.Item.Dimm",
759ac6a4445SGunnar Mills             "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"});
760ac6a4445SGunnar Mills }
761ac6a4445SGunnar Mills 
7627e860f15SJohn Edward Broadbent inline void requestRoutesMemoryCollection(App& app)
763ac6a4445SGunnar Mills {
764ac6a4445SGunnar Mills     /**
765ac6a4445SGunnar Mills      * Functions triggers appropriate requests on DBus
766ac6a4445SGunnar Mills      */
7677e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Memory/")
768ed398213SEd Tanous         .privileges(redfish::privileges::getMemoryCollection)
7697e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
77045ca1b86SEd Tanous             [&app](const crow::Request& req,
7717e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
7723ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
77345ca1b86SEd Tanous         {
77445ca1b86SEd Tanous             return;
77545ca1b86SEd Tanous         }
7768d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.type"] =
7778d1b46d7Szhanghch05             "#MemoryCollection.MemoryCollection";
7788d1b46d7Szhanghch05         asyncResp->res.jsonValue["Name"] = "Memory Module Collection";
7798d1b46d7Szhanghch05         asyncResp->res.jsonValue["@odata.id"] =
7808d1b46d7Szhanghch05             "/redfish/v1/Systems/system/Memory";
781ac6a4445SGunnar Mills 
78205030b8eSGunnar Mills         collection_util::getCollectionMembers(
78305030b8eSGunnar Mills             asyncResp, "/redfish/v1/Systems/system/Memory",
78405030b8eSGunnar Mills             {"xyz.openbmc_project.Inventory.Item.Dimm"});
7857e860f15SJohn Edward Broadbent         });
786ac6a4445SGunnar Mills }
787ac6a4445SGunnar Mills 
7887e860f15SJohn Edward Broadbent inline void requestRoutesMemory(App& app)
7897e860f15SJohn Edward Broadbent {
790ac6a4445SGunnar Mills     /**
791ac6a4445SGunnar Mills      * Functions triggers appropriate requests on DBus
792ac6a4445SGunnar Mills      */
7937e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Memory/<str>/")
794ed398213SEd Tanous         .privileges(redfish::privileges::getMemory)
7957e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
79645ca1b86SEd Tanous             [&app](const crow::Request& req,
7977e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
7987e860f15SJohn Edward Broadbent                    const std::string& dimmId) {
7993ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
80045ca1b86SEd Tanous         {
80145ca1b86SEd Tanous             return;
80245ca1b86SEd Tanous         }
803ac6a4445SGunnar Mills         getDimmData(asyncResp, dimmId);
8047e860f15SJohn Edward Broadbent         });
805ac6a4445SGunnar Mills }
806ac6a4445SGunnar Mills 
807ac6a4445SGunnar Mills } // namespace redfish
808