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> 22ed398213SEd Tanous #include <registries/privilege_registry.hpp> 23ac6a4445SGunnar Mills #include <utils/collection.hpp> 24f201ffb4SEd Tanous #include <utils/hex_utils.hpp> 25ac6a4445SGunnar Mills #include <utils/json_utils.hpp> 26ac6a4445SGunnar Mills 27ac6a4445SGunnar Mills namespace redfish 28ac6a4445SGunnar Mills { 29ac6a4445SGunnar Mills 30313efb1cSGunnar Mills inline std::string translateMemoryTypeToRedfish(const std::string& memoryType) 31313efb1cSGunnar Mills { 32313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR") 33313efb1cSGunnar Mills { 34313efb1cSGunnar Mills return "DDR"; 35313efb1cSGunnar Mills } 36313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2") 37313efb1cSGunnar Mills { 38313efb1cSGunnar Mills return "DDR2"; 39313efb1cSGunnar Mills } 40313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR3") 41313efb1cSGunnar Mills { 42313efb1cSGunnar Mills return "DDR3"; 43313efb1cSGunnar Mills } 44313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4") 45313efb1cSGunnar Mills { 46313efb1cSGunnar Mills return "DDR4"; 47313efb1cSGunnar Mills } 48313efb1cSGunnar Mills if (memoryType == 49313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4E_SDRAM") 50313efb1cSGunnar Mills { 51313efb1cSGunnar Mills return "DDR4E_SDRAM"; 52313efb1cSGunnar Mills } 5311a2f0f0SMansi Joshi if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR5") 5411a2f0f0SMansi Joshi { 5511a2f0f0SMansi Joshi return "DDR5"; 5611a2f0f0SMansi Joshi } 57313efb1cSGunnar Mills if (memoryType == 58313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR4_SDRAM") 59313efb1cSGunnar Mills { 60313efb1cSGunnar Mills return "LPDDR4_SDRAM"; 61313efb1cSGunnar Mills } 62313efb1cSGunnar Mills if (memoryType == 63313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR3_SDRAM") 64313efb1cSGunnar Mills { 65313efb1cSGunnar Mills return "LPDDR3_SDRAM"; 66313efb1cSGunnar Mills } 67313efb1cSGunnar Mills if (memoryType == 68313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM") 69313efb1cSGunnar Mills { 70313efb1cSGunnar Mills return "DDR2_SDRAM_FB_DIMM"; 71313efb1cSGunnar Mills } 720fda0f12SGeorge Liu if (memoryType == 730fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM_PROB") 74313efb1cSGunnar Mills { 75313efb1cSGunnar Mills return "DDR2_SDRAM_FB_DIMM_PROBE"; 76313efb1cSGunnar Mills } 77313efb1cSGunnar Mills if (memoryType == 78313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR_SGRAM") 79313efb1cSGunnar Mills { 80313efb1cSGunnar Mills return "DDR_SGRAM"; 81313efb1cSGunnar Mills } 82313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.ROM") 83313efb1cSGunnar Mills { 84313efb1cSGunnar Mills return "ROM"; 85313efb1cSGunnar Mills } 86313efb1cSGunnar Mills if (memoryType == 87313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.SDRAM") 88313efb1cSGunnar Mills { 89313efb1cSGunnar Mills return "SDRAM"; 90313efb1cSGunnar Mills } 91313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.EDO") 92313efb1cSGunnar Mills { 93313efb1cSGunnar Mills return "EDO"; 94313efb1cSGunnar Mills } 95313efb1cSGunnar Mills if (memoryType == 96313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.FastPageMode") 97313efb1cSGunnar Mills { 98313efb1cSGunnar Mills return "FastPageMode"; 99313efb1cSGunnar Mills } 100313efb1cSGunnar Mills if (memoryType == 101313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.PipelinedNibble") 102313efb1cSGunnar Mills { 103313efb1cSGunnar Mills return "PipelinedNibble"; 104313efb1cSGunnar Mills } 105313efb1cSGunnar Mills if (memoryType == 106313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.Logical") 107313efb1cSGunnar Mills { 108313efb1cSGunnar Mills return "Logical"; 109313efb1cSGunnar Mills } 110313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM") 111313efb1cSGunnar Mills { 112313efb1cSGunnar Mills return "HBM"; 113313efb1cSGunnar Mills } 114313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM2") 115313efb1cSGunnar Mills { 116313efb1cSGunnar Mills return "HBM2"; 117313efb1cSGunnar Mills } 118313efb1cSGunnar Mills // This is values like Other or Unknown 119313efb1cSGunnar Mills // Also D-Bus values: 120313efb1cSGunnar Mills // DRAM 121313efb1cSGunnar Mills // EDRAM 122313efb1cSGunnar Mills // VRAM 123313efb1cSGunnar Mills // SRAM 124313efb1cSGunnar Mills // RAM 125313efb1cSGunnar Mills // FLASH 126313efb1cSGunnar Mills // EEPROM 127313efb1cSGunnar Mills // FEPROM 128313efb1cSGunnar Mills // EPROM 129313efb1cSGunnar Mills // CDRAM 130313efb1cSGunnar Mills // ThreeDRAM 131313efb1cSGunnar Mills // RDRAM 132313efb1cSGunnar Mills // FBD2 133313efb1cSGunnar Mills // LPDDR_SDRAM 134313efb1cSGunnar Mills // LPDDR2_SDRAM 13511a2f0f0SMansi Joshi // LPDDR5_SDRAM 136313efb1cSGunnar Mills return ""; 137313efb1cSGunnar Mills } 138313efb1cSGunnar Mills 139168e20c1SEd Tanous inline void dimmPropToHex( 140168e20c1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& aResp, const char* key, 141168e20c1SEd Tanous const std::pair<std::string, dbus::utility::DbusVariantType>& property) 142ac6a4445SGunnar Mills { 143ac6a4445SGunnar Mills const uint16_t* value = std::get_if<uint16_t>(&property.second); 144ac6a4445SGunnar Mills if (value == nullptr) 145ac6a4445SGunnar Mills { 146ac6a4445SGunnar Mills messages::internalError(aResp->res); 147ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for " << property.first; 148ac6a4445SGunnar Mills return; 149ac6a4445SGunnar Mills } 150ac6a4445SGunnar Mills 151866e4862SEd Tanous aResp->res.jsonValue[key] = "0x" + intToHexString(*value, 4); 152ac6a4445SGunnar Mills } 153ac6a4445SGunnar Mills 1548d1b46d7Szhanghch05 inline void getPersistentMemoryProperties( 1558d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aResp, 15680badf7cSJiaqing Zhao const std::pair<std::string, dbus::utility::DbusVariantType>& property) 157ac6a4445SGunnar Mills { 158ac6a4445SGunnar Mills if (property.first == "ModuleManufacturerID") 159ac6a4445SGunnar Mills { 160ac6a4445SGunnar Mills dimmPropToHex(aResp, "ModuleManufacturerID", property); 161ac6a4445SGunnar Mills } 162ac6a4445SGunnar Mills else if (property.first == "ModuleProductID") 163ac6a4445SGunnar Mills { 164ac6a4445SGunnar Mills dimmPropToHex(aResp, "ModuleProductID", property); 165ac6a4445SGunnar Mills } 166ac6a4445SGunnar Mills else if (property.first == "SubsystemVendorID") 167ac6a4445SGunnar Mills { 168ac6a4445SGunnar Mills dimmPropToHex(aResp, "MemorySubsystemControllerManufacturerID", 169ac6a4445SGunnar Mills property); 170ac6a4445SGunnar Mills } 171ac6a4445SGunnar Mills else if (property.first == "SubsystemDeviceID") 172ac6a4445SGunnar Mills { 17380badf7cSJiaqing Zhao dimmPropToHex(aResp, "MemorySubsystemControllerProductID", property); 174ac6a4445SGunnar Mills } 175ac6a4445SGunnar Mills else if (property.first == "VolatileRegionSizeLimitInKiB") 176ac6a4445SGunnar Mills { 177ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 178ac6a4445SGunnar Mills 179ac6a4445SGunnar Mills if (value == nullptr) 180ac6a4445SGunnar Mills { 181ac6a4445SGunnar Mills messages::internalError(aResp->res); 1820fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 1830fda0f12SGeorge Liu << "Invalid property type for VolatileRegionSizeLimitKiB"; 184601af5edSChicago Duan return; 185ac6a4445SGunnar Mills } 186ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileRegionSizeLimitMiB"] = (*value) >> 10; 187ac6a4445SGunnar Mills } 188ac6a4445SGunnar Mills else if (property.first == "PmRegionSizeLimitInKiB") 189ac6a4445SGunnar Mills { 190ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 191ac6a4445SGunnar Mills 192ac6a4445SGunnar Mills if (value == nullptr) 193ac6a4445SGunnar Mills { 194ac6a4445SGunnar Mills messages::internalError(aResp->res); 19580badf7cSJiaqing Zhao BMCWEB_LOG_DEBUG << "Invalid property type for PmRegioSizeLimitKiB"; 196601af5edSChicago Duan return; 197ac6a4445SGunnar Mills } 19880badf7cSJiaqing Zhao aResp->res.jsonValue["PersistentRegionSizeLimitMiB"] = (*value) >> 10; 199ac6a4445SGunnar Mills } 200ac6a4445SGunnar Mills else if (property.first == "VolatileSizeInKiB") 201ac6a4445SGunnar Mills { 202ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 203ac6a4445SGunnar Mills 204ac6a4445SGunnar Mills if (value == nullptr) 205ac6a4445SGunnar Mills { 206ac6a4445SGunnar Mills messages::internalError(aResp->res); 20780badf7cSJiaqing Zhao BMCWEB_LOG_DEBUG << "Invalid property type for VolatileSizeInKiB"; 208601af5edSChicago Duan return; 209ac6a4445SGunnar Mills } 210ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileSizeMiB"] = (*value) >> 10; 211ac6a4445SGunnar Mills } 212ac6a4445SGunnar Mills else if (property.first == "PmSizeInKiB") 213ac6a4445SGunnar Mills { 214ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 215ac6a4445SGunnar Mills if (value == nullptr) 216ac6a4445SGunnar Mills { 217ac6a4445SGunnar Mills messages::internalError(aResp->res); 218ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for PmSizeInKiB"; 219601af5edSChicago Duan return; 220ac6a4445SGunnar Mills } 221ac6a4445SGunnar Mills aResp->res.jsonValue["NonVolatileSizeMiB"] = (*value) >> 10; 222ac6a4445SGunnar Mills } 223ac6a4445SGunnar Mills else if (property.first == "CacheSizeInKB") 224ac6a4445SGunnar Mills { 225ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 226ac6a4445SGunnar Mills if (value == nullptr) 227ac6a4445SGunnar Mills { 228ac6a4445SGunnar Mills messages::internalError(aResp->res); 229ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for CacheSizeInKB"; 230601af5edSChicago Duan return; 231ac6a4445SGunnar Mills } 232ac6a4445SGunnar Mills aResp->res.jsonValue["CacheSizeMiB"] = (*value >> 10); 233ac6a4445SGunnar Mills } 234ac6a4445SGunnar Mills 235ac6a4445SGunnar Mills else if (property.first == "VoltaileRegionMaxSizeInKib") 236ac6a4445SGunnar Mills { 237ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 238ac6a4445SGunnar Mills 239ac6a4445SGunnar Mills if (value == nullptr) 240ac6a4445SGunnar Mills { 241ac6a4445SGunnar Mills messages::internalError(aResp->res); 2420fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 2430fda0f12SGeorge Liu << "Invalid property type for VolatileRegionMaxSizeInKib"; 244601af5edSChicago Duan return; 245ac6a4445SGunnar Mills } 246ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileRegionSizeMaxMiB"] = (*value) >> 10; 247ac6a4445SGunnar Mills } 248ac6a4445SGunnar Mills else if (property.first == "PmRegionMaxSizeInKiB") 249ac6a4445SGunnar Mills { 250ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 251ac6a4445SGunnar Mills 252ac6a4445SGunnar Mills if (value == nullptr) 253ac6a4445SGunnar Mills { 254ac6a4445SGunnar Mills messages::internalError(aResp->res); 255ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 256ac6a4445SGunnar Mills << "Invalid property type for PmRegionMaxSizeInKiB"; 257601af5edSChicago Duan return; 258ac6a4445SGunnar Mills } 259ac6a4445SGunnar Mills aResp->res.jsonValue["PersistentRegionSizeMaxMiB"] = (*value) >> 10; 260ac6a4445SGunnar Mills } 261ac6a4445SGunnar Mills else if (property.first == "AllocationIncrementInKiB") 262ac6a4445SGunnar Mills { 263ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 264ac6a4445SGunnar Mills 265ac6a4445SGunnar Mills if (value == nullptr) 266ac6a4445SGunnar Mills { 267ac6a4445SGunnar Mills messages::internalError(aResp->res); 2680fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 2690fda0f12SGeorge Liu << "Invalid property type for AllocationIncrementInKiB"; 270601af5edSChicago Duan return; 271ac6a4445SGunnar Mills } 272ac6a4445SGunnar Mills aResp->res.jsonValue["AllocationIncrementMiB"] = (*value) >> 10; 273ac6a4445SGunnar Mills } 274ac6a4445SGunnar Mills else if (property.first == "AllocationAlignmentInKiB") 275ac6a4445SGunnar Mills { 276ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 277ac6a4445SGunnar Mills 278ac6a4445SGunnar Mills if (value == nullptr) 279ac6a4445SGunnar Mills { 280ac6a4445SGunnar Mills messages::internalError(aResp->res); 2810fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 2820fda0f12SGeorge Liu << "Invalid property type for AllocationAlignmentInKiB"; 283601af5edSChicago Duan return; 284ac6a4445SGunnar Mills } 285ac6a4445SGunnar Mills aResp->res.jsonValue["AllocationAlignmentMiB"] = (*value) >> 10; 286ac6a4445SGunnar Mills } 287ac6a4445SGunnar Mills else if (property.first == "VolatileRegionNumberLimit") 288ac6a4445SGunnar Mills { 289ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 290ac6a4445SGunnar Mills if (value == nullptr) 291ac6a4445SGunnar Mills { 292ac6a4445SGunnar Mills messages::internalError(aResp->res); 293601af5edSChicago Duan return; 294ac6a4445SGunnar Mills } 295ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileRegionNumberLimit"] = *value; 296ac6a4445SGunnar Mills } 297ac6a4445SGunnar Mills else if (property.first == "PmRegionNumberLimit") 298ac6a4445SGunnar Mills { 299ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 300ac6a4445SGunnar Mills if (value == nullptr) 301ac6a4445SGunnar Mills { 302ac6a4445SGunnar Mills messages::internalError(aResp->res); 303601af5edSChicago Duan return; 304ac6a4445SGunnar Mills } 305ac6a4445SGunnar Mills aResp->res.jsonValue["PersistentRegionNumberLimit"] = *value; 306ac6a4445SGunnar Mills } 307ac6a4445SGunnar Mills else if (property.first == "SpareDeviceCount") 308ac6a4445SGunnar Mills { 309ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 310ac6a4445SGunnar Mills if (value == nullptr) 311ac6a4445SGunnar Mills { 312ac6a4445SGunnar Mills messages::internalError(aResp->res); 313601af5edSChicago Duan return; 314ac6a4445SGunnar Mills } 315ac6a4445SGunnar Mills aResp->res.jsonValue["SpareDeviceCount"] = *value; 316ac6a4445SGunnar Mills } 317ac6a4445SGunnar Mills else if (property.first == "IsSpareDeviceInUse") 318ac6a4445SGunnar Mills { 319ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 320ac6a4445SGunnar Mills if (value == nullptr) 321ac6a4445SGunnar Mills { 322ac6a4445SGunnar Mills messages::internalError(aResp->res); 323601af5edSChicago Duan return; 324ac6a4445SGunnar Mills } 325ac6a4445SGunnar Mills aResp->res.jsonValue["IsSpareDeviceEnabled"] = *value; 326ac6a4445SGunnar Mills } 327ac6a4445SGunnar Mills else if (property.first == "IsRankSpareEnabled") 328ac6a4445SGunnar Mills { 329ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 330ac6a4445SGunnar Mills if (value == nullptr) 331ac6a4445SGunnar Mills { 332ac6a4445SGunnar Mills messages::internalError(aResp->res); 333601af5edSChicago Duan return; 334ac6a4445SGunnar Mills } 335ac6a4445SGunnar Mills aResp->res.jsonValue["IsRankSpareEnabled"] = *value; 336ac6a4445SGunnar Mills } 337ac6a4445SGunnar Mills else if (property.first == "MaxAveragePowerLimitmW") 338ac6a4445SGunnar Mills { 339ac6a4445SGunnar Mills const auto* value = 340ac6a4445SGunnar Mills std::get_if<std::vector<uint32_t>>(&property.second); 341ac6a4445SGunnar Mills if (value == nullptr) 342ac6a4445SGunnar Mills { 343ac6a4445SGunnar Mills messages::internalError(aResp->res); 3440fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 3450fda0f12SGeorge Liu << "Invalid property type for MaxAveragePowerLimitmW"; 346601af5edSChicago Duan return; 347ac6a4445SGunnar Mills } 348ac6a4445SGunnar Mills aResp->res.jsonValue["MaxTDPMilliWatts"] = *value; 349ac6a4445SGunnar Mills } 350ac6a4445SGunnar Mills else if (property.first == "ConfigurationLocked") 351ac6a4445SGunnar Mills { 352ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 353ac6a4445SGunnar Mills if (value == nullptr) 354ac6a4445SGunnar Mills { 355ac6a4445SGunnar Mills messages::internalError(aResp->res); 356601af5edSChicago Duan return; 357ac6a4445SGunnar Mills } 358ac6a4445SGunnar Mills aResp->res.jsonValue["ConfigurationLocked"] = *value; 359ac6a4445SGunnar Mills } 360ac6a4445SGunnar Mills else if (property.first == "AllowedMemoryModes") 361ac6a4445SGunnar Mills { 36280badf7cSJiaqing Zhao const std::string* value = std::get_if<std::string>(&property.second); 363ac6a4445SGunnar Mills if (value == nullptr) 364ac6a4445SGunnar Mills { 365ac6a4445SGunnar Mills messages::internalError(aResp->res); 366ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for FormFactor"; 367601af5edSChicago Duan return; 368ac6a4445SGunnar Mills } 36980badf7cSJiaqing Zhao constexpr const std::array<const char*, 3> values{"Volatile", "PMEM", 37080badf7cSJiaqing Zhao "Block"}; 371ac6a4445SGunnar Mills 372ac6a4445SGunnar Mills for (const char* v : values) 373ac6a4445SGunnar Mills { 374ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 375ac6a4445SGunnar Mills { 376ac6a4445SGunnar Mills aResp->res.jsonValue["OperatingMemoryModes "] = v; 377ac6a4445SGunnar Mills break; 378ac6a4445SGunnar Mills } 379ac6a4445SGunnar Mills } 380ac6a4445SGunnar Mills } 381ac6a4445SGunnar Mills else if (property.first == "MemoryMedia") 382ac6a4445SGunnar Mills { 38380badf7cSJiaqing Zhao const std::string* value = std::get_if<std::string>(&property.second); 384ac6a4445SGunnar Mills if (value == nullptr) 385ac6a4445SGunnar Mills { 386ac6a4445SGunnar Mills messages::internalError(aResp->res); 387ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for MemoryMedia"; 388601af5edSChicago Duan return; 389ac6a4445SGunnar Mills } 390ac6a4445SGunnar Mills constexpr const std::array<const char*, 3> values{"DRAM", "NAND", 391ac6a4445SGunnar Mills "Intel3DXPoint"}; 392ac6a4445SGunnar Mills 393ac6a4445SGunnar Mills for (const char* v : values) 394ac6a4445SGunnar Mills { 395ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 396ac6a4445SGunnar Mills { 397ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryMedia"] = v; 398ac6a4445SGunnar Mills break; 399ac6a4445SGunnar Mills } 400ac6a4445SGunnar Mills } 401ac6a4445SGunnar Mills } 402ac6a4445SGunnar Mills // PersistantMemory.SecurityCapabilites interface 403ac6a4445SGunnar Mills else if (property.first == "ConfigurationLockCapable" || 404ac6a4445SGunnar Mills property.first == "DataLockCapable" || 405ac6a4445SGunnar Mills property.first == "PassphraseCapable") 406ac6a4445SGunnar Mills { 407ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 408ac6a4445SGunnar Mills if (value == nullptr) 409ac6a4445SGunnar Mills { 410ac6a4445SGunnar Mills messages::internalError(aResp->res); 411601af5edSChicago Duan return; 412ac6a4445SGunnar Mills } 41380badf7cSJiaqing Zhao aResp->res.jsonValue["SecurityCapabilities"][property.first] = *value; 414ac6a4445SGunnar Mills } 415ac6a4445SGunnar Mills else if (property.first == "MaxPassphraseCount" || 416ac6a4445SGunnar Mills property.first == "PassphraseLockLimit") 417ac6a4445SGunnar Mills { 418ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 419ac6a4445SGunnar Mills if (value == nullptr) 420ac6a4445SGunnar Mills { 421ac6a4445SGunnar Mills messages::internalError(aResp->res); 422601af5edSChicago Duan return; 423ac6a4445SGunnar Mills } 42480badf7cSJiaqing Zhao aResp->res.jsonValue["SecurityCapabilities"][property.first] = *value; 425ac6a4445SGunnar Mills } 426ac6a4445SGunnar Mills } 427ac6a4445SGunnar Mills 4288d1b46d7Szhanghch05 inline void getDimmDataByService(std::shared_ptr<bmcweb::AsyncResp> aResp, 429ac6a4445SGunnar Mills const std::string& dimmId, 430ac6a4445SGunnar Mills const std::string& service, 431ac6a4445SGunnar Mills const std::string& objPath) 432ac6a4445SGunnar Mills { 433ac6a4445SGunnar Mills auto health = std::make_shared<HealthPopulate>(aResp); 434ac6a4445SGunnar Mills health->selfPath = objPath; 435ac6a4445SGunnar Mills health->populate(); 436ac6a4445SGunnar Mills 437ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Get available system components."; 438ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 439*b9d36b47SEd Tanous [dimmId, aResp{std::move(aResp)}]( 440*b9d36b47SEd Tanous const boost::system::error_code ec, 441*b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 442ac6a4445SGunnar Mills if (ec) 443ac6a4445SGunnar Mills { 444ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 445ac6a4445SGunnar Mills messages::internalError(aResp->res); 446ac6a4445SGunnar Mills return; 447ac6a4445SGunnar Mills } 448ac6a4445SGunnar Mills aResp->res.jsonValue["Id"] = dimmId; 449ac6a4445SGunnar Mills aResp->res.jsonValue["Name"] = "DIMM Slot"; 450ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["State"] = "Enabled"; 451ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["Health"] = "OK"; 452ac6a4445SGunnar Mills 453ac6a4445SGunnar Mills for (const auto& property : properties) 454ac6a4445SGunnar Mills { 455ac6a4445SGunnar Mills if (property.first == "MemoryDataWidth") 456ac6a4445SGunnar Mills { 457ac6a4445SGunnar Mills const uint16_t* value = 458ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 459ac6a4445SGunnar Mills if (value == nullptr) 460ac6a4445SGunnar Mills { 461ac6a4445SGunnar Mills continue; 462ac6a4445SGunnar Mills } 463ac6a4445SGunnar Mills aResp->res.jsonValue["DataWidthBits"] = *value; 464ac6a4445SGunnar Mills } 465*b9d36b47SEd Tanous else if (property.first == "MemorySizeInKB") 466*b9d36b47SEd Tanous { 467*b9d36b47SEd Tanous const uint32_t* memorySize = 468*b9d36b47SEd Tanous std::get_if<uint32_t>(&property.second); 469*b9d36b47SEd Tanous if (memorySize == nullptr) 470*b9d36b47SEd Tanous { 471*b9d36b47SEd Tanous // Important property not in desired type 472*b9d36b47SEd Tanous messages::internalError(aResp->res); 473*b9d36b47SEd Tanous return; 474*b9d36b47SEd Tanous } 475*b9d36b47SEd Tanous aResp->res.jsonValue["CapacityMiB"] = (*memorySize >> 10); 476*b9d36b47SEd Tanous } 477ac6a4445SGunnar Mills else if (property.first == "PartNumber") 478ac6a4445SGunnar Mills { 479ac6a4445SGunnar Mills const std::string* value = 480ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 481ac6a4445SGunnar Mills if (value == nullptr) 482ac6a4445SGunnar Mills { 483ac6a4445SGunnar Mills continue; 484ac6a4445SGunnar Mills } 485ac6a4445SGunnar Mills aResp->res.jsonValue["PartNumber"] = *value; 486ac6a4445SGunnar Mills } 487ac6a4445SGunnar Mills else if (property.first == "SerialNumber") 488ac6a4445SGunnar Mills { 489ac6a4445SGunnar Mills const std::string* value = 490ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 491ac6a4445SGunnar Mills if (value == nullptr) 492ac6a4445SGunnar Mills { 493ac6a4445SGunnar Mills continue; 494ac6a4445SGunnar Mills } 495ac6a4445SGunnar Mills aResp->res.jsonValue["SerialNumber"] = *value; 496ac6a4445SGunnar Mills } 497ac6a4445SGunnar Mills else if (property.first == "Manufacturer") 498ac6a4445SGunnar Mills { 499ac6a4445SGunnar Mills const std::string* value = 500ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 501ac6a4445SGunnar Mills if (value == nullptr) 502ac6a4445SGunnar Mills { 503ac6a4445SGunnar Mills continue; 504ac6a4445SGunnar Mills } 505ac6a4445SGunnar Mills aResp->res.jsonValue["Manufacturer"] = *value; 506ac6a4445SGunnar Mills } 507ac6a4445SGunnar Mills else if (property.first == "RevisionCode") 508ac6a4445SGunnar Mills { 509ac6a4445SGunnar Mills const uint16_t* value = 510ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 511ac6a4445SGunnar Mills 512ac6a4445SGunnar Mills if (value == nullptr) 513ac6a4445SGunnar Mills { 514ac6a4445SGunnar Mills messages::internalError(aResp->res); 515ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 516ac6a4445SGunnar Mills << "Invalid property type for RevisionCode"; 517601af5edSChicago Duan return; 518ac6a4445SGunnar Mills } 519ac6a4445SGunnar Mills aResp->res.jsonValue["FirmwareRevision"] = 520ac6a4445SGunnar Mills std::to_string(*value); 521ac6a4445SGunnar Mills } 5229a128eb3SJoshi-Mansi else if (property.first == "Present") 5239a128eb3SJoshi-Mansi { 5249a128eb3SJoshi-Mansi const bool* value = std::get_if<bool>(&property.second); 5259a128eb3SJoshi-Mansi if (value == nullptr) 5269a128eb3SJoshi-Mansi { 5279a128eb3SJoshi-Mansi messages::internalError(aResp->res); 5289a128eb3SJoshi-Mansi BMCWEB_LOG_DEBUG 5299a128eb3SJoshi-Mansi << "Invalid property type for Dimm Presence"; 5309a128eb3SJoshi-Mansi return; 5319a128eb3SJoshi-Mansi } 532e05aec50SEd Tanous if (!*value) 5339a128eb3SJoshi-Mansi { 5349a128eb3SJoshi-Mansi aResp->res.jsonValue["Status"]["State"] = "Absent"; 5359a128eb3SJoshi-Mansi } 5369a128eb3SJoshi-Mansi } 537ac6a4445SGunnar Mills else if (property.first == "MemoryTotalWidth") 538ac6a4445SGunnar Mills { 539ac6a4445SGunnar Mills const uint16_t* value = 540ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 541ac6a4445SGunnar Mills if (value == nullptr) 542ac6a4445SGunnar Mills { 543ac6a4445SGunnar Mills continue; 544ac6a4445SGunnar Mills } 545ac6a4445SGunnar Mills aResp->res.jsonValue["BusWidthBits"] = *value; 546ac6a4445SGunnar Mills } 547ac6a4445SGunnar Mills else if (property.first == "ECC") 548ac6a4445SGunnar Mills { 549ac6a4445SGunnar Mills const std::string* value = 550ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 551ac6a4445SGunnar Mills if (value == nullptr) 552ac6a4445SGunnar Mills { 553ac6a4445SGunnar Mills messages::internalError(aResp->res); 554ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for ECC"; 555601af5edSChicago Duan return; 556ac6a4445SGunnar Mills } 557ac6a4445SGunnar Mills constexpr const std::array<const char*, 4> values{ 558ac6a4445SGunnar Mills "NoECC", "SingleBitECC", "MultiBitECC", 559ac6a4445SGunnar Mills "AddressParity"}; 560ac6a4445SGunnar Mills 561ac6a4445SGunnar Mills for (const char* v : values) 562ac6a4445SGunnar Mills { 563ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 564ac6a4445SGunnar Mills { 565ac6a4445SGunnar Mills aResp->res.jsonValue["ErrorCorrection"] = v; 566ac6a4445SGunnar Mills break; 567ac6a4445SGunnar Mills } 568ac6a4445SGunnar Mills } 569ac6a4445SGunnar Mills } 570ac6a4445SGunnar Mills else if (property.first == "FormFactor") 571ac6a4445SGunnar Mills { 572ac6a4445SGunnar Mills const std::string* value = 573ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 574ac6a4445SGunnar Mills if (value == nullptr) 575ac6a4445SGunnar Mills { 576ac6a4445SGunnar Mills messages::internalError(aResp->res); 577ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 578ac6a4445SGunnar Mills << "Invalid property type for FormFactor"; 579601af5edSChicago Duan return; 580ac6a4445SGunnar Mills } 581ac6a4445SGunnar Mills constexpr const std::array<const char*, 11> values{ 582ac6a4445SGunnar Mills "RDIMM", "UDIMM", "SO_DIMM", 583ac6a4445SGunnar Mills "LRDIMM", "Mini_RDIMM", "Mini_UDIMM", 584ac6a4445SGunnar Mills "SO_RDIMM_72b", "SO_UDIMM_72b", "SO_DIMM_16b", 585ac6a4445SGunnar Mills "SO_DIMM_32b", "Die"}; 586ac6a4445SGunnar Mills 587ac6a4445SGunnar Mills for (const char* v : values) 588ac6a4445SGunnar Mills { 589ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 590ac6a4445SGunnar Mills { 591ac6a4445SGunnar Mills aResp->res.jsonValue["BaseModuleType"] = v; 592ac6a4445SGunnar Mills break; 593ac6a4445SGunnar Mills } 594ac6a4445SGunnar Mills } 595ac6a4445SGunnar Mills } 596ac6a4445SGunnar Mills else if (property.first == "AllowedSpeedsMT") 597ac6a4445SGunnar Mills { 598ac6a4445SGunnar Mills const std::vector<uint16_t>* value = 599ac6a4445SGunnar Mills std::get_if<std::vector<uint16_t>>(&property.second); 600ac6a4445SGunnar Mills if (value == nullptr) 601ac6a4445SGunnar Mills { 602ac6a4445SGunnar Mills continue; 603ac6a4445SGunnar Mills } 604ac6a4445SGunnar Mills nlohmann::json& jValue = 605ac6a4445SGunnar Mills aResp->res.jsonValue["AllowedSpeedsMHz"]; 606ac6a4445SGunnar Mills jValue = nlohmann::json::array(); 607ac6a4445SGunnar Mills for (uint16_t subVal : *value) 608ac6a4445SGunnar Mills { 609ac6a4445SGunnar Mills jValue.push_back(subVal); 610ac6a4445SGunnar Mills } 611ac6a4445SGunnar Mills } 612ac6a4445SGunnar Mills else if (property.first == "MemoryAttributes") 613ac6a4445SGunnar Mills { 614ac6a4445SGunnar Mills const uint8_t* value = 615ac6a4445SGunnar Mills std::get_if<uint8_t>(&property.second); 616ac6a4445SGunnar Mills 617ac6a4445SGunnar Mills if (value == nullptr) 618ac6a4445SGunnar Mills { 619ac6a4445SGunnar Mills messages::internalError(aResp->res); 620ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 621ac6a4445SGunnar Mills << "Invalid property type for MemoryAttributes"; 622601af5edSChicago Duan return; 623ac6a4445SGunnar Mills } 624ac6a4445SGunnar Mills aResp->res.jsonValue["RankCount"] = 625ac6a4445SGunnar Mills static_cast<uint64_t>(*value); 626ac6a4445SGunnar Mills } 627ac6a4445SGunnar Mills else if (property.first == "MemoryConfiguredSpeedInMhz") 628ac6a4445SGunnar Mills { 629ac6a4445SGunnar Mills const uint16_t* value = 630ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 631ac6a4445SGunnar Mills if (value == nullptr) 632ac6a4445SGunnar Mills { 633ac6a4445SGunnar Mills continue; 634ac6a4445SGunnar Mills } 635ac6a4445SGunnar Mills aResp->res.jsonValue["OperatingSpeedMhz"] = *value; 636ac6a4445SGunnar Mills } 637ac6a4445SGunnar Mills else if (property.first == "MemoryType") 638ac6a4445SGunnar Mills { 639ac6a4445SGunnar Mills const auto* value = 640ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 641ac6a4445SGunnar Mills if (value != nullptr) 642ac6a4445SGunnar Mills { 643313efb1cSGunnar Mills std::string memoryDeviceType = 644313efb1cSGunnar Mills translateMemoryTypeToRedfish(*value); 645313efb1cSGunnar Mills // Values like "Unknown" or "Other" will return empty 646313efb1cSGunnar Mills // so just leave off 647313efb1cSGunnar Mills if (!memoryDeviceType.empty()) 648ac6a4445SGunnar Mills { 649313efb1cSGunnar Mills aResp->res.jsonValue["MemoryDeviceType"] = 650313efb1cSGunnar Mills memoryDeviceType; 651ac6a4445SGunnar Mills } 652ac6a4445SGunnar Mills if (value->find("DDR") != std::string::npos) 653ac6a4445SGunnar Mills { 654ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryType"] = "DRAM"; 655ac6a4445SGunnar Mills } 656ac6a4445SGunnar Mills else if (boost::ends_with(*value, "Logical")) 657ac6a4445SGunnar Mills { 658ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryType"] = "IntelOptane"; 659ac6a4445SGunnar Mills } 660ac6a4445SGunnar Mills } 661ac6a4445SGunnar Mills } 662ac6a4445SGunnar Mills // memory location interface 663ac6a4445SGunnar Mills else if (property.first == "Channel" || 664ac6a4445SGunnar Mills property.first == "MemoryController" || 665ac6a4445SGunnar Mills property.first == "Slot" || property.first == "Socket") 666ac6a4445SGunnar Mills { 667ac6a4445SGunnar Mills const std::string* value = 668ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 669ac6a4445SGunnar Mills if (value == nullptr) 670ac6a4445SGunnar Mills { 671ac6a4445SGunnar Mills messages::internalError(aResp->res); 672601af5edSChicago Duan return; 673ac6a4445SGunnar Mills } 674ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryLocation"][property.first] = 675ac6a4445SGunnar Mills *value; 676ac6a4445SGunnar Mills } 677ee135e24SSunnySrivastava1984 else if (property.first == "SparePartNumber") 678ee135e24SSunnySrivastava1984 { 679ee135e24SSunnySrivastava1984 const std::string* value = 680ee135e24SSunnySrivastava1984 std::get_if<std::string>(&property.second); 681ee135e24SSunnySrivastava1984 if (value == nullptr) 682ee135e24SSunnySrivastava1984 { 683ee135e24SSunnySrivastava1984 messages::internalError(aResp->res); 684601af5edSChicago Duan return; 685ee135e24SSunnySrivastava1984 } 686ee135e24SSunnySrivastava1984 aResp->res.jsonValue["SparePartNumber"] = *value; 687ee135e24SSunnySrivastava1984 } 688ee135e24SSunnySrivastava1984 else if (property.first == "Model") 689ee135e24SSunnySrivastava1984 { 690ee135e24SSunnySrivastava1984 const std::string* value = 691ee135e24SSunnySrivastava1984 std::get_if<std::string>(&property.second); 692ee135e24SSunnySrivastava1984 if (value == nullptr) 693ee135e24SSunnySrivastava1984 { 694ee135e24SSunnySrivastava1984 messages::internalError(aResp->res); 695601af5edSChicago Duan return; 696ee135e24SSunnySrivastava1984 } 697ee135e24SSunnySrivastava1984 aResp->res.jsonValue["Model"] = *value; 698ee135e24SSunnySrivastava1984 } 699ee135e24SSunnySrivastava1984 else if (property.first == "LocationCode") 700ee135e24SSunnySrivastava1984 { 701ee135e24SSunnySrivastava1984 const std::string* value = 702ee135e24SSunnySrivastava1984 std::get_if<std::string>(&property.second); 703ee135e24SSunnySrivastava1984 if (value == nullptr) 704ee135e24SSunnySrivastava1984 { 705ee135e24SSunnySrivastava1984 messages::internalError(aResp->res); 706601af5edSChicago Duan return; 707ee135e24SSunnySrivastava1984 } 708ee135e24SSunnySrivastava1984 aResp->res 709ee135e24SSunnySrivastava1984 .jsonValue["Location"]["PartLocation"]["ServiceLabel"] = 710ee135e24SSunnySrivastava1984 *value; 711ee135e24SSunnySrivastava1984 } 712ac6a4445SGunnar Mills else 713ac6a4445SGunnar Mills { 71480badf7cSJiaqing Zhao getPersistentMemoryProperties(aResp, property); 715ac6a4445SGunnar Mills } 716ac6a4445SGunnar Mills } 717ac6a4445SGunnar Mills }, 718ac6a4445SGunnar Mills service, objPath, "org.freedesktop.DBus.Properties", "GetAll", ""); 719ac6a4445SGunnar Mills } 720ac6a4445SGunnar Mills 7218d1b46d7Szhanghch05 inline void getDimmPartitionData(std::shared_ptr<bmcweb::AsyncResp> aResp, 722ac6a4445SGunnar Mills const std::string& service, 723ac6a4445SGunnar Mills const std::string& path) 724ac6a4445SGunnar Mills { 725ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 726ac6a4445SGunnar Mills [aResp{std::move(aResp)}]( 727ac6a4445SGunnar Mills const boost::system::error_code ec, 728*b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& properties) { 729ac6a4445SGunnar Mills if (ec) 730ac6a4445SGunnar Mills { 731ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 732ac6a4445SGunnar Mills messages::internalError(aResp->res); 733ac6a4445SGunnar Mills 734ac6a4445SGunnar Mills return; 735ac6a4445SGunnar Mills } 736ac6a4445SGunnar Mills 737ac6a4445SGunnar Mills nlohmann::json& partition = 738ac6a4445SGunnar Mills aResp->res.jsonValue["Regions"].emplace_back( 739ac6a4445SGunnar Mills nlohmann::json::object()); 740ac6a4445SGunnar Mills for (const auto& [key, val] : properties) 741ac6a4445SGunnar Mills { 742ac6a4445SGunnar Mills if (key == "MemoryClassification") 743ac6a4445SGunnar Mills { 744ac6a4445SGunnar Mills const std::string* value = std::get_if<std::string>(&val); 745ac6a4445SGunnar Mills if (value == nullptr) 746ac6a4445SGunnar Mills { 747ac6a4445SGunnar Mills messages::internalError(aResp->res); 748601af5edSChicago Duan return; 749ac6a4445SGunnar Mills } 750ac6a4445SGunnar Mills partition[key] = *value; 751ac6a4445SGunnar Mills } 752ac6a4445SGunnar Mills else if (key == "OffsetInKiB") 753ac6a4445SGunnar Mills { 754ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&val); 755ac6a4445SGunnar Mills if (value == nullptr) 756ac6a4445SGunnar Mills { 757ac6a4445SGunnar Mills messages::internalError(aResp->res); 758601af5edSChicago Duan return; 759ac6a4445SGunnar Mills } 760ac6a4445SGunnar Mills 761ac6a4445SGunnar Mills partition["OffsetMiB"] = (*value >> 10); 762ac6a4445SGunnar Mills } 763ac6a4445SGunnar Mills else if (key == "PartitionId") 764ac6a4445SGunnar Mills { 765ac6a4445SGunnar Mills const std::string* value = std::get_if<std::string>(&val); 766ac6a4445SGunnar Mills if (value == nullptr) 767ac6a4445SGunnar Mills { 768ac6a4445SGunnar Mills messages::internalError(aResp->res); 769601af5edSChicago Duan return; 770ac6a4445SGunnar Mills } 771ac6a4445SGunnar Mills partition["RegionId"] = *value; 772ac6a4445SGunnar Mills } 773ac6a4445SGunnar Mills 774ac6a4445SGunnar Mills else if (key == "PassphraseState") 775ac6a4445SGunnar Mills { 776ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&val); 777ac6a4445SGunnar Mills if (value == nullptr) 778ac6a4445SGunnar Mills { 779ac6a4445SGunnar Mills messages::internalError(aResp->res); 780601af5edSChicago Duan return; 781ac6a4445SGunnar Mills } 782ac6a4445SGunnar Mills partition["PassphraseEnabled"] = *value; 783ac6a4445SGunnar Mills } 784ac6a4445SGunnar Mills else if (key == "SizeInKiB") 785ac6a4445SGunnar Mills { 786ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&val); 787ac6a4445SGunnar Mills if (value == nullptr) 788ac6a4445SGunnar Mills { 789ac6a4445SGunnar Mills messages::internalError(aResp->res); 790ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 791ac6a4445SGunnar Mills << "Invalid property type for SizeInKiB"; 792601af5edSChicago Duan return; 793ac6a4445SGunnar Mills } 794ac6a4445SGunnar Mills partition["SizeMiB"] = (*value >> 10); 795ac6a4445SGunnar Mills } 796ac6a4445SGunnar Mills } 797ac6a4445SGunnar Mills }, 798ac6a4445SGunnar Mills 799ac6a4445SGunnar Mills service, path, "org.freedesktop.DBus.Properties", "GetAll", 800ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"); 801ac6a4445SGunnar Mills } 802ac6a4445SGunnar Mills 8038d1b46d7Szhanghch05 inline void getDimmData(std::shared_ptr<bmcweb::AsyncResp> aResp, 804ac6a4445SGunnar Mills const std::string& dimmId) 805ac6a4445SGunnar Mills { 806ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Get available system dimm resources."; 807ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 808ac6a4445SGunnar Mills [dimmId, aResp{std::move(aResp)}]( 809ac6a4445SGunnar Mills const boost::system::error_code ec, 810*b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 811ac6a4445SGunnar Mills if (ec) 812ac6a4445SGunnar Mills { 813ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 814ac6a4445SGunnar Mills messages::internalError(aResp->res); 815ac6a4445SGunnar Mills 816ac6a4445SGunnar Mills return; 817ac6a4445SGunnar Mills } 818ac6a4445SGunnar Mills bool found = false; 819ac6a4445SGunnar Mills for (const auto& [path, object] : subtree) 820ac6a4445SGunnar Mills { 821ac6a4445SGunnar Mills if (path.find(dimmId) != std::string::npos) 822ac6a4445SGunnar Mills { 823ac6a4445SGunnar Mills for (const auto& [service, interfaces] : object) 824ac6a4445SGunnar Mills { 825*b9d36b47SEd Tanous for (const auto& interface : interfaces) 826ac6a4445SGunnar Mills { 827*b9d36b47SEd Tanous if (interface == 828*b9d36b47SEd Tanous "xyz.openbmc_project.Inventory.Item.Dimm") 829*b9d36b47SEd Tanous { 830*b9d36b47SEd Tanous getDimmDataByService(aResp, dimmId, service, 831*b9d36b47SEd Tanous path); 832ac6a4445SGunnar Mills found = true; 833ac6a4445SGunnar Mills } 834ac6a4445SGunnar Mills 835*b9d36b47SEd Tanous // partitions are separate as there can be multiple 836*b9d36b47SEd Tanous // per 837ac6a4445SGunnar Mills // device, i.e. 838ac6a4445SGunnar Mills // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1 839ac6a4445SGunnar Mills // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2 840*b9d36b47SEd Tanous if (interface == 841*b9d36b47SEd Tanous "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition") 842ac6a4445SGunnar Mills { 843ac6a4445SGunnar Mills getDimmPartitionData(aResp, service, path); 844ac6a4445SGunnar Mills } 845ac6a4445SGunnar Mills } 846ac6a4445SGunnar Mills } 847ac6a4445SGunnar Mills } 848*b9d36b47SEd Tanous } 849ac6a4445SGunnar Mills // Object not found 850ac6a4445SGunnar Mills if (!found) 851ac6a4445SGunnar Mills { 852ac6a4445SGunnar Mills messages::resourceNotFound(aResp->res, "Memory", dimmId); 853ac6a4445SGunnar Mills } 854ac6a4445SGunnar Mills return; 855ac6a4445SGunnar Mills }, 856ac6a4445SGunnar Mills "xyz.openbmc_project.ObjectMapper", 857ac6a4445SGunnar Mills "/xyz/openbmc_project/object_mapper", 858ac6a4445SGunnar Mills "xyz.openbmc_project.ObjectMapper", "GetSubTree", 859ac6a4445SGunnar Mills "/xyz/openbmc_project/inventory", 0, 860ac6a4445SGunnar Mills std::array<const char*, 2>{ 861ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm", 862ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"}); 863ac6a4445SGunnar Mills } 864ac6a4445SGunnar Mills 8657e860f15SJohn Edward Broadbent inline void requestRoutesMemoryCollection(App& app) 866ac6a4445SGunnar Mills { 867ac6a4445SGunnar Mills /** 868ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 869ac6a4445SGunnar Mills */ 8707e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Memory/") 871ed398213SEd Tanous .privileges(redfish::privileges::getMemoryCollection) 8727e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 8737e860f15SJohn Edward Broadbent [](const crow::Request&, 8747e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 8758d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 8768d1b46d7Szhanghch05 "#MemoryCollection.MemoryCollection"; 8778d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Memory Module Collection"; 8788d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = 8798d1b46d7Szhanghch05 "/redfish/v1/Systems/system/Memory"; 880ac6a4445SGunnar Mills 88105030b8eSGunnar Mills collection_util::getCollectionMembers( 88205030b8eSGunnar Mills asyncResp, "/redfish/v1/Systems/system/Memory", 88305030b8eSGunnar Mills {"xyz.openbmc_project.Inventory.Item.Dimm"}); 8847e860f15SJohn Edward Broadbent }); 885ac6a4445SGunnar Mills } 886ac6a4445SGunnar Mills 8877e860f15SJohn Edward Broadbent inline void requestRoutesMemory(App& app) 8887e860f15SJohn Edward Broadbent { 889ac6a4445SGunnar Mills /** 890ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 891ac6a4445SGunnar Mills */ 8927e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Memory/<str>/") 893ed398213SEd Tanous .privileges(redfish::privileges::getMemory) 8947e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 8957e860f15SJohn Edward Broadbent [](const crow::Request&, 8967e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 8977e860f15SJohn Edward Broadbent const std::string& dimmId) { 8987e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["@odata.type"] = 8997e860f15SJohn Edward Broadbent "#Memory.v1_11_0.Memory"; 9008d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = 901ac6a4445SGunnar Mills "/redfish/v1/Systems/system/Memory/" + dimmId; 902ac6a4445SGunnar Mills 903ac6a4445SGunnar Mills getDimmData(asyncResp, dimmId); 9047e860f15SJohn Edward Broadbent }); 905ac6a4445SGunnar Mills } 906ac6a4445SGunnar Mills 907ac6a4445SGunnar Mills } // namespace redfish 908