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> 217267c21dSSui Chen #include <boost/algorithm/string.hpp> 22168e20c1SEd Tanous #include <dbus_utility.hpp> 23d7f04fd9SNan Zhou #include <nlohmann/json.hpp> 2445ca1b86SEd Tanous #include <query.hpp> 25ed398213SEd Tanous #include <registries/privilege_registry.hpp> 26ac6a4445SGunnar Mills #include <utils/collection.hpp> 27f201ffb4SEd Tanous #include <utils/hex_utils.hpp> 28ac6a4445SGunnar Mills #include <utils/json_utils.hpp> 29ac6a4445SGunnar Mills 30ac6a4445SGunnar Mills namespace redfish 31ac6a4445SGunnar Mills { 32ac6a4445SGunnar Mills 33313efb1cSGunnar Mills inline std::string translateMemoryTypeToRedfish(const std::string& memoryType) 34313efb1cSGunnar Mills { 35313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR") 36313efb1cSGunnar Mills { 37313efb1cSGunnar Mills return "DDR"; 38313efb1cSGunnar Mills } 39313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2") 40313efb1cSGunnar Mills { 41313efb1cSGunnar Mills return "DDR2"; 42313efb1cSGunnar Mills } 43313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR3") 44313efb1cSGunnar Mills { 45313efb1cSGunnar Mills return "DDR3"; 46313efb1cSGunnar Mills } 47313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4") 48313efb1cSGunnar Mills { 49313efb1cSGunnar Mills return "DDR4"; 50313efb1cSGunnar Mills } 51313efb1cSGunnar Mills if (memoryType == 52313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4E_SDRAM") 53313efb1cSGunnar Mills { 54313efb1cSGunnar Mills return "DDR4E_SDRAM"; 55313efb1cSGunnar Mills } 5611a2f0f0SMansi Joshi if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR5") 5711a2f0f0SMansi Joshi { 5811a2f0f0SMansi Joshi return "DDR5"; 5911a2f0f0SMansi Joshi } 60313efb1cSGunnar Mills if (memoryType == 61313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR4_SDRAM") 62313efb1cSGunnar Mills { 63313efb1cSGunnar Mills return "LPDDR4_SDRAM"; 64313efb1cSGunnar Mills } 65313efb1cSGunnar Mills if (memoryType == 66313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR3_SDRAM") 67313efb1cSGunnar Mills { 68313efb1cSGunnar Mills return "LPDDR3_SDRAM"; 69313efb1cSGunnar Mills } 70313efb1cSGunnar Mills if (memoryType == 71313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM") 72313efb1cSGunnar Mills { 73313efb1cSGunnar Mills return "DDR2_SDRAM_FB_DIMM"; 74313efb1cSGunnar Mills } 750fda0f12SGeorge Liu if (memoryType == 760fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM_PROB") 77313efb1cSGunnar Mills { 78313efb1cSGunnar Mills return "DDR2_SDRAM_FB_DIMM_PROBE"; 79313efb1cSGunnar Mills } 80313efb1cSGunnar Mills if (memoryType == 81313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR_SGRAM") 82313efb1cSGunnar Mills { 83313efb1cSGunnar Mills return "DDR_SGRAM"; 84313efb1cSGunnar Mills } 85313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.ROM") 86313efb1cSGunnar Mills { 87313efb1cSGunnar Mills return "ROM"; 88313efb1cSGunnar Mills } 89313efb1cSGunnar Mills if (memoryType == 90313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.SDRAM") 91313efb1cSGunnar Mills { 92313efb1cSGunnar Mills return "SDRAM"; 93313efb1cSGunnar Mills } 94313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.EDO") 95313efb1cSGunnar Mills { 96313efb1cSGunnar Mills return "EDO"; 97313efb1cSGunnar Mills } 98313efb1cSGunnar Mills if (memoryType == 99313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.FastPageMode") 100313efb1cSGunnar Mills { 101313efb1cSGunnar Mills return "FastPageMode"; 102313efb1cSGunnar Mills } 103313efb1cSGunnar Mills if (memoryType == 104313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.PipelinedNibble") 105313efb1cSGunnar Mills { 106313efb1cSGunnar Mills return "PipelinedNibble"; 107313efb1cSGunnar Mills } 108313efb1cSGunnar Mills if (memoryType == 109313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.Logical") 110313efb1cSGunnar Mills { 111313efb1cSGunnar Mills return "Logical"; 112313efb1cSGunnar Mills } 113313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM") 114313efb1cSGunnar Mills { 115313efb1cSGunnar Mills return "HBM"; 116313efb1cSGunnar Mills } 117313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM2") 118313efb1cSGunnar Mills { 119313efb1cSGunnar Mills return "HBM2"; 120313efb1cSGunnar Mills } 121313efb1cSGunnar Mills // This is values like Other or Unknown 122313efb1cSGunnar Mills // Also D-Bus values: 123313efb1cSGunnar Mills // DRAM 124313efb1cSGunnar Mills // EDRAM 125313efb1cSGunnar Mills // VRAM 126313efb1cSGunnar Mills // SRAM 127313efb1cSGunnar Mills // RAM 128313efb1cSGunnar Mills // FLASH 129313efb1cSGunnar Mills // EEPROM 130313efb1cSGunnar Mills // FEPROM 131313efb1cSGunnar Mills // EPROM 132313efb1cSGunnar Mills // CDRAM 133313efb1cSGunnar Mills // ThreeDRAM 134313efb1cSGunnar Mills // RDRAM 135313efb1cSGunnar Mills // FBD2 136313efb1cSGunnar Mills // LPDDR_SDRAM 137313efb1cSGunnar Mills // LPDDR2_SDRAM 13811a2f0f0SMansi Joshi // LPDDR5_SDRAM 139313efb1cSGunnar Mills return ""; 140313efb1cSGunnar Mills } 141313efb1cSGunnar Mills 142168e20c1SEd Tanous inline void dimmPropToHex( 143168e20c1SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& aResp, const char* key, 144d7f04fd9SNan Zhou const std::pair<std::string, dbus::utility::DbusVariantType>& property, 145d7f04fd9SNan Zhou const nlohmann::json::json_pointer& jsonPtr) 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 } 154d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr][key] = "0x" + intToHexString(*value, 4); 155ac6a4445SGunnar Mills } 156ac6a4445SGunnar Mills 1578d1b46d7Szhanghch05 inline void getPersistentMemoryProperties( 1588d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aResp, 159d7f04fd9SNan Zhou const std::pair<std::string, dbus::utility::DbusVariantType>& property, 160d7f04fd9SNan Zhou const nlohmann::json::json_pointer& jsonPtr) 161ac6a4445SGunnar Mills { 162ac6a4445SGunnar Mills if (property.first == "ModuleManufacturerID") 163ac6a4445SGunnar Mills { 164d7f04fd9SNan Zhou dimmPropToHex(aResp, "ModuleManufacturerID", property, jsonPtr); 165ac6a4445SGunnar Mills } 166ac6a4445SGunnar Mills else if (property.first == "ModuleProductID") 167ac6a4445SGunnar Mills { 168d7f04fd9SNan Zhou dimmPropToHex(aResp, "ModuleProductID", property, jsonPtr); 169ac6a4445SGunnar Mills } 170ac6a4445SGunnar Mills else if (property.first == "SubsystemVendorID") 171ac6a4445SGunnar Mills { 172ac6a4445SGunnar Mills dimmPropToHex(aResp, "MemorySubsystemControllerManufacturerID", 173d7f04fd9SNan Zhou property, jsonPtr); 174ac6a4445SGunnar Mills } 175ac6a4445SGunnar Mills else if (property.first == "SubsystemDeviceID") 176ac6a4445SGunnar Mills { 177d7f04fd9SNan Zhou dimmPropToHex(aResp, "MemorySubsystemControllerProductID", property, 178d7f04fd9SNan Zhou jsonPtr); 179ac6a4445SGunnar Mills } 180ac6a4445SGunnar Mills else if (property.first == "VolatileRegionSizeLimitInKiB") 181ac6a4445SGunnar Mills { 182ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 183ac6a4445SGunnar Mills 184ac6a4445SGunnar Mills if (value == nullptr) 185ac6a4445SGunnar Mills { 186ac6a4445SGunnar Mills messages::internalError(aResp->res); 1870fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 1880fda0f12SGeorge Liu << "Invalid property type for VolatileRegionSizeLimitKiB"; 189601af5edSChicago Duan return; 190ac6a4445SGunnar Mills } 191d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["VolatileRegionSizeLimitMiB"] = 192d7f04fd9SNan Zhou (*value) >> 10; 193ac6a4445SGunnar Mills } 194ac6a4445SGunnar Mills else if (property.first == "PmRegionSizeLimitInKiB") 195ac6a4445SGunnar Mills { 196ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 197ac6a4445SGunnar Mills 198ac6a4445SGunnar Mills if (value == nullptr) 199ac6a4445SGunnar Mills { 200ac6a4445SGunnar Mills messages::internalError(aResp->res); 20180badf7cSJiaqing Zhao BMCWEB_LOG_DEBUG << "Invalid property type for PmRegioSizeLimitKiB"; 202601af5edSChicago Duan return; 203ac6a4445SGunnar Mills } 204d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["PersistentRegionSizeLimitMiB"] = 205d7f04fd9SNan Zhou (*value) >> 10; 206ac6a4445SGunnar Mills } 207ac6a4445SGunnar Mills else if (property.first == "VolatileSizeInKiB") 208ac6a4445SGunnar Mills { 209ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 210ac6a4445SGunnar Mills 211ac6a4445SGunnar Mills if (value == nullptr) 212ac6a4445SGunnar Mills { 213ac6a4445SGunnar Mills messages::internalError(aResp->res); 21480badf7cSJiaqing Zhao BMCWEB_LOG_DEBUG << "Invalid property type for VolatileSizeInKiB"; 215601af5edSChicago Duan return; 216ac6a4445SGunnar Mills } 217d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["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 } 228d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["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 } 239d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["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); 2490fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 2500fda0f12SGeorge Liu << "Invalid property type for VolatileRegionMaxSizeInKib"; 251601af5edSChicago Duan return; 252ac6a4445SGunnar Mills } 253d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["VolatileRegionSizeMaxMiB"] = 254d7f04fd9SNan Zhou (*value) >> 10; 255ac6a4445SGunnar Mills } 256ac6a4445SGunnar Mills else if (property.first == "PmRegionMaxSizeInKiB") 257ac6a4445SGunnar Mills { 258ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 259ac6a4445SGunnar Mills 260ac6a4445SGunnar Mills if (value == nullptr) 261ac6a4445SGunnar Mills { 262ac6a4445SGunnar Mills messages::internalError(aResp->res); 263ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 264ac6a4445SGunnar Mills << "Invalid property type for PmRegionMaxSizeInKiB"; 265601af5edSChicago Duan return; 266ac6a4445SGunnar Mills } 267d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["PersistentRegionSizeMaxMiB"] = 268d7f04fd9SNan Zhou (*value) >> 10; 269ac6a4445SGunnar Mills } 270ac6a4445SGunnar Mills else if (property.first == "AllocationIncrementInKiB") 271ac6a4445SGunnar Mills { 272ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 273ac6a4445SGunnar Mills 274ac6a4445SGunnar Mills if (value == nullptr) 275ac6a4445SGunnar Mills { 276ac6a4445SGunnar Mills messages::internalError(aResp->res); 2770fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 2780fda0f12SGeorge Liu << "Invalid property type for AllocationIncrementInKiB"; 279601af5edSChicago Duan return; 280ac6a4445SGunnar Mills } 281d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["AllocationIncrementMiB"] = 282d7f04fd9SNan Zhou (*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 } 295d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["AllocationAlignmentMiB"] = 296d7f04fd9SNan Zhou (*value) >> 10; 297ac6a4445SGunnar Mills } 298ac6a4445SGunnar Mills else if (property.first == "VolatileRegionNumberLimit") 299ac6a4445SGunnar Mills { 300ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 301ac6a4445SGunnar Mills if (value == nullptr) 302ac6a4445SGunnar Mills { 303ac6a4445SGunnar Mills messages::internalError(aResp->res); 304601af5edSChicago Duan return; 305ac6a4445SGunnar Mills } 306d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["VolatileRegionNumberLimit"] = *value; 307ac6a4445SGunnar Mills } 308ac6a4445SGunnar Mills else if (property.first == "PmRegionNumberLimit") 309ac6a4445SGunnar Mills { 310ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 311ac6a4445SGunnar Mills if (value == nullptr) 312ac6a4445SGunnar Mills { 313ac6a4445SGunnar Mills messages::internalError(aResp->res); 314601af5edSChicago Duan return; 315ac6a4445SGunnar Mills } 316d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["PersistentRegionNumberLimit"] = *value; 317ac6a4445SGunnar Mills } 318ac6a4445SGunnar Mills else if (property.first == "SpareDeviceCount") 319ac6a4445SGunnar Mills { 320ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&property.second); 321ac6a4445SGunnar Mills if (value == nullptr) 322ac6a4445SGunnar Mills { 323ac6a4445SGunnar Mills messages::internalError(aResp->res); 324601af5edSChicago Duan return; 325ac6a4445SGunnar Mills } 326d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["SpareDeviceCount"] = *value; 327ac6a4445SGunnar Mills } 328ac6a4445SGunnar Mills else if (property.first == "IsSpareDeviceInUse") 329ac6a4445SGunnar Mills { 330ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 331ac6a4445SGunnar Mills if (value == nullptr) 332ac6a4445SGunnar Mills { 333ac6a4445SGunnar Mills messages::internalError(aResp->res); 334601af5edSChicago Duan return; 335ac6a4445SGunnar Mills } 336d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["IsSpareDeviceEnabled"] = *value; 337ac6a4445SGunnar Mills } 338ac6a4445SGunnar Mills else if (property.first == "IsRankSpareEnabled") 339ac6a4445SGunnar Mills { 340ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 341ac6a4445SGunnar Mills if (value == nullptr) 342ac6a4445SGunnar Mills { 343ac6a4445SGunnar Mills messages::internalError(aResp->res); 344601af5edSChicago Duan return; 345ac6a4445SGunnar Mills } 346d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["IsRankSpareEnabled"] = *value; 347ac6a4445SGunnar Mills } 348ac6a4445SGunnar Mills else if (property.first == "MaxAveragePowerLimitmW") 349ac6a4445SGunnar Mills { 350ac6a4445SGunnar Mills const auto* value = 351ac6a4445SGunnar Mills std::get_if<std::vector<uint32_t>>(&property.second); 352ac6a4445SGunnar Mills if (value == nullptr) 353ac6a4445SGunnar Mills { 354ac6a4445SGunnar Mills messages::internalError(aResp->res); 3550fda0f12SGeorge Liu BMCWEB_LOG_DEBUG 3560fda0f12SGeorge Liu << "Invalid property type for MaxAveragePowerLimitmW"; 357601af5edSChicago Duan return; 358ac6a4445SGunnar Mills } 359d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["MaxTDPMilliWatts"] = *value; 360ac6a4445SGunnar Mills } 361ac6a4445SGunnar Mills else if (property.first == "ConfigurationLocked") 362ac6a4445SGunnar Mills { 363ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&property.second); 364ac6a4445SGunnar Mills if (value == nullptr) 365ac6a4445SGunnar Mills { 366ac6a4445SGunnar Mills messages::internalError(aResp->res); 367601af5edSChicago Duan return; 368ac6a4445SGunnar Mills } 369d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["ConfigurationLocked"] = *value; 370ac6a4445SGunnar Mills } 371ac6a4445SGunnar Mills else if (property.first == "AllowedMemoryModes") 372ac6a4445SGunnar Mills { 37380badf7cSJiaqing Zhao const std::string* value = 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 } 38080badf7cSJiaqing Zhao constexpr const std::array<const char*, 3> values{"Volatile", "PMEM", 38180badf7cSJiaqing Zhao "Block"}; 382ac6a4445SGunnar Mills 383ac6a4445SGunnar Mills for (const char* v : values) 384ac6a4445SGunnar Mills { 385ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 386ac6a4445SGunnar Mills { 387d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["OperatingMemoryModes"].push_back( 388d7f04fd9SNan Zhou v); 389ac6a4445SGunnar Mills break; 390ac6a4445SGunnar Mills } 391ac6a4445SGunnar Mills } 392ac6a4445SGunnar Mills } 393ac6a4445SGunnar Mills else if (property.first == "MemoryMedia") 394ac6a4445SGunnar Mills { 39580badf7cSJiaqing Zhao const std::string* value = 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 { 409d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["MemoryMedia"].push_back(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 } 425d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["SecurityCapabilities"][property.first] = 426d7f04fd9SNan Zhou *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 } 437d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["SecurityCapabilities"][property.first] = 438d7f04fd9SNan Zhou *value; 439ac6a4445SGunnar Mills } 440ac6a4445SGunnar Mills } 441ac6a4445SGunnar Mills 4429a5aceacSNan Zhou inline void 4439a5aceacSNan Zhou assembleDimmProperties(std::string_view dimmId, 4449a5aceacSNan Zhou const std::shared_ptr<bmcweb::AsyncResp>& aResp, 445d7f04fd9SNan Zhou const dbus::utility::DBusPropertiesMap& properties, 446d7f04fd9SNan Zhou const nlohmann::json::json_pointer& jsonPtr) 447ac6a4445SGunnar Mills { 448d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["Id"] = dimmId; 449d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["Name"] = "DIMM Slot"; 450d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Enabled"; 451d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["Status"]["Health"] = "OK"; 452ac6a4445SGunnar Mills 453ac6a4445SGunnar Mills for (const auto& property : properties) 454ac6a4445SGunnar Mills { 455ac6a4445SGunnar Mills if (property.first == "MemoryDataWidth") 456ac6a4445SGunnar Mills { 4579a5aceacSNan Zhou const uint16_t* value = std::get_if<uint16_t>(&property.second); 458ac6a4445SGunnar Mills if (value == nullptr) 459ac6a4445SGunnar Mills { 460ac6a4445SGunnar Mills continue; 461ac6a4445SGunnar Mills } 462d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["DataWidthBits"] = *value; 463ac6a4445SGunnar Mills } 464b9d36b47SEd Tanous else if (property.first == "MemorySizeInKB") 465b9d36b47SEd Tanous { 4669a5aceacSNan Zhou const size_t* memorySize = std::get_if<size_t>(&property.second); 467b9d36b47SEd Tanous if (memorySize == nullptr) 468b9d36b47SEd Tanous { 469b9d36b47SEd Tanous // Important property not in desired type 470b9d36b47SEd Tanous messages::internalError(aResp->res); 471b9d36b47SEd Tanous return; 472b9d36b47SEd Tanous } 473d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["CapacityMiB"] = (*memorySize >> 10); 474b9d36b47SEd Tanous } 475ac6a4445SGunnar Mills else if (property.first == "PartNumber") 476ac6a4445SGunnar Mills { 477ac6a4445SGunnar Mills const std::string* value = 478ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 479ac6a4445SGunnar Mills if (value == nullptr) 480ac6a4445SGunnar Mills { 481ac6a4445SGunnar Mills continue; 482ac6a4445SGunnar Mills } 483d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["PartNumber"] = *value; 484ac6a4445SGunnar Mills } 485ac6a4445SGunnar Mills else if (property.first == "SerialNumber") 486ac6a4445SGunnar Mills { 487ac6a4445SGunnar Mills const std::string* value = 488ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 489ac6a4445SGunnar Mills if (value == nullptr) 490ac6a4445SGunnar Mills { 491ac6a4445SGunnar Mills continue; 492ac6a4445SGunnar Mills } 493d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["SerialNumber"] = *value; 494ac6a4445SGunnar Mills } 495ac6a4445SGunnar Mills else if (property.first == "Manufacturer") 496ac6a4445SGunnar Mills { 497ac6a4445SGunnar Mills const std::string* value = 498ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 499ac6a4445SGunnar Mills if (value == nullptr) 500ac6a4445SGunnar Mills { 501ac6a4445SGunnar Mills continue; 502ac6a4445SGunnar Mills } 503d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["Manufacturer"] = *value; 504ac6a4445SGunnar Mills } 505ac6a4445SGunnar Mills else if (property.first == "RevisionCode") 506ac6a4445SGunnar Mills { 5079a5aceacSNan Zhou const uint16_t* value = std::get_if<uint16_t>(&property.second); 508ac6a4445SGunnar Mills 509ac6a4445SGunnar Mills if (value == nullptr) 510ac6a4445SGunnar Mills { 511ac6a4445SGunnar Mills messages::internalError(aResp->res); 5129a5aceacSNan Zhou BMCWEB_LOG_DEBUG << "Invalid property type for RevisionCode"; 513601af5edSChicago Duan return; 514ac6a4445SGunnar Mills } 515d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["FirmwareRevision"] = 516d7f04fd9SNan Zhou std::to_string(*value); 517ac6a4445SGunnar Mills } 5189a128eb3SJoshi-Mansi else if (property.first == "Present") 5199a128eb3SJoshi-Mansi { 5209a128eb3SJoshi-Mansi const bool* value = std::get_if<bool>(&property.second); 5219a128eb3SJoshi-Mansi if (value == nullptr) 5229a128eb3SJoshi-Mansi { 5239a128eb3SJoshi-Mansi messages::internalError(aResp->res); 5249a5aceacSNan Zhou BMCWEB_LOG_DEBUG << "Invalid property type for Dimm Presence"; 5259a128eb3SJoshi-Mansi return; 5269a128eb3SJoshi-Mansi } 527e05aec50SEd Tanous if (!*value) 5289a128eb3SJoshi-Mansi { 529d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Absent"; 5309a128eb3SJoshi-Mansi } 5319a128eb3SJoshi-Mansi } 532ac6a4445SGunnar Mills else if (property.first == "MemoryTotalWidth") 533ac6a4445SGunnar Mills { 5349a5aceacSNan Zhou const uint16_t* value = std::get_if<uint16_t>(&property.second); 535ac6a4445SGunnar Mills if (value == nullptr) 536ac6a4445SGunnar Mills { 537ac6a4445SGunnar Mills continue; 538ac6a4445SGunnar Mills } 539d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["BusWidthBits"] = *value; 540ac6a4445SGunnar Mills } 541ac6a4445SGunnar Mills else if (property.first == "ECC") 542ac6a4445SGunnar Mills { 543ac6a4445SGunnar Mills const std::string* value = 544ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 545ac6a4445SGunnar Mills if (value == nullptr) 546ac6a4445SGunnar Mills { 547ac6a4445SGunnar Mills messages::internalError(aResp->res); 548ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Invalid property type for ECC"; 549601af5edSChicago Duan return; 550ac6a4445SGunnar Mills } 551ac6a4445SGunnar Mills constexpr const std::array<const char*, 4> values{ 5529a5aceacSNan Zhou "NoECC", "SingleBitECC", "MultiBitECC", "AddressParity"}; 553ac6a4445SGunnar Mills 554ac6a4445SGunnar Mills for (const char* v : values) 555ac6a4445SGunnar Mills { 556ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 557ac6a4445SGunnar Mills { 558d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["ErrorCorrection"] = v; 559ac6a4445SGunnar Mills break; 560ac6a4445SGunnar Mills } 561ac6a4445SGunnar Mills } 562ac6a4445SGunnar Mills } 563ac6a4445SGunnar Mills else if (property.first == "FormFactor") 564ac6a4445SGunnar Mills { 565ac6a4445SGunnar Mills const std::string* value = 566ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 567ac6a4445SGunnar Mills if (value == nullptr) 568ac6a4445SGunnar Mills { 569ac6a4445SGunnar Mills messages::internalError(aResp->res); 5709a5aceacSNan Zhou BMCWEB_LOG_DEBUG << "Invalid property type for FormFactor"; 571601af5edSChicago Duan return; 572ac6a4445SGunnar Mills } 573ac6a4445SGunnar Mills constexpr const std::array<const char*, 11> values{ 5749a5aceacSNan Zhou "RDIMM", "UDIMM", "SO_DIMM", "LRDIMM", 5759a5aceacSNan Zhou "Mini_RDIMM", "Mini_UDIMM", "SO_RDIMM_72b", "SO_UDIMM_72b", 5769a5aceacSNan Zhou "SO_DIMM_16b", "SO_DIMM_32b", "Die"}; 577ac6a4445SGunnar Mills 578ac6a4445SGunnar Mills for (const char* v : values) 579ac6a4445SGunnar Mills { 580ac6a4445SGunnar Mills if (boost::ends_with(*value, v)) 581ac6a4445SGunnar Mills { 582d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["BaseModuleType"] = v; 583ac6a4445SGunnar Mills break; 584ac6a4445SGunnar Mills } 585ac6a4445SGunnar Mills } 586ac6a4445SGunnar Mills } 587ac6a4445SGunnar Mills else if (property.first == "AllowedSpeedsMT") 588ac6a4445SGunnar Mills { 589ac6a4445SGunnar Mills const std::vector<uint16_t>* value = 590ac6a4445SGunnar Mills std::get_if<std::vector<uint16_t>>(&property.second); 591ac6a4445SGunnar Mills if (value == nullptr) 592ac6a4445SGunnar Mills { 593ac6a4445SGunnar Mills continue; 594ac6a4445SGunnar Mills } 595d7f04fd9SNan Zhou nlohmann::json& jValue = 596d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["AllowedSpeedsMHz"]; 597ac6a4445SGunnar Mills jValue = nlohmann::json::array(); 598ac6a4445SGunnar Mills for (uint16_t subVal : *value) 599ac6a4445SGunnar Mills { 600ac6a4445SGunnar Mills jValue.push_back(subVal); 601ac6a4445SGunnar Mills } 602ac6a4445SGunnar Mills } 603ac6a4445SGunnar Mills else if (property.first == "MemoryAttributes") 604ac6a4445SGunnar Mills { 6059a5aceacSNan Zhou const uint8_t* value = std::get_if<uint8_t>(&property.second); 606ac6a4445SGunnar Mills 607ac6a4445SGunnar Mills if (value == nullptr) 608ac6a4445SGunnar Mills { 609ac6a4445SGunnar Mills messages::internalError(aResp->res); 610ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG 611ac6a4445SGunnar Mills << "Invalid property type for MemoryAttributes"; 612601af5edSChicago Duan return; 613ac6a4445SGunnar Mills } 614d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["RankCount"] = 615d7f04fd9SNan Zhou static_cast<uint64_t>(*value); 616ac6a4445SGunnar Mills } 617ac6a4445SGunnar Mills else if (property.first == "MemoryConfiguredSpeedInMhz") 618ac6a4445SGunnar Mills { 6199a5aceacSNan Zhou const uint16_t* value = std::get_if<uint16_t>(&property.second); 620ac6a4445SGunnar Mills if (value == nullptr) 621ac6a4445SGunnar Mills { 622ac6a4445SGunnar Mills continue; 623ac6a4445SGunnar Mills } 624d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["OperatingSpeedMhz"] = *value; 625ac6a4445SGunnar Mills } 626ac6a4445SGunnar Mills else if (property.first == "MemoryType") 627ac6a4445SGunnar Mills { 6289a5aceacSNan Zhou const auto* value = std::get_if<std::string>(&property.second); 629ac6a4445SGunnar Mills if (value != nullptr) 630ac6a4445SGunnar Mills { 631313efb1cSGunnar Mills std::string memoryDeviceType = 632313efb1cSGunnar Mills translateMemoryTypeToRedfish(*value); 633313efb1cSGunnar Mills // Values like "Unknown" or "Other" will return empty 634313efb1cSGunnar Mills // so just leave off 635313efb1cSGunnar Mills if (!memoryDeviceType.empty()) 636ac6a4445SGunnar Mills { 637d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["MemoryDeviceType"] = 638d7f04fd9SNan Zhou memoryDeviceType; 639ac6a4445SGunnar Mills } 640ac6a4445SGunnar Mills if (value->find("DDR") != std::string::npos) 641ac6a4445SGunnar Mills { 642d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["MemoryType"] = "DRAM"; 643ac6a4445SGunnar Mills } 644ac6a4445SGunnar Mills else if (boost::ends_with(*value, "Logical")) 645ac6a4445SGunnar Mills { 646d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["MemoryType"] = "IntelOptane"; 647ac6a4445SGunnar Mills } 648ac6a4445SGunnar Mills } 649ac6a4445SGunnar Mills } 650ac6a4445SGunnar Mills // memory location interface 651ac6a4445SGunnar Mills else if (property.first == "Channel" || 652ac6a4445SGunnar Mills property.first == "MemoryController" || 653ac6a4445SGunnar Mills property.first == "Slot" || property.first == "Socket") 654ac6a4445SGunnar Mills { 655ac6a4445SGunnar Mills const std::string* value = 656ac6a4445SGunnar Mills std::get_if<std::string>(&property.second); 657ac6a4445SGunnar Mills if (value == nullptr) 658ac6a4445SGunnar Mills { 659ac6a4445SGunnar Mills messages::internalError(aResp->res); 660601af5edSChicago Duan return; 661ac6a4445SGunnar Mills } 662d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["MemoryLocation"][property.first] = 663d7f04fd9SNan Zhou *value; 664ac6a4445SGunnar Mills } 665ee135e24SSunnySrivastava1984 else if (property.first == "SparePartNumber") 666ee135e24SSunnySrivastava1984 { 667ee135e24SSunnySrivastava1984 const std::string* value = 668ee135e24SSunnySrivastava1984 std::get_if<std::string>(&property.second); 669ee135e24SSunnySrivastava1984 if (value == nullptr) 670ee135e24SSunnySrivastava1984 { 671ee135e24SSunnySrivastava1984 messages::internalError(aResp->res); 672601af5edSChicago Duan return; 673ee135e24SSunnySrivastava1984 } 674d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["SparePartNumber"] = *value; 675ee135e24SSunnySrivastava1984 } 676ee135e24SSunnySrivastava1984 else if (property.first == "Model") 677ee135e24SSunnySrivastava1984 { 678ee135e24SSunnySrivastava1984 const std::string* value = 679ee135e24SSunnySrivastava1984 std::get_if<std::string>(&property.second); 680ee135e24SSunnySrivastava1984 if (value == nullptr) 681ee135e24SSunnySrivastava1984 { 682ee135e24SSunnySrivastava1984 messages::internalError(aResp->res); 683601af5edSChicago Duan return; 684ee135e24SSunnySrivastava1984 } 685d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["Model"] = *value; 686ee135e24SSunnySrivastava1984 } 687ee135e24SSunnySrivastava1984 else if (property.first == "LocationCode") 688ee135e24SSunnySrivastava1984 { 689ee135e24SSunnySrivastava1984 const std::string* value = 690ee135e24SSunnySrivastava1984 std::get_if<std::string>(&property.second); 691ee135e24SSunnySrivastava1984 if (value == nullptr) 692ee135e24SSunnySrivastava1984 { 693ee135e24SSunnySrivastava1984 messages::internalError(aResp->res); 694601af5edSChicago Duan return; 695ee135e24SSunnySrivastava1984 } 696d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["Location"]["PartLocation"] 697d7f04fd9SNan Zhou ["ServiceLabel"] = *value; 698ee135e24SSunnySrivastava1984 } 699ac6a4445SGunnar Mills else 700ac6a4445SGunnar Mills { 701d7f04fd9SNan Zhou getPersistentMemoryProperties(aResp, property, jsonPtr); 702ac6a4445SGunnar Mills } 703ac6a4445SGunnar Mills } 7049a5aceacSNan Zhou } 7059a5aceacSNan Zhou 7069a5aceacSNan Zhou inline void getDimmDataByService(std::shared_ptr<bmcweb::AsyncResp> aResp, 7079a5aceacSNan Zhou const std::string& dimmId, 7089a5aceacSNan Zhou const std::string& service, 7099a5aceacSNan Zhou const std::string& objPath) 7109a5aceacSNan Zhou { 7119a5aceacSNan Zhou auto health = std::make_shared<HealthPopulate>(aResp); 7129a5aceacSNan Zhou health->selfPath = objPath; 7139a5aceacSNan Zhou health->populate(); 7149a5aceacSNan Zhou 7159a5aceacSNan Zhou BMCWEB_LOG_DEBUG << "Get available system components."; 7169a5aceacSNan Zhou crow::connections::systemBus->async_method_call( 7179a5aceacSNan Zhou [dimmId, aResp{std::move(aResp)}]( 7189a5aceacSNan Zhou const boost::system::error_code ec, 7199a5aceacSNan Zhou const dbus::utility::DBusPropertiesMap& properties) { 7209a5aceacSNan Zhou if (ec) 7219a5aceacSNan Zhou { 7229a5aceacSNan Zhou BMCWEB_LOG_DEBUG << "DBUS response error"; 7239a5aceacSNan Zhou messages::internalError(aResp->res); 7249a5aceacSNan Zhou return; 7259a5aceacSNan Zhou } 726d7f04fd9SNan Zhou assembleDimmProperties(dimmId, aResp, properties, ""_json_pointer); 727ac6a4445SGunnar Mills }, 728ac6a4445SGunnar Mills service, objPath, "org.freedesktop.DBus.Properties", "GetAll", ""); 729ac6a4445SGunnar Mills } 730ac6a4445SGunnar Mills 731ef00d7d4SNan Zhou inline void assembleDimmPartitionData( 732ef00d7d4SNan Zhou const std::shared_ptr<bmcweb::AsyncResp>& aResp, 733d7f04fd9SNan Zhou const dbus::utility::DBusPropertiesMap& properties, 734d7f04fd9SNan Zhou const nlohmann::json::json_pointer& regionPtr) 735ac6a4445SGunnar Mills { 736d7f04fd9SNan Zhou nlohmann::json::object_t partition; 737ac6a4445SGunnar Mills for (const auto& [key, val] : properties) 738ac6a4445SGunnar Mills { 739ac6a4445SGunnar Mills if (key == "MemoryClassification") 740ac6a4445SGunnar Mills { 741ac6a4445SGunnar Mills const std::string* value = std::get_if<std::string>(&val); 742ac6a4445SGunnar Mills if (value == nullptr) 743ac6a4445SGunnar Mills { 744ac6a4445SGunnar Mills messages::internalError(aResp->res); 745601af5edSChicago Duan return; 746ac6a4445SGunnar Mills } 747ac6a4445SGunnar Mills partition[key] = *value; 748ac6a4445SGunnar Mills } 749ac6a4445SGunnar Mills else if (key == "OffsetInKiB") 750ac6a4445SGunnar Mills { 751ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&val); 752ac6a4445SGunnar Mills if (value == nullptr) 753ac6a4445SGunnar Mills { 754ac6a4445SGunnar Mills messages::internalError(aResp->res); 755601af5edSChicago Duan return; 756ac6a4445SGunnar Mills } 757ac6a4445SGunnar Mills 758ac6a4445SGunnar Mills partition["OffsetMiB"] = (*value >> 10); 759ac6a4445SGunnar Mills } 760ac6a4445SGunnar Mills else if (key == "PartitionId") 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["RegionId"] = *value; 769ac6a4445SGunnar Mills } 770ac6a4445SGunnar Mills 771ac6a4445SGunnar Mills else if (key == "PassphraseState") 772ac6a4445SGunnar Mills { 773ac6a4445SGunnar Mills const bool* value = std::get_if<bool>(&val); 774ac6a4445SGunnar Mills if (value == nullptr) 775ac6a4445SGunnar Mills { 776ac6a4445SGunnar Mills messages::internalError(aResp->res); 777601af5edSChicago Duan return; 778ac6a4445SGunnar Mills } 779ac6a4445SGunnar Mills partition["PassphraseEnabled"] = *value; 780ac6a4445SGunnar Mills } 781ac6a4445SGunnar Mills else if (key == "SizeInKiB") 782ac6a4445SGunnar Mills { 783ac6a4445SGunnar Mills const uint64_t* value = std::get_if<uint64_t>(&val); 784ac6a4445SGunnar Mills if (value == nullptr) 785ac6a4445SGunnar Mills { 786ac6a4445SGunnar Mills messages::internalError(aResp->res); 787ef00d7d4SNan Zhou BMCWEB_LOG_DEBUG << "Invalid property type for SizeInKiB"; 788601af5edSChicago Duan return; 789ac6a4445SGunnar Mills } 790ac6a4445SGunnar Mills partition["SizeMiB"] = (*value >> 10); 791ac6a4445SGunnar Mills } 792ac6a4445SGunnar Mills } 793d7f04fd9SNan Zhou aResp->res.jsonValue[regionPtr].emplace_back(std::move(partition)); 794ef00d7d4SNan Zhou } 795ef00d7d4SNan Zhou 796ef00d7d4SNan Zhou inline void getDimmPartitionData(std::shared_ptr<bmcweb::AsyncResp> aResp, 797ef00d7d4SNan Zhou const std::string& service, 798ef00d7d4SNan Zhou const std::string& path) 799ef00d7d4SNan Zhou { 800ef00d7d4SNan Zhou crow::connections::systemBus->async_method_call( 801ef00d7d4SNan Zhou [aResp{std::move(aResp)}]( 802ef00d7d4SNan Zhou const boost::system::error_code ec, 803ef00d7d4SNan Zhou const dbus::utility::DBusPropertiesMap& properties) { 804ef00d7d4SNan Zhou if (ec) 805ef00d7d4SNan Zhou { 806ef00d7d4SNan Zhou BMCWEB_LOG_DEBUG << "DBUS response error"; 807ef00d7d4SNan Zhou messages::internalError(aResp->res); 808ef00d7d4SNan Zhou 809ef00d7d4SNan Zhou return; 810ef00d7d4SNan Zhou } 811d7f04fd9SNan Zhou nlohmann::json::json_pointer regionPtr = "/Regions"_json_pointer; 812d7f04fd9SNan Zhou assembleDimmPartitionData(aResp, properties, regionPtr); 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, 826b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 827ac6a4445SGunnar Mills if (ec) 828ac6a4445SGunnar Mills { 829ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 830ac6a4445SGunnar Mills messages::internalError(aResp->res); 831ac6a4445SGunnar Mills 832ac6a4445SGunnar Mills return; 833ac6a4445SGunnar Mills } 834ac6a4445SGunnar Mills bool found = false; 835*76686dccSNan Zhou for (const auto& [rawPath, object] : subtree) 836ac6a4445SGunnar Mills { 837*76686dccSNan Zhou sdbusplus::message::object_path path(rawPath); 838ac6a4445SGunnar Mills for (const auto& [service, interfaces] : object) 839ac6a4445SGunnar Mills { 840b9d36b47SEd Tanous for (const auto& interface : interfaces) 841ac6a4445SGunnar Mills { 842b9d36b47SEd Tanous if (interface == 843*76686dccSNan Zhou "xyz.openbmc_project.Inventory.Item.Dimm" && 844*76686dccSNan Zhou path.filename() == dimmId) 845b9d36b47SEd Tanous { 846*76686dccSNan Zhou getDimmDataByService(aResp, dimmId, service, rawPath); 847ac6a4445SGunnar Mills found = true; 848ac6a4445SGunnar Mills } 849ac6a4445SGunnar Mills 850b9d36b47SEd Tanous // partitions are separate as there can be multiple 851b9d36b47SEd Tanous // per 852ac6a4445SGunnar Mills // device, i.e. 853ac6a4445SGunnar Mills // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1 854ac6a4445SGunnar Mills // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2 855b9d36b47SEd Tanous if (interface == 856*76686dccSNan Zhou "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition" && 857*76686dccSNan Zhou path.parent_path().filename() == dimmId) 858ac6a4445SGunnar Mills { 859*76686dccSNan Zhou getDimmPartitionData(aResp, service, rawPath); 860ac6a4445SGunnar Mills } 861ac6a4445SGunnar Mills } 862ac6a4445SGunnar Mills } 863b9d36b47SEd Tanous } 864ac6a4445SGunnar Mills // Object not found 865ac6a4445SGunnar Mills if (!found) 866ac6a4445SGunnar Mills { 867ac6a4445SGunnar Mills messages::resourceNotFound(aResp->res, "Memory", dimmId); 8681a1d5d6dSNan Zhou return; 869ac6a4445SGunnar Mills } 8701a1d5d6dSNan Zhou // Set @odata only if object is found 8711a1d5d6dSNan Zhou aResp->res.jsonValue["@odata.type"] = "#Memory.v1_11_0.Memory"; 8721a1d5d6dSNan Zhou aResp->res.jsonValue["@odata.id"] = 8731a1d5d6dSNan Zhou "/redfish/v1/Systems/system/Memory/" + dimmId; 874ac6a4445SGunnar Mills return; 875ac6a4445SGunnar Mills }, 876ac6a4445SGunnar Mills "xyz.openbmc_project.ObjectMapper", 877ac6a4445SGunnar Mills "/xyz/openbmc_project/object_mapper", 878ac6a4445SGunnar Mills "xyz.openbmc_project.ObjectMapper", "GetSubTree", 879ac6a4445SGunnar Mills "/xyz/openbmc_project/inventory", 0, 880ac6a4445SGunnar Mills std::array<const char*, 2>{ 881ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm", 882ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"}); 883ac6a4445SGunnar Mills } 884ac6a4445SGunnar Mills 8857e860f15SJohn Edward Broadbent inline void requestRoutesMemoryCollection(App& app) 886ac6a4445SGunnar Mills { 887ac6a4445SGunnar Mills /** 888ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 889ac6a4445SGunnar Mills */ 8907e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Memory/") 891ed398213SEd Tanous .privileges(redfish::privileges::getMemoryCollection) 8927e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 89345ca1b86SEd Tanous [&app](const crow::Request& req, 8947e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 8953ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 89645ca1b86SEd Tanous { 89745ca1b86SEd Tanous return; 89845ca1b86SEd Tanous } 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)( 91945ca1b86SEd Tanous [&app](const crow::Request& req, 9207e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 9217e860f15SJohn Edward Broadbent const std::string& dimmId) { 9223ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 92345ca1b86SEd Tanous { 92445ca1b86SEd Tanous return; 92545ca1b86SEd Tanous } 926ac6a4445SGunnar Mills getDimmData(asyncResp, dimmId); 9277e860f15SJohn Edward Broadbent }); 928ac6a4445SGunnar Mills } 929ac6a4445SGunnar Mills 930ac6a4445SGunnar Mills } // namespace redfish 931