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> 21168e20c1SEd Tanous #include <dbus_utility.hpp> 22d7f04fd9SNan Zhou #include <nlohmann/json.hpp> 2345ca1b86SEd Tanous #include <query.hpp> 24ed398213SEd Tanous #include <registries/privilege_registry.hpp> 25c1343bf6SKrzysztof Grobelny #include <sdbusplus/asio/property.hpp> 26c1343bf6SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp> 27ac6a4445SGunnar Mills #include <utils/collection.hpp> 28f201ffb4SEd Tanous #include <utils/hex_utils.hpp> 29ac6a4445SGunnar Mills #include <utils/json_utils.hpp> 30ac6a4445SGunnar Mills 31*7a1dbc48SGeorge Liu #include <array> 32*7a1dbc48SGeorge Liu #include <string_view> 33*7a1dbc48SGeorge Liu 34ac6a4445SGunnar Mills namespace redfish 35ac6a4445SGunnar Mills { 36ac6a4445SGunnar Mills 37313efb1cSGunnar Mills inline std::string translateMemoryTypeToRedfish(const std::string& memoryType) 38313efb1cSGunnar Mills { 39313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR") 40313efb1cSGunnar Mills { 41313efb1cSGunnar Mills return "DDR"; 42313efb1cSGunnar Mills } 43313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2") 44313efb1cSGunnar Mills { 45313efb1cSGunnar Mills return "DDR2"; 46313efb1cSGunnar Mills } 47313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR3") 48313efb1cSGunnar Mills { 49313efb1cSGunnar Mills return "DDR3"; 50313efb1cSGunnar Mills } 51313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4") 52313efb1cSGunnar Mills { 53313efb1cSGunnar Mills return "DDR4"; 54313efb1cSGunnar Mills } 55313efb1cSGunnar Mills if (memoryType == 56313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4E_SDRAM") 57313efb1cSGunnar Mills { 58313efb1cSGunnar Mills return "DDR4E_SDRAM"; 59313efb1cSGunnar Mills } 6011a2f0f0SMansi Joshi if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR5") 6111a2f0f0SMansi Joshi { 6211a2f0f0SMansi Joshi return "DDR5"; 6311a2f0f0SMansi Joshi } 64313efb1cSGunnar Mills if (memoryType == 65313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR4_SDRAM") 66313efb1cSGunnar Mills { 67313efb1cSGunnar Mills return "LPDDR4_SDRAM"; 68313efb1cSGunnar Mills } 69313efb1cSGunnar Mills if (memoryType == 70313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR3_SDRAM") 71313efb1cSGunnar Mills { 72313efb1cSGunnar Mills return "LPDDR3_SDRAM"; 73313efb1cSGunnar Mills } 74313efb1cSGunnar Mills if (memoryType == 75313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM") 76313efb1cSGunnar Mills { 77313efb1cSGunnar Mills return "DDR2_SDRAM_FB_DIMM"; 78313efb1cSGunnar Mills } 790fda0f12SGeorge Liu if (memoryType == 800fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM_PROB") 81313efb1cSGunnar Mills { 82313efb1cSGunnar Mills return "DDR2_SDRAM_FB_DIMM_PROBE"; 83313efb1cSGunnar Mills } 84313efb1cSGunnar Mills if (memoryType == 85313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR_SGRAM") 86313efb1cSGunnar Mills { 87313efb1cSGunnar Mills return "DDR_SGRAM"; 88313efb1cSGunnar Mills } 89313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.ROM") 90313efb1cSGunnar Mills { 91313efb1cSGunnar Mills return "ROM"; 92313efb1cSGunnar Mills } 93313efb1cSGunnar Mills if (memoryType == 94313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.SDRAM") 95313efb1cSGunnar Mills { 96313efb1cSGunnar Mills return "SDRAM"; 97313efb1cSGunnar Mills } 98313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.EDO") 99313efb1cSGunnar Mills { 100313efb1cSGunnar Mills return "EDO"; 101313efb1cSGunnar Mills } 102313efb1cSGunnar Mills if (memoryType == 103313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.FastPageMode") 104313efb1cSGunnar Mills { 105313efb1cSGunnar Mills return "FastPageMode"; 106313efb1cSGunnar Mills } 107313efb1cSGunnar Mills if (memoryType == 108313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.PipelinedNibble") 109313efb1cSGunnar Mills { 110313efb1cSGunnar Mills return "PipelinedNibble"; 111313efb1cSGunnar Mills } 112313efb1cSGunnar Mills if (memoryType == 113313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.Logical") 114313efb1cSGunnar Mills { 115313efb1cSGunnar Mills return "Logical"; 116313efb1cSGunnar Mills } 117313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM") 118313efb1cSGunnar Mills { 119313efb1cSGunnar Mills return "HBM"; 120313efb1cSGunnar Mills } 121313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM2") 122313efb1cSGunnar Mills { 123313efb1cSGunnar Mills return "HBM2"; 124313efb1cSGunnar Mills } 125ce34d514STyson Tuckerbear if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM3") 126ce34d514STyson Tuckerbear { 127ce34d514STyson Tuckerbear return "HBM3"; 128ce34d514STyson Tuckerbear } 129313efb1cSGunnar Mills // This is values like Other or Unknown 130313efb1cSGunnar Mills // Also D-Bus values: 131313efb1cSGunnar Mills // DRAM 132313efb1cSGunnar Mills // EDRAM 133313efb1cSGunnar Mills // VRAM 134313efb1cSGunnar Mills // SRAM 135313efb1cSGunnar Mills // RAM 136313efb1cSGunnar Mills // FLASH 137313efb1cSGunnar Mills // EEPROM 138313efb1cSGunnar Mills // FEPROM 139313efb1cSGunnar Mills // EPROM 140313efb1cSGunnar Mills // CDRAM 141313efb1cSGunnar Mills // ThreeDRAM 142313efb1cSGunnar Mills // RDRAM 143313efb1cSGunnar Mills // FBD2 144313efb1cSGunnar Mills // LPDDR_SDRAM 145313efb1cSGunnar Mills // LPDDR2_SDRAM 14611a2f0f0SMansi Joshi // LPDDR5_SDRAM 147313efb1cSGunnar Mills return ""; 148313efb1cSGunnar Mills } 149313efb1cSGunnar Mills 150c1343bf6SKrzysztof Grobelny inline void dimmPropToHex(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 151c1343bf6SKrzysztof Grobelny const char* key, const uint16_t* value, 152d7f04fd9SNan Zhou const nlohmann::json::json_pointer& jsonPtr) 153ac6a4445SGunnar Mills { 154ac6a4445SGunnar Mills if (value == nullptr) 155ac6a4445SGunnar Mills { 156ac6a4445SGunnar Mills return; 157ac6a4445SGunnar Mills } 158d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr][key] = "0x" + intToHexString(*value, 4); 159ac6a4445SGunnar Mills } 160ac6a4445SGunnar Mills 1618d1b46d7Szhanghch05 inline void getPersistentMemoryProperties( 1628d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aResp, 163c1343bf6SKrzysztof Grobelny const dbus::utility::DBusPropertiesMap& properties, 164d7f04fd9SNan Zhou const nlohmann::json::json_pointer& jsonPtr) 165ac6a4445SGunnar Mills { 166c1343bf6SKrzysztof Grobelny const uint16_t* moduleManufacturerID = nullptr; 167c1343bf6SKrzysztof Grobelny const uint16_t* moduleProductID = nullptr; 168c1343bf6SKrzysztof Grobelny const uint16_t* subsystemVendorID = nullptr; 169c1343bf6SKrzysztof Grobelny const uint16_t* subsystemDeviceID = nullptr; 170c1343bf6SKrzysztof Grobelny const uint64_t* volatileRegionSizeLimitInKiB = nullptr; 171c1343bf6SKrzysztof Grobelny const uint64_t* pmRegionSizeLimitInKiB = nullptr; 172c1343bf6SKrzysztof Grobelny const uint64_t* volatileSizeInKiB = nullptr; 173c1343bf6SKrzysztof Grobelny const uint64_t* pmSizeInKiB = nullptr; 174c1343bf6SKrzysztof Grobelny const uint64_t* cacheSizeInKB = nullptr; 175c1343bf6SKrzysztof Grobelny const uint64_t* voltaileRegionMaxSizeInKib = nullptr; 176c1343bf6SKrzysztof Grobelny const uint64_t* pmRegionMaxSizeInKiB = nullptr; 177c1343bf6SKrzysztof Grobelny const uint64_t* allocationIncrementInKiB = nullptr; 178c1343bf6SKrzysztof Grobelny const uint64_t* allocationAlignmentInKiB = nullptr; 179c1343bf6SKrzysztof Grobelny const uint64_t* volatileRegionNumberLimit = nullptr; 180c1343bf6SKrzysztof Grobelny const uint64_t* pmRegionNumberLimit = nullptr; 181c1343bf6SKrzysztof Grobelny const uint64_t* spareDeviceCount = nullptr; 182c1343bf6SKrzysztof Grobelny const bool* isSpareDeviceInUse = nullptr; 183c1343bf6SKrzysztof Grobelny const bool* isRankSpareEnabled = nullptr; 184c1343bf6SKrzysztof Grobelny const std::vector<uint32_t>* maxAveragePowerLimitmW = nullptr; 185c1343bf6SKrzysztof Grobelny const bool* configurationLocked = nullptr; 186c1343bf6SKrzysztof Grobelny const std::string* allowedMemoryModes = nullptr; 187c1343bf6SKrzysztof Grobelny const std::string* memoryMedia = nullptr; 188c1343bf6SKrzysztof Grobelny const bool* configurationLockCapable = nullptr; 189c1343bf6SKrzysztof Grobelny const bool* dataLockCapable = nullptr; 190c1343bf6SKrzysztof Grobelny const bool* passphraseCapable = nullptr; 191c1343bf6SKrzysztof Grobelny const uint64_t* maxPassphraseCount = nullptr; 192c1343bf6SKrzysztof Grobelny const uint64_t* passphraseLockLimit = nullptr; 193c1343bf6SKrzysztof Grobelny 194c1343bf6SKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 195c1343bf6SKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "ModuleManufacturerID", 196c1343bf6SKrzysztof Grobelny moduleManufacturerID, "ModuleProductID", moduleProductID, 197c1343bf6SKrzysztof Grobelny "SubsystemVendorID", subsystemVendorID, "SubsystemDeviceID", 198c1343bf6SKrzysztof Grobelny subsystemDeviceID, "VolatileRegionSizeLimitInKiB", 199c1343bf6SKrzysztof Grobelny volatileRegionSizeLimitInKiB, "PmRegionSizeLimitInKiB", 200c1343bf6SKrzysztof Grobelny pmRegionSizeLimitInKiB, "VolatileSizeInKiB", volatileSizeInKiB, 201c1343bf6SKrzysztof Grobelny "PmSizeInKiB", pmSizeInKiB, "CacheSizeInKB", cacheSizeInKB, 202c1343bf6SKrzysztof Grobelny "VoltaileRegionMaxSizeInKib", voltaileRegionMaxSizeInKib, 203c1343bf6SKrzysztof Grobelny "PmRegionMaxSizeInKiB", pmRegionMaxSizeInKiB, 204c1343bf6SKrzysztof Grobelny "AllocationIncrementInKiB", allocationIncrementInKiB, 205c1343bf6SKrzysztof Grobelny "AllocationAlignmentInKiB", allocationAlignmentInKiB, 206c1343bf6SKrzysztof Grobelny "VolatileRegionNumberLimit", volatileRegionNumberLimit, 207c1343bf6SKrzysztof Grobelny "PmRegionNumberLimit", pmRegionNumberLimit, "SpareDeviceCount", 208c1343bf6SKrzysztof Grobelny spareDeviceCount, "IsSpareDeviceInUse", isSpareDeviceInUse, 209c1343bf6SKrzysztof Grobelny "IsRankSpareEnabled", isRankSpareEnabled, "MaxAveragePowerLimitmW", 210c1343bf6SKrzysztof Grobelny maxAveragePowerLimitmW, "ConfigurationLocked", configurationLocked, 211c1343bf6SKrzysztof Grobelny "AllowedMemoryModes", allowedMemoryModes, "MemoryMedia", memoryMedia, 212c1343bf6SKrzysztof Grobelny "ConfigurationLockCapable", configurationLockCapable, "DataLockCapable", 213c1343bf6SKrzysztof Grobelny dataLockCapable, "PassphraseCapable", passphraseCapable, 214c1343bf6SKrzysztof Grobelny "MaxPassphraseCount", maxPassphraseCount, "PassphraseLockLimit", 215c1343bf6SKrzysztof Grobelny passphraseLockLimit); 216c1343bf6SKrzysztof Grobelny 217c1343bf6SKrzysztof Grobelny if (!success) 218ac6a4445SGunnar Mills { 219c1343bf6SKrzysztof Grobelny messages::internalError(aResp->res); 220c1343bf6SKrzysztof Grobelny return; 221ac6a4445SGunnar Mills } 222c1343bf6SKrzysztof Grobelny 223c1343bf6SKrzysztof Grobelny dimmPropToHex(aResp, "ModuleManufacturerID", moduleManufacturerID, jsonPtr); 224c1343bf6SKrzysztof Grobelny dimmPropToHex(aResp, "ModuleProductID", moduleProductID, jsonPtr); 225ac6a4445SGunnar Mills dimmPropToHex(aResp, "MemorySubsystemControllerManufacturerID", 226c1343bf6SKrzysztof Grobelny subsystemVendorID, jsonPtr); 227c1343bf6SKrzysztof Grobelny dimmPropToHex(aResp, "MemorySubsystemControllerProductID", 228c1343bf6SKrzysztof Grobelny subsystemDeviceID, jsonPtr); 229ac6a4445SGunnar Mills 230c1343bf6SKrzysztof Grobelny if (volatileRegionSizeLimitInKiB != nullptr) 231ac6a4445SGunnar Mills { 232d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["VolatileRegionSizeLimitMiB"] = 233c1343bf6SKrzysztof Grobelny (*volatileRegionSizeLimitInKiB) >> 10; 234ac6a4445SGunnar Mills } 235ac6a4445SGunnar Mills 236c1343bf6SKrzysztof Grobelny if (pmRegionSizeLimitInKiB != nullptr) 237ac6a4445SGunnar Mills { 238d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["PersistentRegionSizeLimitMiB"] = 239c1343bf6SKrzysztof Grobelny (*pmRegionSizeLimitInKiB) >> 10; 240ac6a4445SGunnar Mills } 241ac6a4445SGunnar Mills 242c1343bf6SKrzysztof Grobelny if (volatileSizeInKiB != nullptr) 243ac6a4445SGunnar Mills { 244ac6a4445SGunnar Mills 245c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["VolatileSizeMiB"] = 246c1343bf6SKrzysztof Grobelny (*volatileSizeInKiB) >> 10; 247ac6a4445SGunnar Mills } 248c1343bf6SKrzysztof Grobelny 249c1343bf6SKrzysztof Grobelny if (pmSizeInKiB != nullptr) 250c1343bf6SKrzysztof Grobelny { 251c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["NonVolatileSizeMiB"] = 252c1343bf6SKrzysztof Grobelny (*pmSizeInKiB) >> 10; 253c1343bf6SKrzysztof Grobelny } 254c1343bf6SKrzysztof Grobelny 255c1343bf6SKrzysztof Grobelny if (cacheSizeInKB != nullptr) 256c1343bf6SKrzysztof Grobelny { 257c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["CacheSizeMiB"] = (*cacheSizeInKB >> 10); 258c1343bf6SKrzysztof Grobelny } 259c1343bf6SKrzysztof Grobelny 260c1343bf6SKrzysztof Grobelny if (voltaileRegionMaxSizeInKib != nullptr) 261c1343bf6SKrzysztof Grobelny { 262d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["VolatileRegionSizeMaxMiB"] = 263c1343bf6SKrzysztof Grobelny (*voltaileRegionMaxSizeInKib) >> 10; 264ac6a4445SGunnar Mills } 265ac6a4445SGunnar Mills 266c1343bf6SKrzysztof Grobelny if (pmRegionMaxSizeInKiB != nullptr) 267ac6a4445SGunnar Mills { 268d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["PersistentRegionSizeMaxMiB"] = 269c1343bf6SKrzysztof Grobelny (*pmRegionMaxSizeInKiB) >> 10; 270ac6a4445SGunnar Mills } 271ac6a4445SGunnar Mills 272c1343bf6SKrzysztof Grobelny if (allocationIncrementInKiB != nullptr) 273ac6a4445SGunnar Mills { 274d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["AllocationIncrementMiB"] = 275c1343bf6SKrzysztof Grobelny (*allocationIncrementInKiB) >> 10; 276ac6a4445SGunnar Mills } 277ac6a4445SGunnar Mills 278c1343bf6SKrzysztof Grobelny if (allocationAlignmentInKiB != nullptr) 279ac6a4445SGunnar Mills { 280d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["AllocationAlignmentMiB"] = 281c1343bf6SKrzysztof Grobelny (*allocationAlignmentInKiB) >> 10; 282ac6a4445SGunnar Mills } 283c1343bf6SKrzysztof Grobelny 284c1343bf6SKrzysztof Grobelny if (volatileRegionNumberLimit != nullptr) 285ac6a4445SGunnar Mills { 286c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["VolatileRegionNumberLimit"] = 287c1343bf6SKrzysztof Grobelny *volatileRegionNumberLimit; 288ac6a4445SGunnar Mills } 289c1343bf6SKrzysztof Grobelny 290c1343bf6SKrzysztof Grobelny if (pmRegionNumberLimit != nullptr) 291ac6a4445SGunnar Mills { 292c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["PersistentRegionNumberLimit"] = 293c1343bf6SKrzysztof Grobelny *pmRegionNumberLimit; 294ac6a4445SGunnar Mills } 295c1343bf6SKrzysztof Grobelny 296c1343bf6SKrzysztof Grobelny if (spareDeviceCount != nullptr) 297ac6a4445SGunnar Mills { 298c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["SpareDeviceCount"] = *spareDeviceCount; 299ac6a4445SGunnar Mills } 300c1343bf6SKrzysztof Grobelny 301c1343bf6SKrzysztof Grobelny if (isSpareDeviceInUse != nullptr) 302ac6a4445SGunnar Mills { 303c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["IsSpareDeviceEnabled"] = 304c1343bf6SKrzysztof Grobelny *isSpareDeviceInUse; 305ac6a4445SGunnar Mills } 306c1343bf6SKrzysztof Grobelny 307c1343bf6SKrzysztof Grobelny if (isRankSpareEnabled != nullptr) 308ac6a4445SGunnar Mills { 309c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["IsRankSpareEnabled"] = 310c1343bf6SKrzysztof Grobelny *isRankSpareEnabled; 311ac6a4445SGunnar Mills } 312c1343bf6SKrzysztof Grobelny 313c1343bf6SKrzysztof Grobelny if (maxAveragePowerLimitmW != nullptr) 314ac6a4445SGunnar Mills { 315c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["MaxTDPMilliWatts"] = 316c1343bf6SKrzysztof Grobelny *maxAveragePowerLimitmW; 317ac6a4445SGunnar Mills } 318c1343bf6SKrzysztof Grobelny 319c1343bf6SKrzysztof Grobelny if (configurationLocked != nullptr) 320ac6a4445SGunnar Mills { 321c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["ConfigurationLocked"] = 322c1343bf6SKrzysztof Grobelny *configurationLocked; 323ac6a4445SGunnar Mills } 324c1343bf6SKrzysztof Grobelny 325c1343bf6SKrzysztof Grobelny if (allowedMemoryModes != nullptr) 326ac6a4445SGunnar Mills { 32780badf7cSJiaqing Zhao constexpr const std::array<const char*, 3> values{"Volatile", "PMEM", 32880badf7cSJiaqing Zhao "Block"}; 329ac6a4445SGunnar Mills 330ac6a4445SGunnar Mills for (const char* v : values) 331ac6a4445SGunnar Mills { 332c1343bf6SKrzysztof Grobelny if (allowedMemoryModes->ends_with(v)) 333ac6a4445SGunnar Mills { 334d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["OperatingMemoryModes"].push_back( 335d7f04fd9SNan Zhou v); 336ac6a4445SGunnar Mills break; 337ac6a4445SGunnar Mills } 338ac6a4445SGunnar Mills } 339ac6a4445SGunnar Mills } 340c1343bf6SKrzysztof Grobelny 341c1343bf6SKrzysztof Grobelny if (memoryMedia != nullptr) 342ac6a4445SGunnar Mills { 343ac6a4445SGunnar Mills constexpr const std::array<const char*, 3> values{"DRAM", "NAND", 344ac6a4445SGunnar Mills "Intel3DXPoint"}; 345ac6a4445SGunnar Mills 346ac6a4445SGunnar Mills for (const char* v : values) 347ac6a4445SGunnar Mills { 348c1343bf6SKrzysztof Grobelny if (memoryMedia->ends_with(v)) 349ac6a4445SGunnar Mills { 350d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["MemoryMedia"].push_back(v); 351ac6a4445SGunnar Mills break; 352ac6a4445SGunnar Mills } 353ac6a4445SGunnar Mills } 354ac6a4445SGunnar Mills } 355c1343bf6SKrzysztof Grobelny 356c1343bf6SKrzysztof Grobelny if (configurationLockCapable != nullptr) 357ac6a4445SGunnar Mills { 358c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["SecurityCapabilities"] 359c1343bf6SKrzysztof Grobelny ["ConfigurationLockCapable"] = 360c1343bf6SKrzysztof Grobelny *configurationLockCapable; 361ac6a4445SGunnar Mills } 362c1343bf6SKrzysztof Grobelny 363c1343bf6SKrzysztof Grobelny if (dataLockCapable != nullptr) 364ac6a4445SGunnar Mills { 365c1343bf6SKrzysztof Grobelny aResp->res 366c1343bf6SKrzysztof Grobelny .jsonValue[jsonPtr]["SecurityCapabilities"]["DataLockCapable"] = 367c1343bf6SKrzysztof Grobelny *dataLockCapable; 368ac6a4445SGunnar Mills } 369c1343bf6SKrzysztof Grobelny 370c1343bf6SKrzysztof Grobelny if (passphraseCapable != nullptr) 371c1343bf6SKrzysztof Grobelny { 372c1343bf6SKrzysztof Grobelny aResp->res 373c1343bf6SKrzysztof Grobelny .jsonValue[jsonPtr]["SecurityCapabilities"]["PassphraseCapable"] = 374c1343bf6SKrzysztof Grobelny *passphraseCapable; 375c1343bf6SKrzysztof Grobelny } 376c1343bf6SKrzysztof Grobelny 377c1343bf6SKrzysztof Grobelny if (maxPassphraseCount != nullptr) 378c1343bf6SKrzysztof Grobelny { 379c1343bf6SKrzysztof Grobelny aResp->res 380c1343bf6SKrzysztof Grobelny .jsonValue[jsonPtr]["SecurityCapabilities"]["MaxPassphraseCount"] = 381c1343bf6SKrzysztof Grobelny *maxPassphraseCount; 382c1343bf6SKrzysztof Grobelny } 383c1343bf6SKrzysztof Grobelny 384c1343bf6SKrzysztof Grobelny if (passphraseLockLimit != nullptr) 385c1343bf6SKrzysztof Grobelny { 386c1343bf6SKrzysztof Grobelny aResp->res 387c1343bf6SKrzysztof Grobelny .jsonValue[jsonPtr]["SecurityCapabilities"]["PassphraseLockLimit"] = 388c1343bf6SKrzysztof Grobelny *passphraseLockLimit; 389ac6a4445SGunnar Mills } 390ac6a4445SGunnar Mills } 391ac6a4445SGunnar Mills 3929a5aceacSNan Zhou inline void 3939a5aceacSNan Zhou assembleDimmProperties(std::string_view dimmId, 3949a5aceacSNan Zhou const std::shared_ptr<bmcweb::AsyncResp>& aResp, 395d7f04fd9SNan Zhou const dbus::utility::DBusPropertiesMap& properties, 396d7f04fd9SNan Zhou const nlohmann::json::json_pointer& jsonPtr) 397ac6a4445SGunnar Mills { 398d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["Id"] = dimmId; 399d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["Name"] = "DIMM Slot"; 400d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Enabled"; 401d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["Status"]["Health"] = "OK"; 402ac6a4445SGunnar Mills 403c1343bf6SKrzysztof Grobelny const uint16_t* memoryDataWidth = nullptr; 404c1343bf6SKrzysztof Grobelny const size_t* memorySizeInKB = nullptr; 405c1343bf6SKrzysztof Grobelny const std::string* partNumber = nullptr; 406c1343bf6SKrzysztof Grobelny const std::string* serialNumber = nullptr; 407c1343bf6SKrzysztof Grobelny const std::string* manufacturer = nullptr; 408c1343bf6SKrzysztof Grobelny const uint16_t* revisionCode = nullptr; 409c1343bf6SKrzysztof Grobelny const bool* present = nullptr; 410c1343bf6SKrzysztof Grobelny const uint16_t* memoryTotalWidth = nullptr; 411c1343bf6SKrzysztof Grobelny const std::string* ecc = nullptr; 412c1343bf6SKrzysztof Grobelny const std::string* formFactor = nullptr; 413c1343bf6SKrzysztof Grobelny const std::vector<uint16_t>* allowedSpeedsMT = nullptr; 414c1343bf6SKrzysztof Grobelny const uint8_t* memoryAttributes = nullptr; 415c1343bf6SKrzysztof Grobelny const uint16_t* memoryConfiguredSpeedInMhz = nullptr; 416c1343bf6SKrzysztof Grobelny const std::string* memoryType = nullptr; 417c1343bf6SKrzysztof Grobelny const std::string* channel = nullptr; 418c1343bf6SKrzysztof Grobelny const std::string* memoryController = nullptr; 419c1343bf6SKrzysztof Grobelny const std::string* slot = nullptr; 420c1343bf6SKrzysztof Grobelny const std::string* socket = nullptr; 421c1343bf6SKrzysztof Grobelny const std::string* sparePartNumber = nullptr; 422c1343bf6SKrzysztof Grobelny const std::string* model = nullptr; 423c1343bf6SKrzysztof Grobelny const std::string* locationCode = nullptr; 424ac6a4445SGunnar Mills 425c1343bf6SKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 426c1343bf6SKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "MemoryDataWidth", 427c1343bf6SKrzysztof Grobelny memoryDataWidth, "MemorySizeInKB", memorySizeInKB, "PartNumber", 428656472d9SNikhil Namjoshi partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer, 429656472d9SNikhil Namjoshi "RevisionCode", revisionCode, "Present", present, "MemoryTotalWidth", 430656472d9SNikhil Namjoshi memoryTotalWidth, "ECC", ecc, "FormFactor", formFactor, 431656472d9SNikhil Namjoshi "AllowedSpeedsMT", allowedSpeedsMT, "MemoryAttributes", 432c1343bf6SKrzysztof Grobelny memoryAttributes, "MemoryConfiguredSpeedInMhz", 433c1343bf6SKrzysztof Grobelny memoryConfiguredSpeedInMhz, "MemoryType", memoryType, "Channel", 434c1343bf6SKrzysztof Grobelny channel, "MemoryController", memoryController, "Slot", slot, "Socket", 435c1343bf6SKrzysztof Grobelny socket, "SparePartNumber", sparePartNumber, "Model", model, 436c1343bf6SKrzysztof Grobelny "LocationCode", locationCode); 437c1343bf6SKrzysztof Grobelny 438c1343bf6SKrzysztof Grobelny if (!success) 439ac6a4445SGunnar Mills { 440ac6a4445SGunnar Mills messages::internalError(aResp->res); 441601af5edSChicago Duan return; 442ac6a4445SGunnar Mills } 443c1343bf6SKrzysztof Grobelny 444c1343bf6SKrzysztof Grobelny if (memoryDataWidth != nullptr) 445c1343bf6SKrzysztof Grobelny { 446c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["DataWidthBits"] = *memoryDataWidth; 447c1343bf6SKrzysztof Grobelny } 448c1343bf6SKrzysztof Grobelny 449c1343bf6SKrzysztof Grobelny if (memorySizeInKB != nullptr) 450c1343bf6SKrzysztof Grobelny { 451c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["CapacityMiB"] = (*memorySizeInKB >> 10); 452c1343bf6SKrzysztof Grobelny } 453c1343bf6SKrzysztof Grobelny 454c1343bf6SKrzysztof Grobelny if (partNumber != nullptr) 455c1343bf6SKrzysztof Grobelny { 456c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["PartNumber"] = *partNumber; 457c1343bf6SKrzysztof Grobelny } 458c1343bf6SKrzysztof Grobelny 459c1343bf6SKrzysztof Grobelny if (serialNumber != nullptr) 460c1343bf6SKrzysztof Grobelny { 461c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["SerialNumber"] = *serialNumber; 462c1343bf6SKrzysztof Grobelny } 463c1343bf6SKrzysztof Grobelny 464c1343bf6SKrzysztof Grobelny if (manufacturer != nullptr) 465c1343bf6SKrzysztof Grobelny { 466c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["Manufacturer"] = *manufacturer; 467c1343bf6SKrzysztof Grobelny } 468c1343bf6SKrzysztof Grobelny 469c1343bf6SKrzysztof Grobelny if (revisionCode != nullptr) 470c1343bf6SKrzysztof Grobelny { 471d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["FirmwareRevision"] = 472c1343bf6SKrzysztof Grobelny std::to_string(*revisionCode); 473ac6a4445SGunnar Mills } 474c1343bf6SKrzysztof Grobelny 475c1343bf6SKrzysztof Grobelny if (present != nullptr && !*present) 4769a128eb3SJoshi-Mansi { 477d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Absent"; 4789a128eb3SJoshi-Mansi } 479c1343bf6SKrzysztof Grobelny 480c1343bf6SKrzysztof Grobelny if (memoryTotalWidth != nullptr) 481ac6a4445SGunnar Mills { 482c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["BusWidthBits"] = *memoryTotalWidth; 483ac6a4445SGunnar Mills } 484c1343bf6SKrzysztof Grobelny 485c1343bf6SKrzysztof Grobelny if (ecc != nullptr) 486ac6a4445SGunnar Mills { 487ac6a4445SGunnar Mills constexpr const std::array<const char*, 4> values{ 4889a5aceacSNan Zhou "NoECC", "SingleBitECC", "MultiBitECC", "AddressParity"}; 489ac6a4445SGunnar Mills 490ac6a4445SGunnar Mills for (const char* v : values) 491ac6a4445SGunnar Mills { 492c1343bf6SKrzysztof Grobelny if (ecc->ends_with(v)) 493ac6a4445SGunnar Mills { 494d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["ErrorCorrection"] = v; 495ac6a4445SGunnar Mills break; 496ac6a4445SGunnar Mills } 497ac6a4445SGunnar Mills } 498ac6a4445SGunnar Mills } 499c1343bf6SKrzysztof Grobelny 500c1343bf6SKrzysztof Grobelny if (formFactor != nullptr) 501ac6a4445SGunnar Mills { 502ac6a4445SGunnar Mills constexpr const std::array<const char*, 11> values{ 5039a5aceacSNan Zhou "RDIMM", "UDIMM", "SO_DIMM", "LRDIMM", 5049a5aceacSNan Zhou "Mini_RDIMM", "Mini_UDIMM", "SO_RDIMM_72b", "SO_UDIMM_72b", 5059a5aceacSNan Zhou "SO_DIMM_16b", "SO_DIMM_32b", "Die"}; 506ac6a4445SGunnar Mills 507ac6a4445SGunnar Mills for (const char* v : values) 508ac6a4445SGunnar Mills { 509c1343bf6SKrzysztof Grobelny if (formFactor->ends_with(v)) 510ac6a4445SGunnar Mills { 511d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["BaseModuleType"] = v; 512ac6a4445SGunnar Mills break; 513ac6a4445SGunnar Mills } 514ac6a4445SGunnar Mills } 515ac6a4445SGunnar Mills } 516c1343bf6SKrzysztof Grobelny 517c1343bf6SKrzysztof Grobelny if (allowedSpeedsMT != nullptr) 518ac6a4445SGunnar Mills { 519d7f04fd9SNan Zhou nlohmann::json& jValue = 520d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["AllowedSpeedsMHz"]; 521ac6a4445SGunnar Mills jValue = nlohmann::json::array(); 522c1343bf6SKrzysztof Grobelny for (uint16_t subVal : *allowedSpeedsMT) 523ac6a4445SGunnar Mills { 524ac6a4445SGunnar Mills jValue.push_back(subVal); 525ac6a4445SGunnar Mills } 526ac6a4445SGunnar Mills } 527ac6a4445SGunnar Mills 528c1343bf6SKrzysztof Grobelny if (memoryAttributes != nullptr) 529ac6a4445SGunnar Mills { 530d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["RankCount"] = 531c1343bf6SKrzysztof Grobelny static_cast<uint64_t>(*memoryAttributes); 532ac6a4445SGunnar Mills } 533c1343bf6SKrzysztof Grobelny 534c1343bf6SKrzysztof Grobelny if (memoryConfiguredSpeedInMhz != nullptr) 535ac6a4445SGunnar Mills { 536c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["OperatingSpeedMhz"] = 537c1343bf6SKrzysztof Grobelny *memoryConfiguredSpeedInMhz; 538ac6a4445SGunnar Mills } 539c1343bf6SKrzysztof Grobelny 540c1343bf6SKrzysztof Grobelny if (memoryType != nullptr) 541ac6a4445SGunnar Mills { 542313efb1cSGunnar Mills std::string memoryDeviceType = 543c1343bf6SKrzysztof Grobelny translateMemoryTypeToRedfish(*memoryType); 544313efb1cSGunnar Mills // Values like "Unknown" or "Other" will return empty 545313efb1cSGunnar Mills // so just leave off 546313efb1cSGunnar Mills if (!memoryDeviceType.empty()) 547ac6a4445SGunnar Mills { 548d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["MemoryDeviceType"] = 549d7f04fd9SNan Zhou memoryDeviceType; 550ac6a4445SGunnar Mills } 551c1343bf6SKrzysztof Grobelny if (memoryType->find("DDR") != std::string::npos) 552ac6a4445SGunnar Mills { 553d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["MemoryType"] = "DRAM"; 554ac6a4445SGunnar Mills } 555c1343bf6SKrzysztof Grobelny else if (memoryType->ends_with("Logical")) 556ac6a4445SGunnar Mills { 557d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["MemoryType"] = "IntelOptane"; 558ac6a4445SGunnar Mills } 559ac6a4445SGunnar Mills } 560c1343bf6SKrzysztof Grobelny 561c1343bf6SKrzysztof Grobelny if (channel != nullptr) 562ac6a4445SGunnar Mills { 563c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Channel"] = *channel; 564c1343bf6SKrzysztof Grobelny } 565c1343bf6SKrzysztof Grobelny 566c1343bf6SKrzysztof Grobelny if (memoryController != nullptr) 567ac6a4445SGunnar Mills { 568c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["MemoryLocation"]["MemoryController"] = 569c1343bf6SKrzysztof Grobelny *memoryController; 570ac6a4445SGunnar Mills } 571c1343bf6SKrzysztof Grobelny 572c1343bf6SKrzysztof Grobelny if (slot != nullptr) 573ee135e24SSunnySrivastava1984 { 574c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Slot"] = *slot; 575c1343bf6SKrzysztof Grobelny } 576c1343bf6SKrzysztof Grobelny 577c1343bf6SKrzysztof Grobelny if (socket != nullptr) 578ee135e24SSunnySrivastava1984 { 579c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Socket"] = *socket; 580ee135e24SSunnySrivastava1984 } 581c1343bf6SKrzysztof Grobelny 582c1343bf6SKrzysztof Grobelny if (sparePartNumber != nullptr) 583ee135e24SSunnySrivastava1984 { 584c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["SparePartNumber"] = *sparePartNumber; 585c1343bf6SKrzysztof Grobelny } 586c1343bf6SKrzysztof Grobelny 587c1343bf6SKrzysztof Grobelny if (model != nullptr) 588ee135e24SSunnySrivastava1984 { 589c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["Model"] = *model; 590ee135e24SSunnySrivastava1984 } 591c1343bf6SKrzysztof Grobelny 592c1343bf6SKrzysztof Grobelny if (locationCode != nullptr) 593ee135e24SSunnySrivastava1984 { 594c1343bf6SKrzysztof Grobelny aResp->res 595c1343bf6SKrzysztof Grobelny .jsonValue[jsonPtr]["Location"]["PartLocation"]["ServiceLabel"] = 596c1343bf6SKrzysztof Grobelny *locationCode; 597ee135e24SSunnySrivastava1984 } 598c1343bf6SKrzysztof Grobelny 599c1343bf6SKrzysztof Grobelny getPersistentMemoryProperties(aResp, properties, jsonPtr); 6009a5aceacSNan Zhou } 6019a5aceacSNan Zhou 6029a5aceacSNan Zhou inline void getDimmDataByService(std::shared_ptr<bmcweb::AsyncResp> aResp, 6039a5aceacSNan Zhou const std::string& dimmId, 6049a5aceacSNan Zhou const std::string& service, 6059a5aceacSNan Zhou const std::string& objPath) 6069a5aceacSNan Zhou { 6079a5aceacSNan Zhou auto health = std::make_shared<HealthPopulate>(aResp); 6089a5aceacSNan Zhou health->selfPath = objPath; 6099a5aceacSNan Zhou health->populate(); 6109a5aceacSNan Zhou 6119a5aceacSNan Zhou BMCWEB_LOG_DEBUG << "Get available system components."; 612c1343bf6SKrzysztof Grobelny sdbusplus::asio::getAllProperties( 613c1343bf6SKrzysztof Grobelny *crow::connections::systemBus, service, objPath, "", 6149a5aceacSNan Zhou [dimmId, aResp{std::move(aResp)}]( 6159a5aceacSNan Zhou const boost::system::error_code ec, 6169a5aceacSNan Zhou const dbus::utility::DBusPropertiesMap& properties) { 6179a5aceacSNan Zhou if (ec) 6189a5aceacSNan Zhou { 6199a5aceacSNan Zhou BMCWEB_LOG_DEBUG << "DBUS response error"; 6209a5aceacSNan Zhou messages::internalError(aResp->res); 6219a5aceacSNan Zhou return; 6229a5aceacSNan Zhou } 623d7f04fd9SNan Zhou assembleDimmProperties(dimmId, aResp, properties, ""_json_pointer); 624c1343bf6SKrzysztof Grobelny }); 625ac6a4445SGunnar Mills } 626ac6a4445SGunnar Mills 627ef00d7d4SNan Zhou inline void assembleDimmPartitionData( 628ef00d7d4SNan Zhou const std::shared_ptr<bmcweb::AsyncResp>& aResp, 629d7f04fd9SNan Zhou const dbus::utility::DBusPropertiesMap& properties, 630d7f04fd9SNan Zhou const nlohmann::json::json_pointer& regionPtr) 631ac6a4445SGunnar Mills { 632c1343bf6SKrzysztof Grobelny const std::string* memoryClassification = nullptr; 633c1343bf6SKrzysztof Grobelny const uint64_t* offsetInKiB = nullptr; 634c1343bf6SKrzysztof Grobelny const std::string* partitionId = nullptr; 635c1343bf6SKrzysztof Grobelny const bool* passphraseState = nullptr; 636c1343bf6SKrzysztof Grobelny const uint64_t* sizeInKiB = nullptr; 637c1343bf6SKrzysztof Grobelny 638c1343bf6SKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 639c1343bf6SKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "MemoryClassification", 640c1343bf6SKrzysztof Grobelny memoryClassification, "OffsetInKiB", offsetInKiB, "PartitionId", 641c1343bf6SKrzysztof Grobelny partitionId, "PassphraseState", passphraseState, "SizeInKiB", 642c1343bf6SKrzysztof Grobelny sizeInKiB); 643c1343bf6SKrzysztof Grobelny 644c1343bf6SKrzysztof Grobelny if (!success) 645c1343bf6SKrzysztof Grobelny { 646c1343bf6SKrzysztof Grobelny messages::internalError(aResp->res); 647c1343bf6SKrzysztof Grobelny return; 648c1343bf6SKrzysztof Grobelny } 649c1343bf6SKrzysztof Grobelny 650d7f04fd9SNan Zhou nlohmann::json::object_t partition; 651c1343bf6SKrzysztof Grobelny 652c1343bf6SKrzysztof Grobelny if (memoryClassification != nullptr) 653ac6a4445SGunnar Mills { 654c1343bf6SKrzysztof Grobelny partition["MemoryClassification"] = *memoryClassification; 655ac6a4445SGunnar Mills } 656ac6a4445SGunnar Mills 657c1343bf6SKrzysztof Grobelny if (offsetInKiB != nullptr) 658ac6a4445SGunnar Mills { 659c1343bf6SKrzysztof Grobelny partition["OffsetMiB"] = (*offsetInKiB >> 10); 660ac6a4445SGunnar Mills } 661ac6a4445SGunnar Mills 662c1343bf6SKrzysztof Grobelny if (partitionId != nullptr) 663ac6a4445SGunnar Mills { 664c1343bf6SKrzysztof Grobelny partition["RegionId"] = *partitionId; 665c1343bf6SKrzysztof Grobelny } 666c1343bf6SKrzysztof Grobelny 667c1343bf6SKrzysztof Grobelny if (passphraseState != nullptr) 668ac6a4445SGunnar Mills { 669c1343bf6SKrzysztof Grobelny partition["PassphraseEnabled"] = *passphraseState; 670ac6a4445SGunnar Mills } 671c1343bf6SKrzysztof Grobelny 672c1343bf6SKrzysztof Grobelny if (sizeInKiB != nullptr) 673ac6a4445SGunnar Mills { 674c1343bf6SKrzysztof Grobelny partition["SizeMiB"] = (*sizeInKiB >> 10); 675ac6a4445SGunnar Mills } 676c1343bf6SKrzysztof Grobelny 677d7f04fd9SNan Zhou aResp->res.jsonValue[regionPtr].emplace_back(std::move(partition)); 678ef00d7d4SNan Zhou } 679ef00d7d4SNan Zhou 680ef00d7d4SNan Zhou inline void getDimmPartitionData(std::shared_ptr<bmcweb::AsyncResp> aResp, 681ef00d7d4SNan Zhou const std::string& service, 682ef00d7d4SNan Zhou const std::string& path) 683ef00d7d4SNan Zhou { 684c1343bf6SKrzysztof Grobelny sdbusplus::asio::getAllProperties( 685c1343bf6SKrzysztof Grobelny *crow::connections::systemBus, service, path, 686c1343bf6SKrzysztof Grobelny "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition", 687ef00d7d4SNan Zhou [aResp{std::move(aResp)}]( 688ef00d7d4SNan Zhou const boost::system::error_code ec, 689ef00d7d4SNan Zhou const dbus::utility::DBusPropertiesMap& properties) { 690ef00d7d4SNan Zhou if (ec) 691ef00d7d4SNan Zhou { 692ef00d7d4SNan Zhou BMCWEB_LOG_DEBUG << "DBUS response error"; 693ef00d7d4SNan Zhou messages::internalError(aResp->res); 694ef00d7d4SNan Zhou 695ef00d7d4SNan Zhou return; 696ef00d7d4SNan Zhou } 697d7f04fd9SNan Zhou nlohmann::json::json_pointer regionPtr = "/Regions"_json_pointer; 698d7f04fd9SNan Zhou assembleDimmPartitionData(aResp, properties, regionPtr); 699c1343bf6SKrzysztof Grobelny } 700ac6a4445SGunnar Mills 701c1343bf6SKrzysztof Grobelny ); 702ac6a4445SGunnar Mills } 703ac6a4445SGunnar Mills 7048d1b46d7Szhanghch05 inline void getDimmData(std::shared_ptr<bmcweb::AsyncResp> aResp, 705ac6a4445SGunnar Mills const std::string& dimmId) 706ac6a4445SGunnar Mills { 707ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Get available system dimm resources."; 708ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 709ac6a4445SGunnar Mills [dimmId, aResp{std::move(aResp)}]( 710ac6a4445SGunnar Mills const boost::system::error_code ec, 711b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 712ac6a4445SGunnar Mills if (ec) 713ac6a4445SGunnar Mills { 714ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 715ac6a4445SGunnar Mills messages::internalError(aResp->res); 716ac6a4445SGunnar Mills 717ac6a4445SGunnar Mills return; 718ac6a4445SGunnar Mills } 719ac6a4445SGunnar Mills bool found = false; 72076686dccSNan Zhou for (const auto& [rawPath, object] : subtree) 721ac6a4445SGunnar Mills { 72276686dccSNan Zhou sdbusplus::message::object_path path(rawPath); 723ac6a4445SGunnar Mills for (const auto& [service, interfaces] : object) 724ac6a4445SGunnar Mills { 725b9d36b47SEd Tanous for (const auto& interface : interfaces) 726ac6a4445SGunnar Mills { 727b9d36b47SEd Tanous if (interface == 72876686dccSNan Zhou "xyz.openbmc_project.Inventory.Item.Dimm" && 72976686dccSNan Zhou path.filename() == dimmId) 730b9d36b47SEd Tanous { 73176686dccSNan Zhou getDimmDataByService(aResp, dimmId, service, rawPath); 732ac6a4445SGunnar Mills found = true; 733ac6a4445SGunnar Mills } 734ac6a4445SGunnar Mills 735b9d36b47SEd Tanous // partitions are separate as there can be multiple 736b9d36b47SEd Tanous // per 737ac6a4445SGunnar Mills // device, i.e. 738ac6a4445SGunnar Mills // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1 739ac6a4445SGunnar Mills // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2 740b9d36b47SEd Tanous if (interface == 74176686dccSNan Zhou "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition" && 74276686dccSNan Zhou path.parent_path().filename() == dimmId) 743ac6a4445SGunnar Mills { 74476686dccSNan Zhou getDimmPartitionData(aResp, service, rawPath); 745ac6a4445SGunnar Mills } 746ac6a4445SGunnar Mills } 747ac6a4445SGunnar Mills } 748b9d36b47SEd Tanous } 749ac6a4445SGunnar Mills // Object not found 750ac6a4445SGunnar Mills if (!found) 751ac6a4445SGunnar Mills { 752ac6a4445SGunnar Mills messages::resourceNotFound(aResp->res, "Memory", dimmId); 7531a1d5d6dSNan Zhou return; 754ac6a4445SGunnar Mills } 7551a1d5d6dSNan Zhou // Set @odata only if object is found 7561a1d5d6dSNan Zhou aResp->res.jsonValue["@odata.type"] = "#Memory.v1_11_0.Memory"; 7571a1d5d6dSNan Zhou aResp->res.jsonValue["@odata.id"] = 7581a1d5d6dSNan Zhou "/redfish/v1/Systems/system/Memory/" + dimmId; 759ac6a4445SGunnar Mills return; 760ac6a4445SGunnar Mills }, 761ac6a4445SGunnar Mills "xyz.openbmc_project.ObjectMapper", 762ac6a4445SGunnar Mills "/xyz/openbmc_project/object_mapper", 763ac6a4445SGunnar Mills "xyz.openbmc_project.ObjectMapper", "GetSubTree", 764ac6a4445SGunnar Mills "/xyz/openbmc_project/inventory", 0, 765ac6a4445SGunnar Mills std::array<const char*, 2>{ 766ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm", 767ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"}); 768ac6a4445SGunnar Mills } 769ac6a4445SGunnar Mills 7707e860f15SJohn Edward Broadbent inline void requestRoutesMemoryCollection(App& app) 771ac6a4445SGunnar Mills { 772ac6a4445SGunnar Mills /** 773ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 774ac6a4445SGunnar Mills */ 77522d268cbSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/") 776ed398213SEd Tanous .privileges(redfish::privileges::getMemoryCollection) 7777e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 77845ca1b86SEd Tanous [&app](const crow::Request& req, 77922d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 78022d268cbSEd Tanous const std::string& systemName) { 7813ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 78245ca1b86SEd Tanous { 78345ca1b86SEd Tanous return; 78445ca1b86SEd Tanous } 78522d268cbSEd Tanous if (systemName != "system") 78622d268cbSEd Tanous { 78722d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 78822d268cbSEd Tanous systemName); 78922d268cbSEd Tanous return; 79022d268cbSEd Tanous } 79122d268cbSEd Tanous 7928d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 7938d1b46d7Szhanghch05 "#MemoryCollection.MemoryCollection"; 7948d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Memory Module Collection"; 7958d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = 7968d1b46d7Szhanghch05 "/redfish/v1/Systems/system/Memory"; 797ac6a4445SGunnar Mills 798*7a1dbc48SGeorge Liu constexpr std::array<std::string_view, 1> interfaces{ 799*7a1dbc48SGeorge Liu "xyz.openbmc_project.Inventory.Item.Dimm"}; 80005030b8eSGunnar Mills collection_util::getCollectionMembers( 801ae9031f0SWilly Tu asyncResp, boost::urls::url("/redfish/v1/Systems/system/Memory"), 802*7a1dbc48SGeorge Liu interfaces); 8037e860f15SJohn Edward Broadbent }); 804ac6a4445SGunnar Mills } 805ac6a4445SGunnar Mills 8067e860f15SJohn Edward Broadbent inline void requestRoutesMemory(App& app) 8077e860f15SJohn Edward Broadbent { 808ac6a4445SGunnar Mills /** 809ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 810ac6a4445SGunnar Mills */ 81122d268cbSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/<str>/") 812ed398213SEd Tanous .privileges(redfish::privileges::getMemory) 8137e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 81445ca1b86SEd Tanous [&app](const crow::Request& req, 8157e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 81622d268cbSEd Tanous const std::string& systemName, const std::string& dimmId) { 8173ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 81845ca1b86SEd Tanous { 81945ca1b86SEd Tanous return; 82045ca1b86SEd Tanous } 82122d268cbSEd Tanous if (systemName != "system") 82222d268cbSEd Tanous { 82322d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 82422d268cbSEd Tanous systemName); 82522d268cbSEd Tanous return; 82622d268cbSEd Tanous } 82722d268cbSEd Tanous 828ac6a4445SGunnar Mills getDimmData(asyncResp, dimmId); 8297e860f15SJohn Edward Broadbent }); 830ac6a4445SGunnar Mills } 831ac6a4445SGunnar Mills 832ac6a4445SGunnar Mills } // namespace redfish 833