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> 2245ca1b86SEd 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 4299a5aceacSNan Zhou inline void 4309a5aceacSNan Zhou assembleDimmProperties(std::string_view dimmId, 4319a5aceacSNan Zhou const std::shared_ptr<bmcweb::AsyncResp>& aResp, 4329a5aceacSNan Zhou const dbus::utility::DBusPropertiesMap& properties) 433ac6a4445SGunnar Mills { 434ac6a4445SGunnar Mills aResp->res.jsonValue["Id"] = dimmId; 435ac6a4445SGunnar Mills aResp->res.jsonValue["Name"] = "DIMM Slot"; 436ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["State"] = "Enabled"; 437ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["Health"] = "OK"; 438ac6a4445SGunnar Mills 439ac6a4445SGunnar Mills for (const auto& property : properties) 440ac6a4445SGunnar Mills { 441ac6a4445SGunnar Mills if (property.first == "MemoryDataWidth") 442ac6a4445SGunnar Mills { 4439a5aceacSNan Zhou const uint16_t* value = std::get_if<uint16_t>(&property.second); 444ac6a4445SGunnar Mills if (value == nullptr) 445ac6a4445SGunnar Mills { 446ac6a4445SGunnar Mills continue; 447ac6a4445SGunnar Mills } 448ac6a4445SGunnar Mills aResp->res.jsonValue["DataWidthBits"] = *value; 449ac6a4445SGunnar Mills } 450b9d36b47SEd Tanous else if (property.first == "MemorySizeInKB") 451b9d36b47SEd Tanous { 4529a5aceacSNan Zhou const size_t* memorySize = std::get_if<size_t>(&property.second); 453b9d36b47SEd Tanous if (memorySize == nullptr) 454b9d36b47SEd Tanous { 455b9d36b47SEd Tanous // Important property not in desired type 456b9d36b47SEd Tanous messages::internalError(aResp->res); 457b9d36b47SEd Tanous return; 458b9d36b47SEd Tanous } 459b9d36b47SEd Tanous aResp->res.jsonValue["CapacityMiB"] = (*memorySize >> 10); 460b9d36b47SEd Tanous } 461ac6a4445SGunnar Mills else if (property.first == "PartNumber") 462ac6a4445SGunnar Mills { 463ac6a4445SGunnar Mills const std::string* value = 464ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 465ac6a4445SGunnar Mills if (value == nullptr) 466ac6a4445SGunnar Mills { 467ac6a4445SGunnar Mills continue; 468ac6a4445SGunnar Mills } 469ac6a4445SGunnar Mills aResp->res.jsonValue["PartNumber"] = *value; 470ac6a4445SGunnar Mills } 471ac6a4445SGunnar Mills else if (property.first == "SerialNumber") 472ac6a4445SGunnar Mills { 473ac6a4445SGunnar Mills const std::string* value = 474ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 475ac6a4445SGunnar Mills if (value == nullptr) 476ac6a4445SGunnar Mills { 477ac6a4445SGunnar Mills continue; 478ac6a4445SGunnar Mills } 479ac6a4445SGunnar Mills aResp->res.jsonValue["SerialNumber"] = *value; 480ac6a4445SGunnar Mills } 481ac6a4445SGunnar Mills else if (property.first == "Manufacturer") 482ac6a4445SGunnar Mills { 483ac6a4445SGunnar Mills const std::string* value = 484ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 485ac6a4445SGunnar Mills if (value == nullptr) 486ac6a4445SGunnar Mills { 487ac6a4445SGunnar Mills continue; 488ac6a4445SGunnar Mills } 489ac6a4445SGunnar Mills aResp->res.jsonValue["Manufacturer"] = *value; 490ac6a4445SGunnar Mills } 491ac6a4445SGunnar Mills else if (property.first == "RevisionCode") 492ac6a4445SGunnar Mills { 4939a5aceacSNan Zhou const uint16_t* value = std::get_if<uint16_t>(&property.second); 494ac6a4445SGunnar Mills 495ac6a4445SGunnar Mills if (value == nullptr) 496ac6a4445SGunnar Mills { 497ac6a4445SGunnar Mills messages::internalError(aResp->res); 4989a5aceacSNan Zhou BMCWEB_LOG_DEBUG << "Invalid property type for RevisionCode"; 499601af5edSChicago Duan return; 500ac6a4445SGunnar Mills } 5019a5aceacSNan Zhou aResp->res.jsonValue["FirmwareRevision"] = std::to_string(*value); 502ac6a4445SGunnar Mills } 5039a128eb3SJoshi-Mansi else if (property.first == "Present") 5049a128eb3SJoshi-Mansi { 5059a128eb3SJoshi-Mansi const bool* value = std::get_if<bool>(&property.second); 5069a128eb3SJoshi-Mansi if (value == nullptr) 5079a128eb3SJoshi-Mansi { 5089a128eb3SJoshi-Mansi messages::internalError(aResp->res); 5099a5aceacSNan Zhou BMCWEB_LOG_DEBUG << "Invalid property type for Dimm Presence"; 5109a128eb3SJoshi-Mansi return; 5119a128eb3SJoshi-Mansi } 512e05aec50SEd Tanous if (!*value) 5139a128eb3SJoshi-Mansi { 5149a128eb3SJoshi-Mansi aResp->res.jsonValue["Status"]["State"] = "Absent"; 5159a128eb3SJoshi-Mansi } 5169a128eb3SJoshi-Mansi } 517ac6a4445SGunnar Mills else if (property.first == "MemoryTotalWidth") 518ac6a4445SGunnar Mills { 5199a5aceacSNan Zhou const uint16_t* value = std::get_if<uint16_t>(&property.second); 520ac6a4445SGunnar Mills if (value == nullptr) 521ac6a4445SGunnar Mills { 522ac6a4445SGunnar Mills continue; 523ac6a4445SGunnar Mills } 524ac6a4445SGunnar Mills aResp->res.jsonValue["BusWidthBits"] = *value; 525ac6a4445SGunnar Mills } 526ac6a4445SGunnar Mills else if (property.first == "ECC") 527ac6a4445SGunnar Mills { 528ac6a4445SGunnar Mills const std::string* value = 529ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 530ac6a4445SGunnar Mills if (value == nullptr) 531ac6a4445SGunnar Mills { 532ac6a4445SGunnar Mills messages::internalError(aResp->res); 533ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for ECC"; 534601af5edSChicago Duan return; 535ac6a4445SGunnar Mills } 536ac6a4445SGunnar Mills constexpr const std::array<const char*, 4> values{ 5379a5aceacSNan Zhou "NoECC", "SingleBitECC", "MultiBitECC", "AddressParity"}; 538ac6a4445SGunnar Mills 539ac6a4445SGunnar Mills for (const char* v : values) 540ac6a4445SGunnar Mills { 541ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 542ac6a4445SGunnar Mills { 543ac6a4445SGunnar Mills aResp->res.jsonValue["ErrorCorrection"] = v; 544ac6a4445SGunnar Mills break; 545ac6a4445SGunnar Mills } 546ac6a4445SGunnar Mills } 547ac6a4445SGunnar Mills } 548ac6a4445SGunnar Mills else if (property.first == "FormFactor") 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); 5559a5aceacSNan Zhou BMCWEB_LOG_DEBUG << "Invalid property type for FormFactor"; 556601af5edSChicago Duan return; 557ac6a4445SGunnar Mills } 558ac6a4445SGunnar Mills constexpr const std::array<const char*, 11> values{ 5599a5aceacSNan Zhou "RDIMM", "UDIMM", "SO_DIMM", "LRDIMM", 5609a5aceacSNan Zhou "Mini_RDIMM", "Mini_UDIMM", "SO_RDIMM_72b", "SO_UDIMM_72b", 5619a5aceacSNan Zhou "SO_DIMM_16b", "SO_DIMM_32b", "Die"}; 562ac6a4445SGunnar Mills 563ac6a4445SGunnar Mills for (const char* v : values) 564ac6a4445SGunnar Mills { 565ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 566ac6a4445SGunnar Mills { 567ac6a4445SGunnar Mills aResp->res.jsonValue["BaseModuleType"] = v; 568ac6a4445SGunnar Mills break; 569ac6a4445SGunnar Mills } 570ac6a4445SGunnar Mills } 571ac6a4445SGunnar Mills } 572ac6a4445SGunnar Mills else if (property.first == "AllowedSpeedsMT") 573ac6a4445SGunnar Mills { 574ac6a4445SGunnar Mills const std::vector<uint16_t>* value = 575ac6a4445SGunnar Mills std::get_if<std::vector<uint16_t>>(&property.second); 576ac6a4445SGunnar Mills if (value == nullptr) 577ac6a4445SGunnar Mills { 578ac6a4445SGunnar Mills continue; 579ac6a4445SGunnar Mills } 5809a5aceacSNan Zhou nlohmann::json& jValue = aResp->res.jsonValue["AllowedSpeedsMHz"]; 581ac6a4445SGunnar Mills jValue = nlohmann::json::array(); 582ac6a4445SGunnar Mills for (uint16_t subVal : *value) 583ac6a4445SGunnar Mills { 584ac6a4445SGunnar Mills jValue.push_back(subVal); 585ac6a4445SGunnar Mills } 586ac6a4445SGunnar Mills } 587ac6a4445SGunnar Mills else if (property.first == "MemoryAttributes") 588ac6a4445SGunnar Mills { 5899a5aceacSNan Zhou const uint8_t* value = std::get_if<uint8_t>(&property.second); 590ac6a4445SGunnar Mills 591ac6a4445SGunnar Mills if (value == nullptr) 592ac6a4445SGunnar Mills { 593ac6a4445SGunnar Mills messages::internalError(aResp->res); 594ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 595ac6a4445SGunnar Mills << "Invalid property type for MemoryAttributes"; 596601af5edSChicago Duan return; 597ac6a4445SGunnar Mills } 5989a5aceacSNan Zhou aResp->res.jsonValue["RankCount"] = static_cast<uint64_t>(*value); 599ac6a4445SGunnar Mills } 600ac6a4445SGunnar Mills else if (property.first == "MemoryConfiguredSpeedInMhz") 601ac6a4445SGunnar Mills { 6029a5aceacSNan Zhou const uint16_t* value = std::get_if<uint16_t>(&property.second); 603ac6a4445SGunnar Mills if (value == nullptr) 604ac6a4445SGunnar Mills { 605ac6a4445SGunnar Mills continue; 606ac6a4445SGunnar Mills } 607ac6a4445SGunnar Mills aResp->res.jsonValue["OperatingSpeedMhz"] = *value; 608ac6a4445SGunnar Mills } 609ac6a4445SGunnar Mills else if (property.first == "MemoryType") 610ac6a4445SGunnar Mills { 6119a5aceacSNan Zhou const auto* value = std::get_if<std::string>(&property.second); 612ac6a4445SGunnar Mills if (value != nullptr) 613ac6a4445SGunnar Mills { 614313efb1cSGunnar Mills std::string memoryDeviceType = 615313efb1cSGunnar Mills translateMemoryTypeToRedfish(*value); 616313efb1cSGunnar Mills // Values like "Unknown" or "Other" will return empty 617313efb1cSGunnar Mills // so just leave off 618313efb1cSGunnar Mills if (!memoryDeviceType.empty()) 619ac6a4445SGunnar Mills { 6209a5aceacSNan Zhou aResp->res.jsonValue["MemoryDeviceType"] = memoryDeviceType; 621ac6a4445SGunnar Mills } 622ac6a4445SGunnar Mills if (value->find("DDR") != std::string::npos) 623ac6a4445SGunnar Mills { 624ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryType"] = "DRAM"; 625ac6a4445SGunnar Mills } 626ac6a4445SGunnar Mills else if (boost::ends_with(*value, "Logical")) 627ac6a4445SGunnar Mills { 628ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryType"] = "IntelOptane"; 629ac6a4445SGunnar Mills } 630ac6a4445SGunnar Mills } 631ac6a4445SGunnar Mills } 632ac6a4445SGunnar Mills // memory location interface 633ac6a4445SGunnar Mills else if (property.first == "Channel" || 634ac6a4445SGunnar Mills property.first == "MemoryController" || 635ac6a4445SGunnar Mills property.first == "Slot" || property.first == "Socket") 636ac6a4445SGunnar Mills { 637ac6a4445SGunnar Mills const std::string* value = 638ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 639ac6a4445SGunnar Mills if (value == nullptr) 640ac6a4445SGunnar Mills { 641ac6a4445SGunnar Mills messages::internalError(aResp->res); 642601af5edSChicago Duan return; 643ac6a4445SGunnar Mills } 6449a5aceacSNan Zhou aResp->res.jsonValue["MemoryLocation"][property.first] = *value; 645ac6a4445SGunnar Mills } 646ee135e24SSunnySrivastava1984 else if (property.first == "SparePartNumber") 647ee135e24SSunnySrivastava1984 { 648ee135e24SSunnySrivastava1984 const std::string* value = 649ee135e24SSunnySrivastava1984 std::get_if<std::string>(&property.second); 650ee135e24SSunnySrivastava1984 if (value == nullptr) 651ee135e24SSunnySrivastava1984 { 652ee135e24SSunnySrivastava1984 messages::internalError(aResp->res); 653601af5edSChicago Duan return; 654ee135e24SSunnySrivastava1984 } 655ee135e24SSunnySrivastava1984 aResp->res.jsonValue["SparePartNumber"] = *value; 656ee135e24SSunnySrivastava1984 } 657ee135e24SSunnySrivastava1984 else if (property.first == "Model") 658ee135e24SSunnySrivastava1984 { 659ee135e24SSunnySrivastava1984 const std::string* value = 660ee135e24SSunnySrivastava1984 std::get_if<std::string>(&property.second); 661ee135e24SSunnySrivastava1984 if (value == nullptr) 662ee135e24SSunnySrivastava1984 { 663ee135e24SSunnySrivastava1984 messages::internalError(aResp->res); 664601af5edSChicago Duan return; 665ee135e24SSunnySrivastava1984 } 666ee135e24SSunnySrivastava1984 aResp->res.jsonValue["Model"] = *value; 667ee135e24SSunnySrivastava1984 } 668ee135e24SSunnySrivastava1984 else if (property.first == "LocationCode") 669ee135e24SSunnySrivastava1984 { 670ee135e24SSunnySrivastava1984 const std::string* value = 671ee135e24SSunnySrivastava1984 std::get_if<std::string>(&property.second); 672ee135e24SSunnySrivastava1984 if (value == nullptr) 673ee135e24SSunnySrivastava1984 { 674ee135e24SSunnySrivastava1984 messages::internalError(aResp->res); 675601af5edSChicago Duan return; 676ee135e24SSunnySrivastava1984 } 6779a5aceacSNan Zhou aResp->res.jsonValue["Location"]["PartLocation"]["ServiceLabel"] = 678ee135e24SSunnySrivastava1984 *value; 679ee135e24SSunnySrivastava1984 } 680ac6a4445SGunnar Mills else 681ac6a4445SGunnar Mills { 68280badf7cSJiaqing Zhao getPersistentMemoryProperties(aResp, property); 683ac6a4445SGunnar Mills } 684ac6a4445SGunnar Mills } 6859a5aceacSNan Zhou } 6869a5aceacSNan Zhou 6879a5aceacSNan Zhou inline void getDimmDataByService(std::shared_ptr<bmcweb::AsyncResp> aResp, 6889a5aceacSNan Zhou const std::string& dimmId, 6899a5aceacSNan Zhou const std::string& service, 6909a5aceacSNan Zhou const std::string& objPath) 6919a5aceacSNan Zhou { 6929a5aceacSNan Zhou auto health = std::make_shared<HealthPopulate>(aResp); 6939a5aceacSNan Zhou health->selfPath = objPath; 6949a5aceacSNan Zhou health->populate(); 6959a5aceacSNan Zhou 6969a5aceacSNan Zhou BMCWEB_LOG_DEBUG << "Get available system components."; 6979a5aceacSNan Zhou crow::connections::systemBus->async_method_call( 6989a5aceacSNan Zhou [dimmId, aResp{std::move(aResp)}]( 6999a5aceacSNan Zhou const boost::system::error_code ec, 7009a5aceacSNan Zhou const dbus::utility::DBusPropertiesMap& properties) { 7019a5aceacSNan Zhou if (ec) 7029a5aceacSNan Zhou { 7039a5aceacSNan Zhou BMCWEB_LOG_DEBUG << "DBUS response error"; 7049a5aceacSNan Zhou messages::internalError(aResp->res); 7059a5aceacSNan Zhou return; 7069a5aceacSNan Zhou } 7079a5aceacSNan Zhou assembleDimmProperties(dimmId, aResp, properties); 708ac6a4445SGunnar Mills }, 709ac6a4445SGunnar Mills service, objPath, "org.freedesktop.DBus.Properties", "GetAll", ""); 710ac6a4445SGunnar Mills } 711ac6a4445SGunnar Mills 712ef00d7d4SNan Zhou inline void assembleDimmPartitionData( 713ef00d7d4SNan Zhou const std::shared_ptr<bmcweb::AsyncResp>& aResp, 714ef00d7d4SNan Zhou const dbus::utility::DBusPropertiesMap& properties) 715ac6a4445SGunnar Mills { 716ac6a4445SGunnar Mills nlohmann::json& partition = 717ef00d7d4SNan Zhou aResp->res.jsonValue["Regions"].emplace_back(nlohmann::json::object()); 718ac6a4445SGunnar Mills for (const auto& [key, val] : properties) 719ac6a4445SGunnar Mills { 720ac6a4445SGunnar Mills if (key == "MemoryClassification") 721ac6a4445SGunnar Mills { 722ac6a4445SGunnar Mills const std::string* value = std::get_if<std::string>(&val); 723ac6a4445SGunnar Mills if (value == nullptr) 724ac6a4445SGunnar Mills { 725ac6a4445SGunnar Mills messages::internalError(aResp->res); 726601af5edSChicago Duan return; 727ac6a4445SGunnar Mills } 728ac6a4445SGunnar Mills partition[key] = *value; 729ac6a4445SGunnar Mills } 730ac6a4445SGunnar Mills else if (key == "OffsetInKiB") 731ac6a4445SGunnar Mills { 732ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&val); 733ac6a4445SGunnar Mills if (value == nullptr) 734ac6a4445SGunnar Mills { 735ac6a4445SGunnar Mills messages::internalError(aResp->res); 736601af5edSChicago Duan return; 737ac6a4445SGunnar Mills } 738ac6a4445SGunnar Mills 739ac6a4445SGunnar Mills partition["OffsetMiB"] = (*value >> 10); 740ac6a4445SGunnar Mills } 741ac6a4445SGunnar Mills else if (key == "PartitionId") 742ac6a4445SGunnar Mills { 743ac6a4445SGunnar Mills const std::string* value = std::get_if<std::string>(&val); 744ac6a4445SGunnar Mills if (value == nullptr) 745ac6a4445SGunnar Mills { 746ac6a4445SGunnar Mills messages::internalError(aResp->res); 747601af5edSChicago Duan return; 748ac6a4445SGunnar Mills } 749ac6a4445SGunnar Mills partition["RegionId"] = *value; 750ac6a4445SGunnar Mills } 751ac6a4445SGunnar Mills 752ac6a4445SGunnar Mills else if (key == "PassphraseState") 753ac6a4445SGunnar Mills { 754ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&val); 755ac6a4445SGunnar Mills if (value == nullptr) 756ac6a4445SGunnar Mills { 757ac6a4445SGunnar Mills messages::internalError(aResp->res); 758601af5edSChicago Duan return; 759ac6a4445SGunnar Mills } 760ac6a4445SGunnar Mills partition["PassphraseEnabled"] = *value; 761ac6a4445SGunnar Mills } 762ac6a4445SGunnar Mills else if (key == "SizeInKiB") 763ac6a4445SGunnar Mills { 764ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&val); 765ac6a4445SGunnar Mills if (value == nullptr) 766ac6a4445SGunnar Mills { 767ac6a4445SGunnar Mills messages::internalError(aResp->res); 768ef00d7d4SNan Zhou BMCWEB_LOG_DEBUG << "Invalid property type for SizeInKiB"; 769601af5edSChicago Duan return; 770ac6a4445SGunnar Mills } 771ac6a4445SGunnar Mills partition["SizeMiB"] = (*value >> 10); 772ac6a4445SGunnar Mills } 773ac6a4445SGunnar Mills } 774ef00d7d4SNan Zhou } 775ef00d7d4SNan Zhou 776ef00d7d4SNan Zhou inline void getDimmPartitionData(std::shared_ptr<bmcweb::AsyncResp> aResp, 777ef00d7d4SNan Zhou const std::string& service, 778ef00d7d4SNan Zhou const std::string& path) 779ef00d7d4SNan Zhou { 780ef00d7d4SNan Zhou crow::connections::systemBus->async_method_call( 781ef00d7d4SNan Zhou [aResp{std::move(aResp)}]( 782ef00d7d4SNan Zhou const boost::system::error_code ec, 783ef00d7d4SNan Zhou const dbus::utility::DBusPropertiesMap& properties) { 784ef00d7d4SNan Zhou if (ec) 785ef00d7d4SNan Zhou { 786ef00d7d4SNan Zhou BMCWEB_LOG_DEBUG << "DBUS response error"; 787ef00d7d4SNan Zhou messages::internalError(aResp->res); 788ef00d7d4SNan Zhou 789ef00d7d4SNan Zhou return; 790ef00d7d4SNan Zhou } 791ef00d7d4SNan Zhou assembleDimmPartitionData(aResp, properties); 792ac6a4445SGunnar Mills }, 793ac6a4445SGunnar Mills 794ac6a4445SGunnar Mills service, path, "org.freedesktop.DBus.Properties", "GetAll", 795ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"); 796ac6a4445SGunnar Mills } 797ac6a4445SGunnar Mills 7988d1b46d7Szhanghch05 inline void getDimmData(std::shared_ptr<bmcweb::AsyncResp> aResp, 799ac6a4445SGunnar Mills const std::string& dimmId) 800ac6a4445SGunnar Mills { 801ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Get available system dimm resources."; 802ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 803ac6a4445SGunnar Mills [dimmId, aResp{std::move(aResp)}]( 804ac6a4445SGunnar Mills const boost::system::error_code ec, 805b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 806ac6a4445SGunnar Mills if (ec) 807ac6a4445SGunnar Mills { 808ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 809ac6a4445SGunnar Mills messages::internalError(aResp->res); 810ac6a4445SGunnar Mills 811ac6a4445SGunnar Mills return; 812ac6a4445SGunnar Mills } 813ac6a4445SGunnar Mills bool found = false; 814ac6a4445SGunnar Mills for (const auto& [path, object] : subtree) 815ac6a4445SGunnar Mills { 816ac6a4445SGunnar Mills if (path.find(dimmId) != std::string::npos) 817ac6a4445SGunnar Mills { 818ac6a4445SGunnar Mills for (const auto& [service, interfaces] : object) 819ac6a4445SGunnar Mills { 820b9d36b47SEd Tanous for (const auto& interface : interfaces) 821ac6a4445SGunnar Mills { 822b9d36b47SEd Tanous if (interface == 823b9d36b47SEd Tanous "xyz.openbmc_project.Inventory.Item.Dimm") 824b9d36b47SEd Tanous { 825*002d39b4SEd Tanous getDimmDataByService(aResp, dimmId, service, path); 826ac6a4445SGunnar Mills found = true; 827ac6a4445SGunnar Mills } 828ac6a4445SGunnar Mills 829b9d36b47SEd Tanous // partitions are separate as there can be multiple 830b9d36b47SEd Tanous // per 831ac6a4445SGunnar Mills // device, i.e. 832ac6a4445SGunnar Mills // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1 833ac6a4445SGunnar Mills // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2 834b9d36b47SEd Tanous if (interface == 835b9d36b47SEd Tanous "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition") 836ac6a4445SGunnar Mills { 837ac6a4445SGunnar Mills getDimmPartitionData(aResp, service, path); 838ac6a4445SGunnar Mills } 839ac6a4445SGunnar Mills } 840ac6a4445SGunnar Mills } 841ac6a4445SGunnar Mills } 842b9d36b47SEd Tanous } 843ac6a4445SGunnar Mills // Object not found 844ac6a4445SGunnar Mills if (!found) 845ac6a4445SGunnar Mills { 846ac6a4445SGunnar Mills messages::resourceNotFound(aResp->res, "Memory", dimmId); 8471a1d5d6dSNan Zhou return; 848ac6a4445SGunnar Mills } 8491a1d5d6dSNan Zhou // Set @odata only if object is found 8501a1d5d6dSNan Zhou aResp->res.jsonValue["@odata.type"] = "#Memory.v1_11_0.Memory"; 8511a1d5d6dSNan Zhou aResp->res.jsonValue["@odata.id"] = 8521a1d5d6dSNan Zhou "/redfish/v1/Systems/system/Memory/" + dimmId; 853ac6a4445SGunnar Mills return; 854ac6a4445SGunnar Mills }, 855ac6a4445SGunnar Mills "xyz.openbmc_project.ObjectMapper", 856ac6a4445SGunnar Mills "/xyz/openbmc_project/object_mapper", 857ac6a4445SGunnar Mills "xyz.openbmc_project.ObjectMapper", "GetSubTree", 858ac6a4445SGunnar Mills "/xyz/openbmc_project/inventory", 0, 859ac6a4445SGunnar Mills std::array<const char*, 2>{ 860ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm", 861ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"}); 862ac6a4445SGunnar Mills } 863ac6a4445SGunnar Mills 8647e860f15SJohn Edward Broadbent inline void requestRoutesMemoryCollection(App& app) 865ac6a4445SGunnar Mills { 866ac6a4445SGunnar Mills /** 867ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 868ac6a4445SGunnar Mills */ 8697e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Memory/") 870ed398213SEd Tanous .privileges(redfish::privileges::getMemoryCollection) 8717e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 87245ca1b86SEd Tanous [&app](const crow::Request& req, 8737e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 87445ca1b86SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp->res)) 87545ca1b86SEd Tanous { 87645ca1b86SEd Tanous return; 87745ca1b86SEd Tanous } 8788d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 8798d1b46d7Szhanghch05 "#MemoryCollection.MemoryCollection"; 8808d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Memory Module Collection"; 8818d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = 8828d1b46d7Szhanghch05 "/redfish/v1/Systems/system/Memory"; 883ac6a4445SGunnar Mills 88405030b8eSGunnar Mills collection_util::getCollectionMembers( 88505030b8eSGunnar Mills asyncResp, "/redfish/v1/Systems/system/Memory", 88605030b8eSGunnar Mills {"xyz.openbmc_project.Inventory.Item.Dimm"}); 8877e860f15SJohn Edward Broadbent }); 888ac6a4445SGunnar Mills } 889ac6a4445SGunnar Mills 8907e860f15SJohn Edward Broadbent inline void requestRoutesMemory(App& app) 8917e860f15SJohn Edward Broadbent { 892ac6a4445SGunnar Mills /** 893ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 894ac6a4445SGunnar Mills */ 8957e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Memory/<str>/") 896ed398213SEd Tanous .privileges(redfish::privileges::getMemory) 8977e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 89845ca1b86SEd Tanous [&app](const crow::Request& req, 8997e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 9007e860f15SJohn Edward Broadbent const std::string& dimmId) { 90145ca1b86SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp->res)) 90245ca1b86SEd Tanous { 90345ca1b86SEd Tanous return; 90445ca1b86SEd Tanous } 905ac6a4445SGunnar Mills getDimmData(asyncResp, dimmId); 9067e860f15SJohn Edward Broadbent }); 907ac6a4445SGunnar Mills } 908ac6a4445SGunnar Mills 909ac6a4445SGunnar Mills } // namespace redfish 910