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> 22*45ca1b86SEd Tanous #include <query.hpp> 23ed398213SEd Tanous #include <registries/privilege_registry.hpp> 24ac6a4445SGunnar Mills #include <utils/collection.hpp> 25f201ffb4SEd Tanous #include <utils/hex_utils.hpp> 26ac6a4445SGunnar Mills #include <utils/json_utils.hpp> 27ac6a4445SGunnar Mills 28ac6a4445SGunnar Mills namespace redfish 29ac6a4445SGunnar Mills { 30ac6a4445SGunnar Mills 31313efb1cSGunnar Mills inline std::string translateMemoryTypeToRedfish(const std::string& memoryType) 32313efb1cSGunnar Mills { 33313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR") 34313efb1cSGunnar Mills { 35313efb1cSGunnar Mills return "DDR"; 36313efb1cSGunnar Mills } 37313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2") 38313efb1cSGunnar Mills { 39313efb1cSGunnar Mills return "DDR2"; 40313efb1cSGunnar Mills } 41313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR3") 42313efb1cSGunnar Mills { 43313efb1cSGunnar Mills return "DDR3"; 44313efb1cSGunnar Mills } 45313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4") 46313efb1cSGunnar Mills { 47313efb1cSGunnar Mills return "DDR4"; 48313efb1cSGunnar Mills } 49313efb1cSGunnar Mills if (memoryType == 50313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4E_SDRAM") 51313efb1cSGunnar Mills { 52313efb1cSGunnar Mills return "DDR4E_SDRAM"; 53313efb1cSGunnar Mills } 5411a2f0f0SMansi Joshi if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR5") 5511a2f0f0SMansi Joshi { 5611a2f0f0SMansi Joshi return "DDR5"; 5711a2f0f0SMansi Joshi } 58313efb1cSGunnar Mills if (memoryType == 59313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR4_SDRAM") 60313efb1cSGunnar Mills { 61313efb1cSGunnar Mills return "LPDDR4_SDRAM"; 62313efb1cSGunnar Mills } 63313efb1cSGunnar Mills if (memoryType == 64313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR3_SDRAM") 65313efb1cSGunnar Mills { 66313efb1cSGunnar Mills return "LPDDR3_SDRAM"; 67313efb1cSGunnar Mills } 68313efb1cSGunnar Mills if (memoryType == 69313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM") 70313efb1cSGunnar Mills { 71313efb1cSGunnar Mills return "DDR2_SDRAM_FB_DIMM"; 72313efb1cSGunnar Mills } 730fda0f12SGeorge Liu if (memoryType == 740fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM_PROB") 75313efb1cSGunnar Mills { 76313efb1cSGunnar Mills return "DDR2_SDRAM_FB_DIMM_PROBE"; 77313efb1cSGunnar Mills } 78313efb1cSGunnar Mills if (memoryType == 79313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR_SGRAM") 80313efb1cSGunnar Mills { 81313efb1cSGunnar Mills return "DDR_SGRAM"; 82313efb1cSGunnar Mills } 83313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.ROM") 84313efb1cSGunnar Mills { 85313efb1cSGunnar Mills return "ROM"; 86313efb1cSGunnar Mills } 87313efb1cSGunnar Mills if (memoryType == 88313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.SDRAM") 89313efb1cSGunnar Mills { 90313efb1cSGunnar Mills return "SDRAM"; 91313efb1cSGunnar Mills } 92313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.EDO") 93313efb1cSGunnar Mills { 94313efb1cSGunnar Mills return "EDO"; 95313efb1cSGunnar Mills } 96313efb1cSGunnar Mills if (memoryType == 97313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.FastPageMode") 98313efb1cSGunnar Mills { 99313efb1cSGunnar Mills return "FastPageMode"; 100313efb1cSGunnar Mills } 101313efb1cSGunnar Mills if (memoryType == 102313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.PipelinedNibble") 103313efb1cSGunnar Mills { 104313efb1cSGunnar Mills return "PipelinedNibble"; 105313efb1cSGunnar Mills } 106313efb1cSGunnar Mills if (memoryType == 107313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.Logical") 108313efb1cSGunnar Mills { 109313efb1cSGunnar Mills return "Logical"; 110313efb1cSGunnar Mills } 111313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM") 112313efb1cSGunnar Mills { 113313efb1cSGunnar Mills return "HBM"; 114313efb1cSGunnar Mills } 115313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM2") 116313efb1cSGunnar Mills { 117313efb1cSGunnar Mills return "HBM2"; 118313efb1cSGunnar Mills } 119313efb1cSGunnar Mills // This is values like Other or Unknown 120313efb1cSGunnar Mills // Also D-Bus values: 121313efb1cSGunnar Mills // DRAM 122313efb1cSGunnar Mills // EDRAM 123313efb1cSGunnar Mills // VRAM 124313efb1cSGunnar Mills // SRAM 125313efb1cSGunnar Mills // RAM 126313efb1cSGunnar Mills // FLASH 127313efb1cSGunnar Mills // EEPROM 128313efb1cSGunnar Mills // FEPROM 129313efb1cSGunnar Mills // EPROM 130313efb1cSGunnar Mills // CDRAM 131313efb1cSGunnar Mills // ThreeDRAM 132313efb1cSGunnar Mills // RDRAM 133313efb1cSGunnar Mills // FBD2 134313efb1cSGunnar Mills // LPDDR_SDRAM 135313efb1cSGunnar Mills // LPDDR2_SDRAM 13611a2f0f0SMansi Joshi // LPDDR5_SDRAM 137313efb1cSGunnar Mills return ""; 138313efb1cSGunnar Mills } 139313efb1cSGunnar Mills 140168e20c1SEd Tanous inline void dimmPropToHex( 141168e20c1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& aResp, const char* key, 142168e20c1SEd Tanous const std::pair<std::string, dbus::utility::DbusVariantType>& property) 143ac6a4445SGunnar Mills { 144ac6a4445SGunnar Mills const uint16_t* value = std::get_if<uint16_t>(&property.second); 145ac6a4445SGunnar Mills if (value == nullptr) 146ac6a4445SGunnar Mills { 147ac6a4445SGunnar Mills messages::internalError(aResp->res); 148ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for " << property.first; 149ac6a4445SGunnar Mills return; 150ac6a4445SGunnar Mills } 151ac6a4445SGunnar Mills 152866e4862SEd Tanous aResp->res.jsonValue[key] = "0x" + intToHexString(*value, 4); 153ac6a4445SGunnar Mills } 154ac6a4445SGunnar Mills 1558d1b46d7Szhanghch05 inline void getPersistentMemoryProperties( 1568d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aResp, 15780badf7cSJiaqing Zhao const std::pair<std::string, dbus::utility::DbusVariantType>& property) 158ac6a4445SGunnar Mills { 159ac6a4445SGunnar Mills if (property.first == "ModuleManufacturerID") 160ac6a4445SGunnar Mills { 161ac6a4445SGunnar Mills dimmPropToHex(aResp, "ModuleManufacturerID", property); 162ac6a4445SGunnar Mills } 163ac6a4445SGunnar Mills else if (property.first == "ModuleProductID") 164ac6a4445SGunnar Mills { 165ac6a4445SGunnar Mills dimmPropToHex(aResp, "ModuleProductID", property); 166ac6a4445SGunnar Mills } 167ac6a4445SGunnar Mills else if (property.first == "SubsystemVendorID") 168ac6a4445SGunnar Mills { 169ac6a4445SGunnar Mills dimmPropToHex(aResp, "MemorySubsystemControllerManufacturerID", 170ac6a4445SGunnar Mills property); 171ac6a4445SGunnar Mills } 172ac6a4445SGunnar Mills else if (property.first == "SubsystemDeviceID") 173ac6a4445SGunnar Mills { 17480badf7cSJiaqing Zhao dimmPropToHex(aResp, "MemorySubsystemControllerProductID", property); 175ac6a4445SGunnar Mills } 176ac6a4445SGunnar Mills else if (property.first == "VolatileRegionSizeLimitInKiB") 177ac6a4445SGunnar Mills { 178ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 179ac6a4445SGunnar Mills 180ac6a4445SGunnar Mills if (value == nullptr) 181ac6a4445SGunnar Mills { 182ac6a4445SGunnar Mills messages::internalError(aResp->res); 1830fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 1840fda0f12SGeorge Liu << "Invalid property type for VolatileRegionSizeLimitKiB"; 185601af5edSChicago Duan return; 186ac6a4445SGunnar Mills } 187ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileRegionSizeLimitMiB"] = (*value) >> 10; 188ac6a4445SGunnar Mills } 189ac6a4445SGunnar Mills else if (property.first == "PmRegionSizeLimitInKiB") 190ac6a4445SGunnar Mills { 191ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 192ac6a4445SGunnar Mills 193ac6a4445SGunnar Mills if (value == nullptr) 194ac6a4445SGunnar Mills { 195ac6a4445SGunnar Mills messages::internalError(aResp->res); 19680badf7cSJiaqing Zhao BMCWEB_LOG_DEBUG << "Invalid property type for PmRegioSizeLimitKiB"; 197601af5edSChicago Duan return; 198ac6a4445SGunnar Mills } 19980badf7cSJiaqing Zhao aResp->res.jsonValue["PersistentRegionSizeLimitMiB"] = (*value) >> 10; 200ac6a4445SGunnar Mills } 201ac6a4445SGunnar Mills else if (property.first == "VolatileSizeInKiB") 202ac6a4445SGunnar Mills { 203ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 204ac6a4445SGunnar Mills 205ac6a4445SGunnar Mills if (value == nullptr) 206ac6a4445SGunnar Mills { 207ac6a4445SGunnar Mills messages::internalError(aResp->res); 20880badf7cSJiaqing Zhao BMCWEB_LOG_DEBUG << "Invalid property type for VolatileSizeInKiB"; 209601af5edSChicago Duan return; 210ac6a4445SGunnar Mills } 211ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileSizeMiB"] = (*value) >> 10; 212ac6a4445SGunnar Mills } 213ac6a4445SGunnar Mills else if (property.first == "PmSizeInKiB") 214ac6a4445SGunnar Mills { 215ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 216ac6a4445SGunnar Mills if (value == nullptr) 217ac6a4445SGunnar Mills { 218ac6a4445SGunnar Mills messages::internalError(aResp->res); 219ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for PmSizeInKiB"; 220601af5edSChicago Duan return; 221ac6a4445SGunnar Mills } 222ac6a4445SGunnar Mills aResp->res.jsonValue["NonVolatileSizeMiB"] = (*value) >> 10; 223ac6a4445SGunnar Mills } 224ac6a4445SGunnar Mills else if (property.first == "CacheSizeInKB") 225ac6a4445SGunnar Mills { 226ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 227ac6a4445SGunnar Mills if (value == nullptr) 228ac6a4445SGunnar Mills { 229ac6a4445SGunnar Mills messages::internalError(aResp->res); 230ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for CacheSizeInKB"; 231601af5edSChicago Duan return; 232ac6a4445SGunnar Mills } 233ac6a4445SGunnar Mills aResp->res.jsonValue["CacheSizeMiB"] = (*value >> 10); 234ac6a4445SGunnar Mills } 235ac6a4445SGunnar Mills 236ac6a4445SGunnar Mills else if (property.first == "VoltaileRegionMaxSizeInKib") 237ac6a4445SGunnar Mills { 238ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 239ac6a4445SGunnar Mills 240ac6a4445SGunnar Mills if (value == nullptr) 241ac6a4445SGunnar Mills { 242ac6a4445SGunnar Mills messages::internalError(aResp->res); 2430fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 2440fda0f12SGeorge Liu << "Invalid property type for VolatileRegionMaxSizeInKib"; 245601af5edSChicago Duan return; 246ac6a4445SGunnar Mills } 247ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileRegionSizeMaxMiB"] = (*value) >> 10; 248ac6a4445SGunnar Mills } 249ac6a4445SGunnar Mills else if (property.first == "PmRegionMaxSizeInKiB") 250ac6a4445SGunnar Mills { 251ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 252ac6a4445SGunnar Mills 253ac6a4445SGunnar Mills if (value == nullptr) 254ac6a4445SGunnar Mills { 255ac6a4445SGunnar Mills messages::internalError(aResp->res); 256ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 257ac6a4445SGunnar Mills << "Invalid property type for PmRegionMaxSizeInKiB"; 258601af5edSChicago Duan return; 259ac6a4445SGunnar Mills } 260ac6a4445SGunnar Mills aResp->res.jsonValue["PersistentRegionSizeMaxMiB"] = (*value) >> 10; 261ac6a4445SGunnar Mills } 262ac6a4445SGunnar Mills else if (property.first == "AllocationIncrementInKiB") 263ac6a4445SGunnar Mills { 264ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 265ac6a4445SGunnar Mills 266ac6a4445SGunnar Mills if (value == nullptr) 267ac6a4445SGunnar Mills { 268ac6a4445SGunnar Mills messages::internalError(aResp->res); 2690fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 2700fda0f12SGeorge Liu << "Invalid property type for AllocationIncrementInKiB"; 271601af5edSChicago Duan return; 272ac6a4445SGunnar Mills } 273ac6a4445SGunnar Mills aResp->res.jsonValue["AllocationIncrementMiB"] = (*value) >> 10; 274ac6a4445SGunnar Mills } 275ac6a4445SGunnar Mills else if (property.first == "AllocationAlignmentInKiB") 276ac6a4445SGunnar Mills { 277ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 278ac6a4445SGunnar Mills 279ac6a4445SGunnar Mills if (value == nullptr) 280ac6a4445SGunnar Mills { 281ac6a4445SGunnar Mills messages::internalError(aResp->res); 2820fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 2830fda0f12SGeorge Liu << "Invalid property type for AllocationAlignmentInKiB"; 284601af5edSChicago Duan return; 285ac6a4445SGunnar Mills } 286ac6a4445SGunnar Mills aResp->res.jsonValue["AllocationAlignmentMiB"] = (*value) >> 10; 287ac6a4445SGunnar Mills } 288ac6a4445SGunnar Mills else if (property.first == "VolatileRegionNumberLimit") 289ac6a4445SGunnar Mills { 290ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 291ac6a4445SGunnar Mills if (value == nullptr) 292ac6a4445SGunnar Mills { 293ac6a4445SGunnar Mills messages::internalError(aResp->res); 294601af5edSChicago Duan return; 295ac6a4445SGunnar Mills } 296ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileRegionNumberLimit"] = *value; 297ac6a4445SGunnar Mills } 298ac6a4445SGunnar Mills else if (property.first == "PmRegionNumberLimit") 299ac6a4445SGunnar Mills { 300ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 301ac6a4445SGunnar Mills if (value == nullptr) 302ac6a4445SGunnar Mills { 303ac6a4445SGunnar Mills messages::internalError(aResp->res); 304601af5edSChicago Duan return; 305ac6a4445SGunnar Mills } 306ac6a4445SGunnar Mills aResp->res.jsonValue["PersistentRegionNumberLimit"] = *value; 307ac6a4445SGunnar Mills } 308ac6a4445SGunnar Mills else if (property.first == "SpareDeviceCount") 309ac6a4445SGunnar Mills { 310ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 311ac6a4445SGunnar Mills if (value == nullptr) 312ac6a4445SGunnar Mills { 313ac6a4445SGunnar Mills messages::internalError(aResp->res); 314601af5edSChicago Duan return; 315ac6a4445SGunnar Mills } 316ac6a4445SGunnar Mills aResp->res.jsonValue["SpareDeviceCount"] = *value; 317ac6a4445SGunnar Mills } 318ac6a4445SGunnar Mills else if (property.first == "IsSpareDeviceInUse") 319ac6a4445SGunnar Mills { 320ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 321ac6a4445SGunnar Mills if (value == nullptr) 322ac6a4445SGunnar Mills { 323ac6a4445SGunnar Mills messages::internalError(aResp->res); 324601af5edSChicago Duan return; 325ac6a4445SGunnar Mills } 326ac6a4445SGunnar Mills aResp->res.jsonValue["IsSpareDeviceEnabled"] = *value; 327ac6a4445SGunnar Mills } 328ac6a4445SGunnar Mills else if (property.first == "IsRankSpareEnabled") 329ac6a4445SGunnar Mills { 330ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 331ac6a4445SGunnar Mills if (value == nullptr) 332ac6a4445SGunnar Mills { 333ac6a4445SGunnar Mills messages::internalError(aResp->res); 334601af5edSChicago Duan return; 335ac6a4445SGunnar Mills } 336ac6a4445SGunnar Mills aResp->res.jsonValue["IsRankSpareEnabled"] = *value; 337ac6a4445SGunnar Mills } 338ac6a4445SGunnar Mills else if (property.first == "MaxAveragePowerLimitmW") 339ac6a4445SGunnar Mills { 340ac6a4445SGunnar Mills const auto* value = 341ac6a4445SGunnar Mills std::get_if<std::vector<uint32_t>>(&property.second); 342ac6a4445SGunnar Mills if (value == nullptr) 343ac6a4445SGunnar Mills { 344ac6a4445SGunnar Mills messages::internalError(aResp->res); 3450fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 3460fda0f12SGeorge Liu << "Invalid property type for MaxAveragePowerLimitmW"; 347601af5edSChicago Duan return; 348ac6a4445SGunnar Mills } 349ac6a4445SGunnar Mills aResp->res.jsonValue["MaxTDPMilliWatts"] = *value; 350ac6a4445SGunnar Mills } 351ac6a4445SGunnar Mills else if (property.first == "ConfigurationLocked") 352ac6a4445SGunnar Mills { 353ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 354ac6a4445SGunnar Mills if (value == nullptr) 355ac6a4445SGunnar Mills { 356ac6a4445SGunnar Mills messages::internalError(aResp->res); 357601af5edSChicago Duan return; 358ac6a4445SGunnar Mills } 359ac6a4445SGunnar Mills aResp->res.jsonValue["ConfigurationLocked"] = *value; 360ac6a4445SGunnar Mills } 361ac6a4445SGunnar Mills else if (property.first == "AllowedMemoryModes") 362ac6a4445SGunnar Mills { 36380badf7cSJiaqing Zhao const std::string* value = std::get_if<std::string>(&property.second); 364ac6a4445SGunnar Mills if (value == nullptr) 365ac6a4445SGunnar Mills { 366ac6a4445SGunnar Mills messages::internalError(aResp->res); 367ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for FormFactor"; 368601af5edSChicago Duan return; 369ac6a4445SGunnar Mills } 37080badf7cSJiaqing Zhao constexpr const std::array<const char*, 3> values{"Volatile", "PMEM", 37180badf7cSJiaqing Zhao "Block"}; 372ac6a4445SGunnar Mills 373ac6a4445SGunnar Mills for (const char* v : values) 374ac6a4445SGunnar Mills { 375ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 376ac6a4445SGunnar Mills { 3771e04f3b2SJiaqing Zhao aResp->res.jsonValue["OperatingMemoryModes"].push_back(v); 378ac6a4445SGunnar Mills break; 379ac6a4445SGunnar Mills } 380ac6a4445SGunnar Mills } 381ac6a4445SGunnar Mills } 382ac6a4445SGunnar Mills else if (property.first == "MemoryMedia") 383ac6a4445SGunnar Mills { 38480badf7cSJiaqing Zhao const std::string* value = std::get_if<std::string>(&property.second); 385ac6a4445SGunnar Mills if (value == nullptr) 386ac6a4445SGunnar Mills { 387ac6a4445SGunnar Mills messages::internalError(aResp->res); 388ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for MemoryMedia"; 389601af5edSChicago Duan return; 390ac6a4445SGunnar Mills } 391ac6a4445SGunnar Mills constexpr const std::array<const char*, 3> values{"DRAM", "NAND", 392ac6a4445SGunnar Mills "Intel3DXPoint"}; 393ac6a4445SGunnar Mills 394ac6a4445SGunnar Mills for (const char* v : values) 395ac6a4445SGunnar Mills { 396ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 397ac6a4445SGunnar Mills { 3981e04f3b2SJiaqing Zhao aResp->res.jsonValue["MemoryMedia"].push_back(v); 399ac6a4445SGunnar Mills break; 400ac6a4445SGunnar Mills } 401ac6a4445SGunnar Mills } 402ac6a4445SGunnar Mills } 403ac6a4445SGunnar Mills // PersistantMemory.SecurityCapabilites interface 404ac6a4445SGunnar Mills else if (property.first == "ConfigurationLockCapable" || 405ac6a4445SGunnar Mills property.first == "DataLockCapable" || 406ac6a4445SGunnar Mills property.first == "PassphraseCapable") 407ac6a4445SGunnar Mills { 408ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 409ac6a4445SGunnar Mills if (value == nullptr) 410ac6a4445SGunnar Mills { 411ac6a4445SGunnar Mills messages::internalError(aResp->res); 412601af5edSChicago Duan return; 413ac6a4445SGunnar Mills } 41480badf7cSJiaqing Zhao aResp->res.jsonValue["SecurityCapabilities"][property.first] = *value; 415ac6a4445SGunnar Mills } 416ac6a4445SGunnar Mills else if (property.first == "MaxPassphraseCount" || 417ac6a4445SGunnar Mills property.first == "PassphraseLockLimit") 418ac6a4445SGunnar Mills { 419ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 420ac6a4445SGunnar Mills if (value == nullptr) 421ac6a4445SGunnar Mills { 422ac6a4445SGunnar Mills messages::internalError(aResp->res); 423601af5edSChicago Duan return; 424ac6a4445SGunnar Mills } 42580badf7cSJiaqing Zhao aResp->res.jsonValue["SecurityCapabilities"][property.first] = *value; 426ac6a4445SGunnar Mills } 427ac6a4445SGunnar Mills } 428ac6a4445SGunnar Mills 4298d1b46d7Szhanghch05 inline void getDimmDataByService(std::shared_ptr<bmcweb::AsyncResp> aResp, 430ac6a4445SGunnar Mills const std::string& dimmId, 431ac6a4445SGunnar Mills const std::string& service, 432ac6a4445SGunnar Mills const std::string& objPath) 433ac6a4445SGunnar Mills { 434ac6a4445SGunnar Mills auto health = std::make_shared<HealthPopulate>(aResp); 435ac6a4445SGunnar Mills health->selfPath = objPath; 436ac6a4445SGunnar Mills health->populate(); 437ac6a4445SGunnar Mills 438ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Get available system components."; 439ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 440b9d36b47SEd Tanous [dimmId, aResp{std::move(aResp)}]( 441b9d36b47SEd Tanous const boost::system::error_code ec, 442b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 443ac6a4445SGunnar Mills if (ec) 444ac6a4445SGunnar Mills { 445ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 446ac6a4445SGunnar Mills messages::internalError(aResp->res); 447ac6a4445SGunnar Mills return; 448ac6a4445SGunnar Mills } 449ac6a4445SGunnar Mills aResp->res.jsonValue["Id"] = dimmId; 450ac6a4445SGunnar Mills aResp->res.jsonValue["Name"] = "DIMM Slot"; 451ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["State"] = "Enabled"; 452ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["Health"] = "OK"; 453ac6a4445SGunnar Mills 454ac6a4445SGunnar Mills for (const auto& property : properties) 455ac6a4445SGunnar Mills { 456ac6a4445SGunnar Mills if (property.first == "MemoryDataWidth") 457ac6a4445SGunnar Mills { 458ac6a4445SGunnar Mills const uint16_t* value = 459ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 460ac6a4445SGunnar Mills if (value == nullptr) 461ac6a4445SGunnar Mills { 462ac6a4445SGunnar Mills continue; 463ac6a4445SGunnar Mills } 464ac6a4445SGunnar Mills aResp->res.jsonValue["DataWidthBits"] = *value; 465ac6a4445SGunnar Mills } 466b9d36b47SEd Tanous else if (property.first == "MemorySizeInKB") 467b9d36b47SEd Tanous { 468b9d36b47SEd Tanous const uint32_t* memorySize = 469b9d36b47SEd Tanous std::get_if<uint32_t>(&property.second); 470b9d36b47SEd Tanous if (memorySize == nullptr) 471b9d36b47SEd Tanous { 472b9d36b47SEd Tanous // Important property not in desired type 473b9d36b47SEd Tanous messages::internalError(aResp->res); 474b9d36b47SEd Tanous return; 475b9d36b47SEd Tanous } 476b9d36b47SEd Tanous aResp->res.jsonValue["CapacityMiB"] = (*memorySize >> 10); 477b9d36b47SEd Tanous } 478ac6a4445SGunnar Mills else if (property.first == "PartNumber") 479ac6a4445SGunnar Mills { 480ac6a4445SGunnar Mills const std::string* value = 481ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 482ac6a4445SGunnar Mills if (value == nullptr) 483ac6a4445SGunnar Mills { 484ac6a4445SGunnar Mills continue; 485ac6a4445SGunnar Mills } 486ac6a4445SGunnar Mills aResp->res.jsonValue["PartNumber"] = *value; 487ac6a4445SGunnar Mills } 488ac6a4445SGunnar Mills else if (property.first == "SerialNumber") 489ac6a4445SGunnar Mills { 490ac6a4445SGunnar Mills const std::string* value = 491ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 492ac6a4445SGunnar Mills if (value == nullptr) 493ac6a4445SGunnar Mills { 494ac6a4445SGunnar Mills continue; 495ac6a4445SGunnar Mills } 496ac6a4445SGunnar Mills aResp->res.jsonValue["SerialNumber"] = *value; 497ac6a4445SGunnar Mills } 498ac6a4445SGunnar Mills else if (property.first == "Manufacturer") 499ac6a4445SGunnar Mills { 500ac6a4445SGunnar Mills const std::string* value = 501ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 502ac6a4445SGunnar Mills if (value == nullptr) 503ac6a4445SGunnar Mills { 504ac6a4445SGunnar Mills continue; 505ac6a4445SGunnar Mills } 506ac6a4445SGunnar Mills aResp->res.jsonValue["Manufacturer"] = *value; 507ac6a4445SGunnar Mills } 508ac6a4445SGunnar Mills else if (property.first == "RevisionCode") 509ac6a4445SGunnar Mills { 510ac6a4445SGunnar Mills const uint16_t* value = 511ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 512ac6a4445SGunnar Mills 513ac6a4445SGunnar Mills if (value == nullptr) 514ac6a4445SGunnar Mills { 515ac6a4445SGunnar Mills messages::internalError(aResp->res); 516ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 517ac6a4445SGunnar Mills << "Invalid property type for RevisionCode"; 518601af5edSChicago Duan return; 519ac6a4445SGunnar Mills } 520ac6a4445SGunnar Mills aResp->res.jsonValue["FirmwareRevision"] = 521ac6a4445SGunnar Mills std::to_string(*value); 522ac6a4445SGunnar Mills } 5239a128eb3SJoshi-Mansi else if (property.first == "Present") 5249a128eb3SJoshi-Mansi { 5259a128eb3SJoshi-Mansi const bool* value = std::get_if<bool>(&property.second); 5269a128eb3SJoshi-Mansi if (value == nullptr) 5279a128eb3SJoshi-Mansi { 5289a128eb3SJoshi-Mansi messages::internalError(aResp->res); 5299a128eb3SJoshi-Mansi BMCWEB_LOG_DEBUG 5309a128eb3SJoshi-Mansi << "Invalid property type for Dimm Presence"; 5319a128eb3SJoshi-Mansi return; 5329a128eb3SJoshi-Mansi } 533e05aec50SEd Tanous if (!*value) 5349a128eb3SJoshi-Mansi { 5359a128eb3SJoshi-Mansi aResp->res.jsonValue["Status"]["State"] = "Absent"; 5369a128eb3SJoshi-Mansi } 5379a128eb3SJoshi-Mansi } 538ac6a4445SGunnar Mills else if (property.first == "MemoryTotalWidth") 539ac6a4445SGunnar Mills { 540ac6a4445SGunnar Mills const uint16_t* value = 541ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 542ac6a4445SGunnar Mills if (value == nullptr) 543ac6a4445SGunnar Mills { 544ac6a4445SGunnar Mills continue; 545ac6a4445SGunnar Mills } 546ac6a4445SGunnar Mills aResp->res.jsonValue["BusWidthBits"] = *value; 547ac6a4445SGunnar Mills } 548ac6a4445SGunnar Mills else if (property.first == "ECC") 549ac6a4445SGunnar Mills { 550ac6a4445SGunnar Mills const std::string* value = 551ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 552ac6a4445SGunnar Mills if (value == nullptr) 553ac6a4445SGunnar Mills { 554ac6a4445SGunnar Mills messages::internalError(aResp->res); 555ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for ECC"; 556601af5edSChicago Duan return; 557ac6a4445SGunnar Mills } 558ac6a4445SGunnar Mills constexpr const std::array<const char*, 4> values{ 559ac6a4445SGunnar Mills "NoECC", "SingleBitECC", "MultiBitECC", 560ac6a4445SGunnar Mills "AddressParity"}; 561ac6a4445SGunnar Mills 562ac6a4445SGunnar Mills for (const char* v : values) 563ac6a4445SGunnar Mills { 564ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 565ac6a4445SGunnar Mills { 566ac6a4445SGunnar Mills aResp->res.jsonValue["ErrorCorrection"] = v; 567ac6a4445SGunnar Mills break; 568ac6a4445SGunnar Mills } 569ac6a4445SGunnar Mills } 570ac6a4445SGunnar Mills } 571ac6a4445SGunnar Mills else if (property.first == "FormFactor") 572ac6a4445SGunnar Mills { 573ac6a4445SGunnar Mills const std::string* value = 574ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 575ac6a4445SGunnar Mills if (value == nullptr) 576ac6a4445SGunnar Mills { 577ac6a4445SGunnar Mills messages::internalError(aResp->res); 578ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 579ac6a4445SGunnar Mills << "Invalid property type for FormFactor"; 580601af5edSChicago Duan return; 581ac6a4445SGunnar Mills } 582ac6a4445SGunnar Mills constexpr const std::array<const char*, 11> values{ 583ac6a4445SGunnar Mills "RDIMM", "UDIMM", "SO_DIMM", 584ac6a4445SGunnar Mills "LRDIMM", "Mini_RDIMM", "Mini_UDIMM", 585ac6a4445SGunnar Mills "SO_RDIMM_72b", "SO_UDIMM_72b", "SO_DIMM_16b", 586ac6a4445SGunnar Mills "SO_DIMM_32b", "Die"}; 587ac6a4445SGunnar Mills 588ac6a4445SGunnar Mills for (const char* v : values) 589ac6a4445SGunnar Mills { 590ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 591ac6a4445SGunnar Mills { 592ac6a4445SGunnar Mills aResp->res.jsonValue["BaseModuleType"] = v; 593ac6a4445SGunnar Mills break; 594ac6a4445SGunnar Mills } 595ac6a4445SGunnar Mills } 596ac6a4445SGunnar Mills } 597ac6a4445SGunnar Mills else if (property.first == "AllowedSpeedsMT") 598ac6a4445SGunnar Mills { 599ac6a4445SGunnar Mills const std::vector<uint16_t>* value = 600ac6a4445SGunnar Mills std::get_if<std::vector<uint16_t>>(&property.second); 601ac6a4445SGunnar Mills if (value == nullptr) 602ac6a4445SGunnar Mills { 603ac6a4445SGunnar Mills continue; 604ac6a4445SGunnar Mills } 605ac6a4445SGunnar Mills nlohmann::json& jValue = 606ac6a4445SGunnar Mills aResp->res.jsonValue["AllowedSpeedsMHz"]; 607ac6a4445SGunnar Mills jValue = nlohmann::json::array(); 608ac6a4445SGunnar Mills for (uint16_t subVal : *value) 609ac6a4445SGunnar Mills { 610ac6a4445SGunnar Mills jValue.push_back(subVal); 611ac6a4445SGunnar Mills } 612ac6a4445SGunnar Mills } 613ac6a4445SGunnar Mills else if (property.first == "MemoryAttributes") 614ac6a4445SGunnar Mills { 615ac6a4445SGunnar Mills const uint8_t* value = 616ac6a4445SGunnar Mills std::get_if<uint8_t>(&property.second); 617ac6a4445SGunnar Mills 618ac6a4445SGunnar Mills if (value == nullptr) 619ac6a4445SGunnar Mills { 620ac6a4445SGunnar Mills messages::internalError(aResp->res); 621ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 622ac6a4445SGunnar Mills << "Invalid property type for MemoryAttributes"; 623601af5edSChicago Duan return; 624ac6a4445SGunnar Mills } 625ac6a4445SGunnar Mills aResp->res.jsonValue["RankCount"] = 626ac6a4445SGunnar Mills static_cast<uint64_t>(*value); 627ac6a4445SGunnar Mills } 628ac6a4445SGunnar Mills else if (property.first == "MemoryConfiguredSpeedInMhz") 629ac6a4445SGunnar Mills { 630ac6a4445SGunnar Mills const uint16_t* value = 631ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 632ac6a4445SGunnar Mills if (value == nullptr) 633ac6a4445SGunnar Mills { 634ac6a4445SGunnar Mills continue; 635ac6a4445SGunnar Mills } 636ac6a4445SGunnar Mills aResp->res.jsonValue["OperatingSpeedMhz"] = *value; 637ac6a4445SGunnar Mills } 638ac6a4445SGunnar Mills else if (property.first == "MemoryType") 639ac6a4445SGunnar Mills { 640ac6a4445SGunnar Mills const auto* value = 641ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 642ac6a4445SGunnar Mills if (value != nullptr) 643ac6a4445SGunnar Mills { 644313efb1cSGunnar Mills std::string memoryDeviceType = 645313efb1cSGunnar Mills translateMemoryTypeToRedfish(*value); 646313efb1cSGunnar Mills // Values like "Unknown" or "Other" will return empty 647313efb1cSGunnar Mills // so just leave off 648313efb1cSGunnar Mills if (!memoryDeviceType.empty()) 649ac6a4445SGunnar Mills { 650313efb1cSGunnar Mills aResp->res.jsonValue["MemoryDeviceType"] = 651313efb1cSGunnar Mills memoryDeviceType; 652ac6a4445SGunnar Mills } 653ac6a4445SGunnar Mills if (value->find("DDR") != std::string::npos) 654ac6a4445SGunnar Mills { 655ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryType"] = "DRAM"; 656ac6a4445SGunnar Mills } 657ac6a4445SGunnar Mills else if (boost::ends_with(*value, "Logical")) 658ac6a4445SGunnar Mills { 659ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryType"] = "IntelOptane"; 660ac6a4445SGunnar Mills } 661ac6a4445SGunnar Mills } 662ac6a4445SGunnar Mills } 663ac6a4445SGunnar Mills // memory location interface 664ac6a4445SGunnar Mills else if (property.first == "Channel" || 665ac6a4445SGunnar Mills property.first == "MemoryController" || 666ac6a4445SGunnar Mills property.first == "Slot" || property.first == "Socket") 667ac6a4445SGunnar Mills { 668ac6a4445SGunnar Mills const std::string* value = 669ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 670ac6a4445SGunnar Mills if (value == nullptr) 671ac6a4445SGunnar Mills { 672ac6a4445SGunnar Mills messages::internalError(aResp->res); 673601af5edSChicago Duan return; 674ac6a4445SGunnar Mills } 675ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryLocation"][property.first] = 676ac6a4445SGunnar Mills *value; 677ac6a4445SGunnar Mills } 678ee135e24SSunnySrivastava1984 else if (property.first == "SparePartNumber") 679ee135e24SSunnySrivastava1984 { 680ee135e24SSunnySrivastava1984 const std::string* value = 681ee135e24SSunnySrivastava1984 std::get_if<std::string>(&property.second); 682ee135e24SSunnySrivastava1984 if (value == nullptr) 683ee135e24SSunnySrivastava1984 { 684ee135e24SSunnySrivastava1984 messages::internalError(aResp->res); 685601af5edSChicago Duan return; 686ee135e24SSunnySrivastava1984 } 687ee135e24SSunnySrivastava1984 aResp->res.jsonValue["SparePartNumber"] = *value; 688ee135e24SSunnySrivastava1984 } 689ee135e24SSunnySrivastava1984 else if (property.first == "Model") 690ee135e24SSunnySrivastava1984 { 691ee135e24SSunnySrivastava1984 const std::string* value = 692ee135e24SSunnySrivastava1984 std::get_if<std::string>(&property.second); 693ee135e24SSunnySrivastava1984 if (value == nullptr) 694ee135e24SSunnySrivastava1984 { 695ee135e24SSunnySrivastava1984 messages::internalError(aResp->res); 696601af5edSChicago Duan return; 697ee135e24SSunnySrivastava1984 } 698ee135e24SSunnySrivastava1984 aResp->res.jsonValue["Model"] = *value; 699ee135e24SSunnySrivastava1984 } 700ee135e24SSunnySrivastava1984 else if (property.first == "LocationCode") 701ee135e24SSunnySrivastava1984 { 702ee135e24SSunnySrivastava1984 const std::string* value = 703ee135e24SSunnySrivastava1984 std::get_if<std::string>(&property.second); 704ee135e24SSunnySrivastava1984 if (value == nullptr) 705ee135e24SSunnySrivastava1984 { 706ee135e24SSunnySrivastava1984 messages::internalError(aResp->res); 707601af5edSChicago Duan return; 708ee135e24SSunnySrivastava1984 } 709ee135e24SSunnySrivastava1984 aResp->res 710ee135e24SSunnySrivastava1984 .jsonValue["Location"]["PartLocation"]["ServiceLabel"] = 711ee135e24SSunnySrivastava1984 *value; 712ee135e24SSunnySrivastava1984 } 713ac6a4445SGunnar Mills else 714ac6a4445SGunnar Mills { 71580badf7cSJiaqing Zhao getPersistentMemoryProperties(aResp, property); 716ac6a4445SGunnar Mills } 717ac6a4445SGunnar Mills } 718ac6a4445SGunnar Mills }, 719ac6a4445SGunnar Mills service, objPath, "org.freedesktop.DBus.Properties", "GetAll", ""); 720ac6a4445SGunnar Mills } 721ac6a4445SGunnar Mills 7228d1b46d7Szhanghch05 inline void getDimmPartitionData(std::shared_ptr<bmcweb::AsyncResp> aResp, 723ac6a4445SGunnar Mills const std::string& service, 724ac6a4445SGunnar Mills const std::string& path) 725ac6a4445SGunnar Mills { 726ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 727ac6a4445SGunnar Mills [aResp{std::move(aResp)}]( 728ac6a4445SGunnar Mills const boost::system::error_code ec, 729b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 730ac6a4445SGunnar Mills if (ec) 731ac6a4445SGunnar Mills { 732ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 733ac6a4445SGunnar Mills messages::internalError(aResp->res); 734ac6a4445SGunnar Mills 735ac6a4445SGunnar Mills return; 736ac6a4445SGunnar Mills } 737ac6a4445SGunnar Mills 738ac6a4445SGunnar Mills nlohmann::json& partition = 739ac6a4445SGunnar Mills aResp->res.jsonValue["Regions"].emplace_back( 740ac6a4445SGunnar Mills nlohmann::json::object()); 741ac6a4445SGunnar Mills for (const auto& [key, val] : properties) 742ac6a4445SGunnar Mills { 743ac6a4445SGunnar Mills if (key == "MemoryClassification") 744ac6a4445SGunnar Mills { 745ac6a4445SGunnar Mills const std::string* value = std::get_if<std::string>(&val); 746ac6a4445SGunnar Mills if (value == nullptr) 747ac6a4445SGunnar Mills { 748ac6a4445SGunnar Mills messages::internalError(aResp->res); 749601af5edSChicago Duan return; 750ac6a4445SGunnar Mills } 751ac6a4445SGunnar Mills partition[key] = *value; 752ac6a4445SGunnar Mills } 753ac6a4445SGunnar Mills else if (key == "OffsetInKiB") 754ac6a4445SGunnar Mills { 755ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&val); 756ac6a4445SGunnar Mills if (value == nullptr) 757ac6a4445SGunnar Mills { 758ac6a4445SGunnar Mills messages::internalError(aResp->res); 759601af5edSChicago Duan return; 760ac6a4445SGunnar Mills } 761ac6a4445SGunnar Mills 762ac6a4445SGunnar Mills partition["OffsetMiB"] = (*value >> 10); 763ac6a4445SGunnar Mills } 764ac6a4445SGunnar Mills else if (key == "PartitionId") 765ac6a4445SGunnar Mills { 766ac6a4445SGunnar Mills const std::string* value = std::get_if<std::string>(&val); 767ac6a4445SGunnar Mills if (value == nullptr) 768ac6a4445SGunnar Mills { 769ac6a4445SGunnar Mills messages::internalError(aResp->res); 770601af5edSChicago Duan return; 771ac6a4445SGunnar Mills } 772ac6a4445SGunnar Mills partition["RegionId"] = *value; 773ac6a4445SGunnar Mills } 774ac6a4445SGunnar Mills 775ac6a4445SGunnar Mills else if (key == "PassphraseState") 776ac6a4445SGunnar Mills { 777ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&val); 778ac6a4445SGunnar Mills if (value == nullptr) 779ac6a4445SGunnar Mills { 780ac6a4445SGunnar Mills messages::internalError(aResp->res); 781601af5edSChicago Duan return; 782ac6a4445SGunnar Mills } 783ac6a4445SGunnar Mills partition["PassphraseEnabled"] = *value; 784ac6a4445SGunnar Mills } 785ac6a4445SGunnar Mills else if (key == "SizeInKiB") 786ac6a4445SGunnar Mills { 787ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&val); 788ac6a4445SGunnar Mills if (value == nullptr) 789ac6a4445SGunnar Mills { 790ac6a4445SGunnar Mills messages::internalError(aResp->res); 791ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 792ac6a4445SGunnar Mills << "Invalid property type for SizeInKiB"; 793601af5edSChicago Duan return; 794ac6a4445SGunnar Mills } 795ac6a4445SGunnar Mills partition["SizeMiB"] = (*value >> 10); 796ac6a4445SGunnar Mills } 797ac6a4445SGunnar Mills } 798ac6a4445SGunnar Mills }, 799ac6a4445SGunnar Mills 800ac6a4445SGunnar Mills service, path, "org.freedesktop.DBus.Properties", "GetAll", 801ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"); 802ac6a4445SGunnar Mills } 803ac6a4445SGunnar Mills 8048d1b46d7Szhanghch05 inline void getDimmData(std::shared_ptr<bmcweb::AsyncResp> aResp, 805ac6a4445SGunnar Mills const std::string& dimmId) 806ac6a4445SGunnar Mills { 807ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Get available system dimm resources."; 808ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 809ac6a4445SGunnar Mills [dimmId, aResp{std::move(aResp)}]( 810ac6a4445SGunnar Mills const boost::system::error_code ec, 811b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 812ac6a4445SGunnar Mills if (ec) 813ac6a4445SGunnar Mills { 814ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 815ac6a4445SGunnar Mills messages::internalError(aResp->res); 816ac6a4445SGunnar Mills 817ac6a4445SGunnar Mills return; 818ac6a4445SGunnar Mills } 819ac6a4445SGunnar Mills bool found = false; 820ac6a4445SGunnar Mills for (const auto& [path, object] : subtree) 821ac6a4445SGunnar Mills { 822ac6a4445SGunnar Mills if (path.find(dimmId) != std::string::npos) 823ac6a4445SGunnar Mills { 824ac6a4445SGunnar Mills for (const auto& [service, interfaces] : object) 825ac6a4445SGunnar Mills { 826b9d36b47SEd Tanous for (const auto& interface : interfaces) 827ac6a4445SGunnar Mills { 828b9d36b47SEd Tanous if (interface == 829b9d36b47SEd Tanous "xyz.openbmc_project.Inventory.Item.Dimm") 830b9d36b47SEd Tanous { 831b9d36b47SEd Tanous getDimmDataByService(aResp, dimmId, service, 832b9d36b47SEd Tanous path); 833ac6a4445SGunnar Mills found = true; 834ac6a4445SGunnar Mills } 835ac6a4445SGunnar Mills 836b9d36b47SEd Tanous // partitions are separate as there can be multiple 837b9d36b47SEd Tanous // per 838ac6a4445SGunnar Mills // device, i.e. 839ac6a4445SGunnar Mills // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1 840ac6a4445SGunnar Mills // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2 841b9d36b47SEd Tanous if (interface == 842b9d36b47SEd Tanous "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition") 843ac6a4445SGunnar Mills { 844ac6a4445SGunnar Mills getDimmPartitionData(aResp, service, path); 845ac6a4445SGunnar Mills } 846ac6a4445SGunnar Mills } 847ac6a4445SGunnar Mills } 848ac6a4445SGunnar Mills } 849b9d36b47SEd Tanous } 850ac6a4445SGunnar Mills // Object not found 851ac6a4445SGunnar Mills if (!found) 852ac6a4445SGunnar Mills { 853ac6a4445SGunnar Mills messages::resourceNotFound(aResp->res, "Memory", dimmId); 854ac6a4445SGunnar Mills } 855ac6a4445SGunnar Mills return; 856ac6a4445SGunnar Mills }, 857ac6a4445SGunnar Mills "xyz.openbmc_project.ObjectMapper", 858ac6a4445SGunnar Mills "/xyz/openbmc_project/object_mapper", 859ac6a4445SGunnar Mills "xyz.openbmc_project.ObjectMapper", "GetSubTree", 860ac6a4445SGunnar Mills "/xyz/openbmc_project/inventory", 0, 861ac6a4445SGunnar Mills std::array<const char*, 2>{ 862ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm", 863ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"}); 864ac6a4445SGunnar Mills } 865ac6a4445SGunnar Mills 8667e860f15SJohn Edward Broadbent inline void requestRoutesMemoryCollection(App& app) 867ac6a4445SGunnar Mills { 868ac6a4445SGunnar Mills /** 869ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 870ac6a4445SGunnar Mills */ 8717e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Memory/") 872ed398213SEd Tanous .privileges(redfish::privileges::getMemoryCollection) 8737e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 874*45ca1b86SEd Tanous [&app](const crow::Request& req, 8757e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 876*45ca1b86SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp->res)) 877*45ca1b86SEd Tanous { 878*45ca1b86SEd Tanous return; 879*45ca1b86SEd Tanous } 8808d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 8818d1b46d7Szhanghch05 "#MemoryCollection.MemoryCollection"; 8828d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Memory Module Collection"; 8838d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = 8848d1b46d7Szhanghch05 "/redfish/v1/Systems/system/Memory"; 885ac6a4445SGunnar Mills 88605030b8eSGunnar Mills collection_util::getCollectionMembers( 88705030b8eSGunnar Mills asyncResp, "/redfish/v1/Systems/system/Memory", 88805030b8eSGunnar Mills {"xyz.openbmc_project.Inventory.Item.Dimm"}); 8897e860f15SJohn Edward Broadbent }); 890ac6a4445SGunnar Mills } 891ac6a4445SGunnar Mills 8927e860f15SJohn Edward Broadbent inline void requestRoutesMemory(App& app) 8937e860f15SJohn Edward Broadbent { 894ac6a4445SGunnar Mills /** 895ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 896ac6a4445SGunnar Mills */ 8977e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Memory/<str>/") 898ed398213SEd Tanous .privileges(redfish::privileges::getMemory) 8997e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 900*45ca1b86SEd Tanous [&app](const crow::Request& req, 9017e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 9027e860f15SJohn Edward Broadbent const std::string& dimmId) { 903*45ca1b86SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp->res)) 904*45ca1b86SEd Tanous { 905*45ca1b86SEd Tanous return; 906*45ca1b86SEd Tanous } 9077e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["@odata.type"] = 9087e860f15SJohn Edward Broadbent "#Memory.v1_11_0.Memory"; 9098d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = 910ac6a4445SGunnar Mills "/redfish/v1/Systems/system/Memory/" + dimmId; 911ac6a4445SGunnar Mills 912ac6a4445SGunnar Mills getDimmData(asyncResp, dimmId); 9137e860f15SJohn Edward Broadbent }); 914ac6a4445SGunnar Mills } 915ac6a4445SGunnar Mills 916ac6a4445SGunnar Mills } // namespace redfish 917