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