1ac6a4445SGunnar Mills /* 2ac6a4445SGunnar Mills // Copyright (c) 2018 Intel Corporation 3ac6a4445SGunnar Mills // 4ac6a4445SGunnar Mills // Licensed under the Apache License, Version 2.0 (the "License"); 5ac6a4445SGunnar Mills // you may not use this file except in compliance with the License. 6ac6a4445SGunnar Mills // You may obtain a copy of the License at 7ac6a4445SGunnar Mills // 8ac6a4445SGunnar Mills // http://www.apache.org/licenses/LICENSE-2.0 9ac6a4445SGunnar Mills // 10ac6a4445SGunnar Mills // Unless required by applicable law or agreed to in writing, software 11ac6a4445SGunnar Mills // distributed under the License is distributed on an "AS IS" BASIS, 12ac6a4445SGunnar Mills // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ac6a4445SGunnar Mills // See the License for the specific language governing permissions and 14ac6a4445SGunnar Mills // limitations under the License. 15ac6a4445SGunnar Mills */ 16ac6a4445SGunnar Mills #pragma once 17ac6a4445SGunnar Mills 1813451e39SWilly Tu #include "bmcweb_config.h" 1913451e39SWilly Tu 203ccb3adbSEd Tanous #include "app.hpp" 213ccb3adbSEd Tanous #include "dbus_utility.hpp" 223ccb3adbSEd Tanous #include "query.hpp" 233ccb3adbSEd Tanous #include "registries/privilege_registry.hpp" 243ccb3adbSEd Tanous #include "utils/collection.hpp" 253ccb3adbSEd Tanous #include "utils/dbus_utils.hpp" 263ccb3adbSEd Tanous #include "utils/hex_utils.hpp" 273ccb3adbSEd Tanous #include "utils/json_utils.hpp" 28ac6a4445SGunnar Mills 29e99073f5SGeorge Liu #include <boost/system/error_code.hpp> 30ef4c65b7SEd Tanous #include <boost/url/format.hpp> 31d7f04fd9SNan Zhou #include <nlohmann/json.hpp> 32c1343bf6SKrzysztof Grobelny #include <sdbusplus/asio/property.hpp> 33c1343bf6SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp> 34ac6a4445SGunnar Mills 357a1dbc48SGeorge Liu #include <array> 367a1dbc48SGeorge Liu #include <string_view> 377a1dbc48SGeorge Liu 38ac6a4445SGunnar Mills namespace redfish 39ac6a4445SGunnar Mills { 40ac6a4445SGunnar Mills 41313efb1cSGunnar Mills inline std::string translateMemoryTypeToRedfish(const std::string& memoryType) 42313efb1cSGunnar Mills { 43313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR") 44313efb1cSGunnar Mills { 45313efb1cSGunnar Mills return "DDR"; 46313efb1cSGunnar Mills } 47313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2") 48313efb1cSGunnar Mills { 49313efb1cSGunnar Mills return "DDR2"; 50313efb1cSGunnar Mills } 51313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR3") 52313efb1cSGunnar Mills { 53313efb1cSGunnar Mills return "DDR3"; 54313efb1cSGunnar Mills } 55313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4") 56313efb1cSGunnar Mills { 57313efb1cSGunnar Mills return "DDR4"; 58313efb1cSGunnar Mills } 59313efb1cSGunnar Mills if (memoryType == 60313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4E_SDRAM") 61313efb1cSGunnar Mills { 62313efb1cSGunnar Mills return "DDR4E_SDRAM"; 63313efb1cSGunnar Mills } 6411a2f0f0SMansi Joshi if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR5") 6511a2f0f0SMansi Joshi { 6611a2f0f0SMansi Joshi return "DDR5"; 6711a2f0f0SMansi Joshi } 68313efb1cSGunnar Mills if (memoryType == 69313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR4_SDRAM") 70313efb1cSGunnar Mills { 71313efb1cSGunnar Mills return "LPDDR4_SDRAM"; 72313efb1cSGunnar Mills } 73313efb1cSGunnar Mills if (memoryType == 74313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR3_SDRAM") 75313efb1cSGunnar Mills { 76313efb1cSGunnar Mills return "LPDDR3_SDRAM"; 77313efb1cSGunnar Mills } 78313efb1cSGunnar Mills if (memoryType == 79313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM") 80313efb1cSGunnar Mills { 81313efb1cSGunnar Mills return "DDR2_SDRAM_FB_DIMM"; 82313efb1cSGunnar Mills } 830fda0f12SGeorge Liu if (memoryType == 840fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM_PROB") 85313efb1cSGunnar Mills { 86313efb1cSGunnar Mills return "DDR2_SDRAM_FB_DIMM_PROBE"; 87313efb1cSGunnar Mills } 88313efb1cSGunnar Mills if (memoryType == 89313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR_SGRAM") 90313efb1cSGunnar Mills { 91313efb1cSGunnar Mills return "DDR_SGRAM"; 92313efb1cSGunnar Mills } 93313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.ROM") 94313efb1cSGunnar Mills { 95313efb1cSGunnar Mills return "ROM"; 96313efb1cSGunnar Mills } 97313efb1cSGunnar Mills if (memoryType == 98313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.SDRAM") 99313efb1cSGunnar Mills { 100313efb1cSGunnar Mills return "SDRAM"; 101313efb1cSGunnar Mills } 102313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.EDO") 103313efb1cSGunnar Mills { 104313efb1cSGunnar Mills return "EDO"; 105313efb1cSGunnar Mills } 106313efb1cSGunnar Mills if (memoryType == 107313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.FastPageMode") 108313efb1cSGunnar Mills { 109313efb1cSGunnar Mills return "FastPageMode"; 110313efb1cSGunnar Mills } 111313efb1cSGunnar Mills if (memoryType == 112313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.PipelinedNibble") 113313efb1cSGunnar Mills { 114313efb1cSGunnar Mills return "PipelinedNibble"; 115313efb1cSGunnar Mills } 116313efb1cSGunnar Mills if (memoryType == 117313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.Logical") 118313efb1cSGunnar Mills { 119313efb1cSGunnar Mills return "Logical"; 120313efb1cSGunnar Mills } 121313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM") 122313efb1cSGunnar Mills { 123313efb1cSGunnar Mills return "HBM"; 124313efb1cSGunnar Mills } 125313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM2") 126313efb1cSGunnar Mills { 127313efb1cSGunnar Mills return "HBM2"; 128313efb1cSGunnar Mills } 129ce34d514STyson Tuckerbear if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM3") 130ce34d514STyson Tuckerbear { 131ce34d514STyson Tuckerbear return "HBM3"; 132ce34d514STyson Tuckerbear } 133313efb1cSGunnar Mills // This is values like Other or Unknown 134313efb1cSGunnar Mills // Also D-Bus values: 135313efb1cSGunnar Mills // DRAM 136313efb1cSGunnar Mills // EDRAM 137313efb1cSGunnar Mills // VRAM 138313efb1cSGunnar Mills // SRAM 139313efb1cSGunnar Mills // RAM 140313efb1cSGunnar Mills // FLASH 141313efb1cSGunnar Mills // EEPROM 142313efb1cSGunnar Mills // FEPROM 143313efb1cSGunnar Mills // EPROM 144313efb1cSGunnar Mills // CDRAM 145313efb1cSGunnar Mills // ThreeDRAM 146313efb1cSGunnar Mills // RDRAM 147313efb1cSGunnar Mills // FBD2 148313efb1cSGunnar Mills // LPDDR_SDRAM 149313efb1cSGunnar Mills // LPDDR2_SDRAM 15011a2f0f0SMansi Joshi // LPDDR5_SDRAM 151313efb1cSGunnar Mills return ""; 152313efb1cSGunnar Mills } 153313efb1cSGunnar Mills 154ac106bf6SEd Tanous inline void dimmPropToHex(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 155c1343bf6SKrzysztof Grobelny const char* key, const uint16_t* value, 156d7f04fd9SNan Zhou const nlohmann::json::json_pointer& jsonPtr) 157ac6a4445SGunnar Mills { 158ac6a4445SGunnar Mills if (value == nullptr) 159ac6a4445SGunnar Mills { 160ac6a4445SGunnar Mills return; 161ac6a4445SGunnar Mills } 162ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr][key] = "0x" + intToHexString(*value, 4); 163ac6a4445SGunnar Mills } 164ac6a4445SGunnar Mills 1658d1b46d7Szhanghch05 inline void getPersistentMemoryProperties( 166ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 167c1343bf6SKrzysztof Grobelny const dbus::utility::DBusPropertiesMap& properties, 168d7f04fd9SNan Zhou const nlohmann::json::json_pointer& jsonPtr) 169ac6a4445SGunnar Mills { 170c1343bf6SKrzysztof Grobelny const uint16_t* moduleManufacturerID = nullptr; 171c1343bf6SKrzysztof Grobelny const uint16_t* moduleProductID = nullptr; 172c1343bf6SKrzysztof Grobelny const uint16_t* subsystemVendorID = nullptr; 173c1343bf6SKrzysztof Grobelny const uint16_t* subsystemDeviceID = nullptr; 174c1343bf6SKrzysztof Grobelny const uint64_t* volatileRegionSizeLimitInKiB = nullptr; 175c1343bf6SKrzysztof Grobelny const uint64_t* pmRegionSizeLimitInKiB = nullptr; 176c1343bf6SKrzysztof Grobelny const uint64_t* volatileSizeInKiB = nullptr; 177c1343bf6SKrzysztof Grobelny const uint64_t* pmSizeInKiB = nullptr; 178c1343bf6SKrzysztof Grobelny const uint64_t* cacheSizeInKB = nullptr; 179c1343bf6SKrzysztof Grobelny const uint64_t* voltaileRegionMaxSizeInKib = nullptr; 180c1343bf6SKrzysztof Grobelny const uint64_t* pmRegionMaxSizeInKiB = nullptr; 181c1343bf6SKrzysztof Grobelny const uint64_t* allocationIncrementInKiB = nullptr; 182c1343bf6SKrzysztof Grobelny const uint64_t* allocationAlignmentInKiB = nullptr; 183c1343bf6SKrzysztof Grobelny const uint64_t* volatileRegionNumberLimit = nullptr; 184c1343bf6SKrzysztof Grobelny const uint64_t* pmRegionNumberLimit = nullptr; 185c1343bf6SKrzysztof Grobelny const uint64_t* spareDeviceCount = nullptr; 186c1343bf6SKrzysztof Grobelny const bool* isSpareDeviceInUse = nullptr; 187c1343bf6SKrzysztof Grobelny const bool* isRankSpareEnabled = nullptr; 188c1343bf6SKrzysztof Grobelny const std::vector<uint32_t>* maxAveragePowerLimitmW = nullptr; 189c1343bf6SKrzysztof Grobelny const bool* configurationLocked = nullptr; 190c1343bf6SKrzysztof Grobelny const std::string* allowedMemoryModes = nullptr; 191c1343bf6SKrzysztof Grobelny const std::string* memoryMedia = nullptr; 192c1343bf6SKrzysztof Grobelny const bool* configurationLockCapable = nullptr; 193c1343bf6SKrzysztof Grobelny const bool* dataLockCapable = nullptr; 194c1343bf6SKrzysztof Grobelny const bool* passphraseCapable = nullptr; 195c1343bf6SKrzysztof Grobelny const uint64_t* maxPassphraseCount = nullptr; 196c1343bf6SKrzysztof Grobelny const uint64_t* passphraseLockLimit = nullptr; 197c1343bf6SKrzysztof Grobelny 198c1343bf6SKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 199c1343bf6SKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "ModuleManufacturerID", 200c1343bf6SKrzysztof Grobelny moduleManufacturerID, "ModuleProductID", moduleProductID, 201c1343bf6SKrzysztof Grobelny "SubsystemVendorID", subsystemVendorID, "SubsystemDeviceID", 202c1343bf6SKrzysztof Grobelny subsystemDeviceID, "VolatileRegionSizeLimitInKiB", 203c1343bf6SKrzysztof Grobelny volatileRegionSizeLimitInKiB, "PmRegionSizeLimitInKiB", 204c1343bf6SKrzysztof Grobelny pmRegionSizeLimitInKiB, "VolatileSizeInKiB", volatileSizeInKiB, 205c1343bf6SKrzysztof Grobelny "PmSizeInKiB", pmSizeInKiB, "CacheSizeInKB", cacheSizeInKB, 206c1343bf6SKrzysztof Grobelny "VoltaileRegionMaxSizeInKib", voltaileRegionMaxSizeInKib, 207c1343bf6SKrzysztof Grobelny "PmRegionMaxSizeInKiB", pmRegionMaxSizeInKiB, 208c1343bf6SKrzysztof Grobelny "AllocationIncrementInKiB", allocationIncrementInKiB, 209c1343bf6SKrzysztof Grobelny "AllocationAlignmentInKiB", allocationAlignmentInKiB, 210c1343bf6SKrzysztof Grobelny "VolatileRegionNumberLimit", volatileRegionNumberLimit, 211c1343bf6SKrzysztof Grobelny "PmRegionNumberLimit", pmRegionNumberLimit, "SpareDeviceCount", 212c1343bf6SKrzysztof Grobelny spareDeviceCount, "IsSpareDeviceInUse", isSpareDeviceInUse, 213c1343bf6SKrzysztof Grobelny "IsRankSpareEnabled", isRankSpareEnabled, "MaxAveragePowerLimitmW", 214c1343bf6SKrzysztof Grobelny maxAveragePowerLimitmW, "ConfigurationLocked", configurationLocked, 215c1343bf6SKrzysztof Grobelny "AllowedMemoryModes", allowedMemoryModes, "MemoryMedia", memoryMedia, 216c1343bf6SKrzysztof Grobelny "ConfigurationLockCapable", configurationLockCapable, "DataLockCapable", 217c1343bf6SKrzysztof Grobelny dataLockCapable, "PassphraseCapable", passphraseCapable, 218c1343bf6SKrzysztof Grobelny "MaxPassphraseCount", maxPassphraseCount, "PassphraseLockLimit", 219c1343bf6SKrzysztof Grobelny passphraseLockLimit); 220c1343bf6SKrzysztof Grobelny 221c1343bf6SKrzysztof Grobelny if (!success) 222ac6a4445SGunnar Mills { 223ac106bf6SEd Tanous messages::internalError(asyncResp->res); 224c1343bf6SKrzysztof Grobelny return; 225ac6a4445SGunnar Mills } 226c1343bf6SKrzysztof Grobelny 227ac106bf6SEd Tanous dimmPropToHex(asyncResp, "ModuleManufacturerID", moduleManufacturerID, 228ac106bf6SEd Tanous jsonPtr); 229ac106bf6SEd Tanous dimmPropToHex(asyncResp, "ModuleProductID", moduleProductID, jsonPtr); 230ac106bf6SEd Tanous dimmPropToHex(asyncResp, "MemorySubsystemControllerManufacturerID", 231c1343bf6SKrzysztof Grobelny subsystemVendorID, jsonPtr); 232ac106bf6SEd Tanous dimmPropToHex(asyncResp, "MemorySubsystemControllerProductID", 233c1343bf6SKrzysztof Grobelny subsystemDeviceID, jsonPtr); 234ac6a4445SGunnar Mills 235c1343bf6SKrzysztof Grobelny if (volatileRegionSizeLimitInKiB != nullptr) 236ac6a4445SGunnar Mills { 237ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["VolatileRegionSizeLimitMiB"] = 238c1343bf6SKrzysztof Grobelny (*volatileRegionSizeLimitInKiB) >> 10; 239ac6a4445SGunnar Mills } 240ac6a4445SGunnar Mills 241c1343bf6SKrzysztof Grobelny if (pmRegionSizeLimitInKiB != nullptr) 242ac6a4445SGunnar Mills { 243ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["PersistentRegionSizeLimitMiB"] = 244c1343bf6SKrzysztof Grobelny (*pmRegionSizeLimitInKiB) >> 10; 245ac6a4445SGunnar Mills } 246ac6a4445SGunnar Mills 247c1343bf6SKrzysztof Grobelny if (volatileSizeInKiB != nullptr) 248ac6a4445SGunnar Mills { 249ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["VolatileSizeMiB"] = 250c1343bf6SKrzysztof Grobelny (*volatileSizeInKiB) >> 10; 251ac6a4445SGunnar Mills } 252c1343bf6SKrzysztof Grobelny 253c1343bf6SKrzysztof Grobelny if (pmSizeInKiB != nullptr) 254c1343bf6SKrzysztof Grobelny { 255ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["NonVolatileSizeMiB"] = 256ac106bf6SEd Tanous (*pmSizeInKiB) >> 10; 257c1343bf6SKrzysztof Grobelny } 258c1343bf6SKrzysztof Grobelny 259c1343bf6SKrzysztof Grobelny if (cacheSizeInKB != nullptr) 260c1343bf6SKrzysztof Grobelny { 261ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["CacheSizeMiB"] = 262ac106bf6SEd Tanous (*cacheSizeInKB >> 10); 263c1343bf6SKrzysztof Grobelny } 264c1343bf6SKrzysztof Grobelny 265c1343bf6SKrzysztof Grobelny if (voltaileRegionMaxSizeInKib != nullptr) 266c1343bf6SKrzysztof Grobelny { 267ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["VolatileRegionSizeMaxMiB"] = 268c1343bf6SKrzysztof Grobelny (*voltaileRegionMaxSizeInKib) >> 10; 269ac6a4445SGunnar Mills } 270ac6a4445SGunnar Mills 271c1343bf6SKrzysztof Grobelny if (pmRegionMaxSizeInKiB != nullptr) 272ac6a4445SGunnar Mills { 273ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["PersistentRegionSizeMaxMiB"] = 274c1343bf6SKrzysztof Grobelny (*pmRegionMaxSizeInKiB) >> 10; 275ac6a4445SGunnar Mills } 276ac6a4445SGunnar Mills 277c1343bf6SKrzysztof Grobelny if (allocationIncrementInKiB != nullptr) 278ac6a4445SGunnar Mills { 279ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["AllocationIncrementMiB"] = 280c1343bf6SKrzysztof Grobelny (*allocationIncrementInKiB) >> 10; 281ac6a4445SGunnar Mills } 282ac6a4445SGunnar Mills 283c1343bf6SKrzysztof Grobelny if (allocationAlignmentInKiB != nullptr) 284ac6a4445SGunnar Mills { 285ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["AllocationAlignmentMiB"] = 286c1343bf6SKrzysztof Grobelny (*allocationAlignmentInKiB) >> 10; 287ac6a4445SGunnar Mills } 288c1343bf6SKrzysztof Grobelny 289c1343bf6SKrzysztof Grobelny if (volatileRegionNumberLimit != nullptr) 290ac6a4445SGunnar Mills { 291ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["VolatileRegionNumberLimit"] = 292c1343bf6SKrzysztof Grobelny *volatileRegionNumberLimit; 293ac6a4445SGunnar Mills } 294c1343bf6SKrzysztof Grobelny 295c1343bf6SKrzysztof Grobelny if (pmRegionNumberLimit != nullptr) 296ac6a4445SGunnar Mills { 297ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["PersistentRegionNumberLimit"] = 298c1343bf6SKrzysztof Grobelny *pmRegionNumberLimit; 299ac6a4445SGunnar Mills } 300c1343bf6SKrzysztof Grobelny 301c1343bf6SKrzysztof Grobelny if (spareDeviceCount != nullptr) 302ac6a4445SGunnar Mills { 303ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["SpareDeviceCount"] = 304ac106bf6SEd Tanous *spareDeviceCount; 305ac6a4445SGunnar Mills } 306c1343bf6SKrzysztof Grobelny 307c1343bf6SKrzysztof Grobelny if (isSpareDeviceInUse != nullptr) 308ac6a4445SGunnar Mills { 309ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["IsSpareDeviceEnabled"] = 310c1343bf6SKrzysztof Grobelny *isSpareDeviceInUse; 311ac6a4445SGunnar Mills } 312c1343bf6SKrzysztof Grobelny 313c1343bf6SKrzysztof Grobelny if (isRankSpareEnabled != nullptr) 314ac6a4445SGunnar Mills { 315ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["IsRankSpareEnabled"] = 316c1343bf6SKrzysztof Grobelny *isRankSpareEnabled; 317ac6a4445SGunnar Mills } 318c1343bf6SKrzysztof Grobelny 319c1343bf6SKrzysztof Grobelny if (maxAveragePowerLimitmW != nullptr) 320ac6a4445SGunnar Mills { 321ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["MaxTDPMilliWatts"] = 322c1343bf6SKrzysztof Grobelny *maxAveragePowerLimitmW; 323ac6a4445SGunnar Mills } 324c1343bf6SKrzysztof Grobelny 325c1343bf6SKrzysztof Grobelny if (configurationLocked != nullptr) 326ac6a4445SGunnar Mills { 327ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["ConfigurationLocked"] = 328c1343bf6SKrzysztof Grobelny *configurationLocked; 329ac6a4445SGunnar Mills } 330c1343bf6SKrzysztof Grobelny 331c1343bf6SKrzysztof Grobelny if (allowedMemoryModes != nullptr) 332ac6a4445SGunnar Mills { 33380badf7cSJiaqing Zhao constexpr const std::array<const char*, 3> values{"Volatile", "PMEM", 33480badf7cSJiaqing Zhao "Block"}; 335ac6a4445SGunnar Mills 336ac6a4445SGunnar Mills for (const char* v : values) 337ac6a4445SGunnar Mills { 338c1343bf6SKrzysztof Grobelny if (allowedMemoryModes->ends_with(v)) 339ac6a4445SGunnar Mills { 340ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["OperatingMemoryModes"] 341ac106bf6SEd Tanous .push_back(v); 342ac6a4445SGunnar Mills break; 343ac6a4445SGunnar Mills } 344ac6a4445SGunnar Mills } 345ac6a4445SGunnar Mills } 346c1343bf6SKrzysztof Grobelny 347c1343bf6SKrzysztof Grobelny if (memoryMedia != nullptr) 348ac6a4445SGunnar Mills { 349ac6a4445SGunnar Mills constexpr const std::array<const char*, 3> values{"DRAM", "NAND", 350ac6a4445SGunnar Mills "Intel3DXPoint"}; 351ac6a4445SGunnar Mills 352ac6a4445SGunnar Mills for (const char* v : values) 353ac6a4445SGunnar Mills { 354c1343bf6SKrzysztof Grobelny if (memoryMedia->ends_with(v)) 355ac6a4445SGunnar Mills { 356ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["MemoryMedia"].push_back(v); 357ac6a4445SGunnar Mills break; 358ac6a4445SGunnar Mills } 359ac6a4445SGunnar Mills } 360ac6a4445SGunnar Mills } 361c1343bf6SKrzysztof Grobelny 362c1343bf6SKrzysztof Grobelny if (configurationLockCapable != nullptr) 363ac6a4445SGunnar Mills { 364ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["SecurityCapabilities"] 365c1343bf6SKrzysztof Grobelny ["ConfigurationLockCapable"] = 366c1343bf6SKrzysztof Grobelny *configurationLockCapable; 367ac6a4445SGunnar Mills } 368c1343bf6SKrzysztof Grobelny 369c1343bf6SKrzysztof Grobelny if (dataLockCapable != nullptr) 370ac6a4445SGunnar Mills { 371ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["SecurityCapabilities"] 37289492a15SPatrick Williams ["DataLockCapable"] = *dataLockCapable; 373ac6a4445SGunnar Mills } 374c1343bf6SKrzysztof Grobelny 375c1343bf6SKrzysztof Grobelny if (passphraseCapable != nullptr) 376c1343bf6SKrzysztof Grobelny { 377ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["SecurityCapabilities"] 37889492a15SPatrick Williams ["PassphraseCapable"] = *passphraseCapable; 379c1343bf6SKrzysztof Grobelny } 380c1343bf6SKrzysztof Grobelny 381c1343bf6SKrzysztof Grobelny if (maxPassphraseCount != nullptr) 382c1343bf6SKrzysztof Grobelny { 383ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["SecurityCapabilities"] 38489492a15SPatrick Williams ["MaxPassphraseCount"] = *maxPassphraseCount; 385c1343bf6SKrzysztof Grobelny } 386c1343bf6SKrzysztof Grobelny 387c1343bf6SKrzysztof Grobelny if (passphraseLockLimit != nullptr) 388c1343bf6SKrzysztof Grobelny { 389ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["SecurityCapabilities"] 39089492a15SPatrick Williams ["PassphraseLockLimit"] = *passphraseLockLimit; 391ac6a4445SGunnar Mills } 392ac6a4445SGunnar Mills } 393ac6a4445SGunnar Mills 3949a5aceacSNan Zhou inline void 3959a5aceacSNan Zhou assembleDimmProperties(std::string_view dimmId, 396ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 397d7f04fd9SNan Zhou const dbus::utility::DBusPropertiesMap& properties, 398d7f04fd9SNan Zhou const nlohmann::json::json_pointer& jsonPtr) 399ac6a4445SGunnar Mills { 400ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["Id"] = dimmId; 401ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["Name"] = "DIMM Slot"; 402ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Enabled"; 403ac106bf6SEd Tanous asyncResp->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; 4166995c1ceSGeorge Liu const size_t* memoryAttributes = nullptr; 417c1343bf6SKrzysztof Grobelny const uint16_t* memoryConfiguredSpeedInMhz = nullptr; 418c1343bf6SKrzysztof Grobelny const std::string* memoryType = nullptr; 4196fde5971SJayaprakash Mutyala const std::uint8_t* channel = nullptr; 4206fde5971SJayaprakash Mutyala const std::uint8_t* memoryController = nullptr; 4216fde5971SJayaprakash Mutyala const std::uint8_t* slot = nullptr; 4226fde5971SJayaprakash Mutyala const std::uint8_t* 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 { 442ac106bf6SEd Tanous messages::internalError(asyncResp->res); 443601af5edSChicago Duan return; 444ac6a4445SGunnar Mills } 445c1343bf6SKrzysztof Grobelny 446c1343bf6SKrzysztof Grobelny if (memoryDataWidth != nullptr) 447c1343bf6SKrzysztof Grobelny { 448ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["DataWidthBits"] = *memoryDataWidth; 449c1343bf6SKrzysztof Grobelny } 450c1343bf6SKrzysztof Grobelny 451c1343bf6SKrzysztof Grobelny if (memorySizeInKB != nullptr) 452c1343bf6SKrzysztof Grobelny { 453ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["CapacityMiB"] = 454ac106bf6SEd Tanous (*memorySizeInKB >> 10); 455c1343bf6SKrzysztof Grobelny } 456c1343bf6SKrzysztof Grobelny 457c1343bf6SKrzysztof Grobelny if (partNumber != nullptr) 458c1343bf6SKrzysztof Grobelny { 459ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["PartNumber"] = *partNumber; 460c1343bf6SKrzysztof Grobelny } 461c1343bf6SKrzysztof Grobelny 462c1343bf6SKrzysztof Grobelny if (serialNumber != nullptr) 463c1343bf6SKrzysztof Grobelny { 464ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["SerialNumber"] = *serialNumber; 465c1343bf6SKrzysztof Grobelny } 466c1343bf6SKrzysztof Grobelny 467c1343bf6SKrzysztof Grobelny if (manufacturer != nullptr) 468c1343bf6SKrzysztof Grobelny { 469ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["Manufacturer"] = *manufacturer; 470c1343bf6SKrzysztof Grobelny } 471c1343bf6SKrzysztof Grobelny 472c1343bf6SKrzysztof Grobelny if (revisionCode != nullptr) 473c1343bf6SKrzysztof Grobelny { 474ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["FirmwareRevision"] = 475c1343bf6SKrzysztof Grobelny std::to_string(*revisionCode); 476ac6a4445SGunnar Mills } 477c1343bf6SKrzysztof Grobelny 478c1343bf6SKrzysztof Grobelny if (present != nullptr && !*present) 4799a128eb3SJoshi-Mansi { 480ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Absent"; 4819a128eb3SJoshi-Mansi } 482c1343bf6SKrzysztof Grobelny 483c1343bf6SKrzysztof Grobelny if (memoryTotalWidth != nullptr) 484ac6a4445SGunnar Mills { 485ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["BusWidthBits"] = *memoryTotalWidth; 486ac6a4445SGunnar Mills } 487c1343bf6SKrzysztof Grobelny 488c1343bf6SKrzysztof Grobelny if (ecc != nullptr) 489ac6a4445SGunnar Mills { 490ac6a4445SGunnar Mills constexpr const std::array<const char*, 4> values{ 4919a5aceacSNan Zhou "NoECC", "SingleBitECC", "MultiBitECC", "AddressParity"}; 492ac6a4445SGunnar Mills 493ac6a4445SGunnar Mills for (const char* v : values) 494ac6a4445SGunnar Mills { 495c1343bf6SKrzysztof Grobelny if (ecc->ends_with(v)) 496ac6a4445SGunnar Mills { 497ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["ErrorCorrection"] = v; 498ac6a4445SGunnar Mills break; 499ac6a4445SGunnar Mills } 500ac6a4445SGunnar Mills } 501ac6a4445SGunnar Mills } 502c1343bf6SKrzysztof Grobelny 503c1343bf6SKrzysztof Grobelny if (formFactor != nullptr) 504ac6a4445SGunnar Mills { 505ac6a4445SGunnar Mills constexpr const std::array<const char*, 11> values{ 5069a5aceacSNan Zhou "RDIMM", "UDIMM", "SO_DIMM", "LRDIMM", 5079a5aceacSNan Zhou "Mini_RDIMM", "Mini_UDIMM", "SO_RDIMM_72b", "SO_UDIMM_72b", 5089a5aceacSNan Zhou "SO_DIMM_16b", "SO_DIMM_32b", "Die"}; 509ac6a4445SGunnar Mills 510ac6a4445SGunnar Mills for (const char* v : values) 511ac6a4445SGunnar Mills { 512c1343bf6SKrzysztof Grobelny if (formFactor->ends_with(v)) 513ac6a4445SGunnar Mills { 514ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["BaseModuleType"] = v; 515ac6a4445SGunnar Mills break; 516ac6a4445SGunnar Mills } 517ac6a4445SGunnar Mills } 518ac6a4445SGunnar Mills } 519c1343bf6SKrzysztof Grobelny 520c1343bf6SKrzysztof Grobelny if (allowedSpeedsMT != nullptr) 521ac6a4445SGunnar Mills { 522d7f04fd9SNan Zhou nlohmann::json& jValue = 523ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["AllowedSpeedsMHz"]; 524ac6a4445SGunnar Mills jValue = nlohmann::json::array(); 525c1343bf6SKrzysztof Grobelny for (uint16_t subVal : *allowedSpeedsMT) 526ac6a4445SGunnar Mills { 527ac6a4445SGunnar Mills jValue.push_back(subVal); 528ac6a4445SGunnar Mills } 529ac6a4445SGunnar Mills } 530ac6a4445SGunnar Mills 531c1343bf6SKrzysztof Grobelny if (memoryAttributes != nullptr) 532ac6a4445SGunnar Mills { 5336995c1ceSGeorge Liu asyncResp->res.jsonValue[jsonPtr]["RankCount"] = *memoryAttributes; 534ac6a4445SGunnar Mills } 535c1343bf6SKrzysztof Grobelny 536c1343bf6SKrzysztof Grobelny if (memoryConfiguredSpeedInMhz != nullptr) 537ac6a4445SGunnar Mills { 538ac106bf6SEd Tanous asyncResp->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 { 550ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["MemoryDeviceType"] = 551d7f04fd9SNan Zhou memoryDeviceType; 552ac6a4445SGunnar Mills } 553c1343bf6SKrzysztof Grobelny if (memoryType->find("DDR") != std::string::npos) 554ac6a4445SGunnar Mills { 555ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["MemoryType"] = "DRAM"; 556ac6a4445SGunnar Mills } 557c1343bf6SKrzysztof Grobelny else if (memoryType->ends_with("Logical")) 558ac6a4445SGunnar Mills { 559ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["MemoryType"] = "IntelOptane"; 560ac6a4445SGunnar Mills } 561ac6a4445SGunnar Mills } 562c1343bf6SKrzysztof Grobelny 563c1343bf6SKrzysztof Grobelny if (channel != nullptr) 564ac6a4445SGunnar Mills { 565ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Channel"] = 566ac106bf6SEd Tanous *channel; 567c1343bf6SKrzysztof Grobelny } 568c1343bf6SKrzysztof Grobelny 569c1343bf6SKrzysztof Grobelny if (memoryController != nullptr) 570ac6a4445SGunnar Mills { 571ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"] 572ac106bf6SEd Tanous ["MemoryController"] = *memoryController; 573ac6a4445SGunnar Mills } 574c1343bf6SKrzysztof Grobelny 575c1343bf6SKrzysztof Grobelny if (slot != nullptr) 576ee135e24SSunnySrivastava1984 { 577ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Slot"] = *slot; 578c1343bf6SKrzysztof Grobelny } 579c1343bf6SKrzysztof Grobelny 580c1343bf6SKrzysztof Grobelny if (socket != nullptr) 581ee135e24SSunnySrivastava1984 { 582ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Socket"] = *socket; 583ee135e24SSunnySrivastava1984 } 584c1343bf6SKrzysztof Grobelny 585c1343bf6SKrzysztof Grobelny if (sparePartNumber != nullptr) 586ee135e24SSunnySrivastava1984 { 587ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["SparePartNumber"] = *sparePartNumber; 588c1343bf6SKrzysztof Grobelny } 589c1343bf6SKrzysztof Grobelny 590c1343bf6SKrzysztof Grobelny if (model != nullptr) 591ee135e24SSunnySrivastava1984 { 592ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["Model"] = *model; 593ee135e24SSunnySrivastava1984 } 594c1343bf6SKrzysztof Grobelny 595c1343bf6SKrzysztof Grobelny if (locationCode != nullptr) 596ee135e24SSunnySrivastava1984 { 597ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["Location"]["PartLocation"] 59889492a15SPatrick Williams ["ServiceLabel"] = *locationCode; 599ee135e24SSunnySrivastava1984 } 600c1343bf6SKrzysztof Grobelny 601ac106bf6SEd Tanous getPersistentMemoryProperties(asyncResp, properties, jsonPtr); 6029a5aceacSNan Zhou } 6039a5aceacSNan Zhou 604ac106bf6SEd Tanous inline void getDimmDataByService(std::shared_ptr<bmcweb::AsyncResp> asyncResp, 6059a5aceacSNan Zhou const std::string& dimmId, 6069a5aceacSNan Zhou const std::string& service, 6079a5aceacSNan Zhou const std::string& objPath) 6089a5aceacSNan Zhou { 60962598e31SEd Tanous BMCWEB_LOG_DEBUG("Get available system components."); 610c1343bf6SKrzysztof Grobelny sdbusplus::asio::getAllProperties( 611c1343bf6SKrzysztof Grobelny *crow::connections::systemBus, service, objPath, "", 612ac106bf6SEd Tanous [dimmId, asyncResp{std::move(asyncResp)}]( 6135e7e2dc5SEd Tanous const boost::system::error_code& ec, 6149a5aceacSNan Zhou const dbus::utility::DBusPropertiesMap& properties) { 6159a5aceacSNan Zhou if (ec) 6169a5aceacSNan Zhou { 61762598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error"); 618ac106bf6SEd Tanous messages::internalError(asyncResp->res); 6199a5aceacSNan Zhou return; 6209a5aceacSNan Zhou } 621ac106bf6SEd Tanous assembleDimmProperties(dimmId, asyncResp, properties, ""_json_pointer); 622c1343bf6SKrzysztof Grobelny }); 623ac6a4445SGunnar Mills } 624ac6a4445SGunnar Mills 625ef00d7d4SNan Zhou inline void assembleDimmPartitionData( 626ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 627d7f04fd9SNan Zhou const dbus::utility::DBusPropertiesMap& properties, 628d7f04fd9SNan Zhou const nlohmann::json::json_pointer& regionPtr) 629ac6a4445SGunnar Mills { 630c1343bf6SKrzysztof Grobelny const std::string* memoryClassification = nullptr; 631c1343bf6SKrzysztof Grobelny const uint64_t* offsetInKiB = nullptr; 632c1343bf6SKrzysztof Grobelny const std::string* partitionId = nullptr; 633c1343bf6SKrzysztof Grobelny const bool* passphraseState = nullptr; 634c1343bf6SKrzysztof Grobelny const uint64_t* sizeInKiB = nullptr; 635c1343bf6SKrzysztof Grobelny 636c1343bf6SKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 637c1343bf6SKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "MemoryClassification", 638c1343bf6SKrzysztof Grobelny memoryClassification, "OffsetInKiB", offsetInKiB, "PartitionId", 639c1343bf6SKrzysztof Grobelny partitionId, "PassphraseState", passphraseState, "SizeInKiB", 640c1343bf6SKrzysztof Grobelny sizeInKiB); 641c1343bf6SKrzysztof Grobelny 642c1343bf6SKrzysztof Grobelny if (!success) 643c1343bf6SKrzysztof Grobelny { 644ac106bf6SEd Tanous messages::internalError(asyncResp->res); 645c1343bf6SKrzysztof Grobelny return; 646c1343bf6SKrzysztof Grobelny } 647c1343bf6SKrzysztof Grobelny 648d7f04fd9SNan Zhou nlohmann::json::object_t partition; 649c1343bf6SKrzysztof Grobelny 650c1343bf6SKrzysztof Grobelny if (memoryClassification != nullptr) 651ac6a4445SGunnar Mills { 652c1343bf6SKrzysztof Grobelny partition["MemoryClassification"] = *memoryClassification; 653ac6a4445SGunnar Mills } 654ac6a4445SGunnar Mills 655c1343bf6SKrzysztof Grobelny if (offsetInKiB != nullptr) 656ac6a4445SGunnar Mills { 657c1343bf6SKrzysztof Grobelny partition["OffsetMiB"] = (*offsetInKiB >> 10); 658ac6a4445SGunnar Mills } 659ac6a4445SGunnar Mills 660c1343bf6SKrzysztof Grobelny if (partitionId != nullptr) 661ac6a4445SGunnar Mills { 662c1343bf6SKrzysztof Grobelny partition["RegionId"] = *partitionId; 663c1343bf6SKrzysztof Grobelny } 664c1343bf6SKrzysztof Grobelny 665c1343bf6SKrzysztof Grobelny if (passphraseState != nullptr) 666ac6a4445SGunnar Mills { 667c1343bf6SKrzysztof Grobelny partition["PassphraseEnabled"] = *passphraseState; 668ac6a4445SGunnar Mills } 669c1343bf6SKrzysztof Grobelny 670c1343bf6SKrzysztof Grobelny if (sizeInKiB != nullptr) 671ac6a4445SGunnar Mills { 672c1343bf6SKrzysztof Grobelny partition["SizeMiB"] = (*sizeInKiB >> 10); 673ac6a4445SGunnar Mills } 674c1343bf6SKrzysztof Grobelny 675ac106bf6SEd Tanous asyncResp->res.jsonValue[regionPtr].emplace_back(std::move(partition)); 676ef00d7d4SNan Zhou } 677ef00d7d4SNan Zhou 678ac106bf6SEd Tanous inline void getDimmPartitionData(std::shared_ptr<bmcweb::AsyncResp> asyncResp, 679ef00d7d4SNan Zhou const std::string& service, 680ef00d7d4SNan Zhou const std::string& path) 681ef00d7d4SNan Zhou { 682c1343bf6SKrzysztof Grobelny sdbusplus::asio::getAllProperties( 683c1343bf6SKrzysztof Grobelny *crow::connections::systemBus, service, path, 684c1343bf6SKrzysztof Grobelny "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition", 685ac106bf6SEd Tanous [asyncResp{std::move(asyncResp)}]( 6865e7e2dc5SEd Tanous const boost::system::error_code& ec, 687ef00d7d4SNan Zhou const dbus::utility::DBusPropertiesMap& properties) { 688ef00d7d4SNan Zhou if (ec) 689ef00d7d4SNan Zhou { 69062598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error"); 691ac106bf6SEd Tanous messages::internalError(asyncResp->res); 692ef00d7d4SNan Zhou 693ef00d7d4SNan Zhou return; 694ef00d7d4SNan Zhou } 695d7f04fd9SNan Zhou nlohmann::json::json_pointer regionPtr = "/Regions"_json_pointer; 696ac106bf6SEd Tanous assembleDimmPartitionData(asyncResp, properties, regionPtr); 697c1343bf6SKrzysztof Grobelny } 698ac6a4445SGunnar Mills 699c1343bf6SKrzysztof Grobelny ); 700ac6a4445SGunnar Mills } 701ac6a4445SGunnar Mills 702ac106bf6SEd Tanous inline void getDimmData(std::shared_ptr<bmcweb::AsyncResp> asyncResp, 703ac6a4445SGunnar Mills const std::string& dimmId) 704ac6a4445SGunnar Mills { 70562598e31SEd Tanous BMCWEB_LOG_DEBUG("Get available system dimm resources."); 706e99073f5SGeorge Liu constexpr std::array<std::string_view, 2> dimmInterfaces = { 707e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.Dimm", 708e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"}; 709e99073f5SGeorge Liu dbus::utility::getSubTree( 710e99073f5SGeorge Liu "/xyz/openbmc_project/inventory", 0, dimmInterfaces, 711ac106bf6SEd Tanous [dimmId, asyncResp{std::move(asyncResp)}]( 712e99073f5SGeorge Liu const boost::system::error_code& ec, 713b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 714ac6a4445SGunnar Mills if (ec) 715ac6a4445SGunnar Mills { 71662598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error"); 717ac106bf6SEd Tanous messages::internalError(asyncResp->res); 718ac6a4445SGunnar Mills 719ac6a4445SGunnar Mills return; 720ac6a4445SGunnar Mills } 721ac6a4445SGunnar Mills bool found = false; 72276686dccSNan Zhou for (const auto& [rawPath, object] : subtree) 723ac6a4445SGunnar Mills { 72476686dccSNan Zhou sdbusplus::message::object_path path(rawPath); 725ac6a4445SGunnar Mills for (const auto& [service, interfaces] : object) 726ac6a4445SGunnar Mills { 727b9d36b47SEd Tanous for (const auto& interface : interfaces) 728ac6a4445SGunnar Mills { 729b9d36b47SEd Tanous if (interface == 73076686dccSNan Zhou "xyz.openbmc_project.Inventory.Item.Dimm" && 73176686dccSNan Zhou path.filename() == dimmId) 732b9d36b47SEd Tanous { 733ac106bf6SEd Tanous getDimmDataByService(asyncResp, dimmId, service, 734ac106bf6SEd Tanous rawPath); 735ac6a4445SGunnar Mills found = true; 736ac6a4445SGunnar Mills } 737ac6a4445SGunnar Mills 738b9d36b47SEd Tanous // partitions are separate as there can be multiple 739b9d36b47SEd Tanous // per 740ac6a4445SGunnar Mills // device, i.e. 741ac6a4445SGunnar Mills // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1 742ac6a4445SGunnar Mills // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2 743b9d36b47SEd Tanous if (interface == 74476686dccSNan Zhou "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition" && 74576686dccSNan Zhou path.parent_path().filename() == dimmId) 746ac6a4445SGunnar Mills { 747ac106bf6SEd Tanous getDimmPartitionData(asyncResp, service, rawPath); 748ac6a4445SGunnar Mills } 749ac6a4445SGunnar Mills } 750ac6a4445SGunnar Mills } 751b9d36b47SEd Tanous } 752ac6a4445SGunnar Mills // Object not found 753ac6a4445SGunnar Mills if (!found) 754ac6a4445SGunnar Mills { 755ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "Memory", dimmId); 7561a1d5d6dSNan Zhou return; 757ac6a4445SGunnar Mills } 7581a1d5d6dSNan Zhou // Set @odata only if object is found 759ac106bf6SEd Tanous asyncResp->res.jsonValue["@odata.type"] = "#Memory.v1_11_0.Memory"; 760ac106bf6SEd Tanous asyncResp->res.jsonValue["@odata.id"] = 761ef4c65b7SEd Tanous boost::urls::format("/redfish/v1/Systems/system/Memory/{}", dimmId); 762ac6a4445SGunnar Mills return; 763e99073f5SGeorge Liu }); 764ac6a4445SGunnar Mills } 765ac6a4445SGunnar Mills 7667e860f15SJohn Edward Broadbent inline void requestRoutesMemoryCollection(App& app) 767ac6a4445SGunnar Mills { 768ac6a4445SGunnar Mills /** 769ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 770ac6a4445SGunnar Mills */ 77122d268cbSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/") 772ed398213SEd Tanous .privileges(redfish::privileges::getMemoryCollection) 7737e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 77445ca1b86SEd Tanous [&app](const crow::Request& req, 77522d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 77622d268cbSEd Tanous const std::string& systemName) { 7773ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 77845ca1b86SEd Tanous { 77945ca1b86SEd Tanous return; 78045ca1b86SEd Tanous } 781*25b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 7827f3e84a1SEd Tanous { 7837f3e84a1SEd Tanous // Option currently returns no systems. TBD 7847f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 7857f3e84a1SEd Tanous systemName); 7867f3e84a1SEd Tanous return; 7877f3e84a1SEd Tanous } 78822d268cbSEd Tanous if (systemName != "system") 78922d268cbSEd Tanous { 79022d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 79122d268cbSEd Tanous systemName); 79222d268cbSEd Tanous return; 79322d268cbSEd Tanous } 79422d268cbSEd Tanous 7958d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 7968d1b46d7Szhanghch05 "#MemoryCollection.MemoryCollection"; 7978d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Memory Module Collection"; 7988d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = 7998d1b46d7Szhanghch05 "/redfish/v1/Systems/system/Memory"; 800ac6a4445SGunnar Mills 8017a1dbc48SGeorge Liu constexpr std::array<std::string_view, 1> interfaces{ 8027a1dbc48SGeorge Liu "xyz.openbmc_project.Inventory.Item.Dimm"}; 80305030b8eSGunnar Mills collection_util::getCollectionMembers( 804ae9031f0SWilly Tu asyncResp, boost::urls::url("/redfish/v1/Systems/system/Memory"), 80536b5f1edSLakshmi Yadlapati interfaces, "/xyz/openbmc_project/inventory"); 8067e860f15SJohn Edward Broadbent }); 807ac6a4445SGunnar Mills } 808ac6a4445SGunnar Mills 8097e860f15SJohn Edward Broadbent inline void requestRoutesMemory(App& app) 8107e860f15SJohn Edward Broadbent { 811ac6a4445SGunnar Mills /** 812ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 813ac6a4445SGunnar Mills */ 81422d268cbSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/<str>/") 815ed398213SEd Tanous .privileges(redfish::privileges::getMemory) 8167e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 81745ca1b86SEd Tanous [&app](const crow::Request& req, 8187e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 81922d268cbSEd Tanous const std::string& systemName, const std::string& dimmId) { 8203ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 82145ca1b86SEd Tanous { 82245ca1b86SEd Tanous return; 82345ca1b86SEd Tanous } 8247f3e84a1SEd Tanous 825*25b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 8267f3e84a1SEd Tanous { 8277f3e84a1SEd Tanous // Option currently returns no systems. TBD 8287f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 8297f3e84a1SEd Tanous systemName); 8307f3e84a1SEd Tanous return; 8317f3e84a1SEd Tanous } 8327f3e84a1SEd Tanous 83322d268cbSEd Tanous if (systemName != "system") 83422d268cbSEd Tanous { 83522d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 83622d268cbSEd Tanous systemName); 83722d268cbSEd Tanous return; 83822d268cbSEd Tanous } 83922d268cbSEd Tanous 840ac6a4445SGunnar Mills getDimmData(asyncResp, dimmId); 8417e860f15SJohn Edward Broadbent }); 842ac6a4445SGunnar Mills } 843ac6a4445SGunnar Mills 844ac6a4445SGunnar Mills } // namespace redfish 845