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