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> 22ed398213SEd Tanous #include <registries/privilege_registry.hpp> 23ac6a4445SGunnar Mills #include <utils/collection.hpp> 24f201ffb4SEd Tanous #include <utils/hex_utils.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 } 5911a2f0f0SMansi Joshi if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR5") 6011a2f0f0SMansi Joshi { 6111a2f0f0SMansi Joshi return "DDR5"; 6211a2f0f0SMansi Joshi } 63313efb1cSGunnar Mills if (memoryType == 64313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR4_SDRAM") 65313efb1cSGunnar Mills { 66313efb1cSGunnar Mills return "LPDDR4_SDRAM"; 67313efb1cSGunnar Mills } 68313efb1cSGunnar Mills if (memoryType == 69313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR3_SDRAM") 70313efb1cSGunnar Mills { 71313efb1cSGunnar Mills return "LPDDR3_SDRAM"; 72313efb1cSGunnar Mills } 73313efb1cSGunnar Mills if (memoryType == 74313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM") 75313efb1cSGunnar Mills { 76313efb1cSGunnar Mills return "DDR2_SDRAM_FB_DIMM"; 77313efb1cSGunnar Mills } 78*0fda0f12SGeorge Liu if (memoryType == 79*0fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM_PROB") 80313efb1cSGunnar Mills { 81313efb1cSGunnar Mills return "DDR2_SDRAM_FB_DIMM_PROBE"; 82313efb1cSGunnar Mills } 83313efb1cSGunnar Mills if (memoryType == 84313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR_SGRAM") 85313efb1cSGunnar Mills { 86313efb1cSGunnar Mills return "DDR_SGRAM"; 87313efb1cSGunnar Mills } 88313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.ROM") 89313efb1cSGunnar Mills { 90313efb1cSGunnar Mills return "ROM"; 91313efb1cSGunnar Mills } 92313efb1cSGunnar Mills if (memoryType == 93313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.SDRAM") 94313efb1cSGunnar Mills { 95313efb1cSGunnar Mills return "SDRAM"; 96313efb1cSGunnar Mills } 97313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.EDO") 98313efb1cSGunnar Mills { 99313efb1cSGunnar Mills return "EDO"; 100313efb1cSGunnar Mills } 101313efb1cSGunnar Mills if (memoryType == 102313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.FastPageMode") 103313efb1cSGunnar Mills { 104313efb1cSGunnar Mills return "FastPageMode"; 105313efb1cSGunnar Mills } 106313efb1cSGunnar Mills if (memoryType == 107313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.PipelinedNibble") 108313efb1cSGunnar Mills { 109313efb1cSGunnar Mills return "PipelinedNibble"; 110313efb1cSGunnar Mills } 111313efb1cSGunnar Mills if (memoryType == 112313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.Logical") 113313efb1cSGunnar Mills { 114313efb1cSGunnar Mills return "Logical"; 115313efb1cSGunnar Mills } 116313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM") 117313efb1cSGunnar Mills { 118313efb1cSGunnar Mills return "HBM"; 119313efb1cSGunnar Mills } 120313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM2") 121313efb1cSGunnar Mills { 122313efb1cSGunnar Mills return "HBM2"; 123313efb1cSGunnar Mills } 124313efb1cSGunnar Mills // This is values like Other or Unknown 125313efb1cSGunnar Mills // Also D-Bus values: 126313efb1cSGunnar Mills // DRAM 127313efb1cSGunnar Mills // EDRAM 128313efb1cSGunnar Mills // VRAM 129313efb1cSGunnar Mills // SRAM 130313efb1cSGunnar Mills // RAM 131313efb1cSGunnar Mills // FLASH 132313efb1cSGunnar Mills // EEPROM 133313efb1cSGunnar Mills // FEPROM 134313efb1cSGunnar Mills // EPROM 135313efb1cSGunnar Mills // CDRAM 136313efb1cSGunnar Mills // ThreeDRAM 137313efb1cSGunnar Mills // RDRAM 138313efb1cSGunnar Mills // FBD2 139313efb1cSGunnar Mills // LPDDR_SDRAM 140313efb1cSGunnar Mills // LPDDR2_SDRAM 14111a2f0f0SMansi Joshi // LPDDR5_SDRAM 142313efb1cSGunnar Mills return ""; 143313efb1cSGunnar Mills } 144313efb1cSGunnar Mills 1458d1b46d7Szhanghch05 inline void dimmPropToHex(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 146ac6a4445SGunnar Mills const char* key, 147ac6a4445SGunnar Mills const std::pair<std::string, DimmProperty>& property) 148ac6a4445SGunnar Mills { 149ac6a4445SGunnar Mills const uint16_t* value = std::get_if<uint16_t>(&property.second); 150ac6a4445SGunnar Mills if (value == nullptr) 151ac6a4445SGunnar Mills { 152ac6a4445SGunnar Mills messages::internalError(aResp->res); 153ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for " << property.first; 154ac6a4445SGunnar Mills return; 155ac6a4445SGunnar Mills } 156ac6a4445SGunnar Mills 157f201ffb4SEd Tanous aResp->res.jsonValue[key] = "0x" + intToHexString(*value); 158ac6a4445SGunnar Mills } 159ac6a4445SGunnar Mills 1608d1b46d7Szhanghch05 inline void getPersistentMemoryProperties( 1618d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aResp, 162ac6a4445SGunnar Mills const DimmProperties& properties) 163ac6a4445SGunnar Mills { 164ac6a4445SGunnar Mills for (const auto& property : properties) 165ac6a4445SGunnar Mills { 166ac6a4445SGunnar Mills if (property.first == "ModuleManufacturerID") 167ac6a4445SGunnar Mills { 168ac6a4445SGunnar Mills dimmPropToHex(aResp, "ModuleManufacturerID", property); 169ac6a4445SGunnar Mills } 170ac6a4445SGunnar Mills else if (property.first == "ModuleProductID") 171ac6a4445SGunnar Mills { 172ac6a4445SGunnar Mills dimmPropToHex(aResp, "ModuleProductID", property); 173ac6a4445SGunnar Mills } 174ac6a4445SGunnar Mills else if (property.first == "SubsystemVendorID") 175ac6a4445SGunnar Mills { 176ac6a4445SGunnar Mills dimmPropToHex(aResp, "MemorySubsystemControllerManufacturerID", 177ac6a4445SGunnar Mills property); 178ac6a4445SGunnar Mills } 179ac6a4445SGunnar Mills else if (property.first == "SubsystemDeviceID") 180ac6a4445SGunnar Mills { 181ac6a4445SGunnar Mills dimmPropToHex(aResp, "MemorySubsystemControllerProductID", 182ac6a4445SGunnar Mills property); 183ac6a4445SGunnar Mills } 184ac6a4445SGunnar Mills else if (property.first == "VolatileRegionSizeLimitInKiB") 185ac6a4445SGunnar Mills { 186ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 187ac6a4445SGunnar Mills 188ac6a4445SGunnar Mills if (value == nullptr) 189ac6a4445SGunnar Mills { 190ac6a4445SGunnar Mills messages::internalError(aResp->res); 191*0fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 192*0fda0f12SGeorge Liu << "Invalid property type for VolatileRegionSizeLimitKiB"; 193601af5edSChicago Duan return; 194ac6a4445SGunnar Mills } 195ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileRegionSizeLimitMiB"] = (*value) >> 10; 196ac6a4445SGunnar Mills } 197ac6a4445SGunnar Mills else if (property.first == "PmRegionSizeLimitInKiB") 198ac6a4445SGunnar Mills { 199ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 200ac6a4445SGunnar Mills 201ac6a4445SGunnar Mills if (value == nullptr) 202ac6a4445SGunnar Mills { 203ac6a4445SGunnar Mills messages::internalError(aResp->res); 204ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 205ac6a4445SGunnar Mills << "Invalid property type for PmRegioSizeLimitKiB"; 206601af5edSChicago Duan return; 207ac6a4445SGunnar Mills } 208ac6a4445SGunnar Mills aResp->res.jsonValue["PersistentRegionSizeLimitMiB"] = 209ac6a4445SGunnar Mills (*value) >> 10; 210ac6a4445SGunnar Mills } 211ac6a4445SGunnar Mills else if (property.first == "VolatileSizeInKiB") 212ac6a4445SGunnar Mills { 213ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 214ac6a4445SGunnar Mills 215ac6a4445SGunnar Mills if (value == nullptr) 216ac6a4445SGunnar Mills { 217ac6a4445SGunnar Mills messages::internalError(aResp->res); 218ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 219ac6a4445SGunnar Mills << "Invalid property type for VolatileSizeInKiB"; 220601af5edSChicago Duan return; 221ac6a4445SGunnar Mills } 222ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileSizeMiB"] = (*value) >> 10; 223ac6a4445SGunnar Mills } 224ac6a4445SGunnar Mills else if (property.first == "PmSizeInKiB") 225ac6a4445SGunnar Mills { 226ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 227ac6a4445SGunnar Mills if (value == nullptr) 228ac6a4445SGunnar Mills { 229ac6a4445SGunnar Mills messages::internalError(aResp->res); 230ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for PmSizeInKiB"; 231601af5edSChicago Duan return; 232ac6a4445SGunnar Mills } 233ac6a4445SGunnar Mills aResp->res.jsonValue["NonVolatileSizeMiB"] = (*value) >> 10; 234ac6a4445SGunnar Mills } 235ac6a4445SGunnar Mills else if (property.first == "CacheSizeInKB") 236ac6a4445SGunnar Mills { 237ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 238ac6a4445SGunnar Mills if (value == nullptr) 239ac6a4445SGunnar Mills { 240ac6a4445SGunnar Mills messages::internalError(aResp->res); 241ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for CacheSizeInKB"; 242601af5edSChicago Duan return; 243ac6a4445SGunnar Mills } 244ac6a4445SGunnar Mills aResp->res.jsonValue["CacheSizeMiB"] = (*value >> 10); 245ac6a4445SGunnar Mills } 246ac6a4445SGunnar Mills 247ac6a4445SGunnar Mills else if (property.first == "VoltaileRegionMaxSizeInKib") 248ac6a4445SGunnar Mills { 249ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 250ac6a4445SGunnar Mills 251ac6a4445SGunnar Mills if (value == nullptr) 252ac6a4445SGunnar Mills { 253ac6a4445SGunnar Mills messages::internalError(aResp->res); 254*0fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 255*0fda0f12SGeorge Liu << "Invalid property type for VolatileRegionMaxSizeInKib"; 256601af5edSChicago Duan return; 257ac6a4445SGunnar Mills } 258ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileRegionSizeMaxMiB"] = (*value) >> 10; 259ac6a4445SGunnar Mills } 260ac6a4445SGunnar Mills else if (property.first == "PmRegionMaxSizeInKiB") 261ac6a4445SGunnar Mills { 262ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 263ac6a4445SGunnar Mills 264ac6a4445SGunnar Mills if (value == nullptr) 265ac6a4445SGunnar Mills { 266ac6a4445SGunnar Mills messages::internalError(aResp->res); 267ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 268ac6a4445SGunnar Mills << "Invalid property type for PmRegionMaxSizeInKiB"; 269601af5edSChicago Duan return; 270ac6a4445SGunnar Mills } 271ac6a4445SGunnar Mills aResp->res.jsonValue["PersistentRegionSizeMaxMiB"] = (*value) >> 10; 272ac6a4445SGunnar Mills } 273ac6a4445SGunnar Mills else if (property.first == "AllocationIncrementInKiB") 274ac6a4445SGunnar Mills { 275ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 276ac6a4445SGunnar Mills 277ac6a4445SGunnar Mills if (value == nullptr) 278ac6a4445SGunnar Mills { 279ac6a4445SGunnar Mills messages::internalError(aResp->res); 280*0fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 281*0fda0f12SGeorge Liu << "Invalid property type for AllocationIncrementInKiB"; 282601af5edSChicago Duan return; 283ac6a4445SGunnar Mills } 284ac6a4445SGunnar Mills aResp->res.jsonValue["AllocationIncrementMiB"] = (*value) >> 10; 285ac6a4445SGunnar Mills } 286ac6a4445SGunnar Mills else if (property.first == "AllocationAlignmentInKiB") 287ac6a4445SGunnar Mills { 288ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 289ac6a4445SGunnar Mills 290ac6a4445SGunnar Mills if (value == nullptr) 291ac6a4445SGunnar Mills { 292ac6a4445SGunnar Mills messages::internalError(aResp->res); 293*0fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 294*0fda0f12SGeorge Liu << "Invalid property type for AllocationAlignmentInKiB"; 295601af5edSChicago Duan return; 296ac6a4445SGunnar Mills } 297ac6a4445SGunnar Mills aResp->res.jsonValue["AllocationAlignmentMiB"] = (*value) >> 10; 298ac6a4445SGunnar Mills } 299ac6a4445SGunnar Mills else if (property.first == "VolatileRegionNumberLimit") 300ac6a4445SGunnar Mills { 301ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 302ac6a4445SGunnar Mills if (value == nullptr) 303ac6a4445SGunnar Mills { 304ac6a4445SGunnar Mills messages::internalError(aResp->res); 305601af5edSChicago Duan return; 306ac6a4445SGunnar Mills } 307ac6a4445SGunnar Mills aResp->res.jsonValue["VolatileRegionNumberLimit"] = *value; 308ac6a4445SGunnar Mills } 309ac6a4445SGunnar Mills else if (property.first == "PmRegionNumberLimit") 310ac6a4445SGunnar Mills { 311ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 312ac6a4445SGunnar Mills if (value == nullptr) 313ac6a4445SGunnar Mills { 314ac6a4445SGunnar Mills messages::internalError(aResp->res); 315601af5edSChicago Duan return; 316ac6a4445SGunnar Mills } 317ac6a4445SGunnar Mills aResp->res.jsonValue["PersistentRegionNumberLimit"] = *value; 318ac6a4445SGunnar Mills } 319ac6a4445SGunnar Mills else if (property.first == "SpareDeviceCount") 320ac6a4445SGunnar Mills { 321ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 322ac6a4445SGunnar Mills if (value == nullptr) 323ac6a4445SGunnar Mills { 324ac6a4445SGunnar Mills messages::internalError(aResp->res); 325601af5edSChicago Duan return; 326ac6a4445SGunnar Mills } 327ac6a4445SGunnar Mills aResp->res.jsonValue["SpareDeviceCount"] = *value; 328ac6a4445SGunnar Mills } 329ac6a4445SGunnar Mills else if (property.first == "IsSpareDeviceInUse") 330ac6a4445SGunnar Mills { 331ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 332ac6a4445SGunnar Mills if (value == nullptr) 333ac6a4445SGunnar Mills { 334ac6a4445SGunnar Mills messages::internalError(aResp->res); 335601af5edSChicago Duan return; 336ac6a4445SGunnar Mills } 337ac6a4445SGunnar Mills aResp->res.jsonValue["IsSpareDeviceEnabled"] = *value; 338ac6a4445SGunnar Mills } 339ac6a4445SGunnar Mills else if (property.first == "IsRankSpareEnabled") 340ac6a4445SGunnar Mills { 341ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 342ac6a4445SGunnar Mills if (value == nullptr) 343ac6a4445SGunnar Mills { 344ac6a4445SGunnar Mills messages::internalError(aResp->res); 345601af5edSChicago Duan return; 346ac6a4445SGunnar Mills } 347ac6a4445SGunnar Mills aResp->res.jsonValue["IsRankSpareEnabled"] = *value; 348ac6a4445SGunnar Mills } 349ac6a4445SGunnar Mills else if (property.first == "MaxAveragePowerLimitmW") 350ac6a4445SGunnar Mills { 351ac6a4445SGunnar Mills const auto* value = 352ac6a4445SGunnar Mills std::get_if<std::vector<uint32_t>>(&property.second); 353ac6a4445SGunnar Mills if (value == nullptr) 354ac6a4445SGunnar Mills { 355ac6a4445SGunnar Mills messages::internalError(aResp->res); 356*0fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 357*0fda0f12SGeorge Liu << "Invalid property type for MaxAveragePowerLimitmW"; 358601af5edSChicago Duan return; 359ac6a4445SGunnar Mills } 360ac6a4445SGunnar Mills aResp->res.jsonValue["MaxTDPMilliWatts"] = *value; 361ac6a4445SGunnar Mills } 362ac6a4445SGunnar Mills else if (property.first == "ConfigurationLocked") 363ac6a4445SGunnar Mills { 364ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 365ac6a4445SGunnar Mills if (value == nullptr) 366ac6a4445SGunnar Mills { 367ac6a4445SGunnar Mills messages::internalError(aResp->res); 368601af5edSChicago Duan return; 369ac6a4445SGunnar Mills } 370ac6a4445SGunnar Mills aResp->res.jsonValue["ConfigurationLocked"] = *value; 371ac6a4445SGunnar Mills } 372ac6a4445SGunnar Mills else if (property.first == "AllowedMemoryModes") 373ac6a4445SGunnar Mills { 374ac6a4445SGunnar Mills const std::string* value = 375ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 376ac6a4445SGunnar Mills if (value == nullptr) 377ac6a4445SGunnar Mills { 378ac6a4445SGunnar Mills messages::internalError(aResp->res); 379ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for FormFactor"; 380601af5edSChicago Duan return; 381ac6a4445SGunnar Mills } 382ac6a4445SGunnar Mills constexpr const std::array<const char*, 3> values{"Volatile", 383ac6a4445SGunnar Mills "PMEM", "Block"}; 384ac6a4445SGunnar Mills 385ac6a4445SGunnar Mills for (const char* v : values) 386ac6a4445SGunnar Mills { 387ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 388ac6a4445SGunnar Mills { 389ac6a4445SGunnar Mills aResp->res.jsonValue["OperatingMemoryModes "] = v; 390ac6a4445SGunnar Mills break; 391ac6a4445SGunnar Mills } 392ac6a4445SGunnar Mills } 393ac6a4445SGunnar Mills } 394ac6a4445SGunnar Mills else if (property.first == "MemoryMedia") 395ac6a4445SGunnar Mills { 396ac6a4445SGunnar Mills const std::string* value = 397ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 398ac6a4445SGunnar Mills if (value == nullptr) 399ac6a4445SGunnar Mills { 400ac6a4445SGunnar Mills messages::internalError(aResp->res); 401ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for MemoryMedia"; 402601af5edSChicago Duan return; 403ac6a4445SGunnar Mills } 404ac6a4445SGunnar Mills constexpr const std::array<const char*, 3> values{"DRAM", "NAND", 405ac6a4445SGunnar Mills "Intel3DXPoint"}; 406ac6a4445SGunnar Mills 407ac6a4445SGunnar Mills for (const char* v : values) 408ac6a4445SGunnar Mills { 409ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 410ac6a4445SGunnar Mills { 411ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryMedia"] = v; 412ac6a4445SGunnar Mills break; 413ac6a4445SGunnar Mills } 414ac6a4445SGunnar Mills } 415ac6a4445SGunnar Mills } 416ac6a4445SGunnar Mills // PersistantMemory.SecurityCapabilites interface 417ac6a4445SGunnar Mills else if (property.first == "ConfigurationLockCapable" || 418ac6a4445SGunnar Mills property.first == "DataLockCapable" || 419ac6a4445SGunnar Mills property.first == "PassphraseCapable") 420ac6a4445SGunnar Mills { 421ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 422ac6a4445SGunnar Mills if (value == nullptr) 423ac6a4445SGunnar Mills { 424ac6a4445SGunnar Mills messages::internalError(aResp->res); 425601af5edSChicago Duan return; 426ac6a4445SGunnar Mills } 427ac6a4445SGunnar Mills aResp->res.jsonValue["SecurityCapabilities"][property.first] = 428ac6a4445SGunnar Mills *value; 429ac6a4445SGunnar Mills } 430ac6a4445SGunnar Mills else if (property.first == "MaxPassphraseCount" || 431ac6a4445SGunnar Mills property.first == "PassphraseLockLimit") 432ac6a4445SGunnar Mills { 433ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 434ac6a4445SGunnar Mills if (value == nullptr) 435ac6a4445SGunnar Mills { 436ac6a4445SGunnar Mills messages::internalError(aResp->res); 437601af5edSChicago Duan return; 438ac6a4445SGunnar Mills } 439ac6a4445SGunnar Mills aResp->res.jsonValue["SecurityCapabilities"][property.first] = 440ac6a4445SGunnar Mills *value; 441ac6a4445SGunnar Mills } 442ac6a4445SGunnar Mills } 443ac6a4445SGunnar Mills } 444ac6a4445SGunnar Mills 4458d1b46d7Szhanghch05 inline void getDimmDataByService(std::shared_ptr<bmcweb::AsyncResp> aResp, 446ac6a4445SGunnar Mills const std::string& dimmId, 447ac6a4445SGunnar Mills const std::string& service, 448ac6a4445SGunnar Mills const std::string& objPath) 449ac6a4445SGunnar Mills { 450ac6a4445SGunnar Mills auto health = std::make_shared<HealthPopulate>(aResp); 451ac6a4445SGunnar Mills health->selfPath = objPath; 452ac6a4445SGunnar Mills health->populate(); 453ac6a4445SGunnar Mills 454ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Get available system components."; 455ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 456ac6a4445SGunnar Mills [dimmId, aResp{std::move(aResp)}](const boost::system::error_code ec, 457ac6a4445SGunnar Mills const DimmProperties& properties) { 458ac6a4445SGunnar Mills if (ec) 459ac6a4445SGunnar Mills { 460ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 461ac6a4445SGunnar Mills messages::internalError(aResp->res); 462ac6a4445SGunnar Mills 463ac6a4445SGunnar Mills return; 464ac6a4445SGunnar Mills } 465ac6a4445SGunnar Mills aResp->res.jsonValue["Id"] = dimmId; 466ac6a4445SGunnar Mills aResp->res.jsonValue["Name"] = "DIMM Slot"; 467ac6a4445SGunnar Mills 468ac6a4445SGunnar Mills const auto memorySizeProperty = properties.find("MemorySizeInKB"); 469ac6a4445SGunnar Mills if (memorySizeProperty != properties.end()) 470ac6a4445SGunnar Mills { 471ac6a4445SGunnar Mills const uint32_t* memorySize = 472ac6a4445SGunnar Mills std::get_if<uint32_t>(&memorySizeProperty->second); 473ac6a4445SGunnar Mills if (memorySize == nullptr) 474ac6a4445SGunnar Mills { 475ac6a4445SGunnar Mills // Important property not in desired type 476ac6a4445SGunnar Mills messages::internalError(aResp->res); 477ac6a4445SGunnar Mills return; 478ac6a4445SGunnar Mills } 479ac6a4445SGunnar Mills aResp->res.jsonValue["CapacityMiB"] = (*memorySize >> 10); 480ac6a4445SGunnar Mills } 481ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["State"] = "Enabled"; 482ac6a4445SGunnar Mills aResp->res.jsonValue["Status"]["Health"] = "OK"; 483ac6a4445SGunnar Mills 484ac6a4445SGunnar Mills for (const auto& property : properties) 485ac6a4445SGunnar Mills { 486ac6a4445SGunnar Mills if (property.first == "MemoryDataWidth") 487ac6a4445SGunnar Mills { 488ac6a4445SGunnar Mills const uint16_t* value = 489ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 490ac6a4445SGunnar Mills if (value == nullptr) 491ac6a4445SGunnar Mills { 492ac6a4445SGunnar Mills continue; 493ac6a4445SGunnar Mills } 494ac6a4445SGunnar Mills aResp->res.jsonValue["DataWidthBits"] = *value; 495ac6a4445SGunnar Mills } 496ac6a4445SGunnar Mills else if (property.first == "PartNumber") 497ac6a4445SGunnar Mills { 498ac6a4445SGunnar Mills const std::string* value = 499ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 500ac6a4445SGunnar Mills if (value == nullptr) 501ac6a4445SGunnar Mills { 502ac6a4445SGunnar Mills continue; 503ac6a4445SGunnar Mills } 504ac6a4445SGunnar Mills aResp->res.jsonValue["PartNumber"] = *value; 505ac6a4445SGunnar Mills } 506ac6a4445SGunnar Mills else if (property.first == "SerialNumber") 507ac6a4445SGunnar Mills { 508ac6a4445SGunnar Mills const std::string* value = 509ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 510ac6a4445SGunnar Mills if (value == nullptr) 511ac6a4445SGunnar Mills { 512ac6a4445SGunnar Mills continue; 513ac6a4445SGunnar Mills } 514ac6a4445SGunnar Mills aResp->res.jsonValue["SerialNumber"] = *value; 515ac6a4445SGunnar Mills } 516ac6a4445SGunnar Mills else if (property.first == "Manufacturer") 517ac6a4445SGunnar Mills { 518ac6a4445SGunnar Mills const std::string* value = 519ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 520ac6a4445SGunnar Mills if (value == nullptr) 521ac6a4445SGunnar Mills { 522ac6a4445SGunnar Mills continue; 523ac6a4445SGunnar Mills } 524ac6a4445SGunnar Mills aResp->res.jsonValue["Manufacturer"] = *value; 525ac6a4445SGunnar Mills } 526ac6a4445SGunnar Mills else if (property.first == "RevisionCode") 527ac6a4445SGunnar Mills { 528ac6a4445SGunnar Mills const uint16_t* value = 529ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 530ac6a4445SGunnar Mills 531ac6a4445SGunnar Mills if (value == nullptr) 532ac6a4445SGunnar Mills { 533ac6a4445SGunnar Mills messages::internalError(aResp->res); 534ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 535ac6a4445SGunnar Mills << "Invalid property type for RevisionCode"; 536601af5edSChicago Duan return; 537ac6a4445SGunnar Mills } 538ac6a4445SGunnar Mills aResp->res.jsonValue["FirmwareRevision"] = 539ac6a4445SGunnar Mills std::to_string(*value); 540ac6a4445SGunnar Mills } 5419a128eb3SJoshi-Mansi else if (property.first == "Present") 5429a128eb3SJoshi-Mansi { 5439a128eb3SJoshi-Mansi const bool* value = std::get_if<bool>(&property.second); 5449a128eb3SJoshi-Mansi if (value == nullptr) 5459a128eb3SJoshi-Mansi { 5469a128eb3SJoshi-Mansi messages::internalError(aResp->res); 5479a128eb3SJoshi-Mansi BMCWEB_LOG_DEBUG 5489a128eb3SJoshi-Mansi << "Invalid property type for Dimm Presence"; 5499a128eb3SJoshi-Mansi return; 5509a128eb3SJoshi-Mansi } 5519a128eb3SJoshi-Mansi if (*value == false) 5529a128eb3SJoshi-Mansi { 5539a128eb3SJoshi-Mansi aResp->res.jsonValue["Status"]["State"] = "Absent"; 5549a128eb3SJoshi-Mansi } 5559a128eb3SJoshi-Mansi } 556ac6a4445SGunnar Mills else if (property.first == "MemoryTotalWidth") 557ac6a4445SGunnar Mills { 558ac6a4445SGunnar Mills const uint16_t* value = 559ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 560ac6a4445SGunnar Mills if (value == nullptr) 561ac6a4445SGunnar Mills { 562ac6a4445SGunnar Mills continue; 563ac6a4445SGunnar Mills } 564ac6a4445SGunnar Mills aResp->res.jsonValue["BusWidthBits"] = *value; 565ac6a4445SGunnar Mills } 566ac6a4445SGunnar Mills else if (property.first == "ECC") 567ac6a4445SGunnar Mills { 568ac6a4445SGunnar Mills const std::string* value = 569ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 570ac6a4445SGunnar Mills if (value == nullptr) 571ac6a4445SGunnar Mills { 572ac6a4445SGunnar Mills messages::internalError(aResp->res); 573ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for ECC"; 574601af5edSChicago Duan return; 575ac6a4445SGunnar Mills } 576ac6a4445SGunnar Mills constexpr const std::array<const char*, 4> values{ 577ac6a4445SGunnar Mills "NoECC", "SingleBitECC", "MultiBitECC", 578ac6a4445SGunnar Mills "AddressParity"}; 579ac6a4445SGunnar Mills 580ac6a4445SGunnar Mills for (const char* v : values) 581ac6a4445SGunnar Mills { 582ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 583ac6a4445SGunnar Mills { 584ac6a4445SGunnar Mills aResp->res.jsonValue["ErrorCorrection"] = v; 585ac6a4445SGunnar Mills break; 586ac6a4445SGunnar Mills } 587ac6a4445SGunnar Mills } 588ac6a4445SGunnar Mills } 589ac6a4445SGunnar Mills else if (property.first == "FormFactor") 590ac6a4445SGunnar Mills { 591ac6a4445SGunnar Mills const std::string* value = 592ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 593ac6a4445SGunnar Mills if (value == nullptr) 594ac6a4445SGunnar Mills { 595ac6a4445SGunnar Mills messages::internalError(aResp->res); 596ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 597ac6a4445SGunnar Mills << "Invalid property type for FormFactor"; 598601af5edSChicago Duan return; 599ac6a4445SGunnar Mills } 600ac6a4445SGunnar Mills constexpr const std::array<const char*, 11> values{ 601ac6a4445SGunnar Mills "RDIMM", "UDIMM", "SO_DIMM", 602ac6a4445SGunnar Mills "LRDIMM", "Mini_RDIMM", "Mini_UDIMM", 603ac6a4445SGunnar Mills "SO_RDIMM_72b", "SO_UDIMM_72b", "SO_DIMM_16b", 604ac6a4445SGunnar Mills "SO_DIMM_32b", "Die"}; 605ac6a4445SGunnar Mills 606ac6a4445SGunnar Mills for (const char* v : values) 607ac6a4445SGunnar Mills { 608ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 609ac6a4445SGunnar Mills { 610ac6a4445SGunnar Mills aResp->res.jsonValue["BaseModuleType"] = v; 611ac6a4445SGunnar Mills break; 612ac6a4445SGunnar Mills } 613ac6a4445SGunnar Mills } 614ac6a4445SGunnar Mills } 615ac6a4445SGunnar Mills else if (property.first == "AllowedSpeedsMT") 616ac6a4445SGunnar Mills { 617ac6a4445SGunnar Mills const std::vector<uint16_t>* value = 618ac6a4445SGunnar Mills std::get_if<std::vector<uint16_t>>(&property.second); 619ac6a4445SGunnar Mills if (value == nullptr) 620ac6a4445SGunnar Mills { 621ac6a4445SGunnar Mills continue; 622ac6a4445SGunnar Mills } 623ac6a4445SGunnar Mills nlohmann::json& jValue = 624ac6a4445SGunnar Mills aResp->res.jsonValue["AllowedSpeedsMHz"]; 625ac6a4445SGunnar Mills jValue = nlohmann::json::array(); 626ac6a4445SGunnar Mills for (uint16_t subVal : *value) 627ac6a4445SGunnar Mills { 628ac6a4445SGunnar Mills jValue.push_back(subVal); 629ac6a4445SGunnar Mills } 630ac6a4445SGunnar Mills } 631ac6a4445SGunnar Mills else if (property.first == "MemoryAttributes") 632ac6a4445SGunnar Mills { 633ac6a4445SGunnar Mills const uint8_t* value = 634ac6a4445SGunnar Mills std::get_if<uint8_t>(&property.second); 635ac6a4445SGunnar Mills 636ac6a4445SGunnar Mills if (value == nullptr) 637ac6a4445SGunnar Mills { 638ac6a4445SGunnar Mills messages::internalError(aResp->res); 639ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 640ac6a4445SGunnar Mills << "Invalid property type for MemoryAttributes"; 641601af5edSChicago Duan return; 642ac6a4445SGunnar Mills } 643ac6a4445SGunnar Mills aResp->res.jsonValue["RankCount"] = 644ac6a4445SGunnar Mills static_cast<uint64_t>(*value); 645ac6a4445SGunnar Mills } 646ac6a4445SGunnar Mills else if (property.first == "MemoryConfiguredSpeedInMhz") 647ac6a4445SGunnar Mills { 648ac6a4445SGunnar Mills const uint16_t* value = 649ac6a4445SGunnar Mills std::get_if<uint16_t>(&property.second); 650ac6a4445SGunnar Mills if (value == nullptr) 651ac6a4445SGunnar Mills { 652ac6a4445SGunnar Mills continue; 653ac6a4445SGunnar Mills } 654ac6a4445SGunnar Mills aResp->res.jsonValue["OperatingSpeedMhz"] = *value; 655ac6a4445SGunnar Mills } 656ac6a4445SGunnar Mills else if (property.first == "MemoryType") 657ac6a4445SGunnar Mills { 658ac6a4445SGunnar Mills const auto* value = 659ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 660ac6a4445SGunnar Mills if (value != nullptr) 661ac6a4445SGunnar Mills { 662313efb1cSGunnar Mills std::string memoryDeviceType = 663313efb1cSGunnar Mills translateMemoryTypeToRedfish(*value); 664313efb1cSGunnar Mills // Values like "Unknown" or "Other" will return empty 665313efb1cSGunnar Mills // so just leave off 666313efb1cSGunnar Mills if (!memoryDeviceType.empty()) 667ac6a4445SGunnar Mills { 668313efb1cSGunnar Mills aResp->res.jsonValue["MemoryDeviceType"] = 669313efb1cSGunnar Mills memoryDeviceType; 670ac6a4445SGunnar Mills } 671ac6a4445SGunnar Mills if (value->find("DDR") != std::string::npos) 672ac6a4445SGunnar Mills { 673ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryType"] = "DRAM"; 674ac6a4445SGunnar Mills } 675ac6a4445SGunnar Mills else if (boost::ends_with(*value, "Logical")) 676ac6a4445SGunnar Mills { 677ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryType"] = "IntelOptane"; 678ac6a4445SGunnar Mills } 679ac6a4445SGunnar Mills } 680ac6a4445SGunnar Mills } 681ac6a4445SGunnar Mills // memory location interface 682ac6a4445SGunnar Mills else if (property.first == "Channel" || 683ac6a4445SGunnar Mills property.first == "MemoryController" || 684ac6a4445SGunnar Mills property.first == "Slot" || property.first == "Socket") 685ac6a4445SGunnar Mills { 686ac6a4445SGunnar Mills const std::string* value = 687ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 688ac6a4445SGunnar Mills if (value == nullptr) 689ac6a4445SGunnar Mills { 690ac6a4445SGunnar Mills messages::internalError(aResp->res); 691601af5edSChicago Duan return; 692ac6a4445SGunnar Mills } 693ac6a4445SGunnar Mills aResp->res.jsonValue["MemoryLocation"][property.first] = 694ac6a4445SGunnar Mills *value; 695ac6a4445SGunnar Mills } 696ee135e24SSunnySrivastava1984 else if (property.first == "SparePartNumber") 697ee135e24SSunnySrivastava1984 { 698ee135e24SSunnySrivastava1984 const std::string* value = 699ee135e24SSunnySrivastava1984 std::get_if<std::string>(&property.second); 700ee135e24SSunnySrivastava1984 if (value == nullptr) 701ee135e24SSunnySrivastava1984 { 702ee135e24SSunnySrivastava1984 messages::internalError(aResp->res); 703601af5edSChicago Duan return; 704ee135e24SSunnySrivastava1984 } 705ee135e24SSunnySrivastava1984 aResp->res.jsonValue["SparePartNumber"] = *value; 706ee135e24SSunnySrivastava1984 } 707ee135e24SSunnySrivastava1984 else if (property.first == "Model") 708ee135e24SSunnySrivastava1984 { 709ee135e24SSunnySrivastava1984 const std::string* value = 710ee135e24SSunnySrivastava1984 std::get_if<std::string>(&property.second); 711ee135e24SSunnySrivastava1984 if (value == nullptr) 712ee135e24SSunnySrivastava1984 { 713ee135e24SSunnySrivastava1984 messages::internalError(aResp->res); 714601af5edSChicago Duan return; 715ee135e24SSunnySrivastava1984 } 716ee135e24SSunnySrivastava1984 aResp->res.jsonValue["Model"] = *value; 717ee135e24SSunnySrivastava1984 } 718ee135e24SSunnySrivastava1984 else if (property.first == "LocationCode") 719ee135e24SSunnySrivastava1984 { 720ee135e24SSunnySrivastava1984 const std::string* value = 721ee135e24SSunnySrivastava1984 std::get_if<std::string>(&property.second); 722ee135e24SSunnySrivastava1984 if (value == nullptr) 723ee135e24SSunnySrivastava1984 { 724ee135e24SSunnySrivastava1984 messages::internalError(aResp->res); 725601af5edSChicago Duan return; 726ee135e24SSunnySrivastava1984 } 727ee135e24SSunnySrivastava1984 aResp->res 728ee135e24SSunnySrivastava1984 .jsonValue["Location"]["PartLocation"]["ServiceLabel"] = 729ee135e24SSunnySrivastava1984 *value; 730ee135e24SSunnySrivastava1984 } 731ac6a4445SGunnar Mills else 732ac6a4445SGunnar Mills { 733ac6a4445SGunnar Mills getPersistentMemoryProperties(aResp, properties); 734ac6a4445SGunnar Mills } 735ac6a4445SGunnar Mills } 736ac6a4445SGunnar Mills }, 737ac6a4445SGunnar Mills service, objPath, "org.freedesktop.DBus.Properties", "GetAll", ""); 738ac6a4445SGunnar Mills } 739ac6a4445SGunnar Mills 7408d1b46d7Szhanghch05 inline void getDimmPartitionData(std::shared_ptr<bmcweb::AsyncResp> aResp, 741ac6a4445SGunnar Mills const std::string& service, 742ac6a4445SGunnar Mills const std::string& path) 743ac6a4445SGunnar Mills { 744ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 745ac6a4445SGunnar Mills [aResp{std::move(aResp)}]( 746ac6a4445SGunnar Mills const boost::system::error_code ec, 747ac6a4445SGunnar Mills const boost::container::flat_map< 748ac6a4445SGunnar Mills std::string, std::variant<std::string, uint64_t, uint32_t, 749ac6a4445SGunnar Mills bool>>& properties) { 750ac6a4445SGunnar Mills if (ec) 751ac6a4445SGunnar Mills { 752ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 753ac6a4445SGunnar Mills messages::internalError(aResp->res); 754ac6a4445SGunnar Mills 755ac6a4445SGunnar Mills return; 756ac6a4445SGunnar Mills } 757ac6a4445SGunnar Mills 758ac6a4445SGunnar Mills nlohmann::json& partition = 759ac6a4445SGunnar Mills aResp->res.jsonValue["Regions"].emplace_back( 760ac6a4445SGunnar Mills nlohmann::json::object()); 761ac6a4445SGunnar Mills for (const auto& [key, val] : properties) 762ac6a4445SGunnar Mills { 763ac6a4445SGunnar Mills if (key == "MemoryClassification") 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); 769601af5edSChicago Duan return; 770ac6a4445SGunnar Mills } 771ac6a4445SGunnar Mills partition[key] = *value; 772ac6a4445SGunnar Mills } 773ac6a4445SGunnar Mills else if (key == "OffsetInKiB") 774ac6a4445SGunnar Mills { 775ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&val); 776ac6a4445SGunnar Mills if (value == nullptr) 777ac6a4445SGunnar Mills { 778ac6a4445SGunnar Mills messages::internalError(aResp->res); 779601af5edSChicago Duan return; 780ac6a4445SGunnar Mills } 781ac6a4445SGunnar Mills 782ac6a4445SGunnar Mills partition["OffsetMiB"] = (*value >> 10); 783ac6a4445SGunnar Mills } 784ac6a4445SGunnar Mills else if (key == "PartitionId") 785ac6a4445SGunnar Mills { 786ac6a4445SGunnar Mills const std::string* value = std::get_if<std::string>(&val); 787ac6a4445SGunnar Mills if (value == nullptr) 788ac6a4445SGunnar Mills { 789ac6a4445SGunnar Mills messages::internalError(aResp->res); 790601af5edSChicago Duan return; 791ac6a4445SGunnar Mills } 792ac6a4445SGunnar Mills partition["RegionId"] = *value; 793ac6a4445SGunnar Mills } 794ac6a4445SGunnar Mills 795ac6a4445SGunnar Mills else if (key == "PassphraseState") 796ac6a4445SGunnar Mills { 797ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&val); 798ac6a4445SGunnar Mills if (value == nullptr) 799ac6a4445SGunnar Mills { 800ac6a4445SGunnar Mills messages::internalError(aResp->res); 801601af5edSChicago Duan return; 802ac6a4445SGunnar Mills } 803ac6a4445SGunnar Mills partition["PassphraseEnabled"] = *value; 804ac6a4445SGunnar Mills } 805ac6a4445SGunnar Mills else if (key == "SizeInKiB") 806ac6a4445SGunnar Mills { 807ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&val); 808ac6a4445SGunnar Mills if (value == nullptr) 809ac6a4445SGunnar Mills { 810ac6a4445SGunnar Mills messages::internalError(aResp->res); 811ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 812ac6a4445SGunnar Mills << "Invalid property type for SizeInKiB"; 813601af5edSChicago Duan return; 814ac6a4445SGunnar Mills } 815ac6a4445SGunnar Mills partition["SizeMiB"] = (*value >> 10); 816ac6a4445SGunnar Mills } 817ac6a4445SGunnar Mills } 818ac6a4445SGunnar Mills }, 819ac6a4445SGunnar Mills 820ac6a4445SGunnar Mills service, path, "org.freedesktop.DBus.Properties", "GetAll", 821ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"); 822ac6a4445SGunnar Mills } 823ac6a4445SGunnar Mills 8248d1b46d7Szhanghch05 inline void getDimmData(std::shared_ptr<bmcweb::AsyncResp> aResp, 825ac6a4445SGunnar Mills const std::string& dimmId) 826ac6a4445SGunnar Mills { 827ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Get available system dimm resources."; 828ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 829ac6a4445SGunnar Mills [dimmId, aResp{std::move(aResp)}]( 830ac6a4445SGunnar Mills const boost::system::error_code ec, 831ac6a4445SGunnar Mills const boost::container::flat_map< 832ac6a4445SGunnar Mills std::string, boost::container::flat_map< 833ac6a4445SGunnar Mills std::string, std::vector<std::string>>>& 834ac6a4445SGunnar Mills subtree) { 835ac6a4445SGunnar Mills if (ec) 836ac6a4445SGunnar Mills { 837ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 838ac6a4445SGunnar Mills messages::internalError(aResp->res); 839ac6a4445SGunnar Mills 840ac6a4445SGunnar Mills return; 841ac6a4445SGunnar Mills } 842ac6a4445SGunnar Mills bool found = false; 843ac6a4445SGunnar Mills for (const auto& [path, object] : subtree) 844ac6a4445SGunnar Mills { 845ac6a4445SGunnar Mills if (path.find(dimmId) != std::string::npos) 846ac6a4445SGunnar Mills { 847ac6a4445SGunnar Mills for (const auto& [service, interfaces] : object) 848ac6a4445SGunnar Mills { 849ac6a4445SGunnar Mills if (!found && 850ac6a4445SGunnar Mills (std::find( 851ac6a4445SGunnar Mills interfaces.begin(), interfaces.end(), 852ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm") != 853ac6a4445SGunnar Mills interfaces.end())) 854ac6a4445SGunnar Mills { 855ac6a4445SGunnar Mills getDimmDataByService(aResp, dimmId, service, path); 856ac6a4445SGunnar Mills found = true; 857ac6a4445SGunnar Mills } 858ac6a4445SGunnar Mills 859ac6a4445SGunnar Mills // partitions are separate as there can be multiple per 860ac6a4445SGunnar Mills // device, i.e. 861ac6a4445SGunnar Mills // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1 862ac6a4445SGunnar Mills // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2 863*0fda0f12SGeorge Liu if (std::find( 864*0fda0f12SGeorge Liu interfaces.begin(), interfaces.end(), 865*0fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition") != 866ac6a4445SGunnar Mills interfaces.end()) 867ac6a4445SGunnar Mills { 868ac6a4445SGunnar Mills getDimmPartitionData(aResp, service, path); 869ac6a4445SGunnar Mills } 870ac6a4445SGunnar Mills } 871ac6a4445SGunnar Mills } 872ac6a4445SGunnar Mills } 873ac6a4445SGunnar Mills // Object not found 874ac6a4445SGunnar Mills if (!found) 875ac6a4445SGunnar Mills { 876ac6a4445SGunnar Mills messages::resourceNotFound(aResp->res, "Memory", dimmId); 877ac6a4445SGunnar Mills } 878ac6a4445SGunnar Mills return; 879ac6a4445SGunnar Mills }, 880ac6a4445SGunnar Mills "xyz.openbmc_project.ObjectMapper", 881ac6a4445SGunnar Mills "/xyz/openbmc_project/object_mapper", 882ac6a4445SGunnar Mills "xyz.openbmc_project.ObjectMapper", "GetSubTree", 883ac6a4445SGunnar Mills "/xyz/openbmc_project/inventory", 0, 884ac6a4445SGunnar Mills std::array<const char*, 2>{ 885ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm", 886ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"}); 887ac6a4445SGunnar Mills } 888ac6a4445SGunnar Mills 8897e860f15SJohn Edward Broadbent inline void requestRoutesMemoryCollection(App& app) 890ac6a4445SGunnar Mills { 891ac6a4445SGunnar Mills /** 892ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 893ac6a4445SGunnar Mills */ 8947e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Memory/") 895ed398213SEd Tanous .privileges(redfish::privileges::getMemoryCollection) 8967e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 8977e860f15SJohn Edward Broadbent [](const crow::Request&, 8987e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 8998d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 9008d1b46d7Szhanghch05 "#MemoryCollection.MemoryCollection"; 9018d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Memory Module Collection"; 9028d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = 9038d1b46d7Szhanghch05 "/redfish/v1/Systems/system/Memory"; 904ac6a4445SGunnar Mills 90505030b8eSGunnar Mills collection_util::getCollectionMembers( 90605030b8eSGunnar Mills asyncResp, "/redfish/v1/Systems/system/Memory", 90705030b8eSGunnar Mills {"xyz.openbmc_project.Inventory.Item.Dimm"}); 9087e860f15SJohn Edward Broadbent }); 909ac6a4445SGunnar Mills } 910ac6a4445SGunnar Mills 9117e860f15SJohn Edward Broadbent inline void requestRoutesMemory(App& app) 9127e860f15SJohn Edward Broadbent { 913ac6a4445SGunnar Mills /** 914ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 915ac6a4445SGunnar Mills */ 9167e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Memory/<str>/") 917ed398213SEd Tanous .privileges(redfish::privileges::getMemory) 9187e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 9197e860f15SJohn Edward Broadbent [](const crow::Request&, 9207e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 9217e860f15SJohn Edward Broadbent const std::string& dimmId) { 9227e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["@odata.type"] = 9237e860f15SJohn Edward Broadbent "#Memory.v1_11_0.Memory"; 9248d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = 925ac6a4445SGunnar Mills "/redfish/v1/Systems/system/Memory/" + dimmId; 926ac6a4445SGunnar Mills 927ac6a4445SGunnar Mills getDimmData(asyncResp, dimmId); 9287e860f15SJohn Edward Broadbent }); 929ac6a4445SGunnar Mills } 930ac6a4445SGunnar Mills 931ac6a4445SGunnar Mills } // namespace redfish 932