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> 21ac6a4445SGunnar Mills #include <boost/container/flat_map.hpp> 22168e20c1SEd Tanous #include <dbus_utility.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 31168e20c1SEd Tanous using DimmProperties = 32168e20c1SEd Tanous boost::container::flat_map<std::string, dbus::utility::DbusVariantType>; 33ac6a4445SGunnar Mills 34313efb1cSGunnar Mills inline std::string translateMemoryTypeToRedfish(const std::string& memoryType) 35313efb1cSGunnar Mills { 36313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR") 37313efb1cSGunnar Mills { 38313efb1cSGunnar Mills return "DDR"; 39313efb1cSGunnar Mills } 40313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2") 41313efb1cSGunnar Mills { 42313efb1cSGunnar Mills return "DDR2"; 43313efb1cSGunnar Mills } 44313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR3") 45313efb1cSGunnar Mills { 46313efb1cSGunnar Mills return "DDR3"; 47313efb1cSGunnar Mills } 48313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4") 49313efb1cSGunnar Mills { 50313efb1cSGunnar Mills return "DDR4"; 51313efb1cSGunnar Mills } 52313efb1cSGunnar Mills if (memoryType == 53313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4E_SDRAM") 54313efb1cSGunnar Mills { 55313efb1cSGunnar Mills return "DDR4E_SDRAM"; 56313efb1cSGunnar Mills } 5711a2f0f0SMansi Joshi if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR5") 5811a2f0f0SMansi Joshi { 5911a2f0f0SMansi Joshi return "DDR5"; 6011a2f0f0SMansi Joshi } 61313efb1cSGunnar Mills if (memoryType == 62313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR4_SDRAM") 63313efb1cSGunnar Mills { 64313efb1cSGunnar Mills return "LPDDR4_SDRAM"; 65313efb1cSGunnar Mills } 66313efb1cSGunnar Mills if (memoryType == 67313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR3_SDRAM") 68313efb1cSGunnar Mills { 69313efb1cSGunnar Mills return "LPDDR3_SDRAM"; 70313efb1cSGunnar Mills } 71313efb1cSGunnar Mills if (memoryType == 72313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM") 73313efb1cSGunnar Mills { 74313efb1cSGunnar Mills return "DDR2_SDRAM_FB_DIMM"; 75313efb1cSGunnar Mills } 760fda0f12SGeorge Liu if (memoryType == 770fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM_PROB") 78313efb1cSGunnar Mills { 79313efb1cSGunnar Mills return "DDR2_SDRAM_FB_DIMM_PROBE"; 80313efb1cSGunnar Mills } 81313efb1cSGunnar Mills if (memoryType == 82313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR_SGRAM") 83313efb1cSGunnar Mills { 84313efb1cSGunnar Mills return "DDR_SGRAM"; 85313efb1cSGunnar Mills } 86313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.ROM") 87313efb1cSGunnar Mills { 88313efb1cSGunnar Mills return "ROM"; 89313efb1cSGunnar Mills } 90313efb1cSGunnar Mills if (memoryType == 91313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.SDRAM") 92313efb1cSGunnar Mills { 93313efb1cSGunnar Mills return "SDRAM"; 94313efb1cSGunnar Mills } 95313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.EDO") 96313efb1cSGunnar Mills { 97313efb1cSGunnar Mills return "EDO"; 98313efb1cSGunnar Mills } 99313efb1cSGunnar Mills if (memoryType == 100313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.FastPageMode") 101313efb1cSGunnar Mills { 102313efb1cSGunnar Mills return "FastPageMode"; 103313efb1cSGunnar Mills } 104313efb1cSGunnar Mills if (memoryType == 105313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.PipelinedNibble") 106313efb1cSGunnar Mills { 107313efb1cSGunnar Mills return "PipelinedNibble"; 108313efb1cSGunnar Mills } 109313efb1cSGunnar Mills if (memoryType == 110313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.Logical") 111313efb1cSGunnar Mills { 112313efb1cSGunnar Mills return "Logical"; 113313efb1cSGunnar Mills } 114313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM") 115313efb1cSGunnar Mills { 116313efb1cSGunnar Mills return "HBM"; 117313efb1cSGunnar Mills } 118313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM2") 119313efb1cSGunnar Mills { 120313efb1cSGunnar Mills return "HBM2"; 121313efb1cSGunnar Mills } 122313efb1cSGunnar Mills // This is values like Other or Unknown 123313efb1cSGunnar Mills // Also D-Bus values: 124313efb1cSGunnar Mills // DRAM 125313efb1cSGunnar Mills // EDRAM 126313efb1cSGunnar Mills // VRAM 127313efb1cSGunnar Mills // SRAM 128313efb1cSGunnar Mills // RAM 129313efb1cSGunnar Mills // FLASH 130313efb1cSGunnar Mills // EEPROM 131313efb1cSGunnar Mills // FEPROM 132313efb1cSGunnar Mills // EPROM 133313efb1cSGunnar Mills // CDRAM 134313efb1cSGunnar Mills // ThreeDRAM 135313efb1cSGunnar Mills // RDRAM 136313efb1cSGunnar Mills // FBD2 137313efb1cSGunnar Mills // LPDDR_SDRAM 138313efb1cSGunnar Mills // LPDDR2_SDRAM 13911a2f0f0SMansi Joshi // LPDDR5_SDRAM 140313efb1cSGunnar Mills return ""; 141313efb1cSGunnar Mills } 142313efb1cSGunnar Mills 143168e20c1SEd Tanous inline void dimmPropToHex( 144168e20c1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& aResp, const char* key, 145168e20c1SEd Tanous const std::pair<std::string, dbus::utility::DbusVariantType>& property) 146ac6a4445SGunnar Mills { 147ac6a4445SGunnar Mills const uint16_t* value = std::get_if<uint16_t>(&property.second); 148ac6a4445SGunnar Mills if (value == nullptr) 149ac6a4445SGunnar Mills { 150ac6a4445SGunnar Mills messages::internalError(aResp->res); 151ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for " << property.first; 152ac6a4445SGunnar Mills return; 153ac6a4445SGunnar Mills } 154ac6a4445SGunnar Mills 155866e4862SEd Tanous aResp->res.jsonValue[key] = "0x" + intToHexString(*value, 4); 156ac6a4445SGunnar Mills } 157ac6a4445SGunnar Mills 1588d1b46d7Szhanghch05 inline void getPersistentMemoryProperties( 1598d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aResp, 160*80badf7cSJiaqing Zhao const std::pair<std::string, dbus::utility::DbusVariantType>& property) 161ac6a4445SGunnar Mills { 162ac6a4445SGunnar Mills if (property.first == "ModuleManufacturerID") 163ac6a4445SGunnar Mills { 164ac6a4445SGunnar Mills dimmPropToHex(aResp, "ModuleManufacturerID", property); 165ac6a4445SGunnar Mills } 166ac6a4445SGunnar Mills else if (property.first == "ModuleProductID") 167ac6a4445SGunnar Mills { 168ac6a4445SGunnar Mills dimmPropToHex(aResp, "ModuleProductID", property); 169ac6a4445SGunnar Mills } 170ac6a4445SGunnar Mills else if (property.first == "SubsystemVendorID") 171ac6a4445SGunnar Mills { 172ac6a4445SGunnar Mills dimmPropToHex(aResp, "MemorySubsystemControllerManufacturerID", 173ac6a4445SGunnar Mills property); 174ac6a4445SGunnar Mills } 175ac6a4445SGunnar Mills else if (property.first == "SubsystemDeviceID") 176ac6a4445SGunnar Mills { 177*80badf7cSJiaqing Zhao dimmPropToHex(aResp, "MemorySubsystemControllerProductID", property); 178ac6a4445SGunnar Mills } 179ac6a4445SGunnar Mills else if (property.first == "VolatileRegionSizeLimitInKiB") 180ac6a4445SGunnar Mills { 181ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 182ac6a4445SGunnar Mills 183ac6a4445SGunnar Mills if (value == nullptr) 184ac6a4445SGunnar Mills { 185ac6a4445SGunnar Mills messages::internalError(aResp->res); 1860fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 1870fda0f12SGeorge Liu << "Invalid property type for VolatileRegionSizeLimitKiB"; 188601af5edSChicago Duan return; 189ac6a4445SGunnar Mills } 190ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileRegionSizeLimitMiB"] = (*value) >> 10; 191ac6a4445SGunnar Mills } 192ac6a4445SGunnar Mills else if (property.first == "PmRegionSizeLimitInKiB") 193ac6a4445SGunnar Mills { 194ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 195ac6a4445SGunnar Mills 196ac6a4445SGunnar Mills if (value == nullptr) 197ac6a4445SGunnar Mills { 198ac6a4445SGunnar Mills messages::internalError(aResp->res); 199*80badf7cSJiaqing Zhao BMCWEB_LOG_DEBUG << "Invalid property type for PmRegioSizeLimitKiB"; 200601af5edSChicago Duan return; 201ac6a4445SGunnar Mills } 202*80badf7cSJiaqing Zhao aResp->res.jsonValue["PersistentRegionSizeLimitMiB"] = (*value) >> 10; 203ac6a4445SGunnar Mills } 204ac6a4445SGunnar Mills else if (property.first == "VolatileSizeInKiB") 205ac6a4445SGunnar Mills { 206ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 207ac6a4445SGunnar Mills 208ac6a4445SGunnar Mills if (value == nullptr) 209ac6a4445SGunnar Mills { 210ac6a4445SGunnar Mills messages::internalError(aResp->res); 211*80badf7cSJiaqing Zhao BMCWEB_LOG_DEBUG << "Invalid property type for VolatileSizeInKiB"; 212601af5edSChicago Duan return; 213ac6a4445SGunnar Mills } 214ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileSizeMiB"] = (*value) >> 10; 215ac6a4445SGunnar Mills } 216ac6a4445SGunnar Mills else if (property.first == "PmSizeInKiB") 217ac6a4445SGunnar Mills { 218ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 219ac6a4445SGunnar Mills if (value == nullptr) 220ac6a4445SGunnar Mills { 221ac6a4445SGunnar Mills messages::internalError(aResp->res); 222ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for PmSizeInKiB"; 223601af5edSChicago Duan return; 224ac6a4445SGunnar Mills } 225ac6a4445SGunnar Mills aResp->res.jsonValue["NonVolatileSizeMiB"] = (*value) >> 10; 226ac6a4445SGunnar Mills } 227ac6a4445SGunnar Mills else if (property.first == "CacheSizeInKB") 228ac6a4445SGunnar Mills { 229ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 230ac6a4445SGunnar Mills if (value == nullptr) 231ac6a4445SGunnar Mills { 232ac6a4445SGunnar Mills messages::internalError(aResp->res); 233ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for CacheSizeInKB"; 234601af5edSChicago Duan return; 235ac6a4445SGunnar Mills } 236ac6a4445SGunnar Mills aResp->res.jsonValue["CacheSizeMiB"] = (*value >> 10); 237ac6a4445SGunnar Mills } 238ac6a4445SGunnar Mills 239ac6a4445SGunnar Mills else if (property.first == "VoltaileRegionMaxSizeInKib") 240ac6a4445SGunnar Mills { 241ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 242ac6a4445SGunnar Mills 243ac6a4445SGunnar Mills if (value == nullptr) 244ac6a4445SGunnar Mills { 245ac6a4445SGunnar Mills messages::internalError(aResp->res); 2460fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 2470fda0f12SGeorge Liu << "Invalid property type for VolatileRegionMaxSizeInKib"; 248601af5edSChicago Duan return; 249ac6a4445SGunnar Mills } 250ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileRegionSizeMaxMiB"] = (*value) >> 10; 251ac6a4445SGunnar Mills } 252ac6a4445SGunnar Mills else if (property.first == "PmRegionMaxSizeInKiB") 253ac6a4445SGunnar Mills { 254ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 255ac6a4445SGunnar Mills 256ac6a4445SGunnar Mills if (value == nullptr) 257ac6a4445SGunnar Mills { 258ac6a4445SGunnar Mills messages::internalError(aResp->res); 259ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 260ac6a4445SGunnar Mills << "Invalid property type for PmRegionMaxSizeInKiB"; 261601af5edSChicago Duan return; 262ac6a4445SGunnar Mills } 263ac6a4445SGunnar Mills aResp->res.jsonValue["PersistentRegionSizeMaxMiB"] = (*value) >> 10; 264ac6a4445SGunnar Mills } 265ac6a4445SGunnar Mills else if (property.first == "AllocationIncrementInKiB") 266ac6a4445SGunnar Mills { 267ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 268ac6a4445SGunnar Mills 269ac6a4445SGunnar Mills if (value == nullptr) 270ac6a4445SGunnar Mills { 271ac6a4445SGunnar Mills messages::internalError(aResp->res); 2720fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 2730fda0f12SGeorge Liu << "Invalid property type for AllocationIncrementInKiB"; 274601af5edSChicago Duan return; 275ac6a4445SGunnar Mills } 276ac6a4445SGunnar Mills aResp->res.jsonValue["AllocationIncrementMiB"] = (*value) >> 10; 277ac6a4445SGunnar Mills } 278ac6a4445SGunnar Mills else if (property.first == "AllocationAlignmentInKiB") 279ac6a4445SGunnar Mills { 280ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 281ac6a4445SGunnar Mills 282ac6a4445SGunnar Mills if (value == nullptr) 283ac6a4445SGunnar Mills { 284ac6a4445SGunnar Mills messages::internalError(aResp->res); 2850fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 2860fda0f12SGeorge Liu << "Invalid property type for AllocationAlignmentInKiB"; 287601af5edSChicago Duan return; 288ac6a4445SGunnar Mills } 289ac6a4445SGunnar Mills aResp->res.jsonValue["AllocationAlignmentMiB"] = (*value) >> 10; 290ac6a4445SGunnar Mills } 291ac6a4445SGunnar Mills else if (property.first == "VolatileRegionNumberLimit") 292ac6a4445SGunnar Mills { 293ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 294ac6a4445SGunnar Mills if (value == nullptr) 295ac6a4445SGunnar Mills { 296ac6a4445SGunnar Mills messages::internalError(aResp->res); 297601af5edSChicago Duan return; 298ac6a4445SGunnar Mills } 299ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileRegionNumberLimit"] = *value; 300ac6a4445SGunnar Mills } 301ac6a4445SGunnar Mills else if (property.first == "PmRegionNumberLimit") 302ac6a4445SGunnar Mills { 303ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 304ac6a4445SGunnar Mills if (value == nullptr) 305ac6a4445SGunnar Mills { 306ac6a4445SGunnar Mills messages::internalError(aResp->res); 307601af5edSChicago Duan return; 308ac6a4445SGunnar Mills } 309ac6a4445SGunnar Mills aResp->res.jsonValue["PersistentRegionNumberLimit"] = *value; 310ac6a4445SGunnar Mills } 311ac6a4445SGunnar Mills else if (property.first == "SpareDeviceCount") 312ac6a4445SGunnar Mills { 313ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 314ac6a4445SGunnar Mills if (value == nullptr) 315ac6a4445SGunnar Mills { 316ac6a4445SGunnar Mills messages::internalError(aResp->res); 317601af5edSChicago Duan return; 318ac6a4445SGunnar Mills } 319ac6a4445SGunnar Mills aResp->res.jsonValue["SpareDeviceCount"] = *value; 320ac6a4445SGunnar Mills } 321ac6a4445SGunnar Mills else if (property.first == "IsSpareDeviceInUse") 322ac6a4445SGunnar Mills { 323ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 324ac6a4445SGunnar Mills if (value == nullptr) 325ac6a4445SGunnar Mills { 326ac6a4445SGunnar Mills messages::internalError(aResp->res); 327601af5edSChicago Duan return; 328ac6a4445SGunnar Mills } 329ac6a4445SGunnar Mills aResp->res.jsonValue["IsSpareDeviceEnabled"] = *value; 330ac6a4445SGunnar Mills } 331ac6a4445SGunnar Mills else if (property.first == "IsRankSpareEnabled") 332ac6a4445SGunnar Mills { 333ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 334ac6a4445SGunnar Mills if (value == nullptr) 335ac6a4445SGunnar Mills { 336ac6a4445SGunnar Mills messages::internalError(aResp->res); 337601af5edSChicago Duan return; 338ac6a4445SGunnar Mills } 339ac6a4445SGunnar Mills aResp->res.jsonValue["IsRankSpareEnabled"] = *value; 340ac6a4445SGunnar Mills } 341ac6a4445SGunnar Mills else if (property.first == "MaxAveragePowerLimitmW") 342ac6a4445SGunnar Mills { 343ac6a4445SGunnar Mills const auto* value = 344ac6a4445SGunnar Mills std::get_if<std::vector<uint32_t>>(&property.second); 345ac6a4445SGunnar Mills if (value == nullptr) 346ac6a4445SGunnar Mills { 347ac6a4445SGunnar Mills messages::internalError(aResp->res); 3480fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 3490fda0f12SGeorge Liu << "Invalid property type for MaxAveragePowerLimitmW"; 350601af5edSChicago Duan return; 351ac6a4445SGunnar Mills } 352ac6a4445SGunnar Mills aResp->res.jsonValue["MaxTDPMilliWatts"] = *value; 353ac6a4445SGunnar Mills } 354ac6a4445SGunnar Mills else if (property.first == "ConfigurationLocked") 355ac6a4445SGunnar Mills { 356ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 357ac6a4445SGunnar Mills if (value == nullptr) 358ac6a4445SGunnar Mills { 359ac6a4445SGunnar Mills messages::internalError(aResp->res); 360601af5edSChicago Duan return; 361ac6a4445SGunnar Mills } 362ac6a4445SGunnar Mills aResp->res.jsonValue["ConfigurationLocked"] = *value; 363ac6a4445SGunnar Mills } 364ac6a4445SGunnar Mills else if (property.first == "AllowedMemoryModes") 365ac6a4445SGunnar Mills { 366*80badf7cSJiaqing Zhao const std::string* value = std::get_if<std::string>(&property.second); 367ac6a4445SGunnar Mills if (value == nullptr) 368ac6a4445SGunnar Mills { 369ac6a4445SGunnar Mills messages::internalError(aResp->res); 370ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for FormFactor"; 371601af5edSChicago Duan return; 372ac6a4445SGunnar Mills } 373*80badf7cSJiaqing Zhao constexpr const std::array<const char*, 3> values{"Volatile", "PMEM", 374*80badf7cSJiaqing Zhao "Block"}; 375ac6a4445SGunnar Mills 376ac6a4445SGunnar Mills for (const char* v : values) 377ac6a4445SGunnar Mills { 378ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 379ac6a4445SGunnar Mills { 380ac6a4445SGunnar Mills aResp->res.jsonValue["OperatingMemoryModes "] = v; 381ac6a4445SGunnar Mills break; 382ac6a4445SGunnar Mills } 383ac6a4445SGunnar Mills } 384ac6a4445SGunnar Mills } 385ac6a4445SGunnar Mills else if (property.first == "MemoryMedia") 386ac6a4445SGunnar Mills { 387*80badf7cSJiaqing Zhao const std::string* value = std::get_if<std::string>(&property.second); 388ac6a4445SGunnar Mills if (value == nullptr) 389ac6a4445SGunnar Mills { 390ac6a4445SGunnar Mills messages::internalError(aResp->res); 391ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for MemoryMedia"; 392601af5edSChicago Duan return; 393ac6a4445SGunnar Mills } 394ac6a4445SGunnar Mills constexpr const std::array<const char*, 3> values{"DRAM", "NAND", 395ac6a4445SGunnar Mills "Intel3DXPoint"}; 396ac6a4445SGunnar Mills 397ac6a4445SGunnar Mills for (const char* v : values) 398ac6a4445SGunnar Mills { 399ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 400ac6a4445SGunnar Mills { 401ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryMedia"] = v; 402ac6a4445SGunnar Mills break; 403ac6a4445SGunnar Mills } 404ac6a4445SGunnar Mills } 405ac6a4445SGunnar Mills } 406ac6a4445SGunnar Mills // PersistantMemory.SecurityCapabilites interface 407ac6a4445SGunnar Mills else if (property.first == "ConfigurationLockCapable" || 408ac6a4445SGunnar Mills property.first == "DataLockCapable" || 409ac6a4445SGunnar Mills property.first == "PassphraseCapable") 410ac6a4445SGunnar Mills { 411ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 412ac6a4445SGunnar Mills if (value == nullptr) 413ac6a4445SGunnar Mills { 414ac6a4445SGunnar Mills messages::internalError(aResp->res); 415601af5edSChicago Duan return; 416ac6a4445SGunnar Mills } 417*80badf7cSJiaqing Zhao aResp->res.jsonValue["SecurityCapabilities"][property.first] = *value; 418ac6a4445SGunnar Mills } 419ac6a4445SGunnar Mills else if (property.first == "MaxPassphraseCount" || 420ac6a4445SGunnar Mills property.first == "PassphraseLockLimit") 421ac6a4445SGunnar Mills { 422ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 423ac6a4445SGunnar Mills if (value == nullptr) 424ac6a4445SGunnar Mills { 425ac6a4445SGunnar Mills messages::internalError(aResp->res); 426601af5edSChicago Duan return; 427ac6a4445SGunnar Mills } 428*80badf7cSJiaqing Zhao aResp->res.jsonValue["SecurityCapabilities"][property.first] = *value; 429ac6a4445SGunnar Mills } 430ac6a4445SGunnar Mills } 431ac6a4445SGunnar Mills 4328d1b46d7Szhanghch05 inline void getDimmDataByService(std::shared_ptr<bmcweb::AsyncResp> aResp, 433ac6a4445SGunnar Mills const std::string& dimmId, 434ac6a4445SGunnar Mills const std::string& service, 435ac6a4445SGunnar Mills const std::string& objPath) 436ac6a4445SGunnar Mills { 437ac6a4445SGunnar Mills auto health = std::make_shared<HealthPopulate>(aResp); 438ac6a4445SGunnar Mills health->selfPath = objPath; 439ac6a4445SGunnar Mills health->populate(); 440ac6a4445SGunnar Mills 441ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Get available system components."; 442ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 443ac6a4445SGunnar Mills [dimmId, aResp{std::move(aResp)}](const boost::system::error_code ec, 444ac6a4445SGunnar Mills const DimmProperties& properties) { 445ac6a4445SGunnar Mills if (ec) 446ac6a4445SGunnar Mills { 447ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 448ac6a4445SGunnar Mills messages::internalError(aResp->res); 449ac6a4445SGunnar Mills 450ac6a4445SGunnar Mills return; 451ac6a4445SGunnar Mills } 452ac6a4445SGunnar Mills aResp->res.jsonValue["Id"] = dimmId; 453ac6a4445SGunnar Mills aResp->res.jsonValue["Name"] = "DIMM Slot"; 454ac6a4445SGunnar Mills 455ac6a4445SGunnar Mills const auto memorySizeProperty = properties.find("MemorySizeInKB"); 456ac6a4445SGunnar Mills if (memorySizeProperty != properties.end()) 457ac6a4445SGunnar Mills { 458ac6a4445SGunnar Mills const uint32_t* memorySize = 459ac6a4445SGunnar Mills std::get_if<uint32_t>(&memorySizeProperty->second); 460ac6a4445SGunnar Mills if (memorySize == nullptr) 461ac6a4445SGunnar Mills { 462ac6a4445SGunnar Mills // Important property not in desired type 463ac6a4445SGunnar Mills messages::internalError(aResp->res); 464ac6a4445SGunnar Mills return; 465ac6a4445SGunnar Mills } 466ac6a4445SGunnar Mills aResp->res.jsonValue["CapacityMiB"] = (*memorySize >> 10); 467ac6a4445SGunnar Mills } 468ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["State"] = "Enabled"; 469ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["Health"] = "OK"; 470ac6a4445SGunnar Mills 471ac6a4445SGunnar Mills for (const auto& property : properties) 472ac6a4445SGunnar Mills { 473ac6a4445SGunnar Mills if (property.first == "MemoryDataWidth") 474ac6a4445SGunnar Mills { 475ac6a4445SGunnar Mills const uint16_t* value = 476ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 477ac6a4445SGunnar Mills if (value == nullptr) 478ac6a4445SGunnar Mills { 479ac6a4445SGunnar Mills continue; 480ac6a4445SGunnar Mills } 481ac6a4445SGunnar Mills aResp->res.jsonValue["DataWidthBits"] = *value; 482ac6a4445SGunnar Mills } 483ac6a4445SGunnar Mills else if (property.first == "PartNumber") 484ac6a4445SGunnar Mills { 485ac6a4445SGunnar Mills const std::string* value = 486ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 487ac6a4445SGunnar Mills if (value == nullptr) 488ac6a4445SGunnar Mills { 489ac6a4445SGunnar Mills continue; 490ac6a4445SGunnar Mills } 491ac6a4445SGunnar Mills aResp->res.jsonValue["PartNumber"] = *value; 492ac6a4445SGunnar Mills } 493ac6a4445SGunnar Mills else if (property.first == "SerialNumber") 494ac6a4445SGunnar Mills { 495ac6a4445SGunnar Mills const std::string* value = 496ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 497ac6a4445SGunnar Mills if (value == nullptr) 498ac6a4445SGunnar Mills { 499ac6a4445SGunnar Mills continue; 500ac6a4445SGunnar Mills } 501ac6a4445SGunnar Mills aResp->res.jsonValue["SerialNumber"] = *value; 502ac6a4445SGunnar Mills } 503ac6a4445SGunnar Mills else if (property.first == "Manufacturer") 504ac6a4445SGunnar Mills { 505ac6a4445SGunnar Mills const std::string* value = 506ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 507ac6a4445SGunnar Mills if (value == nullptr) 508ac6a4445SGunnar Mills { 509ac6a4445SGunnar Mills continue; 510ac6a4445SGunnar Mills } 511ac6a4445SGunnar Mills aResp->res.jsonValue["Manufacturer"] = *value; 512ac6a4445SGunnar Mills } 513ac6a4445SGunnar Mills else if (property.first == "RevisionCode") 514ac6a4445SGunnar Mills { 515ac6a4445SGunnar Mills const uint16_t* value = 516ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 517ac6a4445SGunnar Mills 518ac6a4445SGunnar Mills if (value == nullptr) 519ac6a4445SGunnar Mills { 520ac6a4445SGunnar Mills messages::internalError(aResp->res); 521ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 522ac6a4445SGunnar Mills << "Invalid property type for RevisionCode"; 523601af5edSChicago Duan return; 524ac6a4445SGunnar Mills } 525ac6a4445SGunnar Mills aResp->res.jsonValue["FirmwareRevision"] = 526ac6a4445SGunnar Mills std::to_string(*value); 527ac6a4445SGunnar Mills } 5289a128eb3SJoshi-Mansi else if (property.first == "Present") 5299a128eb3SJoshi-Mansi { 5309a128eb3SJoshi-Mansi const bool* value = std::get_if<bool>(&property.second); 5319a128eb3SJoshi-Mansi if (value == nullptr) 5329a128eb3SJoshi-Mansi { 5339a128eb3SJoshi-Mansi messages::internalError(aResp->res); 5349a128eb3SJoshi-Mansi BMCWEB_LOG_DEBUG 5359a128eb3SJoshi-Mansi << "Invalid property type for Dimm Presence"; 5369a128eb3SJoshi-Mansi return; 5379a128eb3SJoshi-Mansi } 538e05aec50SEd Tanous if (!*value) 5399a128eb3SJoshi-Mansi { 5409a128eb3SJoshi-Mansi aResp->res.jsonValue["Status"]["State"] = "Absent"; 5419a128eb3SJoshi-Mansi } 5429a128eb3SJoshi-Mansi } 543ac6a4445SGunnar Mills else if (property.first == "MemoryTotalWidth") 544ac6a4445SGunnar Mills { 545ac6a4445SGunnar Mills const uint16_t* value = 546ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 547ac6a4445SGunnar Mills if (value == nullptr) 548ac6a4445SGunnar Mills { 549ac6a4445SGunnar Mills continue; 550ac6a4445SGunnar Mills } 551ac6a4445SGunnar Mills aResp->res.jsonValue["BusWidthBits"] = *value; 552ac6a4445SGunnar Mills } 553ac6a4445SGunnar Mills else if (property.first == "ECC") 554ac6a4445SGunnar Mills { 555ac6a4445SGunnar Mills const std::string* value = 556ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 557ac6a4445SGunnar Mills if (value == nullptr) 558ac6a4445SGunnar Mills { 559ac6a4445SGunnar Mills messages::internalError(aResp->res); 560ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for ECC"; 561601af5edSChicago Duan return; 562ac6a4445SGunnar Mills } 563ac6a4445SGunnar Mills constexpr const std::array<const char*, 4> values{ 564ac6a4445SGunnar Mills "NoECC", "SingleBitECC", "MultiBitECC", 565ac6a4445SGunnar Mills "AddressParity"}; 566ac6a4445SGunnar Mills 567ac6a4445SGunnar Mills for (const char* v : values) 568ac6a4445SGunnar Mills { 569ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 570ac6a4445SGunnar Mills { 571ac6a4445SGunnar Mills aResp->res.jsonValue["ErrorCorrection"] = v; 572ac6a4445SGunnar Mills break; 573ac6a4445SGunnar Mills } 574ac6a4445SGunnar Mills } 575ac6a4445SGunnar Mills } 576ac6a4445SGunnar Mills else if (property.first == "FormFactor") 577ac6a4445SGunnar Mills { 578ac6a4445SGunnar Mills const std::string* value = 579ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 580ac6a4445SGunnar Mills if (value == nullptr) 581ac6a4445SGunnar Mills { 582ac6a4445SGunnar Mills messages::internalError(aResp->res); 583ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 584ac6a4445SGunnar Mills << "Invalid property type for FormFactor"; 585601af5edSChicago Duan return; 586ac6a4445SGunnar Mills } 587ac6a4445SGunnar Mills constexpr const std::array<const char*, 11> values{ 588ac6a4445SGunnar Mills "RDIMM", "UDIMM", "SO_DIMM", 589ac6a4445SGunnar Mills "LRDIMM", "Mini_RDIMM", "Mini_UDIMM", 590ac6a4445SGunnar Mills "SO_RDIMM_72b", "SO_UDIMM_72b", "SO_DIMM_16b", 591ac6a4445SGunnar Mills "SO_DIMM_32b", "Die"}; 592ac6a4445SGunnar Mills 593ac6a4445SGunnar Mills for (const char* v : values) 594ac6a4445SGunnar Mills { 595ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 596ac6a4445SGunnar Mills { 597ac6a4445SGunnar Mills aResp->res.jsonValue["BaseModuleType"] = v; 598ac6a4445SGunnar Mills break; 599ac6a4445SGunnar Mills } 600ac6a4445SGunnar Mills } 601ac6a4445SGunnar Mills } 602ac6a4445SGunnar Mills else if (property.first == "AllowedSpeedsMT") 603ac6a4445SGunnar Mills { 604ac6a4445SGunnar Mills const std::vector<uint16_t>* value = 605ac6a4445SGunnar Mills std::get_if<std::vector<uint16_t>>(&property.second); 606ac6a4445SGunnar Mills if (value == nullptr) 607ac6a4445SGunnar Mills { 608ac6a4445SGunnar Mills continue; 609ac6a4445SGunnar Mills } 610ac6a4445SGunnar Mills nlohmann::json& jValue = 611ac6a4445SGunnar Mills aResp->res.jsonValue["AllowedSpeedsMHz"]; 612ac6a4445SGunnar Mills jValue = nlohmann::json::array(); 613ac6a4445SGunnar Mills for (uint16_t subVal : *value) 614ac6a4445SGunnar Mills { 615ac6a4445SGunnar Mills jValue.push_back(subVal); 616ac6a4445SGunnar Mills } 617ac6a4445SGunnar Mills } 618ac6a4445SGunnar Mills else if (property.first == "MemoryAttributes") 619ac6a4445SGunnar Mills { 620ac6a4445SGunnar Mills const uint8_t* value = 621ac6a4445SGunnar Mills std::get_if<uint8_t>(&property.second); 622ac6a4445SGunnar Mills 623ac6a4445SGunnar Mills if (value == nullptr) 624ac6a4445SGunnar Mills { 625ac6a4445SGunnar Mills messages::internalError(aResp->res); 626ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 627ac6a4445SGunnar Mills << "Invalid property type for MemoryAttributes"; 628601af5edSChicago Duan return; 629ac6a4445SGunnar Mills } 630ac6a4445SGunnar Mills aResp->res.jsonValue["RankCount"] = 631ac6a4445SGunnar Mills static_cast<uint64_t>(*value); 632ac6a4445SGunnar Mills } 633ac6a4445SGunnar Mills else if (property.first == "MemoryConfiguredSpeedInMhz") 634ac6a4445SGunnar Mills { 635ac6a4445SGunnar Mills const uint16_t* value = 636ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 637ac6a4445SGunnar Mills if (value == nullptr) 638ac6a4445SGunnar Mills { 639ac6a4445SGunnar Mills continue; 640ac6a4445SGunnar Mills } 641ac6a4445SGunnar Mills aResp->res.jsonValue["OperatingSpeedMhz"] = *value; 642ac6a4445SGunnar Mills } 643ac6a4445SGunnar Mills else if (property.first == "MemoryType") 644ac6a4445SGunnar Mills { 645ac6a4445SGunnar Mills const auto* value = 646ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 647ac6a4445SGunnar Mills if (value != nullptr) 648ac6a4445SGunnar Mills { 649313efb1cSGunnar Mills std::string memoryDeviceType = 650313efb1cSGunnar Mills translateMemoryTypeToRedfish(*value); 651313efb1cSGunnar Mills // Values like "Unknown" or "Other" will return empty 652313efb1cSGunnar Mills // so just leave off 653313efb1cSGunnar Mills if (!memoryDeviceType.empty()) 654ac6a4445SGunnar Mills { 655313efb1cSGunnar Mills aResp->res.jsonValue["MemoryDeviceType"] = 656313efb1cSGunnar Mills memoryDeviceType; 657ac6a4445SGunnar Mills } 658ac6a4445SGunnar Mills if (value->find("DDR") != std::string::npos) 659ac6a4445SGunnar Mills { 660ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryType"] = "DRAM"; 661ac6a4445SGunnar Mills } 662ac6a4445SGunnar Mills else if (boost::ends_with(*value, "Logical")) 663ac6a4445SGunnar Mills { 664ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryType"] = "IntelOptane"; 665ac6a4445SGunnar Mills } 666ac6a4445SGunnar Mills } 667ac6a4445SGunnar Mills } 668ac6a4445SGunnar Mills // memory location interface 669ac6a4445SGunnar Mills else if (property.first == "Channel" || 670ac6a4445SGunnar Mills property.first == "MemoryController" || 671ac6a4445SGunnar Mills property.first == "Slot" || property.first == "Socket") 672ac6a4445SGunnar Mills { 673ac6a4445SGunnar Mills const std::string* value = 674ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 675ac6a4445SGunnar Mills if (value == nullptr) 676ac6a4445SGunnar Mills { 677ac6a4445SGunnar Mills messages::internalError(aResp->res); 678601af5edSChicago Duan return; 679ac6a4445SGunnar Mills } 680ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryLocation"][property.first] = 681ac6a4445SGunnar Mills *value; 682ac6a4445SGunnar Mills } 683ee135e24SSunnySrivastava1984 else if (property.first == "SparePartNumber") 684ee135e24SSunnySrivastava1984 { 685ee135e24SSunnySrivastava1984 const std::string* value = 686ee135e24SSunnySrivastava1984 std::get_if<std::string>(&property.second); 687ee135e24SSunnySrivastava1984 if (value == nullptr) 688ee135e24SSunnySrivastava1984 { 689ee135e24SSunnySrivastava1984 messages::internalError(aResp->res); 690601af5edSChicago Duan return; 691ee135e24SSunnySrivastava1984 } 692ee135e24SSunnySrivastava1984 aResp->res.jsonValue["SparePartNumber"] = *value; 693ee135e24SSunnySrivastava1984 } 694ee135e24SSunnySrivastava1984 else if (property.first == "Model") 695ee135e24SSunnySrivastava1984 { 696ee135e24SSunnySrivastava1984 const std::string* value = 697ee135e24SSunnySrivastava1984 std::get_if<std::string>(&property.second); 698ee135e24SSunnySrivastava1984 if (value == nullptr) 699ee135e24SSunnySrivastava1984 { 700ee135e24SSunnySrivastava1984 messages::internalError(aResp->res); 701601af5edSChicago Duan return; 702ee135e24SSunnySrivastava1984 } 703ee135e24SSunnySrivastava1984 aResp->res.jsonValue["Model"] = *value; 704ee135e24SSunnySrivastava1984 } 705ee135e24SSunnySrivastava1984 else if (property.first == "LocationCode") 706ee135e24SSunnySrivastava1984 { 707ee135e24SSunnySrivastava1984 const std::string* value = 708ee135e24SSunnySrivastava1984 std::get_if<std::string>(&property.second); 709ee135e24SSunnySrivastava1984 if (value == nullptr) 710ee135e24SSunnySrivastava1984 { 711ee135e24SSunnySrivastava1984 messages::internalError(aResp->res); 712601af5edSChicago Duan return; 713ee135e24SSunnySrivastava1984 } 714ee135e24SSunnySrivastava1984 aResp->res 715ee135e24SSunnySrivastava1984 .jsonValue["Location"]["PartLocation"]["ServiceLabel"] = 716ee135e24SSunnySrivastava1984 *value; 717ee135e24SSunnySrivastava1984 } 718ac6a4445SGunnar Mills else 719ac6a4445SGunnar Mills { 720*80badf7cSJiaqing Zhao getPersistentMemoryProperties(aResp, property); 721ac6a4445SGunnar Mills } 722ac6a4445SGunnar Mills } 723ac6a4445SGunnar Mills }, 724ac6a4445SGunnar Mills service, objPath, "org.freedesktop.DBus.Properties", "GetAll", ""); 725ac6a4445SGunnar Mills } 726ac6a4445SGunnar Mills 7278d1b46d7Szhanghch05 inline void getDimmPartitionData(std::shared_ptr<bmcweb::AsyncResp> aResp, 728ac6a4445SGunnar Mills const std::string& service, 729ac6a4445SGunnar Mills const std::string& path) 730ac6a4445SGunnar Mills { 731ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 732ac6a4445SGunnar Mills [aResp{std::move(aResp)}]( 733ac6a4445SGunnar Mills const boost::system::error_code ec, 734ac6a4445SGunnar Mills const boost::container::flat_map< 735168e20c1SEd Tanous std::string, dbus::utility::DbusVariantType>& properties) { 736ac6a4445SGunnar Mills if (ec) 737ac6a4445SGunnar Mills { 738ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 739ac6a4445SGunnar Mills messages::internalError(aResp->res); 740ac6a4445SGunnar Mills 741ac6a4445SGunnar Mills return; 742ac6a4445SGunnar Mills } 743ac6a4445SGunnar Mills 744ac6a4445SGunnar Mills nlohmann::json& partition = 745ac6a4445SGunnar Mills aResp->res.jsonValue["Regions"].emplace_back( 746ac6a4445SGunnar Mills nlohmann::json::object()); 747ac6a4445SGunnar Mills for (const auto& [key, val] : properties) 748ac6a4445SGunnar Mills { 749ac6a4445SGunnar Mills if (key == "MemoryClassification") 750ac6a4445SGunnar Mills { 751ac6a4445SGunnar Mills const std::string* value = std::get_if<std::string>(&val); 752ac6a4445SGunnar Mills if (value == nullptr) 753ac6a4445SGunnar Mills { 754ac6a4445SGunnar Mills messages::internalError(aResp->res); 755601af5edSChicago Duan return; 756ac6a4445SGunnar Mills } 757ac6a4445SGunnar Mills partition[key] = *value; 758ac6a4445SGunnar Mills } 759ac6a4445SGunnar Mills else if (key == "OffsetInKiB") 760ac6a4445SGunnar Mills { 761ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&val); 762ac6a4445SGunnar Mills if (value == nullptr) 763ac6a4445SGunnar Mills { 764ac6a4445SGunnar Mills messages::internalError(aResp->res); 765601af5edSChicago Duan return; 766ac6a4445SGunnar Mills } 767ac6a4445SGunnar Mills 768ac6a4445SGunnar Mills partition["OffsetMiB"] = (*value >> 10); 769ac6a4445SGunnar Mills } 770ac6a4445SGunnar Mills else if (key == "PartitionId") 771ac6a4445SGunnar Mills { 772ac6a4445SGunnar Mills const std::string* value = std::get_if<std::string>(&val); 773ac6a4445SGunnar Mills if (value == nullptr) 774ac6a4445SGunnar Mills { 775ac6a4445SGunnar Mills messages::internalError(aResp->res); 776601af5edSChicago Duan return; 777ac6a4445SGunnar Mills } 778ac6a4445SGunnar Mills partition["RegionId"] = *value; 779ac6a4445SGunnar Mills } 780ac6a4445SGunnar Mills 781ac6a4445SGunnar Mills else if (key == "PassphraseState") 782ac6a4445SGunnar Mills { 783ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&val); 784ac6a4445SGunnar Mills if (value == nullptr) 785ac6a4445SGunnar Mills { 786ac6a4445SGunnar Mills messages::internalError(aResp->res); 787601af5edSChicago Duan return; 788ac6a4445SGunnar Mills } 789ac6a4445SGunnar Mills partition["PassphraseEnabled"] = *value; 790ac6a4445SGunnar Mills } 791ac6a4445SGunnar Mills else if (key == "SizeInKiB") 792ac6a4445SGunnar Mills { 793ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&val); 794ac6a4445SGunnar Mills if (value == nullptr) 795ac6a4445SGunnar Mills { 796ac6a4445SGunnar Mills messages::internalError(aResp->res); 797ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 798ac6a4445SGunnar Mills << "Invalid property type for SizeInKiB"; 799601af5edSChicago Duan return; 800ac6a4445SGunnar Mills } 801ac6a4445SGunnar Mills partition["SizeMiB"] = (*value >> 10); 802ac6a4445SGunnar Mills } 803ac6a4445SGunnar Mills } 804ac6a4445SGunnar Mills }, 805ac6a4445SGunnar Mills 806ac6a4445SGunnar Mills service, path, "org.freedesktop.DBus.Properties", "GetAll", 807ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"); 808ac6a4445SGunnar Mills } 809ac6a4445SGunnar Mills 8108d1b46d7Szhanghch05 inline void getDimmData(std::shared_ptr<bmcweb::AsyncResp> aResp, 811ac6a4445SGunnar Mills const std::string& dimmId) 812ac6a4445SGunnar Mills { 813ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Get available system dimm resources."; 814ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 815ac6a4445SGunnar Mills [dimmId, aResp{std::move(aResp)}]( 816ac6a4445SGunnar Mills const boost::system::error_code ec, 817ac6a4445SGunnar Mills const boost::container::flat_map< 818ac6a4445SGunnar Mills std::string, boost::container::flat_map< 819ac6a4445SGunnar Mills std::string, std::vector<std::string>>>& 820ac6a4445SGunnar Mills subtree) { 821ac6a4445SGunnar Mills if (ec) 822ac6a4445SGunnar Mills { 823ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 824ac6a4445SGunnar Mills messages::internalError(aResp->res); 825ac6a4445SGunnar Mills 826ac6a4445SGunnar Mills return; 827ac6a4445SGunnar Mills } 828ac6a4445SGunnar Mills bool found = false; 829ac6a4445SGunnar Mills for (const auto& [path, object] : subtree) 830ac6a4445SGunnar Mills { 831ac6a4445SGunnar Mills if (path.find(dimmId) != std::string::npos) 832ac6a4445SGunnar Mills { 833ac6a4445SGunnar Mills for (const auto& [service, interfaces] : object) 834ac6a4445SGunnar Mills { 835ac6a4445SGunnar Mills if (!found && 836ac6a4445SGunnar Mills (std::find( 837ac6a4445SGunnar Mills interfaces.begin(), interfaces.end(), 838ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm") != 839ac6a4445SGunnar Mills interfaces.end())) 840ac6a4445SGunnar Mills { 841ac6a4445SGunnar Mills getDimmDataByService(aResp, dimmId, service, path); 842ac6a4445SGunnar Mills found = true; 843ac6a4445SGunnar Mills } 844ac6a4445SGunnar Mills 845ac6a4445SGunnar Mills // partitions are separate as there can be multiple per 846ac6a4445SGunnar Mills // device, i.e. 847ac6a4445SGunnar Mills // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1 848ac6a4445SGunnar Mills // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2 8490fda0f12SGeorge Liu if (std::find( 8500fda0f12SGeorge Liu interfaces.begin(), interfaces.end(), 8510fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition") != 852ac6a4445SGunnar Mills interfaces.end()) 853ac6a4445SGunnar Mills { 854ac6a4445SGunnar Mills getDimmPartitionData(aResp, service, path); 855ac6a4445SGunnar Mills } 856ac6a4445SGunnar Mills } 857ac6a4445SGunnar Mills } 858ac6a4445SGunnar Mills } 859ac6a4445SGunnar Mills // Object not found 860ac6a4445SGunnar Mills if (!found) 861ac6a4445SGunnar Mills { 862ac6a4445SGunnar Mills messages::resourceNotFound(aResp->res, "Memory", dimmId); 863ac6a4445SGunnar Mills } 864ac6a4445SGunnar Mills return; 865ac6a4445SGunnar Mills }, 866ac6a4445SGunnar Mills "xyz.openbmc_project.ObjectMapper", 867ac6a4445SGunnar Mills "/xyz/openbmc_project/object_mapper", 868ac6a4445SGunnar Mills "xyz.openbmc_project.ObjectMapper", "GetSubTree", 869ac6a4445SGunnar Mills "/xyz/openbmc_project/inventory", 0, 870ac6a4445SGunnar Mills std::array<const char*, 2>{ 871ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm", 872ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"}); 873ac6a4445SGunnar Mills } 874ac6a4445SGunnar Mills 8757e860f15SJohn Edward Broadbent inline void requestRoutesMemoryCollection(App& app) 876ac6a4445SGunnar Mills { 877ac6a4445SGunnar Mills /** 878ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 879ac6a4445SGunnar Mills */ 8807e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Memory/") 881ed398213SEd Tanous .privileges(redfish::privileges::getMemoryCollection) 8827e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 8837e860f15SJohn Edward Broadbent [](const crow::Request&, 8847e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 8858d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 8868d1b46d7Szhanghch05 "#MemoryCollection.MemoryCollection"; 8878d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Memory Module Collection"; 8888d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = 8898d1b46d7Szhanghch05 "/redfish/v1/Systems/system/Memory"; 890ac6a4445SGunnar Mills 89105030b8eSGunnar Mills collection_util::getCollectionMembers( 89205030b8eSGunnar Mills asyncResp, "/redfish/v1/Systems/system/Memory", 89305030b8eSGunnar Mills {"xyz.openbmc_project.Inventory.Item.Dimm"}); 8947e860f15SJohn Edward Broadbent }); 895ac6a4445SGunnar Mills } 896ac6a4445SGunnar Mills 8977e860f15SJohn Edward Broadbent inline void requestRoutesMemory(App& app) 8987e860f15SJohn Edward Broadbent { 899ac6a4445SGunnar Mills /** 900ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 901ac6a4445SGunnar Mills */ 9027e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Memory/<str>/") 903ed398213SEd Tanous .privileges(redfish::privileges::getMemory) 9047e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 9057e860f15SJohn Edward Broadbent [](const crow::Request&, 9067e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 9077e860f15SJohn Edward Broadbent const std::string& dimmId) { 9087e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["@odata.type"] = 9097e860f15SJohn Edward Broadbent "#Memory.v1_11_0.Memory"; 9108d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = 911ac6a4445SGunnar Mills "/redfish/v1/Systems/system/Memory/" + dimmId; 912ac6a4445SGunnar Mills 913ac6a4445SGunnar Mills getDimmData(asyncResp, dimmId); 9147e860f15SJohn Edward Broadbent }); 915ac6a4445SGunnar Mills } 916ac6a4445SGunnar Mills 917ac6a4445SGunnar Mills } // namespace redfish 918