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> 217267c21dSSui Chen #include <boost/algorithm/string.hpp> 22168e20c1SEd Tanous #include <dbus_utility.hpp> 2345ca1b86SEd Tanous #include <query.hpp> 24ed398213SEd Tanous #include <registries/privilege_registry.hpp> 25ac6a4445SGunnar Mills #include <utils/collection.hpp> 26f201ffb4SEd Tanous #include <utils/hex_utils.hpp> 27ac6a4445SGunnar Mills #include <utils/json_utils.hpp> 28ac6a4445SGunnar Mills 29ac6a4445SGunnar Mills namespace redfish 30ac6a4445SGunnar Mills { 31ac6a4445SGunnar Mills 32313efb1cSGunnar Mills inline std::string translateMemoryTypeToRedfish(const std::string& memoryType) 33313efb1cSGunnar Mills { 34313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR") 35313efb1cSGunnar Mills { 36313efb1cSGunnar Mills return "DDR"; 37313efb1cSGunnar Mills } 38313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2") 39313efb1cSGunnar Mills { 40313efb1cSGunnar Mills return "DDR2"; 41313efb1cSGunnar Mills } 42313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR3") 43313efb1cSGunnar Mills { 44313efb1cSGunnar Mills return "DDR3"; 45313efb1cSGunnar Mills } 46313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4") 47313efb1cSGunnar Mills { 48313efb1cSGunnar Mills return "DDR4"; 49313efb1cSGunnar Mills } 50313efb1cSGunnar Mills if (memoryType == 51313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4E_SDRAM") 52313efb1cSGunnar Mills { 53313efb1cSGunnar Mills return "DDR4E_SDRAM"; 54313efb1cSGunnar Mills } 5511a2f0f0SMansi Joshi if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR5") 5611a2f0f0SMansi Joshi { 5711a2f0f0SMansi Joshi return "DDR5"; 5811a2f0f0SMansi Joshi } 59313efb1cSGunnar Mills if (memoryType == 60313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR4_SDRAM") 61313efb1cSGunnar Mills { 62313efb1cSGunnar Mills return "LPDDR4_SDRAM"; 63313efb1cSGunnar Mills } 64313efb1cSGunnar Mills if (memoryType == 65313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR3_SDRAM") 66313efb1cSGunnar Mills { 67313efb1cSGunnar Mills return "LPDDR3_SDRAM"; 68313efb1cSGunnar Mills } 69313efb1cSGunnar Mills if (memoryType == 70313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM") 71313efb1cSGunnar Mills { 72313efb1cSGunnar Mills return "DDR2_SDRAM_FB_DIMM"; 73313efb1cSGunnar Mills } 740fda0f12SGeorge Liu if (memoryType == 750fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM_PROB") 76313efb1cSGunnar Mills { 77313efb1cSGunnar Mills return "DDR2_SDRAM_FB_DIMM_PROBE"; 78313efb1cSGunnar Mills } 79313efb1cSGunnar Mills if (memoryType == 80313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR_SGRAM") 81313efb1cSGunnar Mills { 82313efb1cSGunnar Mills return "DDR_SGRAM"; 83313efb1cSGunnar Mills } 84313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.ROM") 85313efb1cSGunnar Mills { 86313efb1cSGunnar Mills return "ROM"; 87313efb1cSGunnar Mills } 88313efb1cSGunnar Mills if (memoryType == 89313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.SDRAM") 90313efb1cSGunnar Mills { 91313efb1cSGunnar Mills return "SDRAM"; 92313efb1cSGunnar Mills } 93313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.EDO") 94313efb1cSGunnar Mills { 95313efb1cSGunnar Mills return "EDO"; 96313efb1cSGunnar Mills } 97313efb1cSGunnar Mills if (memoryType == 98313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.FastPageMode") 99313efb1cSGunnar Mills { 100313efb1cSGunnar Mills return "FastPageMode"; 101313efb1cSGunnar Mills } 102313efb1cSGunnar Mills if (memoryType == 103313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.PipelinedNibble") 104313efb1cSGunnar Mills { 105313efb1cSGunnar Mills return "PipelinedNibble"; 106313efb1cSGunnar Mills } 107313efb1cSGunnar Mills if (memoryType == 108313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.Logical") 109313efb1cSGunnar Mills { 110313efb1cSGunnar Mills return "Logical"; 111313efb1cSGunnar Mills } 112313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM") 113313efb1cSGunnar Mills { 114313efb1cSGunnar Mills return "HBM"; 115313efb1cSGunnar Mills } 116313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM2") 117313efb1cSGunnar Mills { 118313efb1cSGunnar Mills return "HBM2"; 119313efb1cSGunnar Mills } 120313efb1cSGunnar Mills // This is values like Other or Unknown 121313efb1cSGunnar Mills // Also D-Bus values: 122313efb1cSGunnar Mills // DRAM 123313efb1cSGunnar Mills // EDRAM 124313efb1cSGunnar Mills // VRAM 125313efb1cSGunnar Mills // SRAM 126313efb1cSGunnar Mills // RAM 127313efb1cSGunnar Mills // FLASH 128313efb1cSGunnar Mills // EEPROM 129313efb1cSGunnar Mills // FEPROM 130313efb1cSGunnar Mills // EPROM 131313efb1cSGunnar Mills // CDRAM 132313efb1cSGunnar Mills // ThreeDRAM 133313efb1cSGunnar Mills // RDRAM 134313efb1cSGunnar Mills // FBD2 135313efb1cSGunnar Mills // LPDDR_SDRAM 136313efb1cSGunnar Mills // LPDDR2_SDRAM 13711a2f0f0SMansi Joshi // LPDDR5_SDRAM 138313efb1cSGunnar Mills return ""; 139313efb1cSGunnar Mills } 140313efb1cSGunnar Mills 141168e20c1SEd Tanous inline void dimmPropToHex( 142168e20c1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& aResp, const char* key, 143168e20c1SEd Tanous const std::pair<std::string, dbus::utility::DbusVariantType>& property) 144ac6a4445SGunnar Mills { 145ac6a4445SGunnar Mills const uint16_t* value = std::get_if<uint16_t>(&property.second); 146ac6a4445SGunnar Mills if (value == nullptr) 147ac6a4445SGunnar Mills { 148ac6a4445SGunnar Mills messages::internalError(aResp->res); 149ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for " << property.first; 150ac6a4445SGunnar Mills return; 151ac6a4445SGunnar Mills } 152ac6a4445SGunnar Mills 153866e4862SEd Tanous aResp->res.jsonValue[key] = "0x" + intToHexString(*value, 4); 154ac6a4445SGunnar Mills } 155ac6a4445SGunnar Mills 1568d1b46d7Szhanghch05 inline void getPersistentMemoryProperties( 1578d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aResp, 15880badf7cSJiaqing Zhao const std::pair<std::string, dbus::utility::DbusVariantType>& property) 159ac6a4445SGunnar Mills { 160ac6a4445SGunnar Mills if (property.first == "ModuleManufacturerID") 161ac6a4445SGunnar Mills { 162ac6a4445SGunnar Mills dimmPropToHex(aResp, "ModuleManufacturerID", property); 163ac6a4445SGunnar Mills } 164ac6a4445SGunnar Mills else if (property.first == "ModuleProductID") 165ac6a4445SGunnar Mills { 166ac6a4445SGunnar Mills dimmPropToHex(aResp, "ModuleProductID", property); 167ac6a4445SGunnar Mills } 168ac6a4445SGunnar Mills else if (property.first == "SubsystemVendorID") 169ac6a4445SGunnar Mills { 170ac6a4445SGunnar Mills dimmPropToHex(aResp, "MemorySubsystemControllerManufacturerID", 171ac6a4445SGunnar Mills property); 172ac6a4445SGunnar Mills } 173ac6a4445SGunnar Mills else if (property.first == "SubsystemDeviceID") 174ac6a4445SGunnar Mills { 17580badf7cSJiaqing Zhao dimmPropToHex(aResp, "MemorySubsystemControllerProductID", property); 176ac6a4445SGunnar Mills } 177ac6a4445SGunnar Mills else if (property.first == "VolatileRegionSizeLimitInKiB") 178ac6a4445SGunnar Mills { 179ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 180ac6a4445SGunnar Mills 181ac6a4445SGunnar Mills if (value == nullptr) 182ac6a4445SGunnar Mills { 183ac6a4445SGunnar Mills messages::internalError(aResp->res); 1840fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 1850fda0f12SGeorge Liu << "Invalid property type for VolatileRegionSizeLimitKiB"; 186601af5edSChicago Duan return; 187ac6a4445SGunnar Mills } 188ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileRegionSizeLimitMiB"] = (*value) >> 10; 189ac6a4445SGunnar Mills } 190ac6a4445SGunnar Mills else if (property.first == "PmRegionSizeLimitInKiB") 191ac6a4445SGunnar Mills { 192ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 193ac6a4445SGunnar Mills 194ac6a4445SGunnar Mills if (value == nullptr) 195ac6a4445SGunnar Mills { 196ac6a4445SGunnar Mills messages::internalError(aResp->res); 19780badf7cSJiaqing Zhao BMCWEB_LOG_DEBUG << "Invalid property type for PmRegioSizeLimitKiB"; 198601af5edSChicago Duan return; 199ac6a4445SGunnar Mills } 20080badf7cSJiaqing Zhao aResp->res.jsonValue["PersistentRegionSizeLimitMiB"] = (*value) >> 10; 201ac6a4445SGunnar Mills } 202ac6a4445SGunnar Mills else if (property.first == "VolatileSizeInKiB") 203ac6a4445SGunnar Mills { 204ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 205ac6a4445SGunnar Mills 206ac6a4445SGunnar Mills if (value == nullptr) 207ac6a4445SGunnar Mills { 208ac6a4445SGunnar Mills messages::internalError(aResp->res); 20980badf7cSJiaqing Zhao BMCWEB_LOG_DEBUG << "Invalid property type for VolatileSizeInKiB"; 210601af5edSChicago Duan return; 211ac6a4445SGunnar Mills } 212ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileSizeMiB"] = (*value) >> 10; 213ac6a4445SGunnar Mills } 214ac6a4445SGunnar Mills else if (property.first == "PmSizeInKiB") 215ac6a4445SGunnar Mills { 216ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 217ac6a4445SGunnar Mills if (value == nullptr) 218ac6a4445SGunnar Mills { 219ac6a4445SGunnar Mills messages::internalError(aResp->res); 220ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for PmSizeInKiB"; 221601af5edSChicago Duan return; 222ac6a4445SGunnar Mills } 223ac6a4445SGunnar Mills aResp->res.jsonValue["NonVolatileSizeMiB"] = (*value) >> 10; 224ac6a4445SGunnar Mills } 225ac6a4445SGunnar Mills else if (property.first == "CacheSizeInKB") 226ac6a4445SGunnar Mills { 227ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 228ac6a4445SGunnar Mills if (value == nullptr) 229ac6a4445SGunnar Mills { 230ac6a4445SGunnar Mills messages::internalError(aResp->res); 231ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for CacheSizeInKB"; 232601af5edSChicago Duan return; 233ac6a4445SGunnar Mills } 234ac6a4445SGunnar Mills aResp->res.jsonValue["CacheSizeMiB"] = (*value >> 10); 235ac6a4445SGunnar Mills } 236ac6a4445SGunnar Mills 237ac6a4445SGunnar Mills else if (property.first == "VoltaileRegionMaxSizeInKib") 238ac6a4445SGunnar Mills { 239ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 240ac6a4445SGunnar Mills 241ac6a4445SGunnar Mills if (value == nullptr) 242ac6a4445SGunnar Mills { 243ac6a4445SGunnar Mills messages::internalError(aResp->res); 2440fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 2450fda0f12SGeorge Liu << "Invalid property type for VolatileRegionMaxSizeInKib"; 246601af5edSChicago Duan return; 247ac6a4445SGunnar Mills } 248ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileRegionSizeMaxMiB"] = (*value) >> 10; 249ac6a4445SGunnar Mills } 250ac6a4445SGunnar Mills else if (property.first == "PmRegionMaxSizeInKiB") 251ac6a4445SGunnar Mills { 252ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 253ac6a4445SGunnar Mills 254ac6a4445SGunnar Mills if (value == nullptr) 255ac6a4445SGunnar Mills { 256ac6a4445SGunnar Mills messages::internalError(aResp->res); 257ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 258ac6a4445SGunnar Mills << "Invalid property type for PmRegionMaxSizeInKiB"; 259601af5edSChicago Duan return; 260ac6a4445SGunnar Mills } 261ac6a4445SGunnar Mills aResp->res.jsonValue["PersistentRegionSizeMaxMiB"] = (*value) >> 10; 262ac6a4445SGunnar Mills } 263ac6a4445SGunnar Mills else if (property.first == "AllocationIncrementInKiB") 264ac6a4445SGunnar Mills { 265ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 266ac6a4445SGunnar Mills 267ac6a4445SGunnar Mills if (value == nullptr) 268ac6a4445SGunnar Mills { 269ac6a4445SGunnar Mills messages::internalError(aResp->res); 2700fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 2710fda0f12SGeorge Liu << "Invalid property type for AllocationIncrementInKiB"; 272601af5edSChicago Duan return; 273ac6a4445SGunnar Mills } 274ac6a4445SGunnar Mills aResp->res.jsonValue["AllocationIncrementMiB"] = (*value) >> 10; 275ac6a4445SGunnar Mills } 276ac6a4445SGunnar Mills else if (property.first == "AllocationAlignmentInKiB") 277ac6a4445SGunnar Mills { 278ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 279ac6a4445SGunnar Mills 280ac6a4445SGunnar Mills if (value == nullptr) 281ac6a4445SGunnar Mills { 282ac6a4445SGunnar Mills messages::internalError(aResp->res); 2830fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 2840fda0f12SGeorge Liu << "Invalid property type for AllocationAlignmentInKiB"; 285601af5edSChicago Duan return; 286ac6a4445SGunnar Mills } 287ac6a4445SGunnar Mills aResp->res.jsonValue["AllocationAlignmentMiB"] = (*value) >> 10; 288ac6a4445SGunnar Mills } 289ac6a4445SGunnar Mills else if (property.first == "VolatileRegionNumberLimit") 290ac6a4445SGunnar Mills { 291ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 292ac6a4445SGunnar Mills if (value == nullptr) 293ac6a4445SGunnar Mills { 294ac6a4445SGunnar Mills messages::internalError(aResp->res); 295601af5edSChicago Duan return; 296ac6a4445SGunnar Mills } 297ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileRegionNumberLimit"] = *value; 298ac6a4445SGunnar Mills } 299ac6a4445SGunnar Mills else if (property.first == "PmRegionNumberLimit") 300ac6a4445SGunnar Mills { 301ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 302ac6a4445SGunnar Mills if (value == nullptr) 303ac6a4445SGunnar Mills { 304ac6a4445SGunnar Mills messages::internalError(aResp->res); 305601af5edSChicago Duan return; 306ac6a4445SGunnar Mills } 307ac6a4445SGunnar Mills aResp->res.jsonValue["PersistentRegionNumberLimit"] = *value; 308ac6a4445SGunnar Mills } 309ac6a4445SGunnar Mills else if (property.first == "SpareDeviceCount") 310ac6a4445SGunnar Mills { 311ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 312ac6a4445SGunnar Mills if (value == nullptr) 313ac6a4445SGunnar Mills { 314ac6a4445SGunnar Mills messages::internalError(aResp->res); 315601af5edSChicago Duan return; 316ac6a4445SGunnar Mills } 317ac6a4445SGunnar Mills aResp->res.jsonValue["SpareDeviceCount"] = *value; 318ac6a4445SGunnar Mills } 319ac6a4445SGunnar Mills else if (property.first == "IsSpareDeviceInUse") 320ac6a4445SGunnar Mills { 321ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 322ac6a4445SGunnar Mills if (value == nullptr) 323ac6a4445SGunnar Mills { 324ac6a4445SGunnar Mills messages::internalError(aResp->res); 325601af5edSChicago Duan return; 326ac6a4445SGunnar Mills } 327ac6a4445SGunnar Mills aResp->res.jsonValue["IsSpareDeviceEnabled"] = *value; 328ac6a4445SGunnar Mills } 329ac6a4445SGunnar Mills else if (property.first == "IsRankSpareEnabled") 330ac6a4445SGunnar Mills { 331ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 332ac6a4445SGunnar Mills if (value == nullptr) 333ac6a4445SGunnar Mills { 334ac6a4445SGunnar Mills messages::internalError(aResp->res); 335601af5edSChicago Duan return; 336ac6a4445SGunnar Mills } 337ac6a4445SGunnar Mills aResp->res.jsonValue["IsRankSpareEnabled"] = *value; 338ac6a4445SGunnar Mills } 339ac6a4445SGunnar Mills else if (property.first == "MaxAveragePowerLimitmW") 340ac6a4445SGunnar Mills { 341ac6a4445SGunnar Mills const auto* value = 342ac6a4445SGunnar Mills std::get_if<std::vector<uint32_t>>(&property.second); 343ac6a4445SGunnar Mills if (value == nullptr) 344ac6a4445SGunnar Mills { 345ac6a4445SGunnar Mills messages::internalError(aResp->res); 3460fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 3470fda0f12SGeorge Liu << "Invalid property type for MaxAveragePowerLimitmW"; 348601af5edSChicago Duan return; 349ac6a4445SGunnar Mills } 350ac6a4445SGunnar Mills aResp->res.jsonValue["MaxTDPMilliWatts"] = *value; 351ac6a4445SGunnar Mills } 352ac6a4445SGunnar Mills else if (property.first == "ConfigurationLocked") 353ac6a4445SGunnar Mills { 354ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 355ac6a4445SGunnar Mills if (value == nullptr) 356ac6a4445SGunnar Mills { 357ac6a4445SGunnar Mills messages::internalError(aResp->res); 358601af5edSChicago Duan return; 359ac6a4445SGunnar Mills } 360ac6a4445SGunnar Mills aResp->res.jsonValue["ConfigurationLocked"] = *value; 361ac6a4445SGunnar Mills } 362ac6a4445SGunnar Mills else if (property.first == "AllowedMemoryModes") 363ac6a4445SGunnar Mills { 36480badf7cSJiaqing Zhao const std::string* value = std::get_if<std::string>(&property.second); 365ac6a4445SGunnar Mills if (value == nullptr) 366ac6a4445SGunnar Mills { 367ac6a4445SGunnar Mills messages::internalError(aResp->res); 368ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for FormFactor"; 369601af5edSChicago Duan return; 370ac6a4445SGunnar Mills } 37180badf7cSJiaqing Zhao constexpr const std::array<const char*, 3> values{"Volatile", "PMEM", 37280badf7cSJiaqing Zhao "Block"}; 373ac6a4445SGunnar Mills 374ac6a4445SGunnar Mills for (const char* v : values) 375ac6a4445SGunnar Mills { 376ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 377ac6a4445SGunnar Mills { 3781e04f3b2SJiaqing Zhao aResp->res.jsonValue["OperatingMemoryModes"].push_back(v); 379ac6a4445SGunnar Mills break; 380ac6a4445SGunnar Mills } 381ac6a4445SGunnar Mills } 382ac6a4445SGunnar Mills } 383ac6a4445SGunnar Mills else if (property.first == "MemoryMedia") 384ac6a4445SGunnar Mills { 38580badf7cSJiaqing Zhao const std::string* value = std::get_if<std::string>(&property.second); 386ac6a4445SGunnar Mills if (value == nullptr) 387ac6a4445SGunnar Mills { 388ac6a4445SGunnar Mills messages::internalError(aResp->res); 389ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for MemoryMedia"; 390601af5edSChicago Duan return; 391ac6a4445SGunnar Mills } 392ac6a4445SGunnar Mills constexpr const std::array<const char*, 3> values{"DRAM", "NAND", 393ac6a4445SGunnar Mills "Intel3DXPoint"}; 394ac6a4445SGunnar Mills 395ac6a4445SGunnar Mills for (const char* v : values) 396ac6a4445SGunnar Mills { 397ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 398ac6a4445SGunnar Mills { 3991e04f3b2SJiaqing Zhao aResp->res.jsonValue["MemoryMedia"].push_back(v); 400ac6a4445SGunnar Mills break; 401ac6a4445SGunnar Mills } 402ac6a4445SGunnar Mills } 403ac6a4445SGunnar Mills } 404ac6a4445SGunnar Mills // PersistantMemory.SecurityCapabilites interface 405ac6a4445SGunnar Mills else if (property.first == "ConfigurationLockCapable" || 406ac6a4445SGunnar Mills property.first == "DataLockCapable" || 407ac6a4445SGunnar Mills property.first == "PassphraseCapable") 408ac6a4445SGunnar Mills { 409ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 410ac6a4445SGunnar Mills if (value == nullptr) 411ac6a4445SGunnar Mills { 412ac6a4445SGunnar Mills messages::internalError(aResp->res); 413601af5edSChicago Duan return; 414ac6a4445SGunnar Mills } 41580badf7cSJiaqing Zhao aResp->res.jsonValue["SecurityCapabilities"][property.first] = *value; 416ac6a4445SGunnar Mills } 417ac6a4445SGunnar Mills else if (property.first == "MaxPassphraseCount" || 418ac6a4445SGunnar Mills property.first == "PassphraseLockLimit") 419ac6a4445SGunnar Mills { 420ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 421ac6a4445SGunnar Mills if (value == nullptr) 422ac6a4445SGunnar Mills { 423ac6a4445SGunnar Mills messages::internalError(aResp->res); 424601af5edSChicago Duan return; 425ac6a4445SGunnar Mills } 42680badf7cSJiaqing Zhao aResp->res.jsonValue["SecurityCapabilities"][property.first] = *value; 427ac6a4445SGunnar Mills } 428ac6a4445SGunnar Mills } 429ac6a4445SGunnar Mills 4309a5aceacSNan Zhou inline void 4319a5aceacSNan Zhou assembleDimmProperties(std::string_view dimmId, 4329a5aceacSNan Zhou const std::shared_ptr<bmcweb::AsyncResp>& aResp, 4339a5aceacSNan Zhou const dbus::utility::DBusPropertiesMap& properties) 434ac6a4445SGunnar Mills { 435ac6a4445SGunnar Mills aResp->res.jsonValue["Id"] = dimmId; 436ac6a4445SGunnar Mills aResp->res.jsonValue["Name"] = "DIMM Slot"; 437ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["State"] = "Enabled"; 438ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["Health"] = "OK"; 439ac6a4445SGunnar Mills 440ac6a4445SGunnar Mills for (const auto& property : properties) 441ac6a4445SGunnar Mills { 442ac6a4445SGunnar Mills if (property.first == "MemoryDataWidth") 443ac6a4445SGunnar Mills { 4449a5aceacSNan Zhou const uint16_t* value = std::get_if<uint16_t>(&property.second); 445ac6a4445SGunnar Mills if (value == nullptr) 446ac6a4445SGunnar Mills { 447ac6a4445SGunnar Mills continue; 448ac6a4445SGunnar Mills } 449ac6a4445SGunnar Mills aResp->res.jsonValue["DataWidthBits"] = *value; 450ac6a4445SGunnar Mills } 451b9d36b47SEd Tanous else if (property.first == "MemorySizeInKB") 452b9d36b47SEd Tanous { 4539a5aceacSNan Zhou const size_t* memorySize = std::get_if<size_t>(&property.second); 454b9d36b47SEd Tanous if (memorySize == nullptr) 455b9d36b47SEd Tanous { 456b9d36b47SEd Tanous // Important property not in desired type 457b9d36b47SEd Tanous messages::internalError(aResp->res); 458b9d36b47SEd Tanous return; 459b9d36b47SEd Tanous } 460b9d36b47SEd Tanous aResp->res.jsonValue["CapacityMiB"] = (*memorySize >> 10); 461b9d36b47SEd Tanous } 462ac6a4445SGunnar Mills else if (property.first == "PartNumber") 463ac6a4445SGunnar Mills { 464ac6a4445SGunnar Mills const std::string* value = 465ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 466ac6a4445SGunnar Mills if (value == nullptr) 467ac6a4445SGunnar Mills { 468ac6a4445SGunnar Mills continue; 469ac6a4445SGunnar Mills } 470ac6a4445SGunnar Mills aResp->res.jsonValue["PartNumber"] = *value; 471ac6a4445SGunnar Mills } 472ac6a4445SGunnar Mills else if (property.first == "SerialNumber") 473ac6a4445SGunnar Mills { 474ac6a4445SGunnar Mills const std::string* value = 475ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 476ac6a4445SGunnar Mills if (value == nullptr) 477ac6a4445SGunnar Mills { 478ac6a4445SGunnar Mills continue; 479ac6a4445SGunnar Mills } 480ac6a4445SGunnar Mills aResp->res.jsonValue["SerialNumber"] = *value; 481ac6a4445SGunnar Mills } 482ac6a4445SGunnar Mills else if (property.first == "Manufacturer") 483ac6a4445SGunnar Mills { 484ac6a4445SGunnar Mills const std::string* value = 485ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 486ac6a4445SGunnar Mills if (value == nullptr) 487ac6a4445SGunnar Mills { 488ac6a4445SGunnar Mills continue; 489ac6a4445SGunnar Mills } 490ac6a4445SGunnar Mills aResp->res.jsonValue["Manufacturer"] = *value; 491ac6a4445SGunnar Mills } 492ac6a4445SGunnar Mills else if (property.first == "RevisionCode") 493ac6a4445SGunnar Mills { 4949a5aceacSNan Zhou const uint16_t* value = std::get_if<uint16_t>(&property.second); 495ac6a4445SGunnar Mills 496ac6a4445SGunnar Mills if (value == nullptr) 497ac6a4445SGunnar Mills { 498ac6a4445SGunnar Mills messages::internalError(aResp->res); 4999a5aceacSNan Zhou BMCWEB_LOG_DEBUG << "Invalid property type for RevisionCode"; 500601af5edSChicago Duan return; 501ac6a4445SGunnar Mills } 5029a5aceacSNan Zhou aResp->res.jsonValue["FirmwareRevision"] = std::to_string(*value); 503ac6a4445SGunnar Mills } 5049a128eb3SJoshi-Mansi else if (property.first == "Present") 5059a128eb3SJoshi-Mansi { 5069a128eb3SJoshi-Mansi const bool* value = std::get_if<bool>(&property.second); 5079a128eb3SJoshi-Mansi if (value == nullptr) 5089a128eb3SJoshi-Mansi { 5099a128eb3SJoshi-Mansi messages::internalError(aResp->res); 5109a5aceacSNan Zhou BMCWEB_LOG_DEBUG << "Invalid property type for Dimm Presence"; 5119a128eb3SJoshi-Mansi return; 5129a128eb3SJoshi-Mansi } 513e05aec50SEd Tanous if (!*value) 5149a128eb3SJoshi-Mansi { 5159a128eb3SJoshi-Mansi aResp->res.jsonValue["Status"]["State"] = "Absent"; 5169a128eb3SJoshi-Mansi } 5179a128eb3SJoshi-Mansi } 518ac6a4445SGunnar Mills else if (property.first == "MemoryTotalWidth") 519ac6a4445SGunnar Mills { 5209a5aceacSNan Zhou const uint16_t* value = std::get_if<uint16_t>(&property.second); 521ac6a4445SGunnar Mills if (value == nullptr) 522ac6a4445SGunnar Mills { 523ac6a4445SGunnar Mills continue; 524ac6a4445SGunnar Mills } 525ac6a4445SGunnar Mills aResp->res.jsonValue["BusWidthBits"] = *value; 526ac6a4445SGunnar Mills } 527ac6a4445SGunnar Mills else if (property.first == "ECC") 528ac6a4445SGunnar Mills { 529ac6a4445SGunnar Mills const std::string* value = 530ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 531ac6a4445SGunnar Mills if (value == nullptr) 532ac6a4445SGunnar Mills { 533ac6a4445SGunnar Mills messages::internalError(aResp->res); 534ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for ECC"; 535601af5edSChicago Duan return; 536ac6a4445SGunnar Mills } 537ac6a4445SGunnar Mills constexpr const std::array<const char*, 4> values{ 5389a5aceacSNan Zhou "NoECC", "SingleBitECC", "MultiBitECC", "AddressParity"}; 539ac6a4445SGunnar Mills 540ac6a4445SGunnar Mills for (const char* v : values) 541ac6a4445SGunnar Mills { 542ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 543ac6a4445SGunnar Mills { 544ac6a4445SGunnar Mills aResp->res.jsonValue["ErrorCorrection"] = v; 545ac6a4445SGunnar Mills break; 546ac6a4445SGunnar Mills } 547ac6a4445SGunnar Mills } 548ac6a4445SGunnar Mills } 549ac6a4445SGunnar Mills else if (property.first == "FormFactor") 550ac6a4445SGunnar Mills { 551ac6a4445SGunnar Mills const std::string* value = 552ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 553ac6a4445SGunnar Mills if (value == nullptr) 554ac6a4445SGunnar Mills { 555ac6a4445SGunnar Mills messages::internalError(aResp->res); 5569a5aceacSNan Zhou BMCWEB_LOG_DEBUG << "Invalid property type for FormFactor"; 557601af5edSChicago Duan return; 558ac6a4445SGunnar Mills } 559ac6a4445SGunnar Mills constexpr const std::array<const char*, 11> values{ 5609a5aceacSNan Zhou "RDIMM", "UDIMM", "SO_DIMM", "LRDIMM", 5619a5aceacSNan Zhou "Mini_RDIMM", "Mini_UDIMM", "SO_RDIMM_72b", "SO_UDIMM_72b", 5629a5aceacSNan Zhou "SO_DIMM_16b", "SO_DIMM_32b", "Die"}; 563ac6a4445SGunnar Mills 564ac6a4445SGunnar Mills for (const char* v : values) 565ac6a4445SGunnar Mills { 566ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 567ac6a4445SGunnar Mills { 568ac6a4445SGunnar Mills aResp->res.jsonValue["BaseModuleType"] = v; 569ac6a4445SGunnar Mills break; 570ac6a4445SGunnar Mills } 571ac6a4445SGunnar Mills } 572ac6a4445SGunnar Mills } 573ac6a4445SGunnar Mills else if (property.first == "AllowedSpeedsMT") 574ac6a4445SGunnar Mills { 575ac6a4445SGunnar Mills const std::vector<uint16_t>* value = 576ac6a4445SGunnar Mills std::get_if<std::vector<uint16_t>>(&property.second); 577ac6a4445SGunnar Mills if (value == nullptr) 578ac6a4445SGunnar Mills { 579ac6a4445SGunnar Mills continue; 580ac6a4445SGunnar Mills } 5819a5aceacSNan Zhou nlohmann::json& jValue = aResp->res.jsonValue["AllowedSpeedsMHz"]; 582ac6a4445SGunnar Mills jValue = nlohmann::json::array(); 583ac6a4445SGunnar Mills for (uint16_t subVal : *value) 584ac6a4445SGunnar Mills { 585ac6a4445SGunnar Mills jValue.push_back(subVal); 586ac6a4445SGunnar Mills } 587ac6a4445SGunnar Mills } 588ac6a4445SGunnar Mills else if (property.first == "MemoryAttributes") 589ac6a4445SGunnar Mills { 5909a5aceacSNan Zhou const uint8_t* value = std::get_if<uint8_t>(&property.second); 591ac6a4445SGunnar Mills 592ac6a4445SGunnar Mills if (value == nullptr) 593ac6a4445SGunnar Mills { 594ac6a4445SGunnar Mills messages::internalError(aResp->res); 595ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 596ac6a4445SGunnar Mills << "Invalid property type for MemoryAttributes"; 597601af5edSChicago Duan return; 598ac6a4445SGunnar Mills } 5999a5aceacSNan Zhou aResp->res.jsonValue["RankCount"] = static_cast<uint64_t>(*value); 600ac6a4445SGunnar Mills } 601ac6a4445SGunnar Mills else if (property.first == "MemoryConfiguredSpeedInMhz") 602ac6a4445SGunnar Mills { 6039a5aceacSNan Zhou const uint16_t* value = std::get_if<uint16_t>(&property.second); 604ac6a4445SGunnar Mills if (value == nullptr) 605ac6a4445SGunnar Mills { 606ac6a4445SGunnar Mills continue; 607ac6a4445SGunnar Mills } 608ac6a4445SGunnar Mills aResp->res.jsonValue["OperatingSpeedMhz"] = *value; 609ac6a4445SGunnar Mills } 610ac6a4445SGunnar Mills else if (property.first == "MemoryType") 611ac6a4445SGunnar Mills { 6129a5aceacSNan Zhou const auto* value = std::get_if<std::string>(&property.second); 613ac6a4445SGunnar Mills if (value != nullptr) 614ac6a4445SGunnar Mills { 615313efb1cSGunnar Mills std::string memoryDeviceType = 616313efb1cSGunnar Mills translateMemoryTypeToRedfish(*value); 617313efb1cSGunnar Mills // Values like "Unknown" or "Other" will return empty 618313efb1cSGunnar Mills // so just leave off 619313efb1cSGunnar Mills if (!memoryDeviceType.empty()) 620ac6a4445SGunnar Mills { 6219a5aceacSNan Zhou aResp->res.jsonValue["MemoryDeviceType"] = memoryDeviceType; 622ac6a4445SGunnar Mills } 623ac6a4445SGunnar Mills if (value->find("DDR") != std::string::npos) 624ac6a4445SGunnar Mills { 625ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryType"] = "DRAM"; 626ac6a4445SGunnar Mills } 627ac6a4445SGunnar Mills else if (boost::ends_with(*value, "Logical")) 628ac6a4445SGunnar Mills { 629ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryType"] = "IntelOptane"; 630ac6a4445SGunnar Mills } 631ac6a4445SGunnar Mills } 632ac6a4445SGunnar Mills } 633ac6a4445SGunnar Mills // memory location interface 634ac6a4445SGunnar Mills else if (property.first == "Channel" || 635ac6a4445SGunnar Mills property.first == "MemoryController" || 636ac6a4445SGunnar Mills property.first == "Slot" || property.first == "Socket") 637ac6a4445SGunnar Mills { 638ac6a4445SGunnar Mills const std::string* value = 639ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 640ac6a4445SGunnar Mills if (value == nullptr) 641ac6a4445SGunnar Mills { 642ac6a4445SGunnar Mills messages::internalError(aResp->res); 643601af5edSChicago Duan return; 644ac6a4445SGunnar Mills } 6459a5aceacSNan Zhou aResp->res.jsonValue["MemoryLocation"][property.first] = *value; 646ac6a4445SGunnar Mills } 647ee135e24SSunnySrivastava1984 else if (property.first == "SparePartNumber") 648ee135e24SSunnySrivastava1984 { 649ee135e24SSunnySrivastava1984 const std::string* value = 650ee135e24SSunnySrivastava1984 std::get_if<std::string>(&property.second); 651ee135e24SSunnySrivastava1984 if (value == nullptr) 652ee135e24SSunnySrivastava1984 { 653ee135e24SSunnySrivastava1984 messages::internalError(aResp->res); 654601af5edSChicago Duan return; 655ee135e24SSunnySrivastava1984 } 656ee135e24SSunnySrivastava1984 aResp->res.jsonValue["SparePartNumber"] = *value; 657ee135e24SSunnySrivastava1984 } 658ee135e24SSunnySrivastava1984 else if (property.first == "Model") 659ee135e24SSunnySrivastava1984 { 660ee135e24SSunnySrivastava1984 const std::string* value = 661ee135e24SSunnySrivastava1984 std::get_if<std::string>(&property.second); 662ee135e24SSunnySrivastava1984 if (value == nullptr) 663ee135e24SSunnySrivastava1984 { 664ee135e24SSunnySrivastava1984 messages::internalError(aResp->res); 665601af5edSChicago Duan return; 666ee135e24SSunnySrivastava1984 } 667ee135e24SSunnySrivastava1984 aResp->res.jsonValue["Model"] = *value; 668ee135e24SSunnySrivastava1984 } 669ee135e24SSunnySrivastava1984 else if (property.first == "LocationCode") 670ee135e24SSunnySrivastava1984 { 671ee135e24SSunnySrivastava1984 const std::string* value = 672ee135e24SSunnySrivastava1984 std::get_if<std::string>(&property.second); 673ee135e24SSunnySrivastava1984 if (value == nullptr) 674ee135e24SSunnySrivastava1984 { 675ee135e24SSunnySrivastava1984 messages::internalError(aResp->res); 676601af5edSChicago Duan return; 677ee135e24SSunnySrivastava1984 } 6789a5aceacSNan Zhou aResp->res.jsonValue["Location"]["PartLocation"]["ServiceLabel"] = 679ee135e24SSunnySrivastava1984 *value; 680ee135e24SSunnySrivastava1984 } 681ac6a4445SGunnar Mills else 682ac6a4445SGunnar Mills { 68380badf7cSJiaqing Zhao getPersistentMemoryProperties(aResp, property); 684ac6a4445SGunnar Mills } 685ac6a4445SGunnar Mills } 6869a5aceacSNan Zhou } 6879a5aceacSNan Zhou 6889a5aceacSNan Zhou inline void getDimmDataByService(std::shared_ptr<bmcweb::AsyncResp> aResp, 6899a5aceacSNan Zhou const std::string& dimmId, 6909a5aceacSNan Zhou const std::string& service, 6919a5aceacSNan Zhou const std::string& objPath) 6929a5aceacSNan Zhou { 6939a5aceacSNan Zhou auto health = std::make_shared<HealthPopulate>(aResp); 6949a5aceacSNan Zhou health->selfPath = objPath; 6959a5aceacSNan Zhou health->populate(); 6969a5aceacSNan Zhou 6979a5aceacSNan Zhou BMCWEB_LOG_DEBUG << "Get available system components."; 6989a5aceacSNan Zhou crow::connections::systemBus->async_method_call( 6999a5aceacSNan Zhou [dimmId, aResp{std::move(aResp)}]( 7009a5aceacSNan Zhou const boost::system::error_code ec, 7019a5aceacSNan Zhou const dbus::utility::DBusPropertiesMap& properties) { 7029a5aceacSNan Zhou if (ec) 7039a5aceacSNan Zhou { 7049a5aceacSNan Zhou BMCWEB_LOG_DEBUG << "DBUS response error"; 7059a5aceacSNan Zhou messages::internalError(aResp->res); 7069a5aceacSNan Zhou return; 7079a5aceacSNan Zhou } 7089a5aceacSNan Zhou assembleDimmProperties(dimmId, aResp, properties); 709ac6a4445SGunnar Mills }, 710ac6a4445SGunnar Mills service, objPath, "org.freedesktop.DBus.Properties", "GetAll", ""); 711ac6a4445SGunnar Mills } 712ac6a4445SGunnar Mills 713ef00d7d4SNan Zhou inline void assembleDimmPartitionData( 714ef00d7d4SNan Zhou const std::shared_ptr<bmcweb::AsyncResp>& aResp, 715ef00d7d4SNan Zhou const dbus::utility::DBusPropertiesMap& properties) 716ac6a4445SGunnar Mills { 717ac6a4445SGunnar Mills nlohmann::json& partition = 718ef00d7d4SNan Zhou aResp->res.jsonValue["Regions"].emplace_back(nlohmann::json::object()); 719ac6a4445SGunnar Mills for (const auto& [key, val] : properties) 720ac6a4445SGunnar Mills { 721ac6a4445SGunnar Mills if (key == "MemoryClassification") 722ac6a4445SGunnar Mills { 723ac6a4445SGunnar Mills const std::string* value = std::get_if<std::string>(&val); 724ac6a4445SGunnar Mills if (value == nullptr) 725ac6a4445SGunnar Mills { 726ac6a4445SGunnar Mills messages::internalError(aResp->res); 727601af5edSChicago Duan return; 728ac6a4445SGunnar Mills } 729ac6a4445SGunnar Mills partition[key] = *value; 730ac6a4445SGunnar Mills } 731ac6a4445SGunnar Mills else if (key == "OffsetInKiB") 732ac6a4445SGunnar Mills { 733ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&val); 734ac6a4445SGunnar Mills if (value == nullptr) 735ac6a4445SGunnar Mills { 736ac6a4445SGunnar Mills messages::internalError(aResp->res); 737601af5edSChicago Duan return; 738ac6a4445SGunnar Mills } 739ac6a4445SGunnar Mills 740ac6a4445SGunnar Mills partition["OffsetMiB"] = (*value >> 10); 741ac6a4445SGunnar Mills } 742ac6a4445SGunnar Mills else if (key == "PartitionId") 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["RegionId"] = *value; 751ac6a4445SGunnar Mills } 752ac6a4445SGunnar Mills 753ac6a4445SGunnar Mills else if (key == "PassphraseState") 754ac6a4445SGunnar Mills { 755ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&val); 756ac6a4445SGunnar Mills if (value == nullptr) 757ac6a4445SGunnar Mills { 758ac6a4445SGunnar Mills messages::internalError(aResp->res); 759601af5edSChicago Duan return; 760ac6a4445SGunnar Mills } 761ac6a4445SGunnar Mills partition["PassphraseEnabled"] = *value; 762ac6a4445SGunnar Mills } 763ac6a4445SGunnar Mills else if (key == "SizeInKiB") 764ac6a4445SGunnar Mills { 765ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&val); 766ac6a4445SGunnar Mills if (value == nullptr) 767ac6a4445SGunnar Mills { 768ac6a4445SGunnar Mills messages::internalError(aResp->res); 769ef00d7d4SNan Zhou BMCWEB_LOG_DEBUG << "Invalid property type for SizeInKiB"; 770601af5edSChicago Duan return; 771ac6a4445SGunnar Mills } 772ac6a4445SGunnar Mills partition["SizeMiB"] = (*value >> 10); 773ac6a4445SGunnar Mills } 774ac6a4445SGunnar Mills } 775ef00d7d4SNan Zhou } 776ef00d7d4SNan Zhou 777ef00d7d4SNan Zhou inline void getDimmPartitionData(std::shared_ptr<bmcweb::AsyncResp> aResp, 778ef00d7d4SNan Zhou const std::string& service, 779ef00d7d4SNan Zhou const std::string& path) 780ef00d7d4SNan Zhou { 781ef00d7d4SNan Zhou crow::connections::systemBus->async_method_call( 782ef00d7d4SNan Zhou [aResp{std::move(aResp)}]( 783ef00d7d4SNan Zhou const boost::system::error_code ec, 784ef00d7d4SNan Zhou const dbus::utility::DBusPropertiesMap& properties) { 785ef00d7d4SNan Zhou if (ec) 786ef00d7d4SNan Zhou { 787ef00d7d4SNan Zhou BMCWEB_LOG_DEBUG << "DBUS response error"; 788ef00d7d4SNan Zhou messages::internalError(aResp->res); 789ef00d7d4SNan Zhou 790ef00d7d4SNan Zhou return; 791ef00d7d4SNan Zhou } 792ef00d7d4SNan Zhou assembleDimmPartitionData(aResp, properties); 793ac6a4445SGunnar Mills }, 794ac6a4445SGunnar Mills 795ac6a4445SGunnar Mills service, path, "org.freedesktop.DBus.Properties", "GetAll", 796ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"); 797ac6a4445SGunnar Mills } 798ac6a4445SGunnar Mills 7997267c21dSSui Chen inline bool pathContainsDimmId(const std::string& path, std::string_view dimmId) 8007267c21dSSui Chen { 8017267c21dSSui Chen sdbusplus::message::object_path objectPath(path); 8027267c21dSSui Chen // for /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1 or 8037267c21dSSui Chen // /xyz/openbmc_project/Inventory/Item/Dimm1 8047267c21dSSui Chen return !dimmId.empty() && (objectPath.filename() == dimmId || 8057267c21dSSui Chen objectPath.parent_path().filename() == dimmId); 8067267c21dSSui Chen } 8077267c21dSSui Chen 8088d1b46d7Szhanghch05 inline void getDimmData(std::shared_ptr<bmcweb::AsyncResp> aResp, 809ac6a4445SGunnar Mills const std::string& dimmId) 810ac6a4445SGunnar Mills { 811ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Get available system dimm resources."; 812ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 813ac6a4445SGunnar Mills [dimmId, aResp{std::move(aResp)}]( 814ac6a4445SGunnar Mills const boost::system::error_code ec, 815b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 816ac6a4445SGunnar Mills if (ec) 817ac6a4445SGunnar Mills { 818ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 819ac6a4445SGunnar Mills messages::internalError(aResp->res); 820ac6a4445SGunnar Mills 821ac6a4445SGunnar Mills return; 822ac6a4445SGunnar Mills } 823ac6a4445SGunnar Mills bool found = false; 824ac6a4445SGunnar Mills for (const auto& [path, object] : subtree) 825ac6a4445SGunnar Mills { 8267267c21dSSui Chen if (pathContainsDimmId(path, dimmId)) 827ac6a4445SGunnar Mills { 828ac6a4445SGunnar Mills for (const auto& [service, interfaces] : object) 829ac6a4445SGunnar Mills { 830b9d36b47SEd Tanous for (const auto& interface : interfaces) 831ac6a4445SGunnar Mills { 832b9d36b47SEd Tanous if (interface == 833b9d36b47SEd Tanous "xyz.openbmc_project.Inventory.Item.Dimm") 834b9d36b47SEd Tanous { 835002d39b4SEd Tanous getDimmDataByService(aResp, dimmId, service, path); 836ac6a4445SGunnar Mills found = true; 837ac6a4445SGunnar Mills } 838ac6a4445SGunnar Mills 839b9d36b47SEd Tanous // partitions are separate as there can be multiple 840b9d36b47SEd Tanous // per 841ac6a4445SGunnar Mills // device, i.e. 842ac6a4445SGunnar Mills // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1 843ac6a4445SGunnar Mills // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2 844b9d36b47SEd Tanous if (interface == 845b9d36b47SEd Tanous "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition") 846ac6a4445SGunnar Mills { 847ac6a4445SGunnar Mills getDimmPartitionData(aResp, service, path); 848ac6a4445SGunnar Mills } 849ac6a4445SGunnar Mills } 850ac6a4445SGunnar Mills } 851ac6a4445SGunnar Mills } 852b9d36b47SEd Tanous } 853ac6a4445SGunnar Mills // Object not found 854ac6a4445SGunnar Mills if (!found) 855ac6a4445SGunnar Mills { 856ac6a4445SGunnar Mills messages::resourceNotFound(aResp->res, "Memory", dimmId); 8571a1d5d6dSNan Zhou return; 858ac6a4445SGunnar Mills } 8591a1d5d6dSNan Zhou // Set @odata only if object is found 8601a1d5d6dSNan Zhou aResp->res.jsonValue["@odata.type"] = "#Memory.v1_11_0.Memory"; 8611a1d5d6dSNan Zhou aResp->res.jsonValue["@odata.id"] = 8621a1d5d6dSNan Zhou "/redfish/v1/Systems/system/Memory/" + dimmId; 863ac6a4445SGunnar Mills return; 864ac6a4445SGunnar Mills }, 865ac6a4445SGunnar Mills "xyz.openbmc_project.ObjectMapper", 866ac6a4445SGunnar Mills "/xyz/openbmc_project/object_mapper", 867ac6a4445SGunnar Mills "xyz.openbmc_project.ObjectMapper", "GetSubTree", 868ac6a4445SGunnar Mills "/xyz/openbmc_project/inventory", 0, 869ac6a4445SGunnar Mills std::array<const char*, 2>{ 870ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm", 871ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"}); 872ac6a4445SGunnar Mills } 873ac6a4445SGunnar Mills 8747e860f15SJohn Edward Broadbent inline void requestRoutesMemoryCollection(App& app) 875ac6a4445SGunnar Mills { 876ac6a4445SGunnar Mills /** 877ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 878ac6a4445SGunnar Mills */ 8797e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Memory/") 880ed398213SEd Tanous .privileges(redfish::privileges::getMemoryCollection) 8817e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 88245ca1b86SEd Tanous [&app](const crow::Request& req, 8837e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 884*3ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 88545ca1b86SEd Tanous { 88645ca1b86SEd Tanous return; 88745ca1b86SEd Tanous } 8888d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 8898d1b46d7Szhanghch05 "#MemoryCollection.MemoryCollection"; 8908d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Memory Module Collection"; 8918d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = 8928d1b46d7Szhanghch05 "/redfish/v1/Systems/system/Memory"; 893ac6a4445SGunnar Mills 89405030b8eSGunnar Mills collection_util::getCollectionMembers( 89505030b8eSGunnar Mills asyncResp, "/redfish/v1/Systems/system/Memory", 89605030b8eSGunnar Mills {"xyz.openbmc_project.Inventory.Item.Dimm"}); 8977e860f15SJohn Edward Broadbent }); 898ac6a4445SGunnar Mills } 899ac6a4445SGunnar Mills 9007e860f15SJohn Edward Broadbent inline void requestRoutesMemory(App& app) 9017e860f15SJohn Edward Broadbent { 902ac6a4445SGunnar Mills /** 903ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 904ac6a4445SGunnar Mills */ 9057e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Memory/<str>/") 906ed398213SEd Tanous .privileges(redfish::privileges::getMemory) 9077e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 90845ca1b86SEd Tanous [&app](const crow::Request& req, 9097e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 9107e860f15SJohn Edward Broadbent const std::string& dimmId) { 911*3ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 91245ca1b86SEd Tanous { 91345ca1b86SEd Tanous return; 91445ca1b86SEd Tanous } 915ac6a4445SGunnar Mills getDimmData(asyncResp, dimmId); 9167e860f15SJohn Edward Broadbent }); 917ac6a4445SGunnar Mills } 918ac6a4445SGunnar Mills 919ac6a4445SGunnar Mills } // namespace redfish 920