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 155*866e4862SEd 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, 160ac6a4445SGunnar Mills const DimmProperties& properties) 161ac6a4445SGunnar Mills { 162ac6a4445SGunnar Mills for (const auto& property : properties) 163ac6a4445SGunnar Mills { 164ac6a4445SGunnar Mills if (property.first == "ModuleManufacturerID") 165ac6a4445SGunnar Mills { 166ac6a4445SGunnar Mills dimmPropToHex(aResp, "ModuleManufacturerID", property); 167ac6a4445SGunnar Mills } 168ac6a4445SGunnar Mills else if (property.first == "ModuleProductID") 169ac6a4445SGunnar Mills { 170ac6a4445SGunnar Mills dimmPropToHex(aResp, "ModuleProductID", property); 171ac6a4445SGunnar Mills } 172ac6a4445SGunnar Mills else if (property.first == "SubsystemVendorID") 173ac6a4445SGunnar Mills { 174ac6a4445SGunnar Mills dimmPropToHex(aResp, "MemorySubsystemControllerManufacturerID", 175ac6a4445SGunnar Mills property); 176ac6a4445SGunnar Mills } 177ac6a4445SGunnar Mills else if (property.first == "SubsystemDeviceID") 178ac6a4445SGunnar Mills { 179ac6a4445SGunnar Mills dimmPropToHex(aResp, "MemorySubsystemControllerProductID", 180ac6a4445SGunnar Mills property); 181ac6a4445SGunnar Mills } 182ac6a4445SGunnar Mills else if (property.first == "VolatileRegionSizeLimitInKiB") 183ac6a4445SGunnar Mills { 184ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 185ac6a4445SGunnar Mills 186ac6a4445SGunnar Mills if (value == nullptr) 187ac6a4445SGunnar Mills { 188ac6a4445SGunnar Mills messages::internalError(aResp->res); 1890fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 1900fda0f12SGeorge Liu << "Invalid property type for VolatileRegionSizeLimitKiB"; 191601af5edSChicago Duan return; 192ac6a4445SGunnar Mills } 193ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileRegionSizeLimitMiB"] = (*value) >> 10; 194ac6a4445SGunnar Mills } 195ac6a4445SGunnar Mills else if (property.first == "PmRegionSizeLimitInKiB") 196ac6a4445SGunnar Mills { 197ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 198ac6a4445SGunnar Mills 199ac6a4445SGunnar Mills if (value == nullptr) 200ac6a4445SGunnar Mills { 201ac6a4445SGunnar Mills messages::internalError(aResp->res); 202ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 203ac6a4445SGunnar Mills << "Invalid property type for PmRegioSizeLimitKiB"; 204601af5edSChicago Duan return; 205ac6a4445SGunnar Mills } 206ac6a4445SGunnar Mills aResp->res.jsonValue["PersistentRegionSizeLimitMiB"] = 207ac6a4445SGunnar Mills (*value) >> 10; 208ac6a4445SGunnar Mills } 209ac6a4445SGunnar Mills else if (property.first == "VolatileSizeInKiB") 210ac6a4445SGunnar Mills { 211ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 212ac6a4445SGunnar Mills 213ac6a4445SGunnar Mills if (value == nullptr) 214ac6a4445SGunnar Mills { 215ac6a4445SGunnar Mills messages::internalError(aResp->res); 216ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 217ac6a4445SGunnar Mills << "Invalid property type for VolatileSizeInKiB"; 218601af5edSChicago Duan return; 219ac6a4445SGunnar Mills } 220ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileSizeMiB"] = (*value) >> 10; 221ac6a4445SGunnar Mills } 222ac6a4445SGunnar Mills else if (property.first == "PmSizeInKiB") 223ac6a4445SGunnar Mills { 224ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 225ac6a4445SGunnar Mills if (value == nullptr) 226ac6a4445SGunnar Mills { 227ac6a4445SGunnar Mills messages::internalError(aResp->res); 228ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for PmSizeInKiB"; 229601af5edSChicago Duan return; 230ac6a4445SGunnar Mills } 231ac6a4445SGunnar Mills aResp->res.jsonValue["NonVolatileSizeMiB"] = (*value) >> 10; 232ac6a4445SGunnar Mills } 233ac6a4445SGunnar Mills else if (property.first == "CacheSizeInKB") 234ac6a4445SGunnar Mills { 235ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 236ac6a4445SGunnar Mills if (value == nullptr) 237ac6a4445SGunnar Mills { 238ac6a4445SGunnar Mills messages::internalError(aResp->res); 239ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for CacheSizeInKB"; 240601af5edSChicago Duan return; 241ac6a4445SGunnar Mills } 242ac6a4445SGunnar Mills aResp->res.jsonValue["CacheSizeMiB"] = (*value >> 10); 243ac6a4445SGunnar Mills } 244ac6a4445SGunnar Mills 245ac6a4445SGunnar Mills else if (property.first == "VoltaileRegionMaxSizeInKib") 246ac6a4445SGunnar Mills { 247ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 248ac6a4445SGunnar Mills 249ac6a4445SGunnar Mills if (value == nullptr) 250ac6a4445SGunnar Mills { 251ac6a4445SGunnar Mills messages::internalError(aResp->res); 2520fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 2530fda0f12SGeorge Liu << "Invalid property type for VolatileRegionMaxSizeInKib"; 254601af5edSChicago Duan return; 255ac6a4445SGunnar Mills } 256ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileRegionSizeMaxMiB"] = (*value) >> 10; 257ac6a4445SGunnar Mills } 258ac6a4445SGunnar Mills else if (property.first == "PmRegionMaxSizeInKiB") 259ac6a4445SGunnar Mills { 260ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 261ac6a4445SGunnar Mills 262ac6a4445SGunnar Mills if (value == nullptr) 263ac6a4445SGunnar Mills { 264ac6a4445SGunnar Mills messages::internalError(aResp->res); 265ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 266ac6a4445SGunnar Mills << "Invalid property type for PmRegionMaxSizeInKiB"; 267601af5edSChicago Duan return; 268ac6a4445SGunnar Mills } 269ac6a4445SGunnar Mills aResp->res.jsonValue["PersistentRegionSizeMaxMiB"] = (*value) >> 10; 270ac6a4445SGunnar Mills } 271ac6a4445SGunnar Mills else if (property.first == "AllocationIncrementInKiB") 272ac6a4445SGunnar Mills { 273ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 274ac6a4445SGunnar Mills 275ac6a4445SGunnar Mills if (value == nullptr) 276ac6a4445SGunnar Mills { 277ac6a4445SGunnar Mills messages::internalError(aResp->res); 2780fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 2790fda0f12SGeorge Liu << "Invalid property type for AllocationIncrementInKiB"; 280601af5edSChicago Duan return; 281ac6a4445SGunnar Mills } 282ac6a4445SGunnar Mills aResp->res.jsonValue["AllocationIncrementMiB"] = (*value) >> 10; 283ac6a4445SGunnar Mills } 284ac6a4445SGunnar Mills else if (property.first == "AllocationAlignmentInKiB") 285ac6a4445SGunnar Mills { 286ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 287ac6a4445SGunnar Mills 288ac6a4445SGunnar Mills if (value == nullptr) 289ac6a4445SGunnar Mills { 290ac6a4445SGunnar Mills messages::internalError(aResp->res); 2910fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 2920fda0f12SGeorge Liu << "Invalid property type for AllocationAlignmentInKiB"; 293601af5edSChicago Duan return; 294ac6a4445SGunnar Mills } 295ac6a4445SGunnar Mills aResp->res.jsonValue["AllocationAlignmentMiB"] = (*value) >> 10; 296ac6a4445SGunnar Mills } 297ac6a4445SGunnar Mills else if (property.first == "VolatileRegionNumberLimit") 298ac6a4445SGunnar Mills { 299ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 300ac6a4445SGunnar Mills if (value == nullptr) 301ac6a4445SGunnar Mills { 302ac6a4445SGunnar Mills messages::internalError(aResp->res); 303601af5edSChicago Duan return; 304ac6a4445SGunnar Mills } 305ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileRegionNumberLimit"] = *value; 306ac6a4445SGunnar Mills } 307ac6a4445SGunnar Mills else if (property.first == "PmRegionNumberLimit") 308ac6a4445SGunnar Mills { 309ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 310ac6a4445SGunnar Mills if (value == nullptr) 311ac6a4445SGunnar Mills { 312ac6a4445SGunnar Mills messages::internalError(aResp->res); 313601af5edSChicago Duan return; 314ac6a4445SGunnar Mills } 315ac6a4445SGunnar Mills aResp->res.jsonValue["PersistentRegionNumberLimit"] = *value; 316ac6a4445SGunnar Mills } 317ac6a4445SGunnar Mills else if (property.first == "SpareDeviceCount") 318ac6a4445SGunnar Mills { 319ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 320ac6a4445SGunnar Mills if (value == nullptr) 321ac6a4445SGunnar Mills { 322ac6a4445SGunnar Mills messages::internalError(aResp->res); 323601af5edSChicago Duan return; 324ac6a4445SGunnar Mills } 325ac6a4445SGunnar Mills aResp->res.jsonValue["SpareDeviceCount"] = *value; 326ac6a4445SGunnar Mills } 327ac6a4445SGunnar Mills else if (property.first == "IsSpareDeviceInUse") 328ac6a4445SGunnar Mills { 329ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 330ac6a4445SGunnar Mills if (value == nullptr) 331ac6a4445SGunnar Mills { 332ac6a4445SGunnar Mills messages::internalError(aResp->res); 333601af5edSChicago Duan return; 334ac6a4445SGunnar Mills } 335ac6a4445SGunnar Mills aResp->res.jsonValue["IsSpareDeviceEnabled"] = *value; 336ac6a4445SGunnar Mills } 337ac6a4445SGunnar Mills else if (property.first == "IsRankSpareEnabled") 338ac6a4445SGunnar Mills { 339ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 340ac6a4445SGunnar Mills if (value == nullptr) 341ac6a4445SGunnar Mills { 342ac6a4445SGunnar Mills messages::internalError(aResp->res); 343601af5edSChicago Duan return; 344ac6a4445SGunnar Mills } 345ac6a4445SGunnar Mills aResp->res.jsonValue["IsRankSpareEnabled"] = *value; 346ac6a4445SGunnar Mills } 347ac6a4445SGunnar Mills else if (property.first == "MaxAveragePowerLimitmW") 348ac6a4445SGunnar Mills { 349ac6a4445SGunnar Mills const auto* value = 350ac6a4445SGunnar Mills std::get_if<std::vector<uint32_t>>(&property.second); 351ac6a4445SGunnar Mills if (value == nullptr) 352ac6a4445SGunnar Mills { 353ac6a4445SGunnar Mills messages::internalError(aResp->res); 3540fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 3550fda0f12SGeorge Liu << "Invalid property type for MaxAveragePowerLimitmW"; 356601af5edSChicago Duan return; 357ac6a4445SGunnar Mills } 358ac6a4445SGunnar Mills aResp->res.jsonValue["MaxTDPMilliWatts"] = *value; 359ac6a4445SGunnar Mills } 360ac6a4445SGunnar Mills else if (property.first == "ConfigurationLocked") 361ac6a4445SGunnar Mills { 362ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 363ac6a4445SGunnar Mills if (value == nullptr) 364ac6a4445SGunnar Mills { 365ac6a4445SGunnar Mills messages::internalError(aResp->res); 366601af5edSChicago Duan return; 367ac6a4445SGunnar Mills } 368ac6a4445SGunnar Mills aResp->res.jsonValue["ConfigurationLocked"] = *value; 369ac6a4445SGunnar Mills } 370ac6a4445SGunnar Mills else if (property.first == "AllowedMemoryModes") 371ac6a4445SGunnar Mills { 372ac6a4445SGunnar Mills const std::string* value = 373ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 374ac6a4445SGunnar Mills if (value == nullptr) 375ac6a4445SGunnar Mills { 376ac6a4445SGunnar Mills messages::internalError(aResp->res); 377ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for FormFactor"; 378601af5edSChicago Duan return; 379ac6a4445SGunnar Mills } 380ac6a4445SGunnar Mills constexpr const std::array<const char*, 3> values{"Volatile", 381ac6a4445SGunnar Mills "PMEM", "Block"}; 382ac6a4445SGunnar Mills 383ac6a4445SGunnar Mills for (const char* v : values) 384ac6a4445SGunnar Mills { 385ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 386ac6a4445SGunnar Mills { 387ac6a4445SGunnar Mills aResp->res.jsonValue["OperatingMemoryModes "] = v; 388ac6a4445SGunnar Mills break; 389ac6a4445SGunnar Mills } 390ac6a4445SGunnar Mills } 391ac6a4445SGunnar Mills } 392ac6a4445SGunnar Mills else if (property.first == "MemoryMedia") 393ac6a4445SGunnar Mills { 394ac6a4445SGunnar Mills const std::string* value = 395ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 396ac6a4445SGunnar Mills if (value == nullptr) 397ac6a4445SGunnar Mills { 398ac6a4445SGunnar Mills messages::internalError(aResp->res); 399ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for MemoryMedia"; 400601af5edSChicago Duan return; 401ac6a4445SGunnar Mills } 402ac6a4445SGunnar Mills constexpr const std::array<const char*, 3> values{"DRAM", "NAND", 403ac6a4445SGunnar Mills "Intel3DXPoint"}; 404ac6a4445SGunnar Mills 405ac6a4445SGunnar Mills for (const char* v : values) 406ac6a4445SGunnar Mills { 407ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 408ac6a4445SGunnar Mills { 409ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryMedia"] = v; 410ac6a4445SGunnar Mills break; 411ac6a4445SGunnar Mills } 412ac6a4445SGunnar Mills } 413ac6a4445SGunnar Mills } 414ac6a4445SGunnar Mills // PersistantMemory.SecurityCapabilites interface 415ac6a4445SGunnar Mills else if (property.first == "ConfigurationLockCapable" || 416ac6a4445SGunnar Mills property.first == "DataLockCapable" || 417ac6a4445SGunnar Mills property.first == "PassphraseCapable") 418ac6a4445SGunnar Mills { 419ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 420ac6a4445SGunnar Mills if (value == nullptr) 421ac6a4445SGunnar Mills { 422ac6a4445SGunnar Mills messages::internalError(aResp->res); 423601af5edSChicago Duan return; 424ac6a4445SGunnar Mills } 425ac6a4445SGunnar Mills aResp->res.jsonValue["SecurityCapabilities"][property.first] = 426ac6a4445SGunnar Mills *value; 427ac6a4445SGunnar Mills } 428ac6a4445SGunnar Mills else if (property.first == "MaxPassphraseCount" || 429ac6a4445SGunnar Mills property.first == "PassphraseLockLimit") 430ac6a4445SGunnar Mills { 431ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 432ac6a4445SGunnar Mills if (value == nullptr) 433ac6a4445SGunnar Mills { 434ac6a4445SGunnar Mills messages::internalError(aResp->res); 435601af5edSChicago Duan return; 436ac6a4445SGunnar Mills } 437ac6a4445SGunnar Mills aResp->res.jsonValue["SecurityCapabilities"][property.first] = 438ac6a4445SGunnar Mills *value; 439ac6a4445SGunnar Mills } 440ac6a4445SGunnar Mills } 441ac6a4445SGunnar Mills } 442ac6a4445SGunnar Mills 4438d1b46d7Szhanghch05 inline void getDimmDataByService(std::shared_ptr<bmcweb::AsyncResp> aResp, 444ac6a4445SGunnar Mills const std::string& dimmId, 445ac6a4445SGunnar Mills const std::string& service, 446ac6a4445SGunnar Mills const std::string& objPath) 447ac6a4445SGunnar Mills { 448ac6a4445SGunnar Mills auto health = std::make_shared<HealthPopulate>(aResp); 449ac6a4445SGunnar Mills health->selfPath = objPath; 450ac6a4445SGunnar Mills health->populate(); 451ac6a4445SGunnar Mills 452ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Get available system components."; 453ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 454ac6a4445SGunnar Mills [dimmId, aResp{std::move(aResp)}](const boost::system::error_code ec, 455ac6a4445SGunnar Mills const DimmProperties& properties) { 456ac6a4445SGunnar Mills if (ec) 457ac6a4445SGunnar Mills { 458ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 459ac6a4445SGunnar Mills messages::internalError(aResp->res); 460ac6a4445SGunnar Mills 461ac6a4445SGunnar Mills return; 462ac6a4445SGunnar Mills } 463ac6a4445SGunnar Mills aResp->res.jsonValue["Id"] = dimmId; 464ac6a4445SGunnar Mills aResp->res.jsonValue["Name"] = "DIMM Slot"; 465ac6a4445SGunnar Mills 466ac6a4445SGunnar Mills const auto memorySizeProperty = properties.find("MemorySizeInKB"); 467ac6a4445SGunnar Mills if (memorySizeProperty != properties.end()) 468ac6a4445SGunnar Mills { 469ac6a4445SGunnar Mills const uint32_t* memorySize = 470ac6a4445SGunnar Mills std::get_if<uint32_t>(&memorySizeProperty->second); 471ac6a4445SGunnar Mills if (memorySize == nullptr) 472ac6a4445SGunnar Mills { 473ac6a4445SGunnar Mills // Important property not in desired type 474ac6a4445SGunnar Mills messages::internalError(aResp->res); 475ac6a4445SGunnar Mills return; 476ac6a4445SGunnar Mills } 477ac6a4445SGunnar Mills aResp->res.jsonValue["CapacityMiB"] = (*memorySize >> 10); 478ac6a4445SGunnar Mills } 479ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["State"] = "Enabled"; 480ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["Health"] = "OK"; 481ac6a4445SGunnar Mills 482ac6a4445SGunnar Mills for (const auto& property : properties) 483ac6a4445SGunnar Mills { 484ac6a4445SGunnar Mills if (property.first == "MemoryDataWidth") 485ac6a4445SGunnar Mills { 486ac6a4445SGunnar Mills const uint16_t* value = 487ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 488ac6a4445SGunnar Mills if (value == nullptr) 489ac6a4445SGunnar Mills { 490ac6a4445SGunnar Mills continue; 491ac6a4445SGunnar Mills } 492ac6a4445SGunnar Mills aResp->res.jsonValue["DataWidthBits"] = *value; 493ac6a4445SGunnar Mills } 494ac6a4445SGunnar Mills else if (property.first == "PartNumber") 495ac6a4445SGunnar Mills { 496ac6a4445SGunnar Mills const std::string* value = 497ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 498ac6a4445SGunnar Mills if (value == nullptr) 499ac6a4445SGunnar Mills { 500ac6a4445SGunnar Mills continue; 501ac6a4445SGunnar Mills } 502ac6a4445SGunnar Mills aResp->res.jsonValue["PartNumber"] = *value; 503ac6a4445SGunnar Mills } 504ac6a4445SGunnar Mills else if (property.first == "SerialNumber") 505ac6a4445SGunnar Mills { 506ac6a4445SGunnar Mills const std::string* value = 507ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 508ac6a4445SGunnar Mills if (value == nullptr) 509ac6a4445SGunnar Mills { 510ac6a4445SGunnar Mills continue; 511ac6a4445SGunnar Mills } 512ac6a4445SGunnar Mills aResp->res.jsonValue["SerialNumber"] = *value; 513ac6a4445SGunnar Mills } 514ac6a4445SGunnar Mills else if (property.first == "Manufacturer") 515ac6a4445SGunnar Mills { 516ac6a4445SGunnar Mills const std::string* value = 517ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 518ac6a4445SGunnar Mills if (value == nullptr) 519ac6a4445SGunnar Mills { 520ac6a4445SGunnar Mills continue; 521ac6a4445SGunnar Mills } 522ac6a4445SGunnar Mills aResp->res.jsonValue["Manufacturer"] = *value; 523ac6a4445SGunnar Mills } 524ac6a4445SGunnar Mills else if (property.first == "RevisionCode") 525ac6a4445SGunnar Mills { 526ac6a4445SGunnar Mills const uint16_t* value = 527ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 528ac6a4445SGunnar Mills 529ac6a4445SGunnar Mills if (value == nullptr) 530ac6a4445SGunnar Mills { 531ac6a4445SGunnar Mills messages::internalError(aResp->res); 532ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 533ac6a4445SGunnar Mills << "Invalid property type for RevisionCode"; 534601af5edSChicago Duan return; 535ac6a4445SGunnar Mills } 536ac6a4445SGunnar Mills aResp->res.jsonValue["FirmwareRevision"] = 537ac6a4445SGunnar Mills std::to_string(*value); 538ac6a4445SGunnar Mills } 5399a128eb3SJoshi-Mansi else if (property.first == "Present") 5409a128eb3SJoshi-Mansi { 5419a128eb3SJoshi-Mansi const bool* value = std::get_if<bool>(&property.second); 5429a128eb3SJoshi-Mansi if (value == nullptr) 5439a128eb3SJoshi-Mansi { 5449a128eb3SJoshi-Mansi messages::internalError(aResp->res); 5459a128eb3SJoshi-Mansi BMCWEB_LOG_DEBUG 5469a128eb3SJoshi-Mansi << "Invalid property type for Dimm Presence"; 5479a128eb3SJoshi-Mansi return; 5489a128eb3SJoshi-Mansi } 549e05aec50SEd Tanous if (!*value) 5509a128eb3SJoshi-Mansi { 5519a128eb3SJoshi-Mansi aResp->res.jsonValue["Status"]["State"] = "Absent"; 5529a128eb3SJoshi-Mansi } 5539a128eb3SJoshi-Mansi } 554ac6a4445SGunnar Mills else if (property.first == "MemoryTotalWidth") 555ac6a4445SGunnar Mills { 556ac6a4445SGunnar Mills const uint16_t* value = 557ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 558ac6a4445SGunnar Mills if (value == nullptr) 559ac6a4445SGunnar Mills { 560ac6a4445SGunnar Mills continue; 561ac6a4445SGunnar Mills } 562ac6a4445SGunnar Mills aResp->res.jsonValue["BusWidthBits"] = *value; 563ac6a4445SGunnar Mills } 564ac6a4445SGunnar Mills else if (property.first == "ECC") 565ac6a4445SGunnar Mills { 566ac6a4445SGunnar Mills const std::string* value = 567ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 568ac6a4445SGunnar Mills if (value == nullptr) 569ac6a4445SGunnar Mills { 570ac6a4445SGunnar Mills messages::internalError(aResp->res); 571ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for ECC"; 572601af5edSChicago Duan return; 573ac6a4445SGunnar Mills } 574ac6a4445SGunnar Mills constexpr const std::array<const char*, 4> values{ 575ac6a4445SGunnar Mills "NoECC", "SingleBitECC", "MultiBitECC", 576ac6a4445SGunnar Mills "AddressParity"}; 577ac6a4445SGunnar Mills 578ac6a4445SGunnar Mills for (const char* v : values) 579ac6a4445SGunnar Mills { 580ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 581ac6a4445SGunnar Mills { 582ac6a4445SGunnar Mills aResp->res.jsonValue["ErrorCorrection"] = v; 583ac6a4445SGunnar Mills break; 584ac6a4445SGunnar Mills } 585ac6a4445SGunnar Mills } 586ac6a4445SGunnar Mills } 587ac6a4445SGunnar Mills else if (property.first == "FormFactor") 588ac6a4445SGunnar Mills { 589ac6a4445SGunnar Mills const std::string* value = 590ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 591ac6a4445SGunnar Mills if (value == nullptr) 592ac6a4445SGunnar Mills { 593ac6a4445SGunnar Mills messages::internalError(aResp->res); 594ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 595ac6a4445SGunnar Mills << "Invalid property type for FormFactor"; 596601af5edSChicago Duan return; 597ac6a4445SGunnar Mills } 598ac6a4445SGunnar Mills constexpr const std::array<const char*, 11> values{ 599ac6a4445SGunnar Mills "RDIMM", "UDIMM", "SO_DIMM", 600ac6a4445SGunnar Mills "LRDIMM", "Mini_RDIMM", "Mini_UDIMM", 601ac6a4445SGunnar Mills "SO_RDIMM_72b", "SO_UDIMM_72b", "SO_DIMM_16b", 602ac6a4445SGunnar Mills "SO_DIMM_32b", "Die"}; 603ac6a4445SGunnar Mills 604ac6a4445SGunnar Mills for (const char* v : values) 605ac6a4445SGunnar Mills { 606ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 607ac6a4445SGunnar Mills { 608ac6a4445SGunnar Mills aResp->res.jsonValue["BaseModuleType"] = v; 609ac6a4445SGunnar Mills break; 610ac6a4445SGunnar Mills } 611ac6a4445SGunnar Mills } 612ac6a4445SGunnar Mills } 613ac6a4445SGunnar Mills else if (property.first == "AllowedSpeedsMT") 614ac6a4445SGunnar Mills { 615ac6a4445SGunnar Mills const std::vector<uint16_t>* value = 616ac6a4445SGunnar Mills std::get_if<std::vector<uint16_t>>(&property.second); 617ac6a4445SGunnar Mills if (value == nullptr) 618ac6a4445SGunnar Mills { 619ac6a4445SGunnar Mills continue; 620ac6a4445SGunnar Mills } 621ac6a4445SGunnar Mills nlohmann::json& jValue = 622ac6a4445SGunnar Mills aResp->res.jsonValue["AllowedSpeedsMHz"]; 623ac6a4445SGunnar Mills jValue = nlohmann::json::array(); 624ac6a4445SGunnar Mills for (uint16_t subVal : *value) 625ac6a4445SGunnar Mills { 626ac6a4445SGunnar Mills jValue.push_back(subVal); 627ac6a4445SGunnar Mills } 628ac6a4445SGunnar Mills } 629ac6a4445SGunnar Mills else if (property.first == "MemoryAttributes") 630ac6a4445SGunnar Mills { 631ac6a4445SGunnar Mills const uint8_t* value = 632ac6a4445SGunnar Mills std::get_if<uint8_t>(&property.second); 633ac6a4445SGunnar Mills 634ac6a4445SGunnar Mills if (value == nullptr) 635ac6a4445SGunnar Mills { 636ac6a4445SGunnar Mills messages::internalError(aResp->res); 637ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 638ac6a4445SGunnar Mills << "Invalid property type for MemoryAttributes"; 639601af5edSChicago Duan return; 640ac6a4445SGunnar Mills } 641ac6a4445SGunnar Mills aResp->res.jsonValue["RankCount"] = 642ac6a4445SGunnar Mills static_cast<uint64_t>(*value); 643ac6a4445SGunnar Mills } 644ac6a4445SGunnar Mills else if (property.first == "MemoryConfiguredSpeedInMhz") 645ac6a4445SGunnar Mills { 646ac6a4445SGunnar Mills const uint16_t* value = 647ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 648ac6a4445SGunnar Mills if (value == nullptr) 649ac6a4445SGunnar Mills { 650ac6a4445SGunnar Mills continue; 651ac6a4445SGunnar Mills } 652ac6a4445SGunnar Mills aResp->res.jsonValue["OperatingSpeedMhz"] = *value; 653ac6a4445SGunnar Mills } 654ac6a4445SGunnar Mills else if (property.first == "MemoryType") 655ac6a4445SGunnar Mills { 656ac6a4445SGunnar Mills const auto* value = 657ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 658ac6a4445SGunnar Mills if (value != nullptr) 659ac6a4445SGunnar Mills { 660313efb1cSGunnar Mills std::string memoryDeviceType = 661313efb1cSGunnar Mills translateMemoryTypeToRedfish(*value); 662313efb1cSGunnar Mills // Values like "Unknown" or "Other" will return empty 663313efb1cSGunnar Mills // so just leave off 664313efb1cSGunnar Mills if (!memoryDeviceType.empty()) 665ac6a4445SGunnar Mills { 666313efb1cSGunnar Mills aResp->res.jsonValue["MemoryDeviceType"] = 667313efb1cSGunnar Mills memoryDeviceType; 668ac6a4445SGunnar Mills } 669ac6a4445SGunnar Mills if (value->find("DDR") != std::string::npos) 670ac6a4445SGunnar Mills { 671ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryType"] = "DRAM"; 672ac6a4445SGunnar Mills } 673ac6a4445SGunnar Mills else if (boost::ends_with(*value, "Logical")) 674ac6a4445SGunnar Mills { 675ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryType"] = "IntelOptane"; 676ac6a4445SGunnar Mills } 677ac6a4445SGunnar Mills } 678ac6a4445SGunnar Mills } 679ac6a4445SGunnar Mills // memory location interface 680ac6a4445SGunnar Mills else if (property.first == "Channel" || 681ac6a4445SGunnar Mills property.first == "MemoryController" || 682ac6a4445SGunnar Mills property.first == "Slot" || property.first == "Socket") 683ac6a4445SGunnar Mills { 684ac6a4445SGunnar Mills const std::string* value = 685ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 686ac6a4445SGunnar Mills if (value == nullptr) 687ac6a4445SGunnar Mills { 688ac6a4445SGunnar Mills messages::internalError(aResp->res); 689601af5edSChicago Duan return; 690ac6a4445SGunnar Mills } 691ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryLocation"][property.first] = 692ac6a4445SGunnar Mills *value; 693ac6a4445SGunnar Mills } 694ee135e24SSunnySrivastava1984 else if (property.first == "SparePartNumber") 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["SparePartNumber"] = *value; 704ee135e24SSunnySrivastava1984 } 705ee135e24SSunnySrivastava1984 else if (property.first == "Model") 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.jsonValue["Model"] = *value; 715ee135e24SSunnySrivastava1984 } 716ee135e24SSunnySrivastava1984 else if (property.first == "LocationCode") 717ee135e24SSunnySrivastava1984 { 718ee135e24SSunnySrivastava1984 const std::string* value = 719ee135e24SSunnySrivastava1984 std::get_if<std::string>(&property.second); 720ee135e24SSunnySrivastava1984 if (value == nullptr) 721ee135e24SSunnySrivastava1984 { 722ee135e24SSunnySrivastava1984 messages::internalError(aResp->res); 723601af5edSChicago Duan return; 724ee135e24SSunnySrivastava1984 } 725ee135e24SSunnySrivastava1984 aResp->res 726ee135e24SSunnySrivastava1984 .jsonValue["Location"]["PartLocation"]["ServiceLabel"] = 727ee135e24SSunnySrivastava1984 *value; 728ee135e24SSunnySrivastava1984 } 729ac6a4445SGunnar Mills else 730ac6a4445SGunnar Mills { 731ac6a4445SGunnar Mills getPersistentMemoryProperties(aResp, properties); 732ac6a4445SGunnar Mills } 733ac6a4445SGunnar Mills } 734ac6a4445SGunnar Mills }, 735ac6a4445SGunnar Mills service, objPath, "org.freedesktop.DBus.Properties", "GetAll", ""); 736ac6a4445SGunnar Mills } 737ac6a4445SGunnar Mills 7388d1b46d7Szhanghch05 inline void getDimmPartitionData(std::shared_ptr<bmcweb::AsyncResp> aResp, 739ac6a4445SGunnar Mills const std::string& service, 740ac6a4445SGunnar Mills const std::string& path) 741ac6a4445SGunnar Mills { 742ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 743ac6a4445SGunnar Mills [aResp{std::move(aResp)}]( 744ac6a4445SGunnar Mills const boost::system::error_code ec, 745ac6a4445SGunnar Mills const boost::container::flat_map< 746168e20c1SEd Tanous std::string, dbus::utility::DbusVariantType>& properties) { 747ac6a4445SGunnar Mills if (ec) 748ac6a4445SGunnar Mills { 749ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 750ac6a4445SGunnar Mills messages::internalError(aResp->res); 751ac6a4445SGunnar Mills 752ac6a4445SGunnar Mills return; 753ac6a4445SGunnar Mills } 754ac6a4445SGunnar Mills 755ac6a4445SGunnar Mills nlohmann::json& partition = 756ac6a4445SGunnar Mills aResp->res.jsonValue["Regions"].emplace_back( 757ac6a4445SGunnar Mills nlohmann::json::object()); 758ac6a4445SGunnar Mills for (const auto& [key, val] : properties) 759ac6a4445SGunnar Mills { 760ac6a4445SGunnar Mills if (key == "MemoryClassification") 761ac6a4445SGunnar Mills { 762ac6a4445SGunnar Mills const std::string* value = std::get_if<std::string>(&val); 763ac6a4445SGunnar Mills if (value == nullptr) 764ac6a4445SGunnar Mills { 765ac6a4445SGunnar Mills messages::internalError(aResp->res); 766601af5edSChicago Duan return; 767ac6a4445SGunnar Mills } 768ac6a4445SGunnar Mills partition[key] = *value; 769ac6a4445SGunnar Mills } 770ac6a4445SGunnar Mills else if (key == "OffsetInKiB") 771ac6a4445SGunnar Mills { 772ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&val); 773ac6a4445SGunnar Mills if (value == nullptr) 774ac6a4445SGunnar Mills { 775ac6a4445SGunnar Mills messages::internalError(aResp->res); 776601af5edSChicago Duan return; 777ac6a4445SGunnar Mills } 778ac6a4445SGunnar Mills 779ac6a4445SGunnar Mills partition["OffsetMiB"] = (*value >> 10); 780ac6a4445SGunnar Mills } 781ac6a4445SGunnar Mills else if (key == "PartitionId") 782ac6a4445SGunnar Mills { 783ac6a4445SGunnar Mills const std::string* value = std::get_if<std::string>(&val); 784ac6a4445SGunnar Mills if (value == nullptr) 785ac6a4445SGunnar Mills { 786ac6a4445SGunnar Mills messages::internalError(aResp->res); 787601af5edSChicago Duan return; 788ac6a4445SGunnar Mills } 789ac6a4445SGunnar Mills partition["RegionId"] = *value; 790ac6a4445SGunnar Mills } 791ac6a4445SGunnar Mills 792ac6a4445SGunnar Mills else if (key == "PassphraseState") 793ac6a4445SGunnar Mills { 794ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&val); 795ac6a4445SGunnar Mills if (value == nullptr) 796ac6a4445SGunnar Mills { 797ac6a4445SGunnar Mills messages::internalError(aResp->res); 798601af5edSChicago Duan return; 799ac6a4445SGunnar Mills } 800ac6a4445SGunnar Mills partition["PassphraseEnabled"] = *value; 801ac6a4445SGunnar Mills } 802ac6a4445SGunnar Mills else if (key == "SizeInKiB") 803ac6a4445SGunnar Mills { 804ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&val); 805ac6a4445SGunnar Mills if (value == nullptr) 806ac6a4445SGunnar Mills { 807ac6a4445SGunnar Mills messages::internalError(aResp->res); 808ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 809ac6a4445SGunnar Mills << "Invalid property type for SizeInKiB"; 810601af5edSChicago Duan return; 811ac6a4445SGunnar Mills } 812ac6a4445SGunnar Mills partition["SizeMiB"] = (*value >> 10); 813ac6a4445SGunnar Mills } 814ac6a4445SGunnar Mills } 815ac6a4445SGunnar Mills }, 816ac6a4445SGunnar Mills 817ac6a4445SGunnar Mills service, path, "org.freedesktop.DBus.Properties", "GetAll", 818ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"); 819ac6a4445SGunnar Mills } 820ac6a4445SGunnar Mills 8218d1b46d7Szhanghch05 inline void getDimmData(std::shared_ptr<bmcweb::AsyncResp> aResp, 822ac6a4445SGunnar Mills const std::string& dimmId) 823ac6a4445SGunnar Mills { 824ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Get available system dimm resources."; 825ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 826ac6a4445SGunnar Mills [dimmId, aResp{std::move(aResp)}]( 827ac6a4445SGunnar Mills const boost::system::error_code ec, 828ac6a4445SGunnar Mills const boost::container::flat_map< 829ac6a4445SGunnar Mills std::string, boost::container::flat_map< 830ac6a4445SGunnar Mills std::string, std::vector<std::string>>>& 831ac6a4445SGunnar Mills subtree) { 832ac6a4445SGunnar Mills if (ec) 833ac6a4445SGunnar Mills { 834ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 835ac6a4445SGunnar Mills messages::internalError(aResp->res); 836ac6a4445SGunnar Mills 837ac6a4445SGunnar Mills return; 838ac6a4445SGunnar Mills } 839ac6a4445SGunnar Mills bool found = false; 840ac6a4445SGunnar Mills for (const auto& [path, object] : subtree) 841ac6a4445SGunnar Mills { 842ac6a4445SGunnar Mills if (path.find(dimmId) != std::string::npos) 843ac6a4445SGunnar Mills { 844ac6a4445SGunnar Mills for (const auto& [service, interfaces] : object) 845ac6a4445SGunnar Mills { 846ac6a4445SGunnar Mills if (!found && 847ac6a4445SGunnar Mills (std::find( 848ac6a4445SGunnar Mills interfaces.begin(), interfaces.end(), 849ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm") != 850ac6a4445SGunnar Mills interfaces.end())) 851ac6a4445SGunnar Mills { 852ac6a4445SGunnar Mills getDimmDataByService(aResp, dimmId, service, path); 853ac6a4445SGunnar Mills found = true; 854ac6a4445SGunnar Mills } 855ac6a4445SGunnar Mills 856ac6a4445SGunnar Mills // partitions are separate as there can be multiple per 857ac6a4445SGunnar Mills // device, i.e. 858ac6a4445SGunnar Mills // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1 859ac6a4445SGunnar Mills // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2 8600fda0f12SGeorge Liu if (std::find( 8610fda0f12SGeorge Liu interfaces.begin(), interfaces.end(), 8620fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition") != 863ac6a4445SGunnar Mills interfaces.end()) 864ac6a4445SGunnar Mills { 865ac6a4445SGunnar Mills getDimmPartitionData(aResp, service, path); 866ac6a4445SGunnar Mills } 867ac6a4445SGunnar Mills } 868ac6a4445SGunnar Mills } 869ac6a4445SGunnar Mills } 870ac6a4445SGunnar Mills // Object not found 871ac6a4445SGunnar Mills if (!found) 872ac6a4445SGunnar Mills { 873ac6a4445SGunnar Mills messages::resourceNotFound(aResp->res, "Memory", dimmId); 874ac6a4445SGunnar Mills } 875ac6a4445SGunnar Mills return; 876ac6a4445SGunnar Mills }, 877ac6a4445SGunnar Mills "xyz.openbmc_project.ObjectMapper", 878ac6a4445SGunnar Mills "/xyz/openbmc_project/object_mapper", 879ac6a4445SGunnar Mills "xyz.openbmc_project.ObjectMapper", "GetSubTree", 880ac6a4445SGunnar Mills "/xyz/openbmc_project/inventory", 0, 881ac6a4445SGunnar Mills std::array<const char*, 2>{ 882ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm", 883ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"}); 884ac6a4445SGunnar Mills } 885ac6a4445SGunnar Mills 8867e860f15SJohn Edward Broadbent inline void requestRoutesMemoryCollection(App& app) 887ac6a4445SGunnar Mills { 888ac6a4445SGunnar Mills /** 889ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 890ac6a4445SGunnar Mills */ 8917e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Memory/") 892ed398213SEd Tanous .privileges(redfish::privileges::getMemoryCollection) 8937e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 8947e860f15SJohn Edward Broadbent [](const crow::Request&, 8957e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 8968d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 8978d1b46d7Szhanghch05 "#MemoryCollection.MemoryCollection"; 8988d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Memory Module Collection"; 8998d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = 9008d1b46d7Szhanghch05 "/redfish/v1/Systems/system/Memory"; 901ac6a4445SGunnar Mills 90205030b8eSGunnar Mills collection_util::getCollectionMembers( 90305030b8eSGunnar Mills asyncResp, "/redfish/v1/Systems/system/Memory", 90405030b8eSGunnar Mills {"xyz.openbmc_project.Inventory.Item.Dimm"}); 9057e860f15SJohn Edward Broadbent }); 906ac6a4445SGunnar Mills } 907ac6a4445SGunnar Mills 9087e860f15SJohn Edward Broadbent inline void requestRoutesMemory(App& app) 9097e860f15SJohn Edward Broadbent { 910ac6a4445SGunnar Mills /** 911ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 912ac6a4445SGunnar Mills */ 9137e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Memory/<str>/") 914ed398213SEd Tanous .privileges(redfish::privileges::getMemory) 9157e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 9167e860f15SJohn Edward Broadbent [](const crow::Request&, 9177e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 9187e860f15SJohn Edward Broadbent const std::string& dimmId) { 9197e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["@odata.type"] = 9207e860f15SJohn Edward Broadbent "#Memory.v1_11_0.Memory"; 9218d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = 922ac6a4445SGunnar Mills "/redfish/v1/Systems/system/Memory/" + dimmId; 923ac6a4445SGunnar Mills 924ac6a4445SGunnar Mills getDimmData(asyncResp, dimmId); 9257e860f15SJohn Edward Broadbent }); 926ac6a4445SGunnar Mills } 927ac6a4445SGunnar Mills 928ac6a4445SGunnar Mills } // namespace redfish 929