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 20ac6a4445SGunnar Mills #include <boost/container/flat_map.hpp> 21ac6a4445SGunnar Mills #include <boost/format.hpp> 22ac6a4445SGunnar Mills #include <node.hpp> 23ac6a4445SGunnar Mills #include <utils/collection.hpp> 24ac6a4445SGunnar Mills #include <utils/json_utils.hpp> 25ac6a4445SGunnar Mills 26ac6a4445SGunnar Mills namespace redfish 27ac6a4445SGunnar Mills { 28ac6a4445SGunnar Mills 29ac6a4445SGunnar Mills using DimmProperty = 30ac6a4445SGunnar Mills std::variant<std::string, std::vector<uint32_t>, std::vector<uint16_t>, 31ac6a4445SGunnar Mills uint64_t, uint32_t, uint16_t, uint8_t, bool>; 32ac6a4445SGunnar Mills 33ac6a4445SGunnar Mills using DimmProperties = boost::container::flat_map<std::string, DimmProperty>; 34ac6a4445SGunnar Mills 35313efb1cSGunnar Mills inline std::string translateMemoryTypeToRedfish(const std::string& memoryType) 36313efb1cSGunnar Mills { 37313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR") 38313efb1cSGunnar Mills { 39313efb1cSGunnar Mills return "DDR"; 40313efb1cSGunnar Mills } 41313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2") 42313efb1cSGunnar Mills { 43313efb1cSGunnar Mills return "DDR2"; 44313efb1cSGunnar Mills } 45313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR3") 46313efb1cSGunnar Mills { 47313efb1cSGunnar Mills return "DDR3"; 48313efb1cSGunnar Mills } 49313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4") 50313efb1cSGunnar Mills { 51313efb1cSGunnar Mills return "DDR4"; 52313efb1cSGunnar Mills } 53313efb1cSGunnar Mills if (memoryType == 54313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4E_SDRAM") 55313efb1cSGunnar Mills { 56313efb1cSGunnar Mills return "DDR4E_SDRAM"; 57313efb1cSGunnar Mills } 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 } 73313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_" 74313efb1cSGunnar Mills "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 136313efb1cSGunnar Mills return ""; 137313efb1cSGunnar Mills } 138313efb1cSGunnar Mills 139ac6a4445SGunnar Mills inline void dimmPropToHex(const std::shared_ptr<AsyncResp>& aResp, 140ac6a4445SGunnar Mills const char* key, 141ac6a4445SGunnar Mills const std::pair<std::string, DimmProperty>& property) 142ac6a4445SGunnar Mills { 143ac6a4445SGunnar Mills const uint16_t* value = std::get_if<uint16_t>(&property.second); 144ac6a4445SGunnar Mills if (value == nullptr) 145ac6a4445SGunnar Mills { 146ac6a4445SGunnar Mills messages::internalError(aResp->res); 147ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for " << property.first; 148ac6a4445SGunnar Mills return; 149ac6a4445SGunnar Mills } 150ac6a4445SGunnar Mills 151ac6a4445SGunnar Mills aResp->res.jsonValue[key] = (boost::format("0x%04x") % *value).str(); 152ac6a4445SGunnar Mills } 153ac6a4445SGunnar Mills 154ac6a4445SGunnar Mills inline void 155ac6a4445SGunnar Mills getPersistentMemoryProperties(const std::shared_ptr<AsyncResp>& aResp, 156ac6a4445SGunnar Mills const DimmProperties& properties) 157ac6a4445SGunnar Mills { 158ac6a4445SGunnar Mills for (const auto& property : properties) 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 { 175ac6a4445SGunnar Mills dimmPropToHex(aResp, "MemorySubsystemControllerProductID", 176ac6a4445SGunnar Mills property); 177ac6a4445SGunnar Mills } 178ac6a4445SGunnar Mills else if (property.first == "VolatileRegionSizeLimitInKiB") 179ac6a4445SGunnar Mills { 180ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 181ac6a4445SGunnar Mills 182ac6a4445SGunnar Mills if (value == nullptr) 183ac6a4445SGunnar Mills { 184ac6a4445SGunnar Mills messages::internalError(aResp->res); 185ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for " 186ac6a4445SGunnar Mills "VolatileRegionSizeLimitKiB"; 187ac6a4445SGunnar Mills continue; 188ac6a4445SGunnar Mills } 189ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileRegionSizeLimitMiB"] = (*value) >> 10; 190ac6a4445SGunnar Mills } 191ac6a4445SGunnar Mills else if (property.first == "PmRegionSizeLimitInKiB") 192ac6a4445SGunnar Mills { 193ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 194ac6a4445SGunnar Mills 195ac6a4445SGunnar Mills if (value == nullptr) 196ac6a4445SGunnar Mills { 197ac6a4445SGunnar Mills messages::internalError(aResp->res); 198ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 199ac6a4445SGunnar Mills << "Invalid property type for PmRegioSizeLimitKiB"; 200ac6a4445SGunnar Mills continue; 201ac6a4445SGunnar Mills } 202ac6a4445SGunnar Mills aResp->res.jsonValue["PersistentRegionSizeLimitMiB"] = 203ac6a4445SGunnar Mills (*value) >> 10; 204ac6a4445SGunnar Mills } 205ac6a4445SGunnar Mills else if (property.first == "VolatileSizeInKiB") 206ac6a4445SGunnar Mills { 207ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 208ac6a4445SGunnar Mills 209ac6a4445SGunnar Mills if (value == nullptr) 210ac6a4445SGunnar Mills { 211ac6a4445SGunnar Mills messages::internalError(aResp->res); 212ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 213ac6a4445SGunnar Mills << "Invalid property type for VolatileSizeInKiB"; 214ac6a4445SGunnar Mills continue; 215ac6a4445SGunnar Mills } 216ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileSizeMiB"] = (*value) >> 10; 217ac6a4445SGunnar Mills } 218ac6a4445SGunnar Mills else if (property.first == "PmSizeInKiB") 219ac6a4445SGunnar Mills { 220ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 221ac6a4445SGunnar Mills if (value == nullptr) 222ac6a4445SGunnar Mills { 223ac6a4445SGunnar Mills messages::internalError(aResp->res); 224ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for PmSizeInKiB"; 225ac6a4445SGunnar Mills continue; 226ac6a4445SGunnar Mills } 227ac6a4445SGunnar Mills aResp->res.jsonValue["NonVolatileSizeMiB"] = (*value) >> 10; 228ac6a4445SGunnar Mills } 229ac6a4445SGunnar Mills else if (property.first == "CacheSizeInKB") 230ac6a4445SGunnar Mills { 231ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 232ac6a4445SGunnar Mills if (value == nullptr) 233ac6a4445SGunnar Mills { 234ac6a4445SGunnar Mills messages::internalError(aResp->res); 235ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for CacheSizeInKB"; 236ac6a4445SGunnar Mills continue; 237ac6a4445SGunnar Mills } 238ac6a4445SGunnar Mills aResp->res.jsonValue["CacheSizeMiB"] = (*value >> 10); 239ac6a4445SGunnar Mills } 240ac6a4445SGunnar Mills 241ac6a4445SGunnar Mills else if (property.first == "VoltaileRegionMaxSizeInKib") 242ac6a4445SGunnar Mills { 243ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 244ac6a4445SGunnar Mills 245ac6a4445SGunnar Mills if (value == nullptr) 246ac6a4445SGunnar Mills { 247ac6a4445SGunnar Mills messages::internalError(aResp->res); 248ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for " 249ac6a4445SGunnar Mills "VolatileRegionMaxSizeInKib"; 250ac6a4445SGunnar Mills continue; 251ac6a4445SGunnar Mills } 252ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileRegionSizeMaxMiB"] = (*value) >> 10; 253ac6a4445SGunnar Mills } 254ac6a4445SGunnar Mills else if (property.first == "PmRegionMaxSizeInKiB") 255ac6a4445SGunnar Mills { 256ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 257ac6a4445SGunnar Mills 258ac6a4445SGunnar Mills if (value == nullptr) 259ac6a4445SGunnar Mills { 260ac6a4445SGunnar Mills messages::internalError(aResp->res); 261ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 262ac6a4445SGunnar Mills << "Invalid property type for PmRegionMaxSizeInKiB"; 263ac6a4445SGunnar Mills continue; 264ac6a4445SGunnar Mills } 265ac6a4445SGunnar Mills aResp->res.jsonValue["PersistentRegionSizeMaxMiB"] = (*value) >> 10; 266ac6a4445SGunnar Mills } 267ac6a4445SGunnar Mills else if (property.first == "AllocationIncrementInKiB") 268ac6a4445SGunnar Mills { 269ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 270ac6a4445SGunnar Mills 271ac6a4445SGunnar Mills if (value == nullptr) 272ac6a4445SGunnar Mills { 273ac6a4445SGunnar Mills messages::internalError(aResp->res); 274ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for " 275ac6a4445SGunnar Mills "AllocationIncrementInKiB"; 276ac6a4445SGunnar Mills continue; 277ac6a4445SGunnar Mills } 278ac6a4445SGunnar Mills aResp->res.jsonValue["AllocationIncrementMiB"] = (*value) >> 10; 279ac6a4445SGunnar Mills } 280ac6a4445SGunnar Mills else if (property.first == "AllocationAlignmentInKiB") 281ac6a4445SGunnar Mills { 282ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 283ac6a4445SGunnar Mills 284ac6a4445SGunnar Mills if (value == nullptr) 285ac6a4445SGunnar Mills { 286ac6a4445SGunnar Mills messages::internalError(aResp->res); 287ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for " 288ac6a4445SGunnar Mills "AllocationAlignmentInKiB"; 289ac6a4445SGunnar Mills continue; 290ac6a4445SGunnar Mills } 291ac6a4445SGunnar Mills aResp->res.jsonValue["AllocationAlignmentMiB"] = (*value) >> 10; 292ac6a4445SGunnar Mills } 293ac6a4445SGunnar Mills else if (property.first == "VolatileRegionNumberLimit") 294ac6a4445SGunnar Mills { 295ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 296ac6a4445SGunnar Mills if (value == nullptr) 297ac6a4445SGunnar Mills { 298ac6a4445SGunnar Mills messages::internalError(aResp->res); 299ac6a4445SGunnar Mills continue; 300ac6a4445SGunnar Mills } 301ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileRegionNumberLimit"] = *value; 302ac6a4445SGunnar Mills } 303ac6a4445SGunnar Mills else if (property.first == "PmRegionNumberLimit") 304ac6a4445SGunnar Mills { 305ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 306ac6a4445SGunnar Mills if (value == nullptr) 307ac6a4445SGunnar Mills { 308ac6a4445SGunnar Mills messages::internalError(aResp->res); 309ac6a4445SGunnar Mills continue; 310ac6a4445SGunnar Mills } 311ac6a4445SGunnar Mills aResp->res.jsonValue["PersistentRegionNumberLimit"] = *value; 312ac6a4445SGunnar Mills } 313ac6a4445SGunnar Mills else if (property.first == "SpareDeviceCount") 314ac6a4445SGunnar Mills { 315ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 316ac6a4445SGunnar Mills if (value == nullptr) 317ac6a4445SGunnar Mills { 318ac6a4445SGunnar Mills messages::internalError(aResp->res); 319ac6a4445SGunnar Mills continue; 320ac6a4445SGunnar Mills } 321ac6a4445SGunnar Mills aResp->res.jsonValue["SpareDeviceCount"] = *value; 322ac6a4445SGunnar Mills } 323ac6a4445SGunnar Mills else if (property.first == "IsSpareDeviceInUse") 324ac6a4445SGunnar Mills { 325ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 326ac6a4445SGunnar Mills if (value == nullptr) 327ac6a4445SGunnar Mills { 328ac6a4445SGunnar Mills messages::internalError(aResp->res); 329ac6a4445SGunnar Mills continue; 330ac6a4445SGunnar Mills } 331ac6a4445SGunnar Mills aResp->res.jsonValue["IsSpareDeviceEnabled"] = *value; 332ac6a4445SGunnar Mills } 333ac6a4445SGunnar Mills else if (property.first == "IsRankSpareEnabled") 334ac6a4445SGunnar Mills { 335ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 336ac6a4445SGunnar Mills if (value == nullptr) 337ac6a4445SGunnar Mills { 338ac6a4445SGunnar Mills messages::internalError(aResp->res); 339ac6a4445SGunnar Mills continue; 340ac6a4445SGunnar Mills } 341ac6a4445SGunnar Mills aResp->res.jsonValue["IsRankSpareEnabled"] = *value; 342ac6a4445SGunnar Mills } 343ac6a4445SGunnar Mills else if (property.first == "MaxAveragePowerLimitmW") 344ac6a4445SGunnar Mills { 345ac6a4445SGunnar Mills const auto* value = 346ac6a4445SGunnar Mills std::get_if<std::vector<uint32_t>>(&property.second); 347ac6a4445SGunnar Mills if (value == nullptr) 348ac6a4445SGunnar Mills { 349ac6a4445SGunnar Mills messages::internalError(aResp->res); 350ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for " 351ac6a4445SGunnar Mills "MaxAveragePowerLimitmW"; 352ac6a4445SGunnar Mills continue; 353ac6a4445SGunnar Mills } 354ac6a4445SGunnar Mills aResp->res.jsonValue["MaxTDPMilliWatts"] = *value; 355ac6a4445SGunnar Mills } 356ac6a4445SGunnar Mills else if (property.first == "ConfigurationLocked") 357ac6a4445SGunnar Mills { 358ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 359ac6a4445SGunnar Mills if (value == nullptr) 360ac6a4445SGunnar Mills { 361ac6a4445SGunnar Mills messages::internalError(aResp->res); 362ac6a4445SGunnar Mills continue; 363ac6a4445SGunnar Mills } 364ac6a4445SGunnar Mills aResp->res.jsonValue["ConfigurationLocked"] = *value; 365ac6a4445SGunnar Mills } 366ac6a4445SGunnar Mills else if (property.first == "AllowedMemoryModes") 367ac6a4445SGunnar Mills { 368ac6a4445SGunnar Mills const std::string* value = 369ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 370ac6a4445SGunnar Mills if (value == nullptr) 371ac6a4445SGunnar Mills { 372ac6a4445SGunnar Mills messages::internalError(aResp->res); 373ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for FormFactor"; 374ac6a4445SGunnar Mills continue; 375ac6a4445SGunnar Mills } 376ac6a4445SGunnar Mills constexpr const std::array<const char*, 3> values{"Volatile", 377ac6a4445SGunnar Mills "PMEM", "Block"}; 378ac6a4445SGunnar Mills 379ac6a4445SGunnar Mills for (const char* v : values) 380ac6a4445SGunnar Mills { 381ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 382ac6a4445SGunnar Mills { 383ac6a4445SGunnar Mills aResp->res.jsonValue["OperatingMemoryModes "] = v; 384ac6a4445SGunnar Mills break; 385ac6a4445SGunnar Mills } 386ac6a4445SGunnar Mills } 387ac6a4445SGunnar Mills } 388ac6a4445SGunnar Mills else if (property.first == "MemoryMedia") 389ac6a4445SGunnar Mills { 390ac6a4445SGunnar Mills const std::string* value = 391ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 392ac6a4445SGunnar Mills if (value == nullptr) 393ac6a4445SGunnar Mills { 394ac6a4445SGunnar Mills messages::internalError(aResp->res); 395ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for MemoryMedia"; 396ac6a4445SGunnar Mills continue; 397ac6a4445SGunnar Mills } 398ac6a4445SGunnar Mills constexpr const std::array<const char*, 3> values{"DRAM", "NAND", 399ac6a4445SGunnar Mills "Intel3DXPoint"}; 400ac6a4445SGunnar Mills 401ac6a4445SGunnar Mills for (const char* v : values) 402ac6a4445SGunnar Mills { 403ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 404ac6a4445SGunnar Mills { 405ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryMedia"] = v; 406ac6a4445SGunnar Mills break; 407ac6a4445SGunnar Mills } 408ac6a4445SGunnar Mills } 409ac6a4445SGunnar Mills } 410ac6a4445SGunnar Mills // PersistantMemory.SecurityCapabilites interface 411ac6a4445SGunnar Mills else if (property.first == "ConfigurationLockCapable" || 412ac6a4445SGunnar Mills property.first == "DataLockCapable" || 413ac6a4445SGunnar Mills property.first == "PassphraseCapable") 414ac6a4445SGunnar Mills { 415ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 416ac6a4445SGunnar Mills if (value == nullptr) 417ac6a4445SGunnar Mills { 418ac6a4445SGunnar Mills messages::internalError(aResp->res); 419ac6a4445SGunnar Mills continue; 420ac6a4445SGunnar Mills } 421ac6a4445SGunnar Mills aResp->res.jsonValue["SecurityCapabilities"][property.first] = 422ac6a4445SGunnar Mills *value; 423ac6a4445SGunnar Mills } 424ac6a4445SGunnar Mills else if (property.first == "MaxPassphraseCount" || 425ac6a4445SGunnar Mills property.first == "PassphraseLockLimit") 426ac6a4445SGunnar Mills { 427ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 428ac6a4445SGunnar Mills if (value == nullptr) 429ac6a4445SGunnar Mills { 430ac6a4445SGunnar Mills messages::internalError(aResp->res); 431ac6a4445SGunnar Mills continue; 432ac6a4445SGunnar Mills } 433ac6a4445SGunnar Mills aResp->res.jsonValue["SecurityCapabilities"][property.first] = 434ac6a4445SGunnar Mills *value; 435ac6a4445SGunnar Mills } 436ac6a4445SGunnar Mills } 437ac6a4445SGunnar Mills } 438ac6a4445SGunnar Mills 439ac6a4445SGunnar Mills inline void getDimmDataByService(std::shared_ptr<AsyncResp> aResp, 440ac6a4445SGunnar Mills const std::string& dimmId, 441ac6a4445SGunnar Mills const std::string& service, 442ac6a4445SGunnar Mills const std::string& objPath) 443ac6a4445SGunnar Mills { 444ac6a4445SGunnar Mills auto health = std::make_shared<HealthPopulate>(aResp); 445ac6a4445SGunnar Mills health->selfPath = objPath; 446ac6a4445SGunnar Mills health->populate(); 447ac6a4445SGunnar Mills 448ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Get available system components."; 449ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 450ac6a4445SGunnar Mills [dimmId, aResp{std::move(aResp)}](const boost::system::error_code ec, 451ac6a4445SGunnar Mills const DimmProperties& properties) { 452ac6a4445SGunnar Mills if (ec) 453ac6a4445SGunnar Mills { 454ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 455ac6a4445SGunnar Mills messages::internalError(aResp->res); 456ac6a4445SGunnar Mills 457ac6a4445SGunnar Mills return; 458ac6a4445SGunnar Mills } 459ac6a4445SGunnar Mills aResp->res.jsonValue["Id"] = dimmId; 460ac6a4445SGunnar Mills aResp->res.jsonValue["Name"] = "DIMM Slot"; 461ac6a4445SGunnar Mills 462ac6a4445SGunnar Mills const auto memorySizeProperty = properties.find("MemorySizeInKB"); 463ac6a4445SGunnar Mills if (memorySizeProperty != properties.end()) 464ac6a4445SGunnar Mills { 465ac6a4445SGunnar Mills const uint32_t* memorySize = 466ac6a4445SGunnar Mills std::get_if<uint32_t>(&memorySizeProperty->second); 467ac6a4445SGunnar Mills if (memorySize == nullptr) 468ac6a4445SGunnar Mills { 469ac6a4445SGunnar Mills // Important property not in desired type 470ac6a4445SGunnar Mills messages::internalError(aResp->res); 471ac6a4445SGunnar Mills return; 472ac6a4445SGunnar Mills } 473ac6a4445SGunnar Mills aResp->res.jsonValue["CapacityMiB"] = (*memorySize >> 10); 474ac6a4445SGunnar Mills } 475ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["State"] = "Enabled"; 476ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["Health"] = "OK"; 477ac6a4445SGunnar Mills 478ac6a4445SGunnar Mills for (const auto& property : properties) 479ac6a4445SGunnar Mills { 480ac6a4445SGunnar Mills if (property.first == "MemoryDataWidth") 481ac6a4445SGunnar Mills { 482ac6a4445SGunnar Mills const uint16_t* value = 483ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 484ac6a4445SGunnar Mills if (value == nullptr) 485ac6a4445SGunnar Mills { 486ac6a4445SGunnar Mills continue; 487ac6a4445SGunnar Mills } 488ac6a4445SGunnar Mills aResp->res.jsonValue["DataWidthBits"] = *value; 489ac6a4445SGunnar Mills } 490ac6a4445SGunnar Mills else if (property.first == "PartNumber") 491ac6a4445SGunnar Mills { 492ac6a4445SGunnar Mills const std::string* value = 493ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 494ac6a4445SGunnar Mills if (value == nullptr) 495ac6a4445SGunnar Mills { 496ac6a4445SGunnar Mills continue; 497ac6a4445SGunnar Mills } 498ac6a4445SGunnar Mills aResp->res.jsonValue["PartNumber"] = *value; 499ac6a4445SGunnar Mills } 500ac6a4445SGunnar Mills else if (property.first == "SerialNumber") 501ac6a4445SGunnar Mills { 502ac6a4445SGunnar Mills const std::string* value = 503ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 504ac6a4445SGunnar Mills if (value == nullptr) 505ac6a4445SGunnar Mills { 506ac6a4445SGunnar Mills continue; 507ac6a4445SGunnar Mills } 508ac6a4445SGunnar Mills aResp->res.jsonValue["SerialNumber"] = *value; 509ac6a4445SGunnar Mills } 510ac6a4445SGunnar Mills else if (property.first == "Manufacturer") 511ac6a4445SGunnar Mills { 512ac6a4445SGunnar Mills const std::string* value = 513ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 514ac6a4445SGunnar Mills if (value == nullptr) 515ac6a4445SGunnar Mills { 516ac6a4445SGunnar Mills continue; 517ac6a4445SGunnar Mills } 518ac6a4445SGunnar Mills aResp->res.jsonValue["Manufacturer"] = *value; 519ac6a4445SGunnar Mills } 520ac6a4445SGunnar Mills else if (property.first == "RevisionCode") 521ac6a4445SGunnar Mills { 522ac6a4445SGunnar Mills const uint16_t* value = 523ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 524ac6a4445SGunnar Mills 525ac6a4445SGunnar Mills if (value == nullptr) 526ac6a4445SGunnar Mills { 527ac6a4445SGunnar Mills messages::internalError(aResp->res); 528ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 529ac6a4445SGunnar Mills << "Invalid property type for RevisionCode"; 530ac6a4445SGunnar Mills continue; 531ac6a4445SGunnar Mills } 532ac6a4445SGunnar Mills aResp->res.jsonValue["FirmwareRevision"] = 533ac6a4445SGunnar Mills std::to_string(*value); 534ac6a4445SGunnar Mills } 535ac6a4445SGunnar Mills else if (property.first == "MemoryTotalWidth") 536ac6a4445SGunnar Mills { 537ac6a4445SGunnar Mills const uint16_t* value = 538ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 539ac6a4445SGunnar Mills if (value == nullptr) 540ac6a4445SGunnar Mills { 541ac6a4445SGunnar Mills continue; 542ac6a4445SGunnar Mills } 543ac6a4445SGunnar Mills aResp->res.jsonValue["BusWidthBits"] = *value; 544ac6a4445SGunnar Mills } 545ac6a4445SGunnar Mills else if (property.first == "ECC") 546ac6a4445SGunnar Mills { 547ac6a4445SGunnar Mills const std::string* value = 548ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 549ac6a4445SGunnar Mills if (value == nullptr) 550ac6a4445SGunnar Mills { 551ac6a4445SGunnar Mills messages::internalError(aResp->res); 552ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for ECC"; 553ac6a4445SGunnar Mills continue; 554ac6a4445SGunnar Mills } 555ac6a4445SGunnar Mills constexpr const std::array<const char*, 4> values{ 556ac6a4445SGunnar Mills "NoECC", "SingleBitECC", "MultiBitECC", 557ac6a4445SGunnar Mills "AddressParity"}; 558ac6a4445SGunnar Mills 559ac6a4445SGunnar Mills for (const char* v : values) 560ac6a4445SGunnar Mills { 561ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 562ac6a4445SGunnar Mills { 563ac6a4445SGunnar Mills aResp->res.jsonValue["ErrorCorrection"] = v; 564ac6a4445SGunnar Mills break; 565ac6a4445SGunnar Mills } 566ac6a4445SGunnar Mills } 567ac6a4445SGunnar Mills } 568ac6a4445SGunnar Mills else if (property.first == "FormFactor") 569ac6a4445SGunnar Mills { 570ac6a4445SGunnar Mills const std::string* value = 571ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 572ac6a4445SGunnar Mills if (value == nullptr) 573ac6a4445SGunnar Mills { 574ac6a4445SGunnar Mills messages::internalError(aResp->res); 575ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 576ac6a4445SGunnar Mills << "Invalid property type for FormFactor"; 577ac6a4445SGunnar Mills continue; 578ac6a4445SGunnar Mills } 579ac6a4445SGunnar Mills constexpr const std::array<const char*, 11> values{ 580ac6a4445SGunnar Mills "RDIMM", "UDIMM", "SO_DIMM", 581ac6a4445SGunnar Mills "LRDIMM", "Mini_RDIMM", "Mini_UDIMM", 582ac6a4445SGunnar Mills "SO_RDIMM_72b", "SO_UDIMM_72b", "SO_DIMM_16b", 583ac6a4445SGunnar Mills "SO_DIMM_32b", "Die"}; 584ac6a4445SGunnar Mills 585ac6a4445SGunnar Mills for (const char* v : values) 586ac6a4445SGunnar Mills { 587ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 588ac6a4445SGunnar Mills { 589ac6a4445SGunnar Mills aResp->res.jsonValue["BaseModuleType"] = v; 590ac6a4445SGunnar Mills break; 591ac6a4445SGunnar Mills } 592ac6a4445SGunnar Mills } 593ac6a4445SGunnar Mills } 594ac6a4445SGunnar Mills else if (property.first == "AllowedSpeedsMT") 595ac6a4445SGunnar Mills { 596ac6a4445SGunnar Mills const std::vector<uint16_t>* value = 597ac6a4445SGunnar Mills std::get_if<std::vector<uint16_t>>(&property.second); 598ac6a4445SGunnar Mills if (value == nullptr) 599ac6a4445SGunnar Mills { 600ac6a4445SGunnar Mills continue; 601ac6a4445SGunnar Mills } 602ac6a4445SGunnar Mills nlohmann::json& jValue = 603ac6a4445SGunnar Mills aResp->res.jsonValue["AllowedSpeedsMHz"]; 604ac6a4445SGunnar Mills jValue = nlohmann::json::array(); 605ac6a4445SGunnar Mills for (uint16_t subVal : *value) 606ac6a4445SGunnar Mills { 607ac6a4445SGunnar Mills jValue.push_back(subVal); 608ac6a4445SGunnar Mills } 609ac6a4445SGunnar Mills } 610ac6a4445SGunnar Mills else if (property.first == "MemoryAttributes") 611ac6a4445SGunnar Mills { 612ac6a4445SGunnar Mills const uint8_t* value = 613ac6a4445SGunnar Mills std::get_if<uint8_t>(&property.second); 614ac6a4445SGunnar Mills 615ac6a4445SGunnar Mills if (value == nullptr) 616ac6a4445SGunnar Mills { 617ac6a4445SGunnar Mills messages::internalError(aResp->res); 618ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 619ac6a4445SGunnar Mills << "Invalid property type for MemoryAttributes"; 620ac6a4445SGunnar Mills continue; 621ac6a4445SGunnar Mills } 622ac6a4445SGunnar Mills aResp->res.jsonValue["RankCount"] = 623ac6a4445SGunnar Mills static_cast<uint64_t>(*value); 624ac6a4445SGunnar Mills } 625ac6a4445SGunnar Mills else if (property.first == "MemoryConfiguredSpeedInMhz") 626ac6a4445SGunnar Mills { 627ac6a4445SGunnar Mills const uint16_t* value = 628ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 629ac6a4445SGunnar Mills if (value == nullptr) 630ac6a4445SGunnar Mills { 631ac6a4445SGunnar Mills continue; 632ac6a4445SGunnar Mills } 633ac6a4445SGunnar Mills aResp->res.jsonValue["OperatingSpeedMhz"] = *value; 634ac6a4445SGunnar Mills } 635ac6a4445SGunnar Mills else if (property.first == "MemoryType") 636ac6a4445SGunnar Mills { 637ac6a4445SGunnar Mills const auto* value = 638ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 639ac6a4445SGunnar Mills if (value != nullptr) 640ac6a4445SGunnar Mills { 641313efb1cSGunnar Mills std::string memoryDeviceType = 642313efb1cSGunnar Mills translateMemoryTypeToRedfish(*value); 643313efb1cSGunnar Mills // Values like "Unknown" or "Other" will return empty 644313efb1cSGunnar Mills // so just leave off 645313efb1cSGunnar Mills if (!memoryDeviceType.empty()) 646ac6a4445SGunnar Mills { 647313efb1cSGunnar Mills aResp->res.jsonValue["MemoryDeviceType"] = 648313efb1cSGunnar Mills memoryDeviceType; 649ac6a4445SGunnar Mills } 650ac6a4445SGunnar Mills if (value->find("DDR") != std::string::npos) 651ac6a4445SGunnar Mills { 652ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryType"] = "DRAM"; 653ac6a4445SGunnar Mills } 654ac6a4445SGunnar Mills else if (boost::ends_with(*value, "Logical")) 655ac6a4445SGunnar Mills { 656ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryType"] = "IntelOptane"; 657ac6a4445SGunnar Mills } 658ac6a4445SGunnar Mills } 659ac6a4445SGunnar Mills } 660ac6a4445SGunnar Mills // memory location interface 661ac6a4445SGunnar Mills else if (property.first == "Channel" || 662ac6a4445SGunnar Mills property.first == "MemoryController" || 663ac6a4445SGunnar Mills property.first == "Slot" || property.first == "Socket") 664ac6a4445SGunnar Mills { 665ac6a4445SGunnar Mills const std::string* value = 666ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 667ac6a4445SGunnar Mills if (value == nullptr) 668ac6a4445SGunnar Mills { 669ac6a4445SGunnar Mills messages::internalError(aResp->res); 670ac6a4445SGunnar Mills continue; 671ac6a4445SGunnar Mills } 672ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryLocation"][property.first] = 673ac6a4445SGunnar Mills *value; 674ac6a4445SGunnar Mills } 675*ee135e24SSunnySrivastava1984 else if (property.first == "SparePartNumber") 676*ee135e24SSunnySrivastava1984 { 677*ee135e24SSunnySrivastava1984 const std::string* value = 678*ee135e24SSunnySrivastava1984 std::get_if<std::string>(&property.second); 679*ee135e24SSunnySrivastava1984 if (value == nullptr) 680*ee135e24SSunnySrivastava1984 { 681*ee135e24SSunnySrivastava1984 messages::internalError(aResp->res); 682*ee135e24SSunnySrivastava1984 continue; 683*ee135e24SSunnySrivastava1984 } 684*ee135e24SSunnySrivastava1984 aResp->res.jsonValue["SparePartNumber"] = *value; 685*ee135e24SSunnySrivastava1984 } 686*ee135e24SSunnySrivastava1984 else if (property.first == "Model") 687*ee135e24SSunnySrivastava1984 { 688*ee135e24SSunnySrivastava1984 const std::string* value = 689*ee135e24SSunnySrivastava1984 std::get_if<std::string>(&property.second); 690*ee135e24SSunnySrivastava1984 if (value == nullptr) 691*ee135e24SSunnySrivastava1984 { 692*ee135e24SSunnySrivastava1984 messages::internalError(aResp->res); 693*ee135e24SSunnySrivastava1984 continue; 694*ee135e24SSunnySrivastava1984 } 695*ee135e24SSunnySrivastava1984 aResp->res.jsonValue["Model"] = *value; 696*ee135e24SSunnySrivastava1984 } 697*ee135e24SSunnySrivastava1984 else if (property.first == "LocationCode") 698*ee135e24SSunnySrivastava1984 { 699*ee135e24SSunnySrivastava1984 const std::string* value = 700*ee135e24SSunnySrivastava1984 std::get_if<std::string>(&property.second); 701*ee135e24SSunnySrivastava1984 if (value == nullptr) 702*ee135e24SSunnySrivastava1984 { 703*ee135e24SSunnySrivastava1984 messages::internalError(aResp->res); 704*ee135e24SSunnySrivastava1984 continue; 705*ee135e24SSunnySrivastava1984 } 706*ee135e24SSunnySrivastava1984 aResp->res 707*ee135e24SSunnySrivastava1984 .jsonValue["Location"]["PartLocation"]["ServiceLabel"] = 708*ee135e24SSunnySrivastava1984 *value; 709*ee135e24SSunnySrivastava1984 } 710ac6a4445SGunnar Mills else 711ac6a4445SGunnar Mills { 712ac6a4445SGunnar Mills getPersistentMemoryProperties(aResp, properties); 713ac6a4445SGunnar Mills } 714ac6a4445SGunnar Mills } 715ac6a4445SGunnar Mills }, 716ac6a4445SGunnar Mills service, objPath, "org.freedesktop.DBus.Properties", "GetAll", ""); 717ac6a4445SGunnar Mills } 718ac6a4445SGunnar Mills 719ac6a4445SGunnar Mills inline void getDimmPartitionData(std::shared_ptr<AsyncResp> aResp, 720ac6a4445SGunnar Mills const std::string& service, 721ac6a4445SGunnar Mills const std::string& path) 722ac6a4445SGunnar Mills { 723ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 724ac6a4445SGunnar Mills [aResp{std::move(aResp)}]( 725ac6a4445SGunnar Mills const boost::system::error_code ec, 726ac6a4445SGunnar Mills const boost::container::flat_map< 727ac6a4445SGunnar Mills std::string, std::variant<std::string, uint64_t, uint32_t, 728ac6a4445SGunnar Mills bool>>& properties) { 729ac6a4445SGunnar Mills if (ec) 730ac6a4445SGunnar Mills { 731ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 732ac6a4445SGunnar Mills messages::internalError(aResp->res); 733ac6a4445SGunnar Mills 734ac6a4445SGunnar Mills return; 735ac6a4445SGunnar Mills } 736ac6a4445SGunnar Mills 737ac6a4445SGunnar Mills nlohmann::json& partition = 738ac6a4445SGunnar Mills aResp->res.jsonValue["Regions"].emplace_back( 739ac6a4445SGunnar Mills nlohmann::json::object()); 740ac6a4445SGunnar Mills for (const auto& [key, val] : properties) 741ac6a4445SGunnar Mills { 742ac6a4445SGunnar Mills if (key == "MemoryClassification") 743ac6a4445SGunnar Mills { 744ac6a4445SGunnar Mills const std::string* value = std::get_if<std::string>(&val); 745ac6a4445SGunnar Mills if (value == nullptr) 746ac6a4445SGunnar Mills { 747ac6a4445SGunnar Mills messages::internalError(aResp->res); 748ac6a4445SGunnar Mills continue; 749ac6a4445SGunnar Mills } 750ac6a4445SGunnar Mills partition[key] = *value; 751ac6a4445SGunnar Mills } 752ac6a4445SGunnar Mills else if (key == "OffsetInKiB") 753ac6a4445SGunnar Mills { 754ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&val); 755ac6a4445SGunnar Mills if (value == nullptr) 756ac6a4445SGunnar Mills { 757ac6a4445SGunnar Mills messages::internalError(aResp->res); 758ac6a4445SGunnar Mills continue; 759ac6a4445SGunnar Mills } 760ac6a4445SGunnar Mills 761ac6a4445SGunnar Mills partition["OffsetMiB"] = (*value >> 10); 762ac6a4445SGunnar Mills } 763ac6a4445SGunnar Mills else if (key == "PartitionId") 764ac6a4445SGunnar Mills { 765ac6a4445SGunnar Mills const std::string* value = std::get_if<std::string>(&val); 766ac6a4445SGunnar Mills if (value == nullptr) 767ac6a4445SGunnar Mills { 768ac6a4445SGunnar Mills messages::internalError(aResp->res); 769ac6a4445SGunnar Mills continue; 770ac6a4445SGunnar Mills } 771ac6a4445SGunnar Mills partition["RegionId"] = *value; 772ac6a4445SGunnar Mills } 773ac6a4445SGunnar Mills 774ac6a4445SGunnar Mills else if (key == "PassphraseState") 775ac6a4445SGunnar Mills { 776ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&val); 777ac6a4445SGunnar Mills if (value == nullptr) 778ac6a4445SGunnar Mills { 779ac6a4445SGunnar Mills messages::internalError(aResp->res); 780ac6a4445SGunnar Mills continue; 781ac6a4445SGunnar Mills } 782ac6a4445SGunnar Mills partition["PassphraseEnabled"] = *value; 783ac6a4445SGunnar Mills } 784ac6a4445SGunnar Mills else if (key == "SizeInKiB") 785ac6a4445SGunnar Mills { 786ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&val); 787ac6a4445SGunnar Mills if (value == nullptr) 788ac6a4445SGunnar Mills { 789ac6a4445SGunnar Mills messages::internalError(aResp->res); 790ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 791ac6a4445SGunnar Mills << "Invalid property type for SizeInKiB"; 792ac6a4445SGunnar Mills continue; 793ac6a4445SGunnar Mills } 794ac6a4445SGunnar Mills partition["SizeMiB"] = (*value >> 10); 795ac6a4445SGunnar Mills } 796ac6a4445SGunnar Mills } 797ac6a4445SGunnar Mills }, 798ac6a4445SGunnar Mills 799ac6a4445SGunnar Mills service, path, "org.freedesktop.DBus.Properties", "GetAll", 800ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"); 801ac6a4445SGunnar Mills } 802ac6a4445SGunnar Mills 803ac6a4445SGunnar Mills inline void getDimmData(std::shared_ptr<AsyncResp> aResp, 804ac6a4445SGunnar Mills const std::string& dimmId) 805ac6a4445SGunnar Mills { 806ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Get available system dimm resources."; 807ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 808ac6a4445SGunnar Mills [dimmId, aResp{std::move(aResp)}]( 809ac6a4445SGunnar Mills const boost::system::error_code ec, 810ac6a4445SGunnar Mills const boost::container::flat_map< 811ac6a4445SGunnar Mills std::string, boost::container::flat_map< 812ac6a4445SGunnar Mills std::string, std::vector<std::string>>>& 813ac6a4445SGunnar Mills subtree) { 814ac6a4445SGunnar Mills if (ec) 815ac6a4445SGunnar Mills { 816ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 817ac6a4445SGunnar Mills messages::internalError(aResp->res); 818ac6a4445SGunnar Mills 819ac6a4445SGunnar Mills return; 820ac6a4445SGunnar Mills } 821ac6a4445SGunnar Mills bool found = false; 822ac6a4445SGunnar Mills for (const auto& [path, object] : subtree) 823ac6a4445SGunnar Mills { 824ac6a4445SGunnar Mills if (path.find(dimmId) != std::string::npos) 825ac6a4445SGunnar Mills { 826ac6a4445SGunnar Mills for (const auto& [service, interfaces] : object) 827ac6a4445SGunnar Mills { 828ac6a4445SGunnar Mills if (!found && 829ac6a4445SGunnar Mills (std::find( 830ac6a4445SGunnar Mills interfaces.begin(), interfaces.end(), 831ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm") != 832ac6a4445SGunnar Mills interfaces.end())) 833ac6a4445SGunnar Mills { 834ac6a4445SGunnar Mills getDimmDataByService(aResp, dimmId, service, path); 835ac6a4445SGunnar Mills found = true; 836ac6a4445SGunnar Mills } 837ac6a4445SGunnar Mills 838ac6a4445SGunnar Mills // partitions are separate as there can be multiple per 839ac6a4445SGunnar Mills // device, i.e. 840ac6a4445SGunnar Mills // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1 841ac6a4445SGunnar Mills // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2 842ac6a4445SGunnar Mills if (std::find(interfaces.begin(), interfaces.end(), 843ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item." 844ac6a4445SGunnar Mills "PersistentMemory.Partition") != 845ac6a4445SGunnar Mills interfaces.end()) 846ac6a4445SGunnar Mills { 847ac6a4445SGunnar Mills getDimmPartitionData(aResp, service, path); 848ac6a4445SGunnar Mills } 849ac6a4445SGunnar Mills } 850ac6a4445SGunnar Mills } 851ac6a4445SGunnar Mills } 852ac6a4445SGunnar Mills // Object not found 853ac6a4445SGunnar Mills if (!found) 854ac6a4445SGunnar Mills { 855ac6a4445SGunnar Mills messages::resourceNotFound(aResp->res, "Memory", dimmId); 856ac6a4445SGunnar Mills } 857ac6a4445SGunnar Mills return; 858ac6a4445SGunnar Mills }, 859ac6a4445SGunnar Mills "xyz.openbmc_project.ObjectMapper", 860ac6a4445SGunnar Mills "/xyz/openbmc_project/object_mapper", 861ac6a4445SGunnar Mills "xyz.openbmc_project.ObjectMapper", "GetSubTree", 862ac6a4445SGunnar Mills "/xyz/openbmc_project/inventory", 0, 863ac6a4445SGunnar Mills std::array<const char*, 2>{ 864ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm", 865ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"}); 866ac6a4445SGunnar Mills } 867ac6a4445SGunnar Mills 868ac6a4445SGunnar Mills class MemoryCollection : public Node 869ac6a4445SGunnar Mills { 870ac6a4445SGunnar Mills public: 871ac6a4445SGunnar Mills /* 872ac6a4445SGunnar Mills * Default Constructor 873ac6a4445SGunnar Mills */ 874ac6a4445SGunnar Mills MemoryCollection(App& app) : Node(app, "/redfish/v1/Systems/system/Memory/") 875ac6a4445SGunnar Mills { 876ac6a4445SGunnar Mills entityPrivileges = { 877ac6a4445SGunnar Mills {boost::beast::http::verb::get, {{"Login"}}}, 878ac6a4445SGunnar Mills {boost::beast::http::verb::head, {{"Login"}}}, 879ac6a4445SGunnar Mills {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 880ac6a4445SGunnar Mills {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 881ac6a4445SGunnar Mills {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 882ac6a4445SGunnar Mills {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 883ac6a4445SGunnar Mills } 884ac6a4445SGunnar Mills 885ac6a4445SGunnar Mills private: 886ac6a4445SGunnar Mills /** 887ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 888ac6a4445SGunnar Mills */ 889ac6a4445SGunnar Mills void doGet(crow::Response& res, const crow::Request&, 890ac6a4445SGunnar Mills const std::vector<std::string>&) override 891ac6a4445SGunnar Mills { 892ac6a4445SGunnar Mills res.jsonValue["@odata.type"] = "#MemoryCollection.MemoryCollection"; 893ac6a4445SGunnar Mills res.jsonValue["Name"] = "Memory Module Collection"; 894ac6a4445SGunnar Mills res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system/Memory"; 895ac6a4445SGunnar Mills auto asyncResp = std::make_shared<AsyncResp>(res); 896ac6a4445SGunnar Mills 89705030b8eSGunnar Mills collection_util::getCollectionMembers( 89805030b8eSGunnar Mills asyncResp, "/redfish/v1/Systems/system/Memory", 89905030b8eSGunnar Mills {"xyz.openbmc_project.Inventory.Item.Dimm"}); 900ac6a4445SGunnar Mills } 901ac6a4445SGunnar Mills }; 902ac6a4445SGunnar Mills 903ac6a4445SGunnar Mills class Memory : public Node 904ac6a4445SGunnar Mills { 905ac6a4445SGunnar Mills public: 906ac6a4445SGunnar Mills /* 907ac6a4445SGunnar Mills * Default Constructor 908ac6a4445SGunnar Mills */ 909ac6a4445SGunnar Mills Memory(App& app) : 910ac6a4445SGunnar Mills Node(app, "/redfish/v1/Systems/system/Memory/<str>/", std::string()) 911ac6a4445SGunnar Mills { 912ac6a4445SGunnar Mills entityPrivileges = { 913ac6a4445SGunnar Mills {boost::beast::http::verb::get, {{"Login"}}}, 914ac6a4445SGunnar Mills {boost::beast::http::verb::head, {{"Login"}}}, 915ac6a4445SGunnar Mills {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 916ac6a4445SGunnar Mills {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 917ac6a4445SGunnar Mills {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 918ac6a4445SGunnar Mills {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 919ac6a4445SGunnar Mills } 920ac6a4445SGunnar Mills 921ac6a4445SGunnar Mills private: 922ac6a4445SGunnar Mills /** 923ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 924ac6a4445SGunnar Mills */ 925ac6a4445SGunnar Mills void doGet(crow::Response& res, const crow::Request&, 926ac6a4445SGunnar Mills const std::vector<std::string>& params) override 927ac6a4445SGunnar Mills { 928ac6a4445SGunnar Mills // Check if there is required param, truly entering this shall be 929ac6a4445SGunnar Mills // impossible 930ac6a4445SGunnar Mills if (params.size() != 1) 931ac6a4445SGunnar Mills { 932ac6a4445SGunnar Mills messages::internalError(res); 933ac6a4445SGunnar Mills res.end(); 934ac6a4445SGunnar Mills return; 935ac6a4445SGunnar Mills } 936ac6a4445SGunnar Mills const std::string& dimmId = params[0]; 937ac6a4445SGunnar Mills 938*ee135e24SSunnySrivastava1984 res.jsonValue["@odata.type"] = "#Memory.v1_11_0.Memory"; 939ac6a4445SGunnar Mills res.jsonValue["@odata.id"] = 940ac6a4445SGunnar Mills "/redfish/v1/Systems/system/Memory/" + dimmId; 941ac6a4445SGunnar Mills auto asyncResp = std::make_shared<AsyncResp>(res); 942ac6a4445SGunnar Mills 943ac6a4445SGunnar Mills getDimmData(asyncResp, dimmId); 944ac6a4445SGunnar Mills } 945ac6a4445SGunnar Mills }; 946ac6a4445SGunnar Mills 947ac6a4445SGunnar Mills } // namespace redfish 948