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> 22ac6a4445SGunnar Mills #include <boost/format.hpp> 23*ed398213SEd Tanous #include <registries/privilege_registry.hpp> 24ac6a4445SGunnar Mills #include <utils/collection.hpp> 25ac6a4445SGunnar Mills #include <utils/json_utils.hpp> 26ac6a4445SGunnar Mills 27ac6a4445SGunnar Mills namespace redfish 28ac6a4445SGunnar Mills { 29ac6a4445SGunnar Mills 30ac6a4445SGunnar Mills using DimmProperty = 31ac6a4445SGunnar Mills std::variant<std::string, std::vector<uint32_t>, std::vector<uint16_t>, 32ac6a4445SGunnar Mills uint64_t, uint32_t, uint16_t, uint8_t, bool>; 33ac6a4445SGunnar Mills 34ac6a4445SGunnar Mills using DimmProperties = boost::container::flat_map<std::string, DimmProperty>; 35ac6a4445SGunnar Mills 36313efb1cSGunnar Mills inline std::string translateMemoryTypeToRedfish(const std::string& memoryType) 37313efb1cSGunnar Mills { 38313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR") 39313efb1cSGunnar Mills { 40313efb1cSGunnar Mills return "DDR"; 41313efb1cSGunnar Mills } 42313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2") 43313efb1cSGunnar Mills { 44313efb1cSGunnar Mills return "DDR2"; 45313efb1cSGunnar Mills } 46313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR3") 47313efb1cSGunnar Mills { 48313efb1cSGunnar Mills return "DDR3"; 49313efb1cSGunnar Mills } 50313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4") 51313efb1cSGunnar Mills { 52313efb1cSGunnar Mills return "DDR4"; 53313efb1cSGunnar Mills } 54313efb1cSGunnar Mills if (memoryType == 55313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4E_SDRAM") 56313efb1cSGunnar Mills { 57313efb1cSGunnar Mills return "DDR4E_SDRAM"; 58313efb1cSGunnar Mills } 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 } 74313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_" 75313efb1cSGunnar Mills "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 137313efb1cSGunnar Mills return ""; 138313efb1cSGunnar Mills } 139313efb1cSGunnar Mills 1408d1b46d7Szhanghch05 inline void dimmPropToHex(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 141ac6a4445SGunnar Mills const char* key, 142ac6a4445SGunnar Mills const std::pair<std::string, DimmProperty>& property) 143ac6a4445SGunnar Mills { 144ac6a4445SGunnar Mills const uint16_t* value = std::get_if<uint16_t>(&property.second); 145ac6a4445SGunnar Mills if (value == nullptr) 146ac6a4445SGunnar Mills { 147ac6a4445SGunnar Mills messages::internalError(aResp->res); 148ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for " << property.first; 149ac6a4445SGunnar Mills return; 150ac6a4445SGunnar Mills } 151ac6a4445SGunnar Mills 152ac6a4445SGunnar Mills aResp->res.jsonValue[key] = (boost::format("0x%04x") % *value).str(); 153ac6a4445SGunnar Mills } 154ac6a4445SGunnar Mills 1558d1b46d7Szhanghch05 inline void getPersistentMemoryProperties( 1568d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aResp, 157ac6a4445SGunnar Mills const DimmProperties& properties) 158ac6a4445SGunnar Mills { 159ac6a4445SGunnar Mills for (const auto& property : properties) 160ac6a4445SGunnar Mills { 161ac6a4445SGunnar Mills if (property.first == "ModuleManufacturerID") 162ac6a4445SGunnar Mills { 163ac6a4445SGunnar Mills dimmPropToHex(aResp, "ModuleManufacturerID", property); 164ac6a4445SGunnar Mills } 165ac6a4445SGunnar Mills else if (property.first == "ModuleProductID") 166ac6a4445SGunnar Mills { 167ac6a4445SGunnar Mills dimmPropToHex(aResp, "ModuleProductID", property); 168ac6a4445SGunnar Mills } 169ac6a4445SGunnar Mills else if (property.first == "SubsystemVendorID") 170ac6a4445SGunnar Mills { 171ac6a4445SGunnar Mills dimmPropToHex(aResp, "MemorySubsystemControllerManufacturerID", 172ac6a4445SGunnar Mills property); 173ac6a4445SGunnar Mills } 174ac6a4445SGunnar Mills else if (property.first == "SubsystemDeviceID") 175ac6a4445SGunnar Mills { 176ac6a4445SGunnar Mills dimmPropToHex(aResp, "MemorySubsystemControllerProductID", 177ac6a4445SGunnar Mills 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); 186ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for " 187ac6a4445SGunnar Mills "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); 199ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 200ac6a4445SGunnar Mills << "Invalid property type for PmRegioSizeLimitKiB"; 201601af5edSChicago Duan return; 202ac6a4445SGunnar Mills } 203ac6a4445SGunnar Mills aResp->res.jsonValue["PersistentRegionSizeLimitMiB"] = 204ac6a4445SGunnar Mills (*value) >> 10; 205ac6a4445SGunnar Mills } 206ac6a4445SGunnar Mills else if (property.first == "VolatileSizeInKiB") 207ac6a4445SGunnar Mills { 208ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 209ac6a4445SGunnar Mills 210ac6a4445SGunnar Mills if (value == nullptr) 211ac6a4445SGunnar Mills { 212ac6a4445SGunnar Mills messages::internalError(aResp->res); 213ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 214ac6a4445SGunnar Mills << "Invalid property type for VolatileSizeInKiB"; 215601af5edSChicago Duan return; 216ac6a4445SGunnar Mills } 217ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileSizeMiB"] = (*value) >> 10; 218ac6a4445SGunnar Mills } 219ac6a4445SGunnar Mills else if (property.first == "PmSizeInKiB") 220ac6a4445SGunnar Mills { 221ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 222ac6a4445SGunnar Mills if (value == nullptr) 223ac6a4445SGunnar Mills { 224ac6a4445SGunnar Mills messages::internalError(aResp->res); 225ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for PmSizeInKiB"; 226601af5edSChicago Duan return; 227ac6a4445SGunnar Mills } 228ac6a4445SGunnar Mills aResp->res.jsonValue["NonVolatileSizeMiB"] = (*value) >> 10; 229ac6a4445SGunnar Mills } 230ac6a4445SGunnar Mills else if (property.first == "CacheSizeInKB") 231ac6a4445SGunnar Mills { 232ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 233ac6a4445SGunnar Mills if (value == nullptr) 234ac6a4445SGunnar Mills { 235ac6a4445SGunnar Mills messages::internalError(aResp->res); 236ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for CacheSizeInKB"; 237601af5edSChicago Duan return; 238ac6a4445SGunnar Mills } 239ac6a4445SGunnar Mills aResp->res.jsonValue["CacheSizeMiB"] = (*value >> 10); 240ac6a4445SGunnar Mills } 241ac6a4445SGunnar Mills 242ac6a4445SGunnar Mills else if (property.first == "VoltaileRegionMaxSizeInKib") 243ac6a4445SGunnar Mills { 244ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 245ac6a4445SGunnar Mills 246ac6a4445SGunnar Mills if (value == nullptr) 247ac6a4445SGunnar Mills { 248ac6a4445SGunnar Mills messages::internalError(aResp->res); 249ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for " 250ac6a4445SGunnar Mills "VolatileRegionMaxSizeInKib"; 251601af5edSChicago Duan return; 252ac6a4445SGunnar Mills } 253ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileRegionSizeMaxMiB"] = (*value) >> 10; 254ac6a4445SGunnar Mills } 255ac6a4445SGunnar Mills else if (property.first == "PmRegionMaxSizeInKiB") 256ac6a4445SGunnar Mills { 257ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 258ac6a4445SGunnar Mills 259ac6a4445SGunnar Mills if (value == nullptr) 260ac6a4445SGunnar Mills { 261ac6a4445SGunnar Mills messages::internalError(aResp->res); 262ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 263ac6a4445SGunnar Mills << "Invalid property type for PmRegionMaxSizeInKiB"; 264601af5edSChicago Duan return; 265ac6a4445SGunnar Mills } 266ac6a4445SGunnar Mills aResp->res.jsonValue["PersistentRegionSizeMaxMiB"] = (*value) >> 10; 267ac6a4445SGunnar Mills } 268ac6a4445SGunnar Mills else if (property.first == "AllocationIncrementInKiB") 269ac6a4445SGunnar Mills { 270ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 271ac6a4445SGunnar Mills 272ac6a4445SGunnar Mills if (value == nullptr) 273ac6a4445SGunnar Mills { 274ac6a4445SGunnar Mills messages::internalError(aResp->res); 275ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for " 276ac6a4445SGunnar Mills "AllocationIncrementInKiB"; 277601af5edSChicago Duan return; 278ac6a4445SGunnar Mills } 279ac6a4445SGunnar Mills aResp->res.jsonValue["AllocationIncrementMiB"] = (*value) >> 10; 280ac6a4445SGunnar Mills } 281ac6a4445SGunnar Mills else if (property.first == "AllocationAlignmentInKiB") 282ac6a4445SGunnar Mills { 283ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 284ac6a4445SGunnar Mills 285ac6a4445SGunnar Mills if (value == nullptr) 286ac6a4445SGunnar Mills { 287ac6a4445SGunnar Mills messages::internalError(aResp->res); 288ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for " 289ac6a4445SGunnar Mills "AllocationAlignmentInKiB"; 290601af5edSChicago Duan return; 291ac6a4445SGunnar Mills } 292ac6a4445SGunnar Mills aResp->res.jsonValue["AllocationAlignmentMiB"] = (*value) >> 10; 293ac6a4445SGunnar Mills } 294ac6a4445SGunnar Mills else if (property.first == "VolatileRegionNumberLimit") 295ac6a4445SGunnar Mills { 296ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 297ac6a4445SGunnar Mills if (value == nullptr) 298ac6a4445SGunnar Mills { 299ac6a4445SGunnar Mills messages::internalError(aResp->res); 300601af5edSChicago Duan return; 301ac6a4445SGunnar Mills } 302ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileRegionNumberLimit"] = *value; 303ac6a4445SGunnar Mills } 304ac6a4445SGunnar Mills else if (property.first == "PmRegionNumberLimit") 305ac6a4445SGunnar Mills { 306ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 307ac6a4445SGunnar Mills if (value == nullptr) 308ac6a4445SGunnar Mills { 309ac6a4445SGunnar Mills messages::internalError(aResp->res); 310601af5edSChicago Duan return; 311ac6a4445SGunnar Mills } 312ac6a4445SGunnar Mills aResp->res.jsonValue["PersistentRegionNumberLimit"] = *value; 313ac6a4445SGunnar Mills } 314ac6a4445SGunnar Mills else if (property.first == "SpareDeviceCount") 315ac6a4445SGunnar Mills { 316ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 317ac6a4445SGunnar Mills if (value == nullptr) 318ac6a4445SGunnar Mills { 319ac6a4445SGunnar Mills messages::internalError(aResp->res); 320601af5edSChicago Duan return; 321ac6a4445SGunnar Mills } 322ac6a4445SGunnar Mills aResp->res.jsonValue["SpareDeviceCount"] = *value; 323ac6a4445SGunnar Mills } 324ac6a4445SGunnar Mills else if (property.first == "IsSpareDeviceInUse") 325ac6a4445SGunnar Mills { 326ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 327ac6a4445SGunnar Mills if (value == nullptr) 328ac6a4445SGunnar Mills { 329ac6a4445SGunnar Mills messages::internalError(aResp->res); 330601af5edSChicago Duan return; 331ac6a4445SGunnar Mills } 332ac6a4445SGunnar Mills aResp->res.jsonValue["IsSpareDeviceEnabled"] = *value; 333ac6a4445SGunnar Mills } 334ac6a4445SGunnar Mills else if (property.first == "IsRankSpareEnabled") 335ac6a4445SGunnar Mills { 336ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 337ac6a4445SGunnar Mills if (value == nullptr) 338ac6a4445SGunnar Mills { 339ac6a4445SGunnar Mills messages::internalError(aResp->res); 340601af5edSChicago Duan return; 341ac6a4445SGunnar Mills } 342ac6a4445SGunnar Mills aResp->res.jsonValue["IsRankSpareEnabled"] = *value; 343ac6a4445SGunnar Mills } 344ac6a4445SGunnar Mills else if (property.first == "MaxAveragePowerLimitmW") 345ac6a4445SGunnar Mills { 346ac6a4445SGunnar Mills const auto* value = 347ac6a4445SGunnar Mills std::get_if<std::vector<uint32_t>>(&property.second); 348ac6a4445SGunnar Mills if (value == nullptr) 349ac6a4445SGunnar Mills { 350ac6a4445SGunnar Mills messages::internalError(aResp->res); 351ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for " 352ac6a4445SGunnar Mills "MaxAveragePowerLimitmW"; 353601af5edSChicago Duan return; 354ac6a4445SGunnar Mills } 355ac6a4445SGunnar Mills aResp->res.jsonValue["MaxTDPMilliWatts"] = *value; 356ac6a4445SGunnar Mills } 357ac6a4445SGunnar Mills else if (property.first == "ConfigurationLocked") 358ac6a4445SGunnar Mills { 359ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 360ac6a4445SGunnar Mills if (value == nullptr) 361ac6a4445SGunnar Mills { 362ac6a4445SGunnar Mills messages::internalError(aResp->res); 363601af5edSChicago Duan return; 364ac6a4445SGunnar Mills } 365ac6a4445SGunnar Mills aResp->res.jsonValue["ConfigurationLocked"] = *value; 366ac6a4445SGunnar Mills } 367ac6a4445SGunnar Mills else if (property.first == "AllowedMemoryModes") 368ac6a4445SGunnar Mills { 369ac6a4445SGunnar Mills const std::string* value = 370ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 371ac6a4445SGunnar Mills if (value == nullptr) 372ac6a4445SGunnar Mills { 373ac6a4445SGunnar Mills messages::internalError(aResp->res); 374ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for FormFactor"; 375601af5edSChicago Duan return; 376ac6a4445SGunnar Mills } 377ac6a4445SGunnar Mills constexpr const std::array<const char*, 3> values{"Volatile", 378ac6a4445SGunnar Mills "PMEM", "Block"}; 379ac6a4445SGunnar Mills 380ac6a4445SGunnar Mills for (const char* v : values) 381ac6a4445SGunnar Mills { 382ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 383ac6a4445SGunnar Mills { 384ac6a4445SGunnar Mills aResp->res.jsonValue["OperatingMemoryModes "] = v; 385ac6a4445SGunnar Mills break; 386ac6a4445SGunnar Mills } 387ac6a4445SGunnar Mills } 388ac6a4445SGunnar Mills } 389ac6a4445SGunnar Mills else if (property.first == "MemoryMedia") 390ac6a4445SGunnar Mills { 391ac6a4445SGunnar Mills const std::string* value = 392ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 393ac6a4445SGunnar Mills if (value == nullptr) 394ac6a4445SGunnar Mills { 395ac6a4445SGunnar Mills messages::internalError(aResp->res); 396ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for MemoryMedia"; 397601af5edSChicago Duan return; 398ac6a4445SGunnar Mills } 399ac6a4445SGunnar Mills constexpr const std::array<const char*, 3> values{"DRAM", "NAND", 400ac6a4445SGunnar Mills "Intel3DXPoint"}; 401ac6a4445SGunnar Mills 402ac6a4445SGunnar Mills for (const char* v : values) 403ac6a4445SGunnar Mills { 404ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 405ac6a4445SGunnar Mills { 406ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryMedia"] = v; 407ac6a4445SGunnar Mills break; 408ac6a4445SGunnar Mills } 409ac6a4445SGunnar Mills } 410ac6a4445SGunnar Mills } 411ac6a4445SGunnar Mills // PersistantMemory.SecurityCapabilites interface 412ac6a4445SGunnar Mills else if (property.first == "ConfigurationLockCapable" || 413ac6a4445SGunnar Mills property.first == "DataLockCapable" || 414ac6a4445SGunnar Mills property.first == "PassphraseCapable") 415ac6a4445SGunnar Mills { 416ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 417ac6a4445SGunnar Mills if (value == nullptr) 418ac6a4445SGunnar Mills { 419ac6a4445SGunnar Mills messages::internalError(aResp->res); 420601af5edSChicago Duan return; 421ac6a4445SGunnar Mills } 422ac6a4445SGunnar Mills aResp->res.jsonValue["SecurityCapabilities"][property.first] = 423ac6a4445SGunnar Mills *value; 424ac6a4445SGunnar Mills } 425ac6a4445SGunnar Mills else if (property.first == "MaxPassphraseCount" || 426ac6a4445SGunnar Mills property.first == "PassphraseLockLimit") 427ac6a4445SGunnar Mills { 428ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 429ac6a4445SGunnar Mills if (value == nullptr) 430ac6a4445SGunnar Mills { 431ac6a4445SGunnar Mills messages::internalError(aResp->res); 432601af5edSChicago Duan return; 433ac6a4445SGunnar Mills } 434ac6a4445SGunnar Mills aResp->res.jsonValue["SecurityCapabilities"][property.first] = 435ac6a4445SGunnar Mills *value; 436ac6a4445SGunnar Mills } 437ac6a4445SGunnar Mills } 438ac6a4445SGunnar Mills } 439ac6a4445SGunnar Mills 4408d1b46d7Szhanghch05 inline void getDimmDataByService(std::shared_ptr<bmcweb::AsyncResp> aResp, 441ac6a4445SGunnar Mills const std::string& dimmId, 442ac6a4445SGunnar Mills const std::string& service, 443ac6a4445SGunnar Mills const std::string& objPath) 444ac6a4445SGunnar Mills { 445ac6a4445SGunnar Mills auto health = std::make_shared<HealthPopulate>(aResp); 446ac6a4445SGunnar Mills health->selfPath = objPath; 447ac6a4445SGunnar Mills health->populate(); 448ac6a4445SGunnar Mills 449ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Get available system components."; 450ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 451ac6a4445SGunnar Mills [dimmId, aResp{std::move(aResp)}](const boost::system::error_code ec, 452ac6a4445SGunnar Mills const DimmProperties& properties) { 453ac6a4445SGunnar Mills if (ec) 454ac6a4445SGunnar Mills { 455ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 456ac6a4445SGunnar Mills messages::internalError(aResp->res); 457ac6a4445SGunnar Mills 458ac6a4445SGunnar Mills return; 459ac6a4445SGunnar Mills } 460ac6a4445SGunnar Mills aResp->res.jsonValue["Id"] = dimmId; 461ac6a4445SGunnar Mills aResp->res.jsonValue["Name"] = "DIMM Slot"; 462ac6a4445SGunnar Mills 463ac6a4445SGunnar Mills const auto memorySizeProperty = properties.find("MemorySizeInKB"); 464ac6a4445SGunnar Mills if (memorySizeProperty != properties.end()) 465ac6a4445SGunnar Mills { 466ac6a4445SGunnar Mills const uint32_t* memorySize = 467ac6a4445SGunnar Mills std::get_if<uint32_t>(&memorySizeProperty->second); 468ac6a4445SGunnar Mills if (memorySize == nullptr) 469ac6a4445SGunnar Mills { 470ac6a4445SGunnar Mills // Important property not in desired type 471ac6a4445SGunnar Mills messages::internalError(aResp->res); 472ac6a4445SGunnar Mills return; 473ac6a4445SGunnar Mills } 474ac6a4445SGunnar Mills aResp->res.jsonValue["CapacityMiB"] = (*memorySize >> 10); 475ac6a4445SGunnar Mills } 476ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["State"] = "Enabled"; 477ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["Health"] = "OK"; 478ac6a4445SGunnar Mills 479ac6a4445SGunnar Mills for (const auto& property : properties) 480ac6a4445SGunnar Mills { 481ac6a4445SGunnar Mills if (property.first == "MemoryDataWidth") 482ac6a4445SGunnar Mills { 483ac6a4445SGunnar Mills const uint16_t* value = 484ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 485ac6a4445SGunnar Mills if (value == nullptr) 486ac6a4445SGunnar Mills { 487ac6a4445SGunnar Mills continue; 488ac6a4445SGunnar Mills } 489ac6a4445SGunnar Mills aResp->res.jsonValue["DataWidthBits"] = *value; 490ac6a4445SGunnar Mills } 491ac6a4445SGunnar Mills else if (property.first == "PartNumber") 492ac6a4445SGunnar Mills { 493ac6a4445SGunnar Mills const std::string* value = 494ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 495ac6a4445SGunnar Mills if (value == nullptr) 496ac6a4445SGunnar Mills { 497ac6a4445SGunnar Mills continue; 498ac6a4445SGunnar Mills } 499ac6a4445SGunnar Mills aResp->res.jsonValue["PartNumber"] = *value; 500ac6a4445SGunnar Mills } 501ac6a4445SGunnar Mills else if (property.first == "SerialNumber") 502ac6a4445SGunnar Mills { 503ac6a4445SGunnar Mills const std::string* value = 504ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 505ac6a4445SGunnar Mills if (value == nullptr) 506ac6a4445SGunnar Mills { 507ac6a4445SGunnar Mills continue; 508ac6a4445SGunnar Mills } 509ac6a4445SGunnar Mills aResp->res.jsonValue["SerialNumber"] = *value; 510ac6a4445SGunnar Mills } 511ac6a4445SGunnar Mills else if (property.first == "Manufacturer") 512ac6a4445SGunnar Mills { 513ac6a4445SGunnar Mills const std::string* value = 514ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 515ac6a4445SGunnar Mills if (value == nullptr) 516ac6a4445SGunnar Mills { 517ac6a4445SGunnar Mills continue; 518ac6a4445SGunnar Mills } 519ac6a4445SGunnar Mills aResp->res.jsonValue["Manufacturer"] = *value; 520ac6a4445SGunnar Mills } 521ac6a4445SGunnar Mills else if (property.first == "RevisionCode") 522ac6a4445SGunnar Mills { 523ac6a4445SGunnar Mills const uint16_t* value = 524ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 525ac6a4445SGunnar Mills 526ac6a4445SGunnar Mills if (value == nullptr) 527ac6a4445SGunnar Mills { 528ac6a4445SGunnar Mills messages::internalError(aResp->res); 529ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 530ac6a4445SGunnar Mills << "Invalid property type for RevisionCode"; 531601af5edSChicago Duan return; 532ac6a4445SGunnar Mills } 533ac6a4445SGunnar Mills aResp->res.jsonValue["FirmwareRevision"] = 534ac6a4445SGunnar Mills std::to_string(*value); 535ac6a4445SGunnar Mills } 5369a128eb3SJoshi-Mansi else if (property.first == "Present") 5379a128eb3SJoshi-Mansi { 5389a128eb3SJoshi-Mansi const bool* value = std::get_if<bool>(&property.second); 5399a128eb3SJoshi-Mansi if (value == nullptr) 5409a128eb3SJoshi-Mansi { 5419a128eb3SJoshi-Mansi messages::internalError(aResp->res); 5429a128eb3SJoshi-Mansi BMCWEB_LOG_DEBUG 5439a128eb3SJoshi-Mansi << "Invalid property type for Dimm Presence"; 5449a128eb3SJoshi-Mansi return; 5459a128eb3SJoshi-Mansi } 5469a128eb3SJoshi-Mansi if (*value == false) 5479a128eb3SJoshi-Mansi { 5489a128eb3SJoshi-Mansi aResp->res.jsonValue["Status"]["State"] = "Absent"; 5499a128eb3SJoshi-Mansi } 5509a128eb3SJoshi-Mansi } 551ac6a4445SGunnar Mills else if (property.first == "MemoryTotalWidth") 552ac6a4445SGunnar Mills { 553ac6a4445SGunnar Mills const uint16_t* value = 554ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 555ac6a4445SGunnar Mills if (value == nullptr) 556ac6a4445SGunnar Mills { 557ac6a4445SGunnar Mills continue; 558ac6a4445SGunnar Mills } 559ac6a4445SGunnar Mills aResp->res.jsonValue["BusWidthBits"] = *value; 560ac6a4445SGunnar Mills } 561ac6a4445SGunnar Mills else if (property.first == "ECC") 562ac6a4445SGunnar Mills { 563ac6a4445SGunnar Mills const std::string* value = 564ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 565ac6a4445SGunnar Mills if (value == nullptr) 566ac6a4445SGunnar Mills { 567ac6a4445SGunnar Mills messages::internalError(aResp->res); 568ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for ECC"; 569601af5edSChicago Duan return; 570ac6a4445SGunnar Mills } 571ac6a4445SGunnar Mills constexpr const std::array<const char*, 4> values{ 572ac6a4445SGunnar Mills "NoECC", "SingleBitECC", "MultiBitECC", 573ac6a4445SGunnar Mills "AddressParity"}; 574ac6a4445SGunnar Mills 575ac6a4445SGunnar Mills for (const char* v : values) 576ac6a4445SGunnar Mills { 577ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 578ac6a4445SGunnar Mills { 579ac6a4445SGunnar Mills aResp->res.jsonValue["ErrorCorrection"] = v; 580ac6a4445SGunnar Mills break; 581ac6a4445SGunnar Mills } 582ac6a4445SGunnar Mills } 583ac6a4445SGunnar Mills } 584ac6a4445SGunnar Mills else if (property.first == "FormFactor") 585ac6a4445SGunnar Mills { 586ac6a4445SGunnar Mills const std::string* value = 587ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 588ac6a4445SGunnar Mills if (value == nullptr) 589ac6a4445SGunnar Mills { 590ac6a4445SGunnar Mills messages::internalError(aResp->res); 591ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 592ac6a4445SGunnar Mills << "Invalid property type for FormFactor"; 593601af5edSChicago Duan return; 594ac6a4445SGunnar Mills } 595ac6a4445SGunnar Mills constexpr const std::array<const char*, 11> values{ 596ac6a4445SGunnar Mills "RDIMM", "UDIMM", "SO_DIMM", 597ac6a4445SGunnar Mills "LRDIMM", "Mini_RDIMM", "Mini_UDIMM", 598ac6a4445SGunnar Mills "SO_RDIMM_72b", "SO_UDIMM_72b", "SO_DIMM_16b", 599ac6a4445SGunnar Mills "SO_DIMM_32b", "Die"}; 600ac6a4445SGunnar Mills 601ac6a4445SGunnar Mills for (const char* v : values) 602ac6a4445SGunnar Mills { 603ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 604ac6a4445SGunnar Mills { 605ac6a4445SGunnar Mills aResp->res.jsonValue["BaseModuleType"] = v; 606ac6a4445SGunnar Mills break; 607ac6a4445SGunnar Mills } 608ac6a4445SGunnar Mills } 609ac6a4445SGunnar Mills } 610ac6a4445SGunnar Mills else if (property.first == "AllowedSpeedsMT") 611ac6a4445SGunnar Mills { 612ac6a4445SGunnar Mills const std::vector<uint16_t>* value = 613ac6a4445SGunnar Mills std::get_if<std::vector<uint16_t>>(&property.second); 614ac6a4445SGunnar Mills if (value == nullptr) 615ac6a4445SGunnar Mills { 616ac6a4445SGunnar Mills continue; 617ac6a4445SGunnar Mills } 618ac6a4445SGunnar Mills nlohmann::json& jValue = 619ac6a4445SGunnar Mills aResp->res.jsonValue["AllowedSpeedsMHz"]; 620ac6a4445SGunnar Mills jValue = nlohmann::json::array(); 621ac6a4445SGunnar Mills for (uint16_t subVal : *value) 622ac6a4445SGunnar Mills { 623ac6a4445SGunnar Mills jValue.push_back(subVal); 624ac6a4445SGunnar Mills } 625ac6a4445SGunnar Mills } 626ac6a4445SGunnar Mills else if (property.first == "MemoryAttributes") 627ac6a4445SGunnar Mills { 628ac6a4445SGunnar Mills const uint8_t* value = 629ac6a4445SGunnar Mills std::get_if<uint8_t>(&property.second); 630ac6a4445SGunnar Mills 631ac6a4445SGunnar Mills if (value == nullptr) 632ac6a4445SGunnar Mills { 633ac6a4445SGunnar Mills messages::internalError(aResp->res); 634ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 635ac6a4445SGunnar Mills << "Invalid property type for MemoryAttributes"; 636601af5edSChicago Duan return; 637ac6a4445SGunnar Mills } 638ac6a4445SGunnar Mills aResp->res.jsonValue["RankCount"] = 639ac6a4445SGunnar Mills static_cast<uint64_t>(*value); 640ac6a4445SGunnar Mills } 641ac6a4445SGunnar Mills else if (property.first == "MemoryConfiguredSpeedInMhz") 642ac6a4445SGunnar Mills { 643ac6a4445SGunnar Mills const uint16_t* value = 644ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 645ac6a4445SGunnar Mills if (value == nullptr) 646ac6a4445SGunnar Mills { 647ac6a4445SGunnar Mills continue; 648ac6a4445SGunnar Mills } 649ac6a4445SGunnar Mills aResp->res.jsonValue["OperatingSpeedMhz"] = *value; 650ac6a4445SGunnar Mills } 651ac6a4445SGunnar Mills else if (property.first == "MemoryType") 652ac6a4445SGunnar Mills { 653ac6a4445SGunnar Mills const auto* value = 654ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 655ac6a4445SGunnar Mills if (value != nullptr) 656ac6a4445SGunnar Mills { 657313efb1cSGunnar Mills std::string memoryDeviceType = 658313efb1cSGunnar Mills translateMemoryTypeToRedfish(*value); 659313efb1cSGunnar Mills // Values like "Unknown" or "Other" will return empty 660313efb1cSGunnar Mills // so just leave off 661313efb1cSGunnar Mills if (!memoryDeviceType.empty()) 662ac6a4445SGunnar Mills { 663313efb1cSGunnar Mills aResp->res.jsonValue["MemoryDeviceType"] = 664313efb1cSGunnar Mills memoryDeviceType; 665ac6a4445SGunnar Mills } 666ac6a4445SGunnar Mills if (value->find("DDR") != std::string::npos) 667ac6a4445SGunnar Mills { 668ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryType"] = "DRAM"; 669ac6a4445SGunnar Mills } 670ac6a4445SGunnar Mills else if (boost::ends_with(*value, "Logical")) 671ac6a4445SGunnar Mills { 672ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryType"] = "IntelOptane"; 673ac6a4445SGunnar Mills } 674ac6a4445SGunnar Mills } 675ac6a4445SGunnar Mills } 676ac6a4445SGunnar Mills // memory location interface 677ac6a4445SGunnar Mills else if (property.first == "Channel" || 678ac6a4445SGunnar Mills property.first == "MemoryController" || 679ac6a4445SGunnar Mills property.first == "Slot" || property.first == "Socket") 680ac6a4445SGunnar Mills { 681ac6a4445SGunnar Mills const std::string* value = 682ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 683ac6a4445SGunnar Mills if (value == nullptr) 684ac6a4445SGunnar Mills { 685ac6a4445SGunnar Mills messages::internalError(aResp->res); 686601af5edSChicago Duan return; 687ac6a4445SGunnar Mills } 688ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryLocation"][property.first] = 689ac6a4445SGunnar Mills *value; 690ac6a4445SGunnar Mills } 691ee135e24SSunnySrivastava1984 else if (property.first == "SparePartNumber") 692ee135e24SSunnySrivastava1984 { 693ee135e24SSunnySrivastava1984 const std::string* value = 694ee135e24SSunnySrivastava1984 std::get_if<std::string>(&property.second); 695ee135e24SSunnySrivastava1984 if (value == nullptr) 696ee135e24SSunnySrivastava1984 { 697ee135e24SSunnySrivastava1984 messages::internalError(aResp->res); 698601af5edSChicago Duan return; 699ee135e24SSunnySrivastava1984 } 700ee135e24SSunnySrivastava1984 aResp->res.jsonValue["SparePartNumber"] = *value; 701ee135e24SSunnySrivastava1984 } 702ee135e24SSunnySrivastava1984 else if (property.first == "Model") 703ee135e24SSunnySrivastava1984 { 704ee135e24SSunnySrivastava1984 const std::string* value = 705ee135e24SSunnySrivastava1984 std::get_if<std::string>(&property.second); 706ee135e24SSunnySrivastava1984 if (value == nullptr) 707ee135e24SSunnySrivastava1984 { 708ee135e24SSunnySrivastava1984 messages::internalError(aResp->res); 709601af5edSChicago Duan return; 710ee135e24SSunnySrivastava1984 } 711ee135e24SSunnySrivastava1984 aResp->res.jsonValue["Model"] = *value; 712ee135e24SSunnySrivastava1984 } 713ee135e24SSunnySrivastava1984 else if (property.first == "LocationCode") 714ee135e24SSunnySrivastava1984 { 715ee135e24SSunnySrivastava1984 const std::string* value = 716ee135e24SSunnySrivastava1984 std::get_if<std::string>(&property.second); 717ee135e24SSunnySrivastava1984 if (value == nullptr) 718ee135e24SSunnySrivastava1984 { 719ee135e24SSunnySrivastava1984 messages::internalError(aResp->res); 720601af5edSChicago Duan return; 721ee135e24SSunnySrivastava1984 } 722ee135e24SSunnySrivastava1984 aResp->res 723ee135e24SSunnySrivastava1984 .jsonValue["Location"]["PartLocation"]["ServiceLabel"] = 724ee135e24SSunnySrivastava1984 *value; 725ee135e24SSunnySrivastava1984 } 726ac6a4445SGunnar Mills else 727ac6a4445SGunnar Mills { 728ac6a4445SGunnar Mills getPersistentMemoryProperties(aResp, properties); 729ac6a4445SGunnar Mills } 730ac6a4445SGunnar Mills } 731ac6a4445SGunnar Mills }, 732ac6a4445SGunnar Mills service, objPath, "org.freedesktop.DBus.Properties", "GetAll", ""); 733ac6a4445SGunnar Mills } 734ac6a4445SGunnar Mills 7358d1b46d7Szhanghch05 inline void getDimmPartitionData(std::shared_ptr<bmcweb::AsyncResp> aResp, 736ac6a4445SGunnar Mills const std::string& service, 737ac6a4445SGunnar Mills const std::string& path) 738ac6a4445SGunnar Mills { 739ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 740ac6a4445SGunnar Mills [aResp{std::move(aResp)}]( 741ac6a4445SGunnar Mills const boost::system::error_code ec, 742ac6a4445SGunnar Mills const boost::container::flat_map< 743ac6a4445SGunnar Mills std::string, std::variant<std::string, uint64_t, uint32_t, 744ac6a4445SGunnar Mills bool>>& properties) { 745ac6a4445SGunnar Mills if (ec) 746ac6a4445SGunnar Mills { 747ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 748ac6a4445SGunnar Mills messages::internalError(aResp->res); 749ac6a4445SGunnar Mills 750ac6a4445SGunnar Mills return; 751ac6a4445SGunnar Mills } 752ac6a4445SGunnar Mills 753ac6a4445SGunnar Mills nlohmann::json& partition = 754ac6a4445SGunnar Mills aResp->res.jsonValue["Regions"].emplace_back( 755ac6a4445SGunnar Mills nlohmann::json::object()); 756ac6a4445SGunnar Mills for (const auto& [key, val] : properties) 757ac6a4445SGunnar Mills { 758ac6a4445SGunnar Mills if (key == "MemoryClassification") 759ac6a4445SGunnar Mills { 760ac6a4445SGunnar Mills const std::string* value = std::get_if<std::string>(&val); 761ac6a4445SGunnar Mills if (value == nullptr) 762ac6a4445SGunnar Mills { 763ac6a4445SGunnar Mills messages::internalError(aResp->res); 764601af5edSChicago Duan return; 765ac6a4445SGunnar Mills } 766ac6a4445SGunnar Mills partition[key] = *value; 767ac6a4445SGunnar Mills } 768ac6a4445SGunnar Mills else if (key == "OffsetInKiB") 769ac6a4445SGunnar Mills { 770ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&val); 771ac6a4445SGunnar Mills if (value == nullptr) 772ac6a4445SGunnar Mills { 773ac6a4445SGunnar Mills messages::internalError(aResp->res); 774601af5edSChicago Duan return; 775ac6a4445SGunnar Mills } 776ac6a4445SGunnar Mills 777ac6a4445SGunnar Mills partition["OffsetMiB"] = (*value >> 10); 778ac6a4445SGunnar Mills } 779ac6a4445SGunnar Mills else if (key == "PartitionId") 780ac6a4445SGunnar Mills { 781ac6a4445SGunnar Mills const std::string* value = std::get_if<std::string>(&val); 782ac6a4445SGunnar Mills if (value == nullptr) 783ac6a4445SGunnar Mills { 784ac6a4445SGunnar Mills messages::internalError(aResp->res); 785601af5edSChicago Duan return; 786ac6a4445SGunnar Mills } 787ac6a4445SGunnar Mills partition["RegionId"] = *value; 788ac6a4445SGunnar Mills } 789ac6a4445SGunnar Mills 790ac6a4445SGunnar Mills else if (key == "PassphraseState") 791ac6a4445SGunnar Mills { 792ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&val); 793ac6a4445SGunnar Mills if (value == nullptr) 794ac6a4445SGunnar Mills { 795ac6a4445SGunnar Mills messages::internalError(aResp->res); 796601af5edSChicago Duan return; 797ac6a4445SGunnar Mills } 798ac6a4445SGunnar Mills partition["PassphraseEnabled"] = *value; 799ac6a4445SGunnar Mills } 800ac6a4445SGunnar Mills else if (key == "SizeInKiB") 801ac6a4445SGunnar Mills { 802ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&val); 803ac6a4445SGunnar Mills if (value == nullptr) 804ac6a4445SGunnar Mills { 805ac6a4445SGunnar Mills messages::internalError(aResp->res); 806ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 807ac6a4445SGunnar Mills << "Invalid property type for SizeInKiB"; 808601af5edSChicago Duan return; 809ac6a4445SGunnar Mills } 810ac6a4445SGunnar Mills partition["SizeMiB"] = (*value >> 10); 811ac6a4445SGunnar Mills } 812ac6a4445SGunnar Mills } 813ac6a4445SGunnar Mills }, 814ac6a4445SGunnar Mills 815ac6a4445SGunnar Mills service, path, "org.freedesktop.DBus.Properties", "GetAll", 816ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"); 817ac6a4445SGunnar Mills } 818ac6a4445SGunnar Mills 8198d1b46d7Szhanghch05 inline void getDimmData(std::shared_ptr<bmcweb::AsyncResp> aResp, 820ac6a4445SGunnar Mills const std::string& dimmId) 821ac6a4445SGunnar Mills { 822ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Get available system dimm resources."; 823ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 824ac6a4445SGunnar Mills [dimmId, aResp{std::move(aResp)}]( 825ac6a4445SGunnar Mills const boost::system::error_code ec, 826ac6a4445SGunnar Mills const boost::container::flat_map< 827ac6a4445SGunnar Mills std::string, boost::container::flat_map< 828ac6a4445SGunnar Mills std::string, std::vector<std::string>>>& 829ac6a4445SGunnar Mills subtree) { 830ac6a4445SGunnar Mills if (ec) 831ac6a4445SGunnar Mills { 832ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 833ac6a4445SGunnar Mills messages::internalError(aResp->res); 834ac6a4445SGunnar Mills 835ac6a4445SGunnar Mills return; 836ac6a4445SGunnar Mills } 837ac6a4445SGunnar Mills bool found = false; 838ac6a4445SGunnar Mills for (const auto& [path, object] : subtree) 839ac6a4445SGunnar Mills { 840ac6a4445SGunnar Mills if (path.find(dimmId) != std::string::npos) 841ac6a4445SGunnar Mills { 842ac6a4445SGunnar Mills for (const auto& [service, interfaces] : object) 843ac6a4445SGunnar Mills { 844ac6a4445SGunnar Mills if (!found && 845ac6a4445SGunnar Mills (std::find( 846ac6a4445SGunnar Mills interfaces.begin(), interfaces.end(), 847ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm") != 848ac6a4445SGunnar Mills interfaces.end())) 849ac6a4445SGunnar Mills { 850ac6a4445SGunnar Mills getDimmDataByService(aResp, dimmId, service, path); 851ac6a4445SGunnar Mills found = true; 852ac6a4445SGunnar Mills } 853ac6a4445SGunnar Mills 854ac6a4445SGunnar Mills // partitions are separate as there can be multiple per 855ac6a4445SGunnar Mills // device, i.e. 856ac6a4445SGunnar Mills // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1 857ac6a4445SGunnar Mills // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2 858ac6a4445SGunnar Mills if (std::find(interfaces.begin(), interfaces.end(), 859ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item." 860ac6a4445SGunnar Mills "PersistentMemory.Partition") != 861ac6a4445SGunnar Mills interfaces.end()) 862ac6a4445SGunnar Mills { 863ac6a4445SGunnar Mills getDimmPartitionData(aResp, service, path); 864ac6a4445SGunnar Mills } 865ac6a4445SGunnar Mills } 866ac6a4445SGunnar Mills } 867ac6a4445SGunnar Mills } 868ac6a4445SGunnar Mills // Object not found 869ac6a4445SGunnar Mills if (!found) 870ac6a4445SGunnar Mills { 871ac6a4445SGunnar Mills messages::resourceNotFound(aResp->res, "Memory", dimmId); 872ac6a4445SGunnar Mills } 873ac6a4445SGunnar Mills return; 874ac6a4445SGunnar Mills }, 875ac6a4445SGunnar Mills "xyz.openbmc_project.ObjectMapper", 876ac6a4445SGunnar Mills "/xyz/openbmc_project/object_mapper", 877ac6a4445SGunnar Mills "xyz.openbmc_project.ObjectMapper", "GetSubTree", 878ac6a4445SGunnar Mills "/xyz/openbmc_project/inventory", 0, 879ac6a4445SGunnar Mills std::array<const char*, 2>{ 880ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm", 881ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"}); 882ac6a4445SGunnar Mills } 883ac6a4445SGunnar Mills 8847e860f15SJohn Edward Broadbent inline void requestRoutesMemoryCollection(App& app) 885ac6a4445SGunnar Mills { 886ac6a4445SGunnar Mills /** 887ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 888ac6a4445SGunnar Mills */ 8897e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Memory/") 890*ed398213SEd Tanous .privileges(redfish::privileges::getMemoryCollection) 8917e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 8927e860f15SJohn Edward Broadbent [](const crow::Request&, 8937e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 8948d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 8958d1b46d7Szhanghch05 "#MemoryCollection.MemoryCollection"; 8968d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Memory Module Collection"; 8978d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = 8988d1b46d7Szhanghch05 "/redfish/v1/Systems/system/Memory"; 899ac6a4445SGunnar Mills 90005030b8eSGunnar Mills collection_util::getCollectionMembers( 90105030b8eSGunnar Mills asyncResp, "/redfish/v1/Systems/system/Memory", 90205030b8eSGunnar Mills {"xyz.openbmc_project.Inventory.Item.Dimm"}); 9037e860f15SJohn Edward Broadbent }); 904ac6a4445SGunnar Mills } 905ac6a4445SGunnar Mills 9067e860f15SJohn Edward Broadbent inline void requestRoutesMemory(App& app) 9077e860f15SJohn Edward Broadbent { 908ac6a4445SGunnar Mills /** 909ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 910ac6a4445SGunnar Mills */ 9117e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Memory/<str>/") 912*ed398213SEd Tanous .privileges(redfish::privileges::getMemory) 9137e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 9147e860f15SJohn Edward Broadbent [](const crow::Request&, 9157e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 9167e860f15SJohn Edward Broadbent const std::string& dimmId) { 9177e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["@odata.type"] = 9187e860f15SJohn Edward Broadbent "#Memory.v1_11_0.Memory"; 9198d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = 920ac6a4445SGunnar Mills "/redfish/v1/Systems/system/Memory/" + dimmId; 921ac6a4445SGunnar Mills 922ac6a4445SGunnar Mills getDimmData(asyncResp, dimmId); 9237e860f15SJohn Edward Broadbent }); 924ac6a4445SGunnar Mills } 925ac6a4445SGunnar Mills 926ac6a4445SGunnar Mills } // namespace redfish 927