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