140e9b92eSEd Tanous // SPDX-License-Identifier: Apache-2.0 240e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright OpenBMC Authors 340e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright 2018 Intel Corporation 4ac6a4445SGunnar Mills #pragma once 5ac6a4445SGunnar Mills 613451e39SWilly Tu #include "bmcweb_config.h" 713451e39SWilly Tu 83ccb3adbSEd Tanous #include "app.hpp" 9*d7857201SEd Tanous #include "async_resp.hpp" 103ccb3adbSEd Tanous #include "dbus_utility.hpp" 11*d7857201SEd Tanous #include "error_messages.hpp" 12539d8c6bSEd Tanous #include "generated/enums/memory.hpp" 13539d8c6bSEd Tanous #include "generated/enums/resource.hpp" 14*d7857201SEd Tanous #include "http_request.hpp" 15*d7857201SEd Tanous #include "logging.hpp" 163ccb3adbSEd Tanous #include "query.hpp" 173ccb3adbSEd Tanous #include "registries/privilege_registry.hpp" 183ccb3adbSEd Tanous #include "utils/collection.hpp" 193ccb3adbSEd Tanous #include "utils/dbus_utils.hpp" 203ccb3adbSEd Tanous #include "utils/hex_utils.hpp" 21ac6a4445SGunnar Mills 22*d7857201SEd Tanous #include <boost/beast/http/verb.hpp> 23e99073f5SGeorge Liu #include <boost/system/error_code.hpp> 24ef4c65b7SEd Tanous #include <boost/url/format.hpp> 25d7f04fd9SNan Zhou #include <nlohmann/json.hpp> 26*d7857201SEd Tanous #include <sdbusplus/message/native_types.hpp> 27c1343bf6SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp> 28ac6a4445SGunnar Mills 297a1dbc48SGeorge Liu #include <array> 30*d7857201SEd Tanous #include <cstddef> 31*d7857201SEd Tanous #include <cstdint> 32*d7857201SEd Tanous #include <memory> 33*d7857201SEd Tanous #include <string> 347a1dbc48SGeorge Liu #include <string_view> 35*d7857201SEd Tanous #include <utility> 36*d7857201SEd Tanous #include <vector> 377a1dbc48SGeorge Liu 38ac6a4445SGunnar Mills namespace redfish 39ac6a4445SGunnar Mills { 40ac6a4445SGunnar Mills 41313efb1cSGunnar Mills inline std::string translateMemoryTypeToRedfish(const std::string& memoryType) 42313efb1cSGunnar Mills { 43313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR") 44313efb1cSGunnar Mills { 45313efb1cSGunnar Mills return "DDR"; 46313efb1cSGunnar Mills } 47313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2") 48313efb1cSGunnar Mills { 49313efb1cSGunnar Mills return "DDR2"; 50313efb1cSGunnar Mills } 51313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR3") 52313efb1cSGunnar Mills { 53313efb1cSGunnar Mills return "DDR3"; 54313efb1cSGunnar Mills } 55313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4") 56313efb1cSGunnar Mills { 57313efb1cSGunnar Mills return "DDR4"; 58313efb1cSGunnar Mills } 59313efb1cSGunnar Mills if (memoryType == 60313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4E_SDRAM") 61313efb1cSGunnar Mills { 62313efb1cSGunnar Mills return "DDR4E_SDRAM"; 63313efb1cSGunnar Mills } 6411a2f0f0SMansi Joshi if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR5") 6511a2f0f0SMansi Joshi { 6611a2f0f0SMansi Joshi return "DDR5"; 6711a2f0f0SMansi Joshi } 68313efb1cSGunnar Mills if (memoryType == 69313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR4_SDRAM") 70313efb1cSGunnar Mills { 71313efb1cSGunnar Mills return "LPDDR4_SDRAM"; 72313efb1cSGunnar Mills } 73313efb1cSGunnar Mills if (memoryType == 74313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR3_SDRAM") 75313efb1cSGunnar Mills { 76313efb1cSGunnar Mills return "LPDDR3_SDRAM"; 77313efb1cSGunnar Mills } 78313efb1cSGunnar Mills if (memoryType == 79313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM") 80313efb1cSGunnar Mills { 81313efb1cSGunnar Mills return "DDR2_SDRAM_FB_DIMM"; 82313efb1cSGunnar Mills } 830fda0f12SGeorge Liu if (memoryType == 840fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM_PROB") 85313efb1cSGunnar Mills { 86313efb1cSGunnar Mills return "DDR2_SDRAM_FB_DIMM_PROBE"; 87313efb1cSGunnar Mills } 88313efb1cSGunnar Mills if (memoryType == 89313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR_SGRAM") 90313efb1cSGunnar Mills { 91313efb1cSGunnar Mills return "DDR_SGRAM"; 92313efb1cSGunnar Mills } 93313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.ROM") 94313efb1cSGunnar Mills { 95313efb1cSGunnar Mills return "ROM"; 96313efb1cSGunnar Mills } 97313efb1cSGunnar Mills if (memoryType == 98313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.SDRAM") 99313efb1cSGunnar Mills { 100313efb1cSGunnar Mills return "SDRAM"; 101313efb1cSGunnar Mills } 102313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.EDO") 103313efb1cSGunnar Mills { 104313efb1cSGunnar Mills return "EDO"; 105313efb1cSGunnar Mills } 106313efb1cSGunnar Mills if (memoryType == 107313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.FastPageMode") 108313efb1cSGunnar Mills { 109313efb1cSGunnar Mills return "FastPageMode"; 110313efb1cSGunnar Mills } 111313efb1cSGunnar Mills if (memoryType == 112313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.PipelinedNibble") 113313efb1cSGunnar Mills { 114313efb1cSGunnar Mills return "PipelinedNibble"; 115313efb1cSGunnar Mills } 116313efb1cSGunnar Mills if (memoryType == 117313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.Logical") 118313efb1cSGunnar Mills { 119313efb1cSGunnar Mills return "Logical"; 120313efb1cSGunnar Mills } 121313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM") 122313efb1cSGunnar Mills { 123313efb1cSGunnar Mills return "HBM"; 124313efb1cSGunnar Mills } 125313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM2") 126313efb1cSGunnar Mills { 127313efb1cSGunnar Mills return "HBM2"; 128313efb1cSGunnar Mills } 129ce34d514STyson Tuckerbear if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM3") 130ce34d514STyson Tuckerbear { 131ce34d514STyson Tuckerbear return "HBM3"; 132ce34d514STyson Tuckerbear } 133313efb1cSGunnar Mills // This is values like Other or Unknown 134313efb1cSGunnar Mills // Also D-Bus values: 135313efb1cSGunnar Mills // DRAM 136313efb1cSGunnar Mills // EDRAM 137313efb1cSGunnar Mills // VRAM 138313efb1cSGunnar Mills // SRAM 139313efb1cSGunnar Mills // RAM 140313efb1cSGunnar Mills // FLASH 141313efb1cSGunnar Mills // EEPROM 142313efb1cSGunnar Mills // FEPROM 143313efb1cSGunnar Mills // EPROM 144313efb1cSGunnar Mills // CDRAM 145313efb1cSGunnar Mills // ThreeDRAM 146313efb1cSGunnar Mills // RDRAM 147313efb1cSGunnar Mills // FBD2 148313efb1cSGunnar Mills // LPDDR_SDRAM 149313efb1cSGunnar Mills // LPDDR2_SDRAM 15011a2f0f0SMansi Joshi // LPDDR5_SDRAM 151313efb1cSGunnar Mills return ""; 152313efb1cSGunnar Mills } 153313efb1cSGunnar Mills 154ac106bf6SEd Tanous inline void dimmPropToHex(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 155c1343bf6SKrzysztof Grobelny const char* key, const uint16_t* value, 156d7f04fd9SNan Zhou const nlohmann::json::json_pointer& jsonPtr) 157ac6a4445SGunnar Mills { 158ac6a4445SGunnar Mills if (value == nullptr) 159ac6a4445SGunnar Mills { 160ac6a4445SGunnar Mills return; 161ac6a4445SGunnar Mills } 162ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr][key] = "0x" + intToHexString(*value, 4); 163ac6a4445SGunnar Mills } 164ac6a4445SGunnar Mills 1658d1b46d7Szhanghch05 inline void getPersistentMemoryProperties( 166ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 167c1343bf6SKrzysztof Grobelny const dbus::utility::DBusPropertiesMap& properties, 168d7f04fd9SNan Zhou const nlohmann::json::json_pointer& jsonPtr) 169ac6a4445SGunnar Mills { 170c1343bf6SKrzysztof Grobelny const uint16_t* moduleManufacturerID = nullptr; 171c1343bf6SKrzysztof Grobelny const uint16_t* moduleProductID = nullptr; 172c1343bf6SKrzysztof Grobelny const uint16_t* subsystemVendorID = nullptr; 173c1343bf6SKrzysztof Grobelny const uint16_t* subsystemDeviceID = nullptr; 174c1343bf6SKrzysztof Grobelny const uint64_t* volatileRegionSizeLimitInKiB = nullptr; 175c1343bf6SKrzysztof Grobelny const uint64_t* pmRegionSizeLimitInKiB = nullptr; 176c1343bf6SKrzysztof Grobelny const uint64_t* volatileSizeInKiB = nullptr; 177c1343bf6SKrzysztof Grobelny const uint64_t* pmSizeInKiB = nullptr; 178c1343bf6SKrzysztof Grobelny const uint64_t* cacheSizeInKB = nullptr; 179c1343bf6SKrzysztof Grobelny const uint64_t* voltaileRegionMaxSizeInKib = nullptr; 180c1343bf6SKrzysztof Grobelny const uint64_t* pmRegionMaxSizeInKiB = nullptr; 181c1343bf6SKrzysztof Grobelny const uint64_t* allocationIncrementInKiB = nullptr; 182c1343bf6SKrzysztof Grobelny const uint64_t* allocationAlignmentInKiB = nullptr; 183c1343bf6SKrzysztof Grobelny const uint64_t* volatileRegionNumberLimit = nullptr; 184c1343bf6SKrzysztof Grobelny const uint64_t* pmRegionNumberLimit = nullptr; 185c1343bf6SKrzysztof Grobelny const uint64_t* spareDeviceCount = nullptr; 186c1343bf6SKrzysztof Grobelny const bool* isSpareDeviceInUse = nullptr; 187c1343bf6SKrzysztof Grobelny const bool* isRankSpareEnabled = nullptr; 188c1343bf6SKrzysztof Grobelny const std::vector<uint32_t>* maxAveragePowerLimitmW = nullptr; 189c1343bf6SKrzysztof Grobelny const bool* configurationLocked = nullptr; 190c1343bf6SKrzysztof Grobelny const std::string* allowedMemoryModes = nullptr; 191c1343bf6SKrzysztof Grobelny const std::string* memoryMedia = nullptr; 192c1343bf6SKrzysztof Grobelny const bool* configurationLockCapable = nullptr; 193c1343bf6SKrzysztof Grobelny const bool* dataLockCapable = nullptr; 194c1343bf6SKrzysztof Grobelny const bool* passphraseCapable = nullptr; 195c1343bf6SKrzysztof Grobelny const uint64_t* maxPassphraseCount = nullptr; 196c1343bf6SKrzysztof Grobelny const uint64_t* passphraseLockLimit = nullptr; 197c1343bf6SKrzysztof Grobelny 198c1343bf6SKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 199c1343bf6SKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "ModuleManufacturerID", 200c1343bf6SKrzysztof Grobelny moduleManufacturerID, "ModuleProductID", moduleProductID, 201c1343bf6SKrzysztof Grobelny "SubsystemVendorID", subsystemVendorID, "SubsystemDeviceID", 202c1343bf6SKrzysztof Grobelny subsystemDeviceID, "VolatileRegionSizeLimitInKiB", 203c1343bf6SKrzysztof Grobelny volatileRegionSizeLimitInKiB, "PmRegionSizeLimitInKiB", 204c1343bf6SKrzysztof Grobelny pmRegionSizeLimitInKiB, "VolatileSizeInKiB", volatileSizeInKiB, 205c1343bf6SKrzysztof Grobelny "PmSizeInKiB", pmSizeInKiB, "CacheSizeInKB", cacheSizeInKB, 206c1343bf6SKrzysztof Grobelny "VoltaileRegionMaxSizeInKib", voltaileRegionMaxSizeInKib, 207c1343bf6SKrzysztof Grobelny "PmRegionMaxSizeInKiB", pmRegionMaxSizeInKiB, 208c1343bf6SKrzysztof Grobelny "AllocationIncrementInKiB", allocationIncrementInKiB, 209c1343bf6SKrzysztof Grobelny "AllocationAlignmentInKiB", allocationAlignmentInKiB, 210c1343bf6SKrzysztof Grobelny "VolatileRegionNumberLimit", volatileRegionNumberLimit, 211c1343bf6SKrzysztof Grobelny "PmRegionNumberLimit", pmRegionNumberLimit, "SpareDeviceCount", 212c1343bf6SKrzysztof Grobelny spareDeviceCount, "IsSpareDeviceInUse", isSpareDeviceInUse, 213c1343bf6SKrzysztof Grobelny "IsRankSpareEnabled", isRankSpareEnabled, "MaxAveragePowerLimitmW", 214c1343bf6SKrzysztof Grobelny maxAveragePowerLimitmW, "ConfigurationLocked", configurationLocked, 215c1343bf6SKrzysztof Grobelny "AllowedMemoryModes", allowedMemoryModes, "MemoryMedia", memoryMedia, 216c1343bf6SKrzysztof Grobelny "ConfigurationLockCapable", configurationLockCapable, "DataLockCapable", 217c1343bf6SKrzysztof Grobelny dataLockCapable, "PassphraseCapable", passphraseCapable, 218c1343bf6SKrzysztof Grobelny "MaxPassphraseCount", maxPassphraseCount, "PassphraseLockLimit", 219c1343bf6SKrzysztof Grobelny passphraseLockLimit); 220c1343bf6SKrzysztof Grobelny 221c1343bf6SKrzysztof Grobelny if (!success) 222ac6a4445SGunnar Mills { 223ac106bf6SEd Tanous messages::internalError(asyncResp->res); 224c1343bf6SKrzysztof Grobelny return; 225ac6a4445SGunnar Mills } 226c1343bf6SKrzysztof Grobelny 227ac106bf6SEd Tanous dimmPropToHex(asyncResp, "ModuleManufacturerID", moduleManufacturerID, 228ac106bf6SEd Tanous jsonPtr); 229ac106bf6SEd Tanous dimmPropToHex(asyncResp, "ModuleProductID", moduleProductID, jsonPtr); 230ac106bf6SEd Tanous dimmPropToHex(asyncResp, "MemorySubsystemControllerManufacturerID", 231c1343bf6SKrzysztof Grobelny subsystemVendorID, jsonPtr); 232ac106bf6SEd Tanous dimmPropToHex(asyncResp, "MemorySubsystemControllerProductID", 233c1343bf6SKrzysztof Grobelny subsystemDeviceID, jsonPtr); 234ac6a4445SGunnar Mills 235c1343bf6SKrzysztof Grobelny if (volatileRegionSizeLimitInKiB != nullptr) 236ac6a4445SGunnar Mills { 237ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["VolatileRegionSizeLimitMiB"] = 238c1343bf6SKrzysztof Grobelny (*volatileRegionSizeLimitInKiB) >> 10; 239ac6a4445SGunnar Mills } 240ac6a4445SGunnar Mills 241c1343bf6SKrzysztof Grobelny if (pmRegionSizeLimitInKiB != nullptr) 242ac6a4445SGunnar Mills { 243ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["PersistentRegionSizeLimitMiB"] = 244c1343bf6SKrzysztof Grobelny (*pmRegionSizeLimitInKiB) >> 10; 245ac6a4445SGunnar Mills } 246ac6a4445SGunnar Mills 247c1343bf6SKrzysztof Grobelny if (volatileSizeInKiB != nullptr) 248ac6a4445SGunnar Mills { 249ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["VolatileSizeMiB"] = 250c1343bf6SKrzysztof Grobelny (*volatileSizeInKiB) >> 10; 251ac6a4445SGunnar Mills } 252c1343bf6SKrzysztof Grobelny 253c1343bf6SKrzysztof Grobelny if (pmSizeInKiB != nullptr) 254c1343bf6SKrzysztof Grobelny { 255ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["NonVolatileSizeMiB"] = 256ac106bf6SEd Tanous (*pmSizeInKiB) >> 10; 257c1343bf6SKrzysztof Grobelny } 258c1343bf6SKrzysztof Grobelny 259c1343bf6SKrzysztof Grobelny if (cacheSizeInKB != nullptr) 260c1343bf6SKrzysztof Grobelny { 261ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["CacheSizeMiB"] = 262ac106bf6SEd Tanous (*cacheSizeInKB >> 10); 263c1343bf6SKrzysztof Grobelny } 264c1343bf6SKrzysztof Grobelny 265c1343bf6SKrzysztof Grobelny if (voltaileRegionMaxSizeInKib != nullptr) 266c1343bf6SKrzysztof Grobelny { 267ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["VolatileRegionSizeMaxMiB"] = 268c1343bf6SKrzysztof Grobelny (*voltaileRegionMaxSizeInKib) >> 10; 269ac6a4445SGunnar Mills } 270ac6a4445SGunnar Mills 271c1343bf6SKrzysztof Grobelny if (pmRegionMaxSizeInKiB != nullptr) 272ac6a4445SGunnar Mills { 273ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["PersistentRegionSizeMaxMiB"] = 274c1343bf6SKrzysztof Grobelny (*pmRegionMaxSizeInKiB) >> 10; 275ac6a4445SGunnar Mills } 276ac6a4445SGunnar Mills 277c1343bf6SKrzysztof Grobelny if (allocationIncrementInKiB != nullptr) 278ac6a4445SGunnar Mills { 279ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["AllocationIncrementMiB"] = 280c1343bf6SKrzysztof Grobelny (*allocationIncrementInKiB) >> 10; 281ac6a4445SGunnar Mills } 282ac6a4445SGunnar Mills 283c1343bf6SKrzysztof Grobelny if (allocationAlignmentInKiB != nullptr) 284ac6a4445SGunnar Mills { 285ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["AllocationAlignmentMiB"] = 286c1343bf6SKrzysztof Grobelny (*allocationAlignmentInKiB) >> 10; 287ac6a4445SGunnar Mills } 288c1343bf6SKrzysztof Grobelny 289c1343bf6SKrzysztof Grobelny if (volatileRegionNumberLimit != nullptr) 290ac6a4445SGunnar Mills { 291ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["VolatileRegionNumberLimit"] = 292c1343bf6SKrzysztof Grobelny *volatileRegionNumberLimit; 293ac6a4445SGunnar Mills } 294c1343bf6SKrzysztof Grobelny 295c1343bf6SKrzysztof Grobelny if (pmRegionNumberLimit != nullptr) 296ac6a4445SGunnar Mills { 297ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["PersistentRegionNumberLimit"] = 298c1343bf6SKrzysztof Grobelny *pmRegionNumberLimit; 299ac6a4445SGunnar Mills } 300c1343bf6SKrzysztof Grobelny 301c1343bf6SKrzysztof Grobelny if (spareDeviceCount != nullptr) 302ac6a4445SGunnar Mills { 303ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["SpareDeviceCount"] = 304ac106bf6SEd Tanous *spareDeviceCount; 305ac6a4445SGunnar Mills } 306c1343bf6SKrzysztof Grobelny 307c1343bf6SKrzysztof Grobelny if (isSpareDeviceInUse != nullptr) 308ac6a4445SGunnar Mills { 309ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["IsSpareDeviceEnabled"] = 310c1343bf6SKrzysztof Grobelny *isSpareDeviceInUse; 311ac6a4445SGunnar Mills } 312c1343bf6SKrzysztof Grobelny 313c1343bf6SKrzysztof Grobelny if (isRankSpareEnabled != nullptr) 314ac6a4445SGunnar Mills { 315ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["IsRankSpareEnabled"] = 316c1343bf6SKrzysztof Grobelny *isRankSpareEnabled; 317ac6a4445SGunnar Mills } 318c1343bf6SKrzysztof Grobelny 319c1343bf6SKrzysztof Grobelny if (maxAveragePowerLimitmW != nullptr) 320ac6a4445SGunnar Mills { 321ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["MaxTDPMilliWatts"] = 322c1343bf6SKrzysztof Grobelny *maxAveragePowerLimitmW; 323ac6a4445SGunnar Mills } 324c1343bf6SKrzysztof Grobelny 325c1343bf6SKrzysztof Grobelny if (configurationLocked != nullptr) 326ac6a4445SGunnar Mills { 327ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["ConfigurationLocked"] = 328c1343bf6SKrzysztof Grobelny *configurationLocked; 329ac6a4445SGunnar Mills } 330c1343bf6SKrzysztof Grobelny 331c1343bf6SKrzysztof Grobelny if (allowedMemoryModes != nullptr) 332ac6a4445SGunnar Mills { 33380badf7cSJiaqing Zhao constexpr const std::array<const char*, 3> values{"Volatile", "PMEM", 33480badf7cSJiaqing Zhao "Block"}; 335ac6a4445SGunnar Mills 336ac6a4445SGunnar Mills for (const char* v : values) 337ac6a4445SGunnar Mills { 338c1343bf6SKrzysztof Grobelny if (allowedMemoryModes->ends_with(v)) 339ac6a4445SGunnar Mills { 340ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["OperatingMemoryModes"] 341ac106bf6SEd Tanous .push_back(v); 342ac6a4445SGunnar Mills break; 343ac6a4445SGunnar Mills } 344ac6a4445SGunnar Mills } 345ac6a4445SGunnar Mills } 346c1343bf6SKrzysztof Grobelny 347c1343bf6SKrzysztof Grobelny if (memoryMedia != nullptr) 348ac6a4445SGunnar Mills { 349ac6a4445SGunnar Mills constexpr const std::array<const char*, 3> values{"DRAM", "NAND", 350ac6a4445SGunnar Mills "Intel3DXPoint"}; 351ac6a4445SGunnar Mills 352ac6a4445SGunnar Mills for (const char* v : values) 353ac6a4445SGunnar Mills { 354c1343bf6SKrzysztof Grobelny if (memoryMedia->ends_with(v)) 355ac6a4445SGunnar Mills { 356ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["MemoryMedia"].push_back(v); 357ac6a4445SGunnar Mills break; 358ac6a4445SGunnar Mills } 359ac6a4445SGunnar Mills } 360ac6a4445SGunnar Mills } 361c1343bf6SKrzysztof Grobelny 362c1343bf6SKrzysztof Grobelny if (configurationLockCapable != nullptr) 363ac6a4445SGunnar Mills { 364ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["SecurityCapabilities"] 365c1343bf6SKrzysztof Grobelny ["ConfigurationLockCapable"] = 366c1343bf6SKrzysztof Grobelny *configurationLockCapable; 367ac6a4445SGunnar Mills } 368c1343bf6SKrzysztof Grobelny 369c1343bf6SKrzysztof Grobelny if (dataLockCapable != nullptr) 370ac6a4445SGunnar Mills { 371bd79bce8SPatrick Williams asyncResp->res 372bd79bce8SPatrick Williams .jsonValue[jsonPtr]["SecurityCapabilities"]["DataLockCapable"] = 373bd79bce8SPatrick Williams *dataLockCapable; 374ac6a4445SGunnar Mills } 375c1343bf6SKrzysztof Grobelny 376c1343bf6SKrzysztof Grobelny if (passphraseCapable != nullptr) 377c1343bf6SKrzysztof Grobelny { 378bd79bce8SPatrick Williams asyncResp->res 379bd79bce8SPatrick Williams .jsonValue[jsonPtr]["SecurityCapabilities"]["PassphraseCapable"] = 380bd79bce8SPatrick Williams *passphraseCapable; 381c1343bf6SKrzysztof Grobelny } 382c1343bf6SKrzysztof Grobelny 383c1343bf6SKrzysztof Grobelny if (maxPassphraseCount != nullptr) 384c1343bf6SKrzysztof Grobelny { 385bd79bce8SPatrick Williams asyncResp->res 386bd79bce8SPatrick Williams .jsonValue[jsonPtr]["SecurityCapabilities"]["MaxPassphraseCount"] = 387bd79bce8SPatrick Williams *maxPassphraseCount; 388c1343bf6SKrzysztof Grobelny } 389c1343bf6SKrzysztof Grobelny 390c1343bf6SKrzysztof Grobelny if (passphraseLockLimit != nullptr) 391c1343bf6SKrzysztof Grobelny { 392bd79bce8SPatrick Williams asyncResp->res 393bd79bce8SPatrick Williams .jsonValue[jsonPtr]["SecurityCapabilities"]["PassphraseLockLimit"] = 394bd79bce8SPatrick Williams *passphraseLockLimit; 395ac6a4445SGunnar Mills } 396ac6a4445SGunnar Mills } 397ac6a4445SGunnar Mills 398bd79bce8SPatrick Williams inline void assembleDimmProperties( 399bd79bce8SPatrick Williams std::string_view dimmId, 400ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 401d7f04fd9SNan Zhou const dbus::utility::DBusPropertiesMap& properties, 402d7f04fd9SNan Zhou const nlohmann::json::json_pointer& jsonPtr) 403ac6a4445SGunnar Mills { 404ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["Id"] = dimmId; 405ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["Name"] = "DIMM Slot"; 406539d8c6bSEd Tanous asyncResp->res.jsonValue[jsonPtr]["Status"]["State"] = 407539d8c6bSEd Tanous resource::State::Enabled; 408539d8c6bSEd Tanous asyncResp->res.jsonValue[jsonPtr]["Status"]["Health"] = 409539d8c6bSEd Tanous resource::Health::OK; 410ac6a4445SGunnar Mills 411c1343bf6SKrzysztof Grobelny const uint16_t* memoryDataWidth = nullptr; 412c1343bf6SKrzysztof Grobelny const size_t* memorySizeInKB = nullptr; 413c1343bf6SKrzysztof Grobelny const std::string* partNumber = nullptr; 414c1343bf6SKrzysztof Grobelny const std::string* serialNumber = nullptr; 415c1343bf6SKrzysztof Grobelny const std::string* manufacturer = nullptr; 416c1343bf6SKrzysztof Grobelny const uint16_t* revisionCode = nullptr; 417c1343bf6SKrzysztof Grobelny const bool* present = nullptr; 418c1343bf6SKrzysztof Grobelny const uint16_t* memoryTotalWidth = nullptr; 419c1343bf6SKrzysztof Grobelny const std::string* ecc = nullptr; 420c1343bf6SKrzysztof Grobelny const std::string* formFactor = nullptr; 421c1343bf6SKrzysztof Grobelny const std::vector<uint16_t>* allowedSpeedsMT = nullptr; 4226995c1ceSGeorge Liu const size_t* memoryAttributes = nullptr; 423c1343bf6SKrzysztof Grobelny const uint16_t* memoryConfiguredSpeedInMhz = nullptr; 424c1343bf6SKrzysztof Grobelny const std::string* memoryType = nullptr; 4256fde5971SJayaprakash Mutyala const std::uint8_t* channel = nullptr; 4266fde5971SJayaprakash Mutyala const std::uint8_t* memoryController = nullptr; 4276fde5971SJayaprakash Mutyala const std::uint8_t* slot = nullptr; 4286fde5971SJayaprakash Mutyala const std::uint8_t* socket = nullptr; 429c1343bf6SKrzysztof Grobelny const std::string* sparePartNumber = nullptr; 430c1343bf6SKrzysztof Grobelny const std::string* model = nullptr; 431c1343bf6SKrzysztof Grobelny const std::string* locationCode = nullptr; 432ac6a4445SGunnar Mills 433c1343bf6SKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 434c1343bf6SKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "MemoryDataWidth", 435c1343bf6SKrzysztof Grobelny memoryDataWidth, "MemorySizeInKB", memorySizeInKB, "PartNumber", 436656472d9SNikhil Namjoshi partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer, 437656472d9SNikhil Namjoshi "RevisionCode", revisionCode, "Present", present, "MemoryTotalWidth", 438656472d9SNikhil Namjoshi memoryTotalWidth, "ECC", ecc, "FormFactor", formFactor, 439656472d9SNikhil Namjoshi "AllowedSpeedsMT", allowedSpeedsMT, "MemoryAttributes", 440c1343bf6SKrzysztof Grobelny memoryAttributes, "MemoryConfiguredSpeedInMhz", 441c1343bf6SKrzysztof Grobelny memoryConfiguredSpeedInMhz, "MemoryType", memoryType, "Channel", 442c1343bf6SKrzysztof Grobelny channel, "MemoryController", memoryController, "Slot", slot, "Socket", 443c1343bf6SKrzysztof Grobelny socket, "SparePartNumber", sparePartNumber, "Model", model, 444c1343bf6SKrzysztof Grobelny "LocationCode", locationCode); 445c1343bf6SKrzysztof Grobelny 446c1343bf6SKrzysztof Grobelny if (!success) 447ac6a4445SGunnar Mills { 448ac106bf6SEd Tanous messages::internalError(asyncResp->res); 449601af5edSChicago Duan return; 450ac6a4445SGunnar Mills } 451c1343bf6SKrzysztof Grobelny 452c1343bf6SKrzysztof Grobelny if (memoryDataWidth != nullptr) 453c1343bf6SKrzysztof Grobelny { 454ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["DataWidthBits"] = *memoryDataWidth; 455c1343bf6SKrzysztof Grobelny } 456c1343bf6SKrzysztof Grobelny 457c1343bf6SKrzysztof Grobelny if (memorySizeInKB != nullptr) 458c1343bf6SKrzysztof Grobelny { 459ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["CapacityMiB"] = 460ac106bf6SEd Tanous (*memorySizeInKB >> 10); 461c1343bf6SKrzysztof Grobelny } 462c1343bf6SKrzysztof Grobelny 463c1343bf6SKrzysztof Grobelny if (partNumber != nullptr) 464c1343bf6SKrzysztof Grobelny { 465ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["PartNumber"] = *partNumber; 466c1343bf6SKrzysztof Grobelny } 467c1343bf6SKrzysztof Grobelny 468c1343bf6SKrzysztof Grobelny if (serialNumber != nullptr) 469c1343bf6SKrzysztof Grobelny { 470ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["SerialNumber"] = *serialNumber; 471c1343bf6SKrzysztof Grobelny } 472c1343bf6SKrzysztof Grobelny 473c1343bf6SKrzysztof Grobelny if (manufacturer != nullptr) 474c1343bf6SKrzysztof Grobelny { 475ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["Manufacturer"] = *manufacturer; 476c1343bf6SKrzysztof Grobelny } 477c1343bf6SKrzysztof Grobelny 478c1343bf6SKrzysztof Grobelny if (revisionCode != nullptr) 479c1343bf6SKrzysztof Grobelny { 480ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["FirmwareRevision"] = 481c1343bf6SKrzysztof Grobelny std::to_string(*revisionCode); 482ac6a4445SGunnar Mills } 483c1343bf6SKrzysztof Grobelny 484c1343bf6SKrzysztof Grobelny if (present != nullptr && !*present) 4859a128eb3SJoshi-Mansi { 486539d8c6bSEd Tanous asyncResp->res.jsonValue[jsonPtr]["Status"]["State"] = 487539d8c6bSEd Tanous resource::State::Absent; 4889a128eb3SJoshi-Mansi } 489c1343bf6SKrzysztof Grobelny 490c1343bf6SKrzysztof Grobelny if (memoryTotalWidth != nullptr) 491ac6a4445SGunnar Mills { 492ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["BusWidthBits"] = *memoryTotalWidth; 493ac6a4445SGunnar Mills } 494c1343bf6SKrzysztof Grobelny 495c1343bf6SKrzysztof Grobelny if (ecc != nullptr) 496ac6a4445SGunnar Mills { 497ac6a4445SGunnar Mills constexpr const std::array<const char*, 4> values{ 4989a5aceacSNan Zhou "NoECC", "SingleBitECC", "MultiBitECC", "AddressParity"}; 499ac6a4445SGunnar Mills 500ac6a4445SGunnar Mills for (const char* v : values) 501ac6a4445SGunnar Mills { 502c1343bf6SKrzysztof Grobelny if (ecc->ends_with(v)) 503ac6a4445SGunnar Mills { 504ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["ErrorCorrection"] = v; 505ac6a4445SGunnar Mills break; 506ac6a4445SGunnar Mills } 507ac6a4445SGunnar Mills } 508ac6a4445SGunnar Mills } 509c1343bf6SKrzysztof Grobelny 510c1343bf6SKrzysztof Grobelny if (formFactor != nullptr) 511ac6a4445SGunnar Mills { 512ac6a4445SGunnar Mills constexpr const std::array<const char*, 11> values{ 5139a5aceacSNan Zhou "RDIMM", "UDIMM", "SO_DIMM", "LRDIMM", 5149a5aceacSNan Zhou "Mini_RDIMM", "Mini_UDIMM", "SO_RDIMM_72b", "SO_UDIMM_72b", 5159a5aceacSNan Zhou "SO_DIMM_16b", "SO_DIMM_32b", "Die"}; 516ac6a4445SGunnar Mills 517ac6a4445SGunnar Mills for (const char* v : values) 518ac6a4445SGunnar Mills { 519c1343bf6SKrzysztof Grobelny if (formFactor->ends_with(v)) 520ac6a4445SGunnar Mills { 521ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["BaseModuleType"] = v; 522ac6a4445SGunnar Mills break; 523ac6a4445SGunnar Mills } 524ac6a4445SGunnar Mills } 525ac6a4445SGunnar Mills } 526c1343bf6SKrzysztof Grobelny 527c1343bf6SKrzysztof Grobelny if (allowedSpeedsMT != nullptr) 528ac6a4445SGunnar Mills { 529d7f04fd9SNan Zhou nlohmann::json& jValue = 530ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["AllowedSpeedsMHz"]; 531ac6a4445SGunnar Mills jValue = nlohmann::json::array(); 532c1343bf6SKrzysztof Grobelny for (uint16_t subVal : *allowedSpeedsMT) 533ac6a4445SGunnar Mills { 534ac6a4445SGunnar Mills jValue.push_back(subVal); 535ac6a4445SGunnar Mills } 536ac6a4445SGunnar Mills } 537ac6a4445SGunnar Mills 538c1343bf6SKrzysztof Grobelny if (memoryAttributes != nullptr) 539ac6a4445SGunnar Mills { 5406995c1ceSGeorge Liu asyncResp->res.jsonValue[jsonPtr]["RankCount"] = *memoryAttributes; 541ac6a4445SGunnar Mills } 542c1343bf6SKrzysztof Grobelny 543c1343bf6SKrzysztof Grobelny if (memoryConfiguredSpeedInMhz != nullptr) 544ac6a4445SGunnar Mills { 545ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["OperatingSpeedMhz"] = 546c1343bf6SKrzysztof Grobelny *memoryConfiguredSpeedInMhz; 547ac6a4445SGunnar Mills } 548c1343bf6SKrzysztof Grobelny 549c1343bf6SKrzysztof Grobelny if (memoryType != nullptr) 550ac6a4445SGunnar Mills { 551313efb1cSGunnar Mills std::string memoryDeviceType = 552c1343bf6SKrzysztof Grobelny translateMemoryTypeToRedfish(*memoryType); 553313efb1cSGunnar Mills // Values like "Unknown" or "Other" will return empty 554313efb1cSGunnar Mills // so just leave off 555313efb1cSGunnar Mills if (!memoryDeviceType.empty()) 556ac6a4445SGunnar Mills { 557ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["MemoryDeviceType"] = 558d7f04fd9SNan Zhou memoryDeviceType; 559ac6a4445SGunnar Mills } 560c1343bf6SKrzysztof Grobelny if (memoryType->find("DDR") != std::string::npos) 561ac6a4445SGunnar Mills { 562539d8c6bSEd Tanous asyncResp->res.jsonValue[jsonPtr]["MemoryType"] = 563539d8c6bSEd Tanous memory::MemoryType::DRAM; 564ac6a4445SGunnar Mills } 565c1343bf6SKrzysztof Grobelny else if (memoryType->ends_with("Logical")) 566ac6a4445SGunnar Mills { 567539d8c6bSEd Tanous asyncResp->res.jsonValue[jsonPtr]["MemoryType"] = 568539d8c6bSEd Tanous memory::MemoryType::IntelOptane; 569ac6a4445SGunnar Mills } 570ac6a4445SGunnar Mills } 571c1343bf6SKrzysztof Grobelny 572c1343bf6SKrzysztof Grobelny if (channel != nullptr) 573ac6a4445SGunnar Mills { 574ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Channel"] = 575ac106bf6SEd Tanous *channel; 576c1343bf6SKrzysztof Grobelny } 577c1343bf6SKrzysztof Grobelny 578c1343bf6SKrzysztof Grobelny if (memoryController != nullptr) 579ac6a4445SGunnar Mills { 580bd79bce8SPatrick Williams asyncResp->res 581bd79bce8SPatrick Williams .jsonValue[jsonPtr]["MemoryLocation"]["MemoryController"] = 582bd79bce8SPatrick Williams *memoryController; 583ac6a4445SGunnar Mills } 584c1343bf6SKrzysztof Grobelny 585c1343bf6SKrzysztof Grobelny if (slot != nullptr) 586ee135e24SSunnySrivastava1984 { 587ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Slot"] = *slot; 588c1343bf6SKrzysztof Grobelny } 589c1343bf6SKrzysztof Grobelny 590c1343bf6SKrzysztof Grobelny if (socket != nullptr) 591ee135e24SSunnySrivastava1984 { 592ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Socket"] = *socket; 593ee135e24SSunnySrivastava1984 } 594c1343bf6SKrzysztof Grobelny 595c1343bf6SKrzysztof Grobelny if (sparePartNumber != nullptr) 596ee135e24SSunnySrivastava1984 { 597ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["SparePartNumber"] = *sparePartNumber; 598c1343bf6SKrzysztof Grobelny } 599c1343bf6SKrzysztof Grobelny 600c1343bf6SKrzysztof Grobelny if (model != nullptr) 601ee135e24SSunnySrivastava1984 { 602ac106bf6SEd Tanous asyncResp->res.jsonValue[jsonPtr]["Model"] = *model; 603ee135e24SSunnySrivastava1984 } 604c1343bf6SKrzysztof Grobelny 605c1343bf6SKrzysztof Grobelny if (locationCode != nullptr) 606ee135e24SSunnySrivastava1984 { 607bd79bce8SPatrick Williams asyncResp->res 608bd79bce8SPatrick Williams .jsonValue[jsonPtr]["Location"]["PartLocation"]["ServiceLabel"] = 609bd79bce8SPatrick Williams *locationCode; 610ee135e24SSunnySrivastava1984 } 611c1343bf6SKrzysztof Grobelny 612ac106bf6SEd Tanous getPersistentMemoryProperties(asyncResp, properties, jsonPtr); 6139a5aceacSNan Zhou } 6149a5aceacSNan Zhou 615bd79bce8SPatrick Williams inline void getDimmDataByService( 616bd79bce8SPatrick Williams std::shared_ptr<bmcweb::AsyncResp> asyncResp, const std::string& dimmId, 617bd79bce8SPatrick Williams const std::string& service, const std::string& objPath) 6189a5aceacSNan Zhou { 61962598e31SEd Tanous BMCWEB_LOG_DEBUG("Get available system components."); 620deae6a78SEd Tanous dbus::utility::getAllProperties( 621deae6a78SEd Tanous service, objPath, "", 622ac106bf6SEd Tanous [dimmId, asyncResp{std::move(asyncResp)}]( 6235e7e2dc5SEd Tanous const boost::system::error_code& ec, 6249a5aceacSNan Zhou const dbus::utility::DBusPropertiesMap& properties) { 6259a5aceacSNan Zhou if (ec) 6269a5aceacSNan Zhou { 62762598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error"); 628ac106bf6SEd Tanous messages::internalError(asyncResp->res); 6299a5aceacSNan Zhou return; 6309a5aceacSNan Zhou } 631bd79bce8SPatrick Williams assembleDimmProperties(dimmId, asyncResp, properties, 632bd79bce8SPatrick Williams ""_json_pointer); 633c1343bf6SKrzysztof Grobelny }); 634ac6a4445SGunnar Mills } 635ac6a4445SGunnar Mills 636ef00d7d4SNan Zhou inline void assembleDimmPartitionData( 637ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 638d7f04fd9SNan Zhou const dbus::utility::DBusPropertiesMap& properties, 639d7f04fd9SNan Zhou const nlohmann::json::json_pointer& regionPtr) 640ac6a4445SGunnar Mills { 641c1343bf6SKrzysztof Grobelny const std::string* memoryClassification = nullptr; 642c1343bf6SKrzysztof Grobelny const uint64_t* offsetInKiB = nullptr; 643c1343bf6SKrzysztof Grobelny const std::string* partitionId = nullptr; 644c1343bf6SKrzysztof Grobelny const bool* passphraseState = nullptr; 645c1343bf6SKrzysztof Grobelny const uint64_t* sizeInKiB = nullptr; 646c1343bf6SKrzysztof Grobelny 647c1343bf6SKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 648c1343bf6SKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "MemoryClassification", 649c1343bf6SKrzysztof Grobelny memoryClassification, "OffsetInKiB", offsetInKiB, "PartitionId", 650c1343bf6SKrzysztof Grobelny partitionId, "PassphraseState", passphraseState, "SizeInKiB", 651c1343bf6SKrzysztof Grobelny sizeInKiB); 652c1343bf6SKrzysztof Grobelny 653c1343bf6SKrzysztof Grobelny if (!success) 654c1343bf6SKrzysztof Grobelny { 655ac106bf6SEd Tanous messages::internalError(asyncResp->res); 656c1343bf6SKrzysztof Grobelny return; 657c1343bf6SKrzysztof Grobelny } 658c1343bf6SKrzysztof Grobelny 659d7f04fd9SNan Zhou nlohmann::json::object_t partition; 660c1343bf6SKrzysztof Grobelny 661c1343bf6SKrzysztof Grobelny if (memoryClassification != nullptr) 662ac6a4445SGunnar Mills { 663c1343bf6SKrzysztof Grobelny partition["MemoryClassification"] = *memoryClassification; 664ac6a4445SGunnar Mills } 665ac6a4445SGunnar Mills 666c1343bf6SKrzysztof Grobelny if (offsetInKiB != nullptr) 667ac6a4445SGunnar Mills { 668c1343bf6SKrzysztof Grobelny partition["OffsetMiB"] = (*offsetInKiB >> 10); 669ac6a4445SGunnar Mills } 670ac6a4445SGunnar Mills 671c1343bf6SKrzysztof Grobelny if (partitionId != nullptr) 672ac6a4445SGunnar Mills { 673c1343bf6SKrzysztof Grobelny partition["RegionId"] = *partitionId; 674c1343bf6SKrzysztof Grobelny } 675c1343bf6SKrzysztof Grobelny 676c1343bf6SKrzysztof Grobelny if (passphraseState != nullptr) 677ac6a4445SGunnar Mills { 678c1343bf6SKrzysztof Grobelny partition["PassphraseEnabled"] = *passphraseState; 679ac6a4445SGunnar Mills } 680c1343bf6SKrzysztof Grobelny 681c1343bf6SKrzysztof Grobelny if (sizeInKiB != nullptr) 682ac6a4445SGunnar Mills { 683c1343bf6SKrzysztof Grobelny partition["SizeMiB"] = (*sizeInKiB >> 10); 684ac6a4445SGunnar Mills } 685c1343bf6SKrzysztof Grobelny 686ac106bf6SEd Tanous asyncResp->res.jsonValue[regionPtr].emplace_back(std::move(partition)); 687ef00d7d4SNan Zhou } 688ef00d7d4SNan Zhou 689ac106bf6SEd Tanous inline void getDimmPartitionData(std::shared_ptr<bmcweb::AsyncResp> asyncResp, 690ef00d7d4SNan Zhou const std::string& service, 691ef00d7d4SNan Zhou const std::string& path) 692ef00d7d4SNan Zhou { 693deae6a78SEd Tanous dbus::utility::getAllProperties( 694deae6a78SEd Tanous service, path, 695c1343bf6SKrzysztof Grobelny "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition", 696ac106bf6SEd Tanous [asyncResp{std::move(asyncResp)}]( 6975e7e2dc5SEd Tanous const boost::system::error_code& ec, 698ef00d7d4SNan Zhou const dbus::utility::DBusPropertiesMap& properties) { 699ef00d7d4SNan Zhou if (ec) 700ef00d7d4SNan Zhou { 70162598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error"); 702ac106bf6SEd Tanous messages::internalError(asyncResp->res); 703ef00d7d4SNan Zhou 704ef00d7d4SNan Zhou return; 705ef00d7d4SNan Zhou } 706d7f04fd9SNan Zhou nlohmann::json::json_pointer regionPtr = "/Regions"_json_pointer; 707ac106bf6SEd Tanous assembleDimmPartitionData(asyncResp, properties, regionPtr); 708c1343bf6SKrzysztof Grobelny } 709ac6a4445SGunnar Mills 710c1343bf6SKrzysztof Grobelny ); 711ac6a4445SGunnar Mills } 712ac6a4445SGunnar Mills 713ac106bf6SEd Tanous inline void getDimmData(std::shared_ptr<bmcweb::AsyncResp> asyncResp, 714ac6a4445SGunnar Mills const std::string& dimmId) 715ac6a4445SGunnar Mills { 71662598e31SEd Tanous BMCWEB_LOG_DEBUG("Get available system dimm resources."); 717e99073f5SGeorge Liu constexpr std::array<std::string_view, 2> dimmInterfaces = { 718e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.Dimm", 719e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"}; 720e99073f5SGeorge Liu dbus::utility::getSubTree( 721e99073f5SGeorge Liu "/xyz/openbmc_project/inventory", 0, dimmInterfaces, 722ac106bf6SEd Tanous [dimmId, asyncResp{std::move(asyncResp)}]( 723e99073f5SGeorge Liu const boost::system::error_code& ec, 724b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 725ac6a4445SGunnar Mills if (ec) 726ac6a4445SGunnar Mills { 72762598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error"); 728ac106bf6SEd Tanous messages::internalError(asyncResp->res); 729ac6a4445SGunnar Mills 730ac6a4445SGunnar Mills return; 731ac6a4445SGunnar Mills } 732ac6a4445SGunnar Mills bool found = false; 73376686dccSNan Zhou for (const auto& [rawPath, object] : subtree) 734ac6a4445SGunnar Mills { 73576686dccSNan Zhou sdbusplus::message::object_path path(rawPath); 736ac6a4445SGunnar Mills for (const auto& [service, interfaces] : object) 737ac6a4445SGunnar Mills { 738b9d36b47SEd Tanous for (const auto& interface : interfaces) 739ac6a4445SGunnar Mills { 740b9d36b47SEd Tanous if (interface == 74176686dccSNan Zhou "xyz.openbmc_project.Inventory.Item.Dimm" && 74276686dccSNan Zhou path.filename() == dimmId) 743b9d36b47SEd Tanous { 744ac106bf6SEd Tanous getDimmDataByService(asyncResp, dimmId, service, 745ac106bf6SEd Tanous rawPath); 746ac6a4445SGunnar Mills found = true; 747ac6a4445SGunnar Mills } 748ac6a4445SGunnar Mills 749b9d36b47SEd Tanous // partitions are separate as there can be multiple 750b9d36b47SEd Tanous // per 751ac6a4445SGunnar Mills // device, i.e. 752ac6a4445SGunnar Mills // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1 753ac6a4445SGunnar Mills // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2 754b9d36b47SEd Tanous if (interface == 75576686dccSNan Zhou "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition" && 75676686dccSNan Zhou path.parent_path().filename() == dimmId) 757ac6a4445SGunnar Mills { 758ac106bf6SEd Tanous getDimmPartitionData(asyncResp, service, rawPath); 759ac6a4445SGunnar Mills } 760ac6a4445SGunnar Mills } 761ac6a4445SGunnar Mills } 762b9d36b47SEd Tanous } 763ac6a4445SGunnar Mills // Object not found 764ac6a4445SGunnar Mills if (!found) 765ac6a4445SGunnar Mills { 766ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "Memory", dimmId); 7671a1d5d6dSNan Zhou return; 768ac6a4445SGunnar Mills } 7691a1d5d6dSNan Zhou // Set @odata only if object is found 770ac106bf6SEd Tanous asyncResp->res.jsonValue["@odata.type"] = "#Memory.v1_11_0.Memory"; 771ac106bf6SEd Tanous asyncResp->res.jsonValue["@odata.id"] = 772253f11b8SEd Tanous boost::urls::format("/redfish/v1/Systems/{}/Memory/{}", 773253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME, dimmId); 774ac6a4445SGunnar Mills return; 775e99073f5SGeorge Liu }); 776ac6a4445SGunnar Mills } 777ac6a4445SGunnar Mills 7787e860f15SJohn Edward Broadbent inline void requestRoutesMemoryCollection(App& app) 779ac6a4445SGunnar Mills { 780ac6a4445SGunnar Mills /** 781ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 782ac6a4445SGunnar Mills */ 78322d268cbSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/") 784ed398213SEd Tanous .privileges(redfish::privileges::getMemoryCollection) 7857e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 78645ca1b86SEd Tanous [&app](const crow::Request& req, 78722d268cbSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 78822d268cbSEd Tanous const std::string& systemName) { 7893ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 79045ca1b86SEd Tanous { 79145ca1b86SEd Tanous return; 79245ca1b86SEd Tanous } 79325b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 7947f3e84a1SEd Tanous { 7957f3e84a1SEd Tanous // Option currently returns no systems. TBD 7967f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 7977f3e84a1SEd Tanous systemName); 7987f3e84a1SEd Tanous return; 7997f3e84a1SEd Tanous } 800253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 80122d268cbSEd Tanous { 80222d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 80322d268cbSEd Tanous systemName); 80422d268cbSEd Tanous return; 80522d268cbSEd Tanous } 80622d268cbSEd Tanous 8078d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 8088d1b46d7Szhanghch05 "#MemoryCollection.MemoryCollection"; 8098d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Memory Module Collection"; 810bd79bce8SPatrick Williams asyncResp->res.jsonValue["@odata.id"] = 811bd79bce8SPatrick Williams boost::urls::format("/redfish/v1/Systems/{}/Memory", 812bd79bce8SPatrick Williams BMCWEB_REDFISH_SYSTEM_URI_NAME); 813ac6a4445SGunnar Mills 8147a1dbc48SGeorge Liu constexpr std::array<std::string_view, 1> interfaces{ 8157a1dbc48SGeorge Liu "xyz.openbmc_project.Inventory.Item.Dimm"}; 81605030b8eSGunnar Mills collection_util::getCollectionMembers( 817253f11b8SEd Tanous asyncResp, 818253f11b8SEd Tanous boost::urls::format("/redfish/v1/Systems/{}/Memory", 819253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME), 82036b5f1edSLakshmi Yadlapati interfaces, "/xyz/openbmc_project/inventory"); 8217e860f15SJohn Edward Broadbent }); 822ac6a4445SGunnar Mills } 823ac6a4445SGunnar Mills 8247e860f15SJohn Edward Broadbent inline void requestRoutesMemory(App& app) 8257e860f15SJohn Edward Broadbent { 826ac6a4445SGunnar Mills /** 827ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 828ac6a4445SGunnar Mills */ 82922d268cbSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Memory/<str>/") 830ed398213SEd Tanous .privileges(redfish::privileges::getMemory) 8317e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 83245ca1b86SEd Tanous [&app](const crow::Request& req, 8337e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 83422d268cbSEd Tanous const std::string& systemName, const std::string& dimmId) { 8353ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 83645ca1b86SEd Tanous { 83745ca1b86SEd Tanous return; 83845ca1b86SEd Tanous } 8397f3e84a1SEd Tanous 84025b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 8417f3e84a1SEd Tanous { 8427f3e84a1SEd Tanous // Option currently returns no systems. TBD 8437f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 8447f3e84a1SEd Tanous systemName); 8457f3e84a1SEd Tanous return; 8467f3e84a1SEd Tanous } 8477f3e84a1SEd Tanous 848253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 84922d268cbSEd Tanous { 85022d268cbSEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 85122d268cbSEd Tanous systemName); 85222d268cbSEd Tanous return; 85322d268cbSEd Tanous } 85422d268cbSEd Tanous 855ac6a4445SGunnar Mills getDimmData(asyncResp, dimmId); 8567e860f15SJohn Edward Broadbent }); 857ac6a4445SGunnar Mills } 858ac6a4445SGunnar Mills 859ac6a4445SGunnar Mills } // namespace redfish 860