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 31ac6a4445SGunnar Mills namespace redfish 32ac6a4445SGunnar Mills { 33ac6a4445SGunnar Mills 34313efb1cSGunnar Mills inline std::string translateMemoryTypeToRedfish(const std::string& memoryType) 35313efb1cSGunnar Mills { 36313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR") 37313efb1cSGunnar Mills { 38313efb1cSGunnar Mills return "DDR"; 39313efb1cSGunnar Mills } 40313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2") 41313efb1cSGunnar Mills { 42313efb1cSGunnar Mills return "DDR2"; 43313efb1cSGunnar Mills } 44313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR3") 45313efb1cSGunnar Mills { 46313efb1cSGunnar Mills return "DDR3"; 47313efb1cSGunnar Mills } 48313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4") 49313efb1cSGunnar Mills { 50313efb1cSGunnar Mills return "DDR4"; 51313efb1cSGunnar Mills } 52313efb1cSGunnar Mills if (memoryType == 53313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR4E_SDRAM") 54313efb1cSGunnar Mills { 55313efb1cSGunnar Mills return "DDR4E_SDRAM"; 56313efb1cSGunnar Mills } 5711a2f0f0SMansi Joshi if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR5") 5811a2f0f0SMansi Joshi { 5911a2f0f0SMansi Joshi return "DDR5"; 6011a2f0f0SMansi Joshi } 61313efb1cSGunnar Mills if (memoryType == 62313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR4_SDRAM") 63313efb1cSGunnar Mills { 64313efb1cSGunnar Mills return "LPDDR4_SDRAM"; 65313efb1cSGunnar Mills } 66313efb1cSGunnar Mills if (memoryType == 67313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.LPDDR3_SDRAM") 68313efb1cSGunnar Mills { 69313efb1cSGunnar Mills return "LPDDR3_SDRAM"; 70313efb1cSGunnar Mills } 71313efb1cSGunnar Mills if (memoryType == 72313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM") 73313efb1cSGunnar Mills { 74313efb1cSGunnar Mills return "DDR2_SDRAM_FB_DIMM"; 75313efb1cSGunnar Mills } 760fda0f12SGeorge Liu if (memoryType == 770fda0f12SGeorge Liu "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR2_SDRAM_FB_DIMM_PROB") 78313efb1cSGunnar Mills { 79313efb1cSGunnar Mills return "DDR2_SDRAM_FB_DIMM_PROBE"; 80313efb1cSGunnar Mills } 81313efb1cSGunnar Mills if (memoryType == 82313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.DDR_SGRAM") 83313efb1cSGunnar Mills { 84313efb1cSGunnar Mills return "DDR_SGRAM"; 85313efb1cSGunnar Mills } 86313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.ROM") 87313efb1cSGunnar Mills { 88313efb1cSGunnar Mills return "ROM"; 89313efb1cSGunnar Mills } 90313efb1cSGunnar Mills if (memoryType == 91313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.SDRAM") 92313efb1cSGunnar Mills { 93313efb1cSGunnar Mills return "SDRAM"; 94313efb1cSGunnar Mills } 95313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.EDO") 96313efb1cSGunnar Mills { 97313efb1cSGunnar Mills return "EDO"; 98313efb1cSGunnar Mills } 99313efb1cSGunnar Mills if (memoryType == 100313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.FastPageMode") 101313efb1cSGunnar Mills { 102313efb1cSGunnar Mills return "FastPageMode"; 103313efb1cSGunnar Mills } 104313efb1cSGunnar Mills if (memoryType == 105313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.PipelinedNibble") 106313efb1cSGunnar Mills { 107313efb1cSGunnar Mills return "PipelinedNibble"; 108313efb1cSGunnar Mills } 109313efb1cSGunnar Mills if (memoryType == 110313efb1cSGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.Logical") 111313efb1cSGunnar Mills { 112313efb1cSGunnar Mills return "Logical"; 113313efb1cSGunnar Mills } 114313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM") 115313efb1cSGunnar Mills { 116313efb1cSGunnar Mills return "HBM"; 117313efb1cSGunnar Mills } 118313efb1cSGunnar Mills if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM2") 119313efb1cSGunnar Mills { 120313efb1cSGunnar Mills return "HBM2"; 121313efb1cSGunnar Mills } 122*ce34d514STyson Tuckerbear if (memoryType == "xyz.openbmc_project.Inventory.Item.Dimm.DeviceType.HBM3") 123*ce34d514STyson Tuckerbear { 124*ce34d514STyson Tuckerbear return "HBM3"; 125*ce34d514STyson Tuckerbear } 126313efb1cSGunnar Mills // This is values like Other or Unknown 127313efb1cSGunnar Mills // Also D-Bus values: 128313efb1cSGunnar Mills // DRAM 129313efb1cSGunnar Mills // EDRAM 130313efb1cSGunnar Mills // VRAM 131313efb1cSGunnar Mills // SRAM 132313efb1cSGunnar Mills // RAM 133313efb1cSGunnar Mills // FLASH 134313efb1cSGunnar Mills // EEPROM 135313efb1cSGunnar Mills // FEPROM 136313efb1cSGunnar Mills // EPROM 137313efb1cSGunnar Mills // CDRAM 138313efb1cSGunnar Mills // ThreeDRAM 139313efb1cSGunnar Mills // RDRAM 140313efb1cSGunnar Mills // FBD2 141313efb1cSGunnar Mills // LPDDR_SDRAM 142313efb1cSGunnar Mills // LPDDR2_SDRAM 14311a2f0f0SMansi Joshi // LPDDR5_SDRAM 144313efb1cSGunnar Mills return ""; 145313efb1cSGunnar Mills } 146313efb1cSGunnar Mills 147c1343bf6SKrzysztof Grobelny inline void dimmPropToHex(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 148c1343bf6SKrzysztof Grobelny const char* key, const uint16_t* value, 149d7f04fd9SNan Zhou const nlohmann::json::json_pointer& jsonPtr) 150ac6a4445SGunnar Mills { 151ac6a4445SGunnar Mills if (value == nullptr) 152ac6a4445SGunnar Mills { 153ac6a4445SGunnar Mills return; 154ac6a4445SGunnar Mills } 155d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr][key] = "0x" + intToHexString(*value, 4); 156ac6a4445SGunnar Mills } 157ac6a4445SGunnar Mills 1588d1b46d7Szhanghch05 inline void getPersistentMemoryProperties( 1598d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& aResp, 160c1343bf6SKrzysztof Grobelny const dbus::utility::DBusPropertiesMap& properties, 161d7f04fd9SNan Zhou const nlohmann::json::json_pointer& jsonPtr) 162ac6a4445SGunnar Mills { 163c1343bf6SKrzysztof Grobelny const uint16_t* moduleManufacturerID = nullptr; 164c1343bf6SKrzysztof Grobelny const uint16_t* moduleProductID = nullptr; 165c1343bf6SKrzysztof Grobelny const uint16_t* subsystemVendorID = nullptr; 166c1343bf6SKrzysztof Grobelny const uint16_t* subsystemDeviceID = nullptr; 167c1343bf6SKrzysztof Grobelny const uint64_t* volatileRegionSizeLimitInKiB = nullptr; 168c1343bf6SKrzysztof Grobelny const uint64_t* pmRegionSizeLimitInKiB = nullptr; 169c1343bf6SKrzysztof Grobelny const uint64_t* volatileSizeInKiB = nullptr; 170c1343bf6SKrzysztof Grobelny const uint64_t* pmSizeInKiB = nullptr; 171c1343bf6SKrzysztof Grobelny const uint64_t* cacheSizeInKB = nullptr; 172c1343bf6SKrzysztof Grobelny const uint64_t* voltaileRegionMaxSizeInKib = nullptr; 173c1343bf6SKrzysztof Grobelny const uint64_t* pmRegionMaxSizeInKiB = nullptr; 174c1343bf6SKrzysztof Grobelny const uint64_t* allocationIncrementInKiB = nullptr; 175c1343bf6SKrzysztof Grobelny const uint64_t* allocationAlignmentInKiB = nullptr; 176c1343bf6SKrzysztof Grobelny const uint64_t* volatileRegionNumberLimit = nullptr; 177c1343bf6SKrzysztof Grobelny const uint64_t* pmRegionNumberLimit = nullptr; 178c1343bf6SKrzysztof Grobelny const uint64_t* spareDeviceCount = nullptr; 179c1343bf6SKrzysztof Grobelny const bool* isSpareDeviceInUse = nullptr; 180c1343bf6SKrzysztof Grobelny const bool* isRankSpareEnabled = nullptr; 181c1343bf6SKrzysztof Grobelny const std::vector<uint32_t>* maxAveragePowerLimitmW = nullptr; 182c1343bf6SKrzysztof Grobelny const bool* configurationLocked = nullptr; 183c1343bf6SKrzysztof Grobelny const std::string* allowedMemoryModes = nullptr; 184c1343bf6SKrzysztof Grobelny const std::string* memoryMedia = nullptr; 185c1343bf6SKrzysztof Grobelny const bool* configurationLockCapable = nullptr; 186c1343bf6SKrzysztof Grobelny const bool* dataLockCapable = nullptr; 187c1343bf6SKrzysztof Grobelny const bool* passphraseCapable = nullptr; 188c1343bf6SKrzysztof Grobelny const uint64_t* maxPassphraseCount = nullptr; 189c1343bf6SKrzysztof Grobelny const uint64_t* passphraseLockLimit = nullptr; 190c1343bf6SKrzysztof Grobelny 191c1343bf6SKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 192c1343bf6SKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "ModuleManufacturerID", 193c1343bf6SKrzysztof Grobelny moduleManufacturerID, "ModuleProductID", moduleProductID, 194c1343bf6SKrzysztof Grobelny "SubsystemVendorID", subsystemVendorID, "SubsystemDeviceID", 195c1343bf6SKrzysztof Grobelny subsystemDeviceID, "VolatileRegionSizeLimitInKiB", 196c1343bf6SKrzysztof Grobelny volatileRegionSizeLimitInKiB, "PmRegionSizeLimitInKiB", 197c1343bf6SKrzysztof Grobelny pmRegionSizeLimitInKiB, "VolatileSizeInKiB", volatileSizeInKiB, 198c1343bf6SKrzysztof Grobelny "PmSizeInKiB", pmSizeInKiB, "CacheSizeInKB", cacheSizeInKB, 199c1343bf6SKrzysztof Grobelny "VoltaileRegionMaxSizeInKib", voltaileRegionMaxSizeInKib, 200c1343bf6SKrzysztof Grobelny "PmRegionMaxSizeInKiB", pmRegionMaxSizeInKiB, 201c1343bf6SKrzysztof Grobelny "AllocationIncrementInKiB", allocationIncrementInKiB, 202c1343bf6SKrzysztof Grobelny "AllocationAlignmentInKiB", allocationAlignmentInKiB, 203c1343bf6SKrzysztof Grobelny "VolatileRegionNumberLimit", volatileRegionNumberLimit, 204c1343bf6SKrzysztof Grobelny "PmRegionNumberLimit", pmRegionNumberLimit, "SpareDeviceCount", 205c1343bf6SKrzysztof Grobelny spareDeviceCount, "IsSpareDeviceInUse", isSpareDeviceInUse, 206c1343bf6SKrzysztof Grobelny "IsRankSpareEnabled", isRankSpareEnabled, "MaxAveragePowerLimitmW", 207c1343bf6SKrzysztof Grobelny maxAveragePowerLimitmW, "ConfigurationLocked", configurationLocked, 208c1343bf6SKrzysztof Grobelny "AllowedMemoryModes", allowedMemoryModes, "MemoryMedia", memoryMedia, 209c1343bf6SKrzysztof Grobelny "ConfigurationLockCapable", configurationLockCapable, "DataLockCapable", 210c1343bf6SKrzysztof Grobelny dataLockCapable, "PassphraseCapable", passphraseCapable, 211c1343bf6SKrzysztof Grobelny "MaxPassphraseCount", maxPassphraseCount, "PassphraseLockLimit", 212c1343bf6SKrzysztof Grobelny passphraseLockLimit); 213c1343bf6SKrzysztof Grobelny 214c1343bf6SKrzysztof Grobelny if (!success) 215ac6a4445SGunnar Mills { 216c1343bf6SKrzysztof Grobelny messages::internalError(aResp->res); 217c1343bf6SKrzysztof Grobelny return; 218ac6a4445SGunnar Mills } 219c1343bf6SKrzysztof Grobelny 220c1343bf6SKrzysztof Grobelny dimmPropToHex(aResp, "ModuleManufacturerID", moduleManufacturerID, jsonPtr); 221c1343bf6SKrzysztof Grobelny dimmPropToHex(aResp, "ModuleProductID", moduleProductID, jsonPtr); 222ac6a4445SGunnar Mills dimmPropToHex(aResp, "MemorySubsystemControllerManufacturerID", 223c1343bf6SKrzysztof Grobelny subsystemVendorID, jsonPtr); 224c1343bf6SKrzysztof Grobelny dimmPropToHex(aResp, "MemorySubsystemControllerProductID", 225c1343bf6SKrzysztof Grobelny subsystemDeviceID, jsonPtr); 226ac6a4445SGunnar Mills 227c1343bf6SKrzysztof Grobelny if (volatileRegionSizeLimitInKiB != nullptr) 228ac6a4445SGunnar Mills { 229d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["VolatileRegionSizeLimitMiB"] = 230c1343bf6SKrzysztof Grobelny (*volatileRegionSizeLimitInKiB) >> 10; 231ac6a4445SGunnar Mills } 232ac6a4445SGunnar Mills 233c1343bf6SKrzysztof Grobelny if (pmRegionSizeLimitInKiB != nullptr) 234ac6a4445SGunnar Mills { 235d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["PersistentRegionSizeLimitMiB"] = 236c1343bf6SKrzysztof Grobelny (*pmRegionSizeLimitInKiB) >> 10; 237ac6a4445SGunnar Mills } 238ac6a4445SGunnar Mills 239c1343bf6SKrzysztof Grobelny if (volatileSizeInKiB != nullptr) 240ac6a4445SGunnar Mills { 241ac6a4445SGunnar Mills 242c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["VolatileSizeMiB"] = 243c1343bf6SKrzysztof Grobelny (*volatileSizeInKiB) >> 10; 244ac6a4445SGunnar Mills } 245c1343bf6SKrzysztof Grobelny 246c1343bf6SKrzysztof Grobelny if (pmSizeInKiB != nullptr) 247c1343bf6SKrzysztof Grobelny { 248c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["NonVolatileSizeMiB"] = 249c1343bf6SKrzysztof Grobelny (*pmSizeInKiB) >> 10; 250c1343bf6SKrzysztof Grobelny } 251c1343bf6SKrzysztof Grobelny 252c1343bf6SKrzysztof Grobelny if (cacheSizeInKB != nullptr) 253c1343bf6SKrzysztof Grobelny { 254c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["CacheSizeMiB"] = (*cacheSizeInKB >> 10); 255c1343bf6SKrzysztof Grobelny } 256c1343bf6SKrzysztof Grobelny 257c1343bf6SKrzysztof Grobelny if (voltaileRegionMaxSizeInKib != nullptr) 258c1343bf6SKrzysztof Grobelny { 259d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["VolatileRegionSizeMaxMiB"] = 260c1343bf6SKrzysztof Grobelny (*voltaileRegionMaxSizeInKib) >> 10; 261ac6a4445SGunnar Mills } 262ac6a4445SGunnar Mills 263c1343bf6SKrzysztof Grobelny if (pmRegionMaxSizeInKiB != nullptr) 264ac6a4445SGunnar Mills { 265d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["PersistentRegionSizeMaxMiB"] = 266c1343bf6SKrzysztof Grobelny (*pmRegionMaxSizeInKiB) >> 10; 267ac6a4445SGunnar Mills } 268ac6a4445SGunnar Mills 269c1343bf6SKrzysztof Grobelny if (allocationIncrementInKiB != nullptr) 270ac6a4445SGunnar Mills { 271d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["AllocationIncrementMiB"] = 272c1343bf6SKrzysztof Grobelny (*allocationIncrementInKiB) >> 10; 273ac6a4445SGunnar Mills } 274ac6a4445SGunnar Mills 275c1343bf6SKrzysztof Grobelny if (allocationAlignmentInKiB != nullptr) 276ac6a4445SGunnar Mills { 277d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["AllocationAlignmentMiB"] = 278c1343bf6SKrzysztof Grobelny (*allocationAlignmentInKiB) >> 10; 279ac6a4445SGunnar Mills } 280c1343bf6SKrzysztof Grobelny 281c1343bf6SKrzysztof Grobelny if (volatileRegionNumberLimit != nullptr) 282ac6a4445SGunnar Mills { 283c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["VolatileRegionNumberLimit"] = 284c1343bf6SKrzysztof Grobelny *volatileRegionNumberLimit; 285ac6a4445SGunnar Mills } 286c1343bf6SKrzysztof Grobelny 287c1343bf6SKrzysztof Grobelny if (pmRegionNumberLimit != nullptr) 288ac6a4445SGunnar Mills { 289c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["PersistentRegionNumberLimit"] = 290c1343bf6SKrzysztof Grobelny *pmRegionNumberLimit; 291ac6a4445SGunnar Mills } 292c1343bf6SKrzysztof Grobelny 293c1343bf6SKrzysztof Grobelny if (spareDeviceCount != nullptr) 294ac6a4445SGunnar Mills { 295c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["SpareDeviceCount"] = *spareDeviceCount; 296ac6a4445SGunnar Mills } 297c1343bf6SKrzysztof Grobelny 298c1343bf6SKrzysztof Grobelny if (isSpareDeviceInUse != nullptr) 299ac6a4445SGunnar Mills { 300c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["IsSpareDeviceEnabled"] = 301c1343bf6SKrzysztof Grobelny *isSpareDeviceInUse; 302ac6a4445SGunnar Mills } 303c1343bf6SKrzysztof Grobelny 304c1343bf6SKrzysztof Grobelny if (isRankSpareEnabled != nullptr) 305ac6a4445SGunnar Mills { 306c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["IsRankSpareEnabled"] = 307c1343bf6SKrzysztof Grobelny *isRankSpareEnabled; 308ac6a4445SGunnar Mills } 309c1343bf6SKrzysztof Grobelny 310c1343bf6SKrzysztof Grobelny if (maxAveragePowerLimitmW != nullptr) 311ac6a4445SGunnar Mills { 312c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["MaxTDPMilliWatts"] = 313c1343bf6SKrzysztof Grobelny *maxAveragePowerLimitmW; 314ac6a4445SGunnar Mills } 315c1343bf6SKrzysztof Grobelny 316c1343bf6SKrzysztof Grobelny if (configurationLocked != nullptr) 317ac6a4445SGunnar Mills { 318c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["ConfigurationLocked"] = 319c1343bf6SKrzysztof Grobelny *configurationLocked; 320ac6a4445SGunnar Mills } 321c1343bf6SKrzysztof Grobelny 322c1343bf6SKrzysztof Grobelny if (allowedMemoryModes != nullptr) 323ac6a4445SGunnar Mills { 32480badf7cSJiaqing Zhao constexpr const std::array<const char*, 3> values{"Volatile", "PMEM", 32580badf7cSJiaqing Zhao "Block"}; 326ac6a4445SGunnar Mills 327ac6a4445SGunnar Mills for (const char* v : values) 328ac6a4445SGunnar Mills { 329c1343bf6SKrzysztof Grobelny if (allowedMemoryModes->ends_with(v)) 330ac6a4445SGunnar Mills { 331d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["OperatingMemoryModes"].push_back( 332d7f04fd9SNan Zhou v); 333ac6a4445SGunnar Mills break; 334ac6a4445SGunnar Mills } 335ac6a4445SGunnar Mills } 336ac6a4445SGunnar Mills } 337c1343bf6SKrzysztof Grobelny 338c1343bf6SKrzysztof Grobelny if (memoryMedia != nullptr) 339ac6a4445SGunnar Mills { 340ac6a4445SGunnar Mills constexpr const std::array<const char*, 3> values{"DRAM", "NAND", 341ac6a4445SGunnar Mills "Intel3DXPoint"}; 342ac6a4445SGunnar Mills 343ac6a4445SGunnar Mills for (const char* v : values) 344ac6a4445SGunnar Mills { 345c1343bf6SKrzysztof Grobelny if (memoryMedia->ends_with(v)) 346ac6a4445SGunnar Mills { 347d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["MemoryMedia"].push_back(v); 348ac6a4445SGunnar Mills break; 349ac6a4445SGunnar Mills } 350ac6a4445SGunnar Mills } 351ac6a4445SGunnar Mills } 352c1343bf6SKrzysztof Grobelny 353c1343bf6SKrzysztof Grobelny if (configurationLockCapable != nullptr) 354ac6a4445SGunnar Mills { 355c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["SecurityCapabilities"] 356c1343bf6SKrzysztof Grobelny ["ConfigurationLockCapable"] = 357c1343bf6SKrzysztof Grobelny *configurationLockCapable; 358ac6a4445SGunnar Mills } 359c1343bf6SKrzysztof Grobelny 360c1343bf6SKrzysztof Grobelny if (dataLockCapable != nullptr) 361ac6a4445SGunnar Mills { 362c1343bf6SKrzysztof Grobelny aResp->res 363c1343bf6SKrzysztof Grobelny .jsonValue[jsonPtr]["SecurityCapabilities"]["DataLockCapable"] = 364c1343bf6SKrzysztof Grobelny *dataLockCapable; 365ac6a4445SGunnar Mills } 366c1343bf6SKrzysztof Grobelny 367c1343bf6SKrzysztof Grobelny if (passphraseCapable != nullptr) 368c1343bf6SKrzysztof Grobelny { 369c1343bf6SKrzysztof Grobelny aResp->res 370c1343bf6SKrzysztof Grobelny .jsonValue[jsonPtr]["SecurityCapabilities"]["PassphraseCapable"] = 371c1343bf6SKrzysztof Grobelny *passphraseCapable; 372c1343bf6SKrzysztof Grobelny } 373c1343bf6SKrzysztof Grobelny 374c1343bf6SKrzysztof Grobelny if (maxPassphraseCount != nullptr) 375c1343bf6SKrzysztof Grobelny { 376c1343bf6SKrzysztof Grobelny aResp->res 377c1343bf6SKrzysztof Grobelny .jsonValue[jsonPtr]["SecurityCapabilities"]["MaxPassphraseCount"] = 378c1343bf6SKrzysztof Grobelny *maxPassphraseCount; 379c1343bf6SKrzysztof Grobelny } 380c1343bf6SKrzysztof Grobelny 381c1343bf6SKrzysztof Grobelny if (passphraseLockLimit != nullptr) 382c1343bf6SKrzysztof Grobelny { 383c1343bf6SKrzysztof Grobelny aResp->res 384c1343bf6SKrzysztof Grobelny .jsonValue[jsonPtr]["SecurityCapabilities"]["PassphraseLockLimit"] = 385c1343bf6SKrzysztof Grobelny *passphraseLockLimit; 386ac6a4445SGunnar Mills } 387ac6a4445SGunnar Mills } 388ac6a4445SGunnar Mills 3899a5aceacSNan Zhou inline void 3909a5aceacSNan Zhou assembleDimmProperties(std::string_view dimmId, 3919a5aceacSNan Zhou const std::shared_ptr<bmcweb::AsyncResp>& aResp, 392d7f04fd9SNan Zhou const dbus::utility::DBusPropertiesMap& properties, 393d7f04fd9SNan Zhou const nlohmann::json::json_pointer& jsonPtr) 394ac6a4445SGunnar Mills { 395d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["Id"] = dimmId; 396d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["Name"] = "DIMM Slot"; 397d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Enabled"; 398d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["Status"]["Health"] = "OK"; 399ac6a4445SGunnar Mills 400c1343bf6SKrzysztof Grobelny const uint16_t* memoryDataWidth = nullptr; 401c1343bf6SKrzysztof Grobelny const size_t* memorySizeInKB = nullptr; 402c1343bf6SKrzysztof Grobelny const std::string* partNumber = nullptr; 403c1343bf6SKrzysztof Grobelny const std::string* serialNumber = nullptr; 404c1343bf6SKrzysztof Grobelny const std::string* manufacturer = nullptr; 405c1343bf6SKrzysztof Grobelny const uint16_t* revisionCode = nullptr; 406c1343bf6SKrzysztof Grobelny const bool* present = nullptr; 407c1343bf6SKrzysztof Grobelny const uint16_t* memoryTotalWidth = nullptr; 408c1343bf6SKrzysztof Grobelny const std::string* ecc = nullptr; 409c1343bf6SKrzysztof Grobelny const std::string* formFactor = nullptr; 410c1343bf6SKrzysztof Grobelny const std::vector<uint16_t>* allowedSpeedsMT = nullptr; 411c1343bf6SKrzysztof Grobelny const uint8_t* memoryAttributes = nullptr; 412c1343bf6SKrzysztof Grobelny const uint16_t* memoryConfiguredSpeedInMhz = nullptr; 413c1343bf6SKrzysztof Grobelny const std::string* memoryType = nullptr; 414c1343bf6SKrzysztof Grobelny const std::string* channel = nullptr; 415c1343bf6SKrzysztof Grobelny const std::string* memoryController = nullptr; 416c1343bf6SKrzysztof Grobelny const std::string* slot = nullptr; 417c1343bf6SKrzysztof Grobelny const std::string* socket = nullptr; 418c1343bf6SKrzysztof Grobelny const std::string* sparePartNumber = nullptr; 419c1343bf6SKrzysztof Grobelny const std::string* model = nullptr; 420c1343bf6SKrzysztof Grobelny const std::string* locationCode = nullptr; 421ac6a4445SGunnar Mills 422c1343bf6SKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 423c1343bf6SKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "MemoryDataWidth", 424c1343bf6SKrzysztof Grobelny memoryDataWidth, "MemorySizeInKB", memorySizeInKB, "PartNumber", 425c1343bf6SKrzysztof Grobelny partNumber, "SerialNumber", serialNumber, "Present", present, 426c1343bf6SKrzysztof Grobelny "MemoryTotalWidth", memoryTotalWidth, "ECC", ecc, "FormFactor", 427c1343bf6SKrzysztof Grobelny formFactor, "AllowedSpeedsMT", allowedSpeedsMT, "MemoryAttributes", 428c1343bf6SKrzysztof Grobelny memoryAttributes, "MemoryConfiguredSpeedInMhz", 429c1343bf6SKrzysztof Grobelny memoryConfiguredSpeedInMhz, "MemoryType", memoryType, "Channel", 430c1343bf6SKrzysztof Grobelny channel, "MemoryController", memoryController, "Slot", slot, "Socket", 431c1343bf6SKrzysztof Grobelny socket, "SparePartNumber", sparePartNumber, "Model", model, 432c1343bf6SKrzysztof Grobelny "LocationCode", locationCode); 433c1343bf6SKrzysztof Grobelny 434c1343bf6SKrzysztof Grobelny if (!success) 435ac6a4445SGunnar Mills { 436ac6a4445SGunnar Mills messages::internalError(aResp->res); 437601af5edSChicago Duan return; 438ac6a4445SGunnar Mills } 439c1343bf6SKrzysztof Grobelny 440c1343bf6SKrzysztof Grobelny if (memoryDataWidth != nullptr) 441c1343bf6SKrzysztof Grobelny { 442c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["DataWidthBits"] = *memoryDataWidth; 443c1343bf6SKrzysztof Grobelny } 444c1343bf6SKrzysztof Grobelny 445c1343bf6SKrzysztof Grobelny if (memorySizeInKB != nullptr) 446c1343bf6SKrzysztof Grobelny { 447c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["CapacityMiB"] = (*memorySizeInKB >> 10); 448c1343bf6SKrzysztof Grobelny } 449c1343bf6SKrzysztof Grobelny 450c1343bf6SKrzysztof Grobelny if (partNumber != nullptr) 451c1343bf6SKrzysztof Grobelny { 452c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["PartNumber"] = *partNumber; 453c1343bf6SKrzysztof Grobelny } 454c1343bf6SKrzysztof Grobelny 455c1343bf6SKrzysztof Grobelny if (serialNumber != nullptr) 456c1343bf6SKrzysztof Grobelny { 457c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["SerialNumber"] = *serialNumber; 458c1343bf6SKrzysztof Grobelny } 459c1343bf6SKrzysztof Grobelny 460c1343bf6SKrzysztof Grobelny if (manufacturer != nullptr) 461c1343bf6SKrzysztof Grobelny { 462c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["Manufacturer"] = *manufacturer; 463c1343bf6SKrzysztof Grobelny } 464c1343bf6SKrzysztof Grobelny 465c1343bf6SKrzysztof Grobelny if (revisionCode != nullptr) 466c1343bf6SKrzysztof Grobelny { 467d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["FirmwareRevision"] = 468c1343bf6SKrzysztof Grobelny std::to_string(*revisionCode); 469ac6a4445SGunnar Mills } 470c1343bf6SKrzysztof Grobelny 471c1343bf6SKrzysztof Grobelny if (present != nullptr && !*present) 4729a128eb3SJoshi-Mansi { 473d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["Status"]["State"] = "Absent"; 4749a128eb3SJoshi-Mansi } 475c1343bf6SKrzysztof Grobelny 476c1343bf6SKrzysztof Grobelny if (memoryTotalWidth != nullptr) 477ac6a4445SGunnar Mills { 478c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["BusWidthBits"] = *memoryTotalWidth; 479ac6a4445SGunnar Mills } 480c1343bf6SKrzysztof Grobelny 481c1343bf6SKrzysztof Grobelny if (ecc != nullptr) 482ac6a4445SGunnar Mills { 483ac6a4445SGunnar Mills constexpr const std::array<const char*, 4> values{ 4849a5aceacSNan Zhou "NoECC", "SingleBitECC", "MultiBitECC", "AddressParity"}; 485ac6a4445SGunnar Mills 486ac6a4445SGunnar Mills for (const char* v : values) 487ac6a4445SGunnar Mills { 488c1343bf6SKrzysztof Grobelny if (ecc->ends_with(v)) 489ac6a4445SGunnar Mills { 490d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["ErrorCorrection"] = v; 491ac6a4445SGunnar Mills break; 492ac6a4445SGunnar Mills } 493ac6a4445SGunnar Mills } 494ac6a4445SGunnar Mills } 495c1343bf6SKrzysztof Grobelny 496c1343bf6SKrzysztof Grobelny if (formFactor != nullptr) 497ac6a4445SGunnar Mills { 498ac6a4445SGunnar Mills constexpr const std::array<const char*, 11> values{ 4999a5aceacSNan Zhou "RDIMM", "UDIMM", "SO_DIMM", "LRDIMM", 5009a5aceacSNan Zhou "Mini_RDIMM", "Mini_UDIMM", "SO_RDIMM_72b", "SO_UDIMM_72b", 5019a5aceacSNan Zhou "SO_DIMM_16b", "SO_DIMM_32b", "Die"}; 502ac6a4445SGunnar Mills 503ac6a4445SGunnar Mills for (const char* v : values) 504ac6a4445SGunnar Mills { 505c1343bf6SKrzysztof Grobelny if (formFactor->ends_with(v)) 506ac6a4445SGunnar Mills { 507d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["BaseModuleType"] = v; 508ac6a4445SGunnar Mills break; 509ac6a4445SGunnar Mills } 510ac6a4445SGunnar Mills } 511ac6a4445SGunnar Mills } 512c1343bf6SKrzysztof Grobelny 513c1343bf6SKrzysztof Grobelny if (allowedSpeedsMT != nullptr) 514ac6a4445SGunnar Mills { 515d7f04fd9SNan Zhou nlohmann::json& jValue = 516d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["AllowedSpeedsMHz"]; 517ac6a4445SGunnar Mills jValue = nlohmann::json::array(); 518c1343bf6SKrzysztof Grobelny for (uint16_t subVal : *allowedSpeedsMT) 519ac6a4445SGunnar Mills { 520ac6a4445SGunnar Mills jValue.push_back(subVal); 521ac6a4445SGunnar Mills } 522ac6a4445SGunnar Mills } 523ac6a4445SGunnar Mills 524c1343bf6SKrzysztof Grobelny if (memoryAttributes != nullptr) 525ac6a4445SGunnar Mills { 526d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["RankCount"] = 527c1343bf6SKrzysztof Grobelny static_cast<uint64_t>(*memoryAttributes); 528ac6a4445SGunnar Mills } 529c1343bf6SKrzysztof Grobelny 530c1343bf6SKrzysztof Grobelny if (memoryConfiguredSpeedInMhz != nullptr) 531ac6a4445SGunnar Mills { 532c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["OperatingSpeedMhz"] = 533c1343bf6SKrzysztof Grobelny *memoryConfiguredSpeedInMhz; 534ac6a4445SGunnar Mills } 535c1343bf6SKrzysztof Grobelny 536c1343bf6SKrzysztof Grobelny if (memoryType != nullptr) 537ac6a4445SGunnar Mills { 538313efb1cSGunnar Mills std::string memoryDeviceType = 539c1343bf6SKrzysztof Grobelny translateMemoryTypeToRedfish(*memoryType); 540313efb1cSGunnar Mills // Values like "Unknown" or "Other" will return empty 541313efb1cSGunnar Mills // so just leave off 542313efb1cSGunnar Mills if (!memoryDeviceType.empty()) 543ac6a4445SGunnar Mills { 544d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["MemoryDeviceType"] = 545d7f04fd9SNan Zhou memoryDeviceType; 546ac6a4445SGunnar Mills } 547c1343bf6SKrzysztof Grobelny if (memoryType->find("DDR") != std::string::npos) 548ac6a4445SGunnar Mills { 549d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["MemoryType"] = "DRAM"; 550ac6a4445SGunnar Mills } 551c1343bf6SKrzysztof Grobelny else if (memoryType->ends_with("Logical")) 552ac6a4445SGunnar Mills { 553d7f04fd9SNan Zhou aResp->res.jsonValue[jsonPtr]["MemoryType"] = "IntelOptane"; 554ac6a4445SGunnar Mills } 555ac6a4445SGunnar Mills } 556c1343bf6SKrzysztof Grobelny 557c1343bf6SKrzysztof Grobelny if (channel != nullptr) 558ac6a4445SGunnar Mills { 559c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Channel"] = *channel; 560c1343bf6SKrzysztof Grobelny } 561c1343bf6SKrzysztof Grobelny 562c1343bf6SKrzysztof Grobelny if (memoryController != nullptr) 563ac6a4445SGunnar Mills { 564c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["MemoryLocation"]["MemoryController"] = 565c1343bf6SKrzysztof Grobelny *memoryController; 566ac6a4445SGunnar Mills } 567c1343bf6SKrzysztof Grobelny 568c1343bf6SKrzysztof Grobelny if (slot != nullptr) 569ee135e24SSunnySrivastava1984 { 570c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Slot"] = *slot; 571c1343bf6SKrzysztof Grobelny } 572c1343bf6SKrzysztof Grobelny 573c1343bf6SKrzysztof Grobelny if (socket != nullptr) 574ee135e24SSunnySrivastava1984 { 575c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["MemoryLocation"]["Socket"] = *socket; 576ee135e24SSunnySrivastava1984 } 577c1343bf6SKrzysztof Grobelny 578c1343bf6SKrzysztof Grobelny if (sparePartNumber != nullptr) 579ee135e24SSunnySrivastava1984 { 580c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["SparePartNumber"] = *sparePartNumber; 581c1343bf6SKrzysztof Grobelny } 582c1343bf6SKrzysztof Grobelny 583c1343bf6SKrzysztof Grobelny if (model != nullptr) 584ee135e24SSunnySrivastava1984 { 585c1343bf6SKrzysztof Grobelny aResp->res.jsonValue[jsonPtr]["Model"] = *model; 586ee135e24SSunnySrivastava1984 } 587c1343bf6SKrzysztof Grobelny 588c1343bf6SKrzysztof Grobelny if (locationCode != nullptr) 589ee135e24SSunnySrivastava1984 { 590c1343bf6SKrzysztof Grobelny aResp->res 591c1343bf6SKrzysztof Grobelny .jsonValue[jsonPtr]["Location"]["PartLocation"]["ServiceLabel"] = 592c1343bf6SKrzysztof Grobelny *locationCode; 593ee135e24SSunnySrivastava1984 } 594c1343bf6SKrzysztof Grobelny 595c1343bf6SKrzysztof Grobelny getPersistentMemoryProperties(aResp, properties, jsonPtr); 5969a5aceacSNan Zhou } 5979a5aceacSNan Zhou 5989a5aceacSNan Zhou inline void getDimmDataByService(std::shared_ptr<bmcweb::AsyncResp> aResp, 5999a5aceacSNan Zhou const std::string& dimmId, 6009a5aceacSNan Zhou const std::string& service, 6019a5aceacSNan Zhou const std::string& objPath) 6029a5aceacSNan Zhou { 6039a5aceacSNan Zhou auto health = std::make_shared<HealthPopulate>(aResp); 6049a5aceacSNan Zhou health->selfPath = objPath; 6059a5aceacSNan Zhou health->populate(); 6069a5aceacSNan Zhou 6079a5aceacSNan Zhou BMCWEB_LOG_DEBUG << "Get available system components."; 608c1343bf6SKrzysztof Grobelny sdbusplus::asio::getAllProperties( 609c1343bf6SKrzysztof Grobelny *crow::connections::systemBus, service, objPath, "", 6109a5aceacSNan Zhou [dimmId, aResp{std::move(aResp)}]( 6119a5aceacSNan Zhou const boost::system::error_code ec, 6129a5aceacSNan Zhou const dbus::utility::DBusPropertiesMap& properties) { 6139a5aceacSNan Zhou if (ec) 6149a5aceacSNan Zhou { 6159a5aceacSNan Zhou BMCWEB_LOG_DEBUG << "DBUS response error"; 6169a5aceacSNan Zhou messages::internalError(aResp->res); 6179a5aceacSNan Zhou return; 6189a5aceacSNan Zhou } 619d7f04fd9SNan Zhou assembleDimmProperties(dimmId, aResp, properties, ""_json_pointer); 620c1343bf6SKrzysztof Grobelny }); 621ac6a4445SGunnar Mills } 622ac6a4445SGunnar Mills 623ef00d7d4SNan Zhou inline void assembleDimmPartitionData( 624ef00d7d4SNan Zhou const std::shared_ptr<bmcweb::AsyncResp>& aResp, 625d7f04fd9SNan Zhou const dbus::utility::DBusPropertiesMap& properties, 626d7f04fd9SNan Zhou const nlohmann::json::json_pointer& regionPtr) 627ac6a4445SGunnar Mills { 628c1343bf6SKrzysztof Grobelny const std::string* memoryClassification = nullptr; 629c1343bf6SKrzysztof Grobelny const uint64_t* offsetInKiB = nullptr; 630c1343bf6SKrzysztof Grobelny const std::string* partitionId = nullptr; 631c1343bf6SKrzysztof Grobelny const bool* passphraseState = nullptr; 632c1343bf6SKrzysztof Grobelny const uint64_t* sizeInKiB = nullptr; 633c1343bf6SKrzysztof Grobelny 634c1343bf6SKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 635c1343bf6SKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "MemoryClassification", 636c1343bf6SKrzysztof Grobelny memoryClassification, "OffsetInKiB", offsetInKiB, "PartitionId", 637c1343bf6SKrzysztof Grobelny partitionId, "PassphraseState", passphraseState, "SizeInKiB", 638c1343bf6SKrzysztof Grobelny sizeInKiB); 639c1343bf6SKrzysztof Grobelny 640c1343bf6SKrzysztof Grobelny if (!success) 641c1343bf6SKrzysztof Grobelny { 642c1343bf6SKrzysztof Grobelny messages::internalError(aResp->res); 643c1343bf6SKrzysztof Grobelny return; 644c1343bf6SKrzysztof Grobelny } 645c1343bf6SKrzysztof Grobelny 646d7f04fd9SNan Zhou nlohmann::json::object_t partition; 647c1343bf6SKrzysztof Grobelny 648c1343bf6SKrzysztof Grobelny if (memoryClassification != nullptr) 649ac6a4445SGunnar Mills { 650c1343bf6SKrzysztof Grobelny partition["MemoryClassification"] = *memoryClassification; 651ac6a4445SGunnar Mills } 652ac6a4445SGunnar Mills 653c1343bf6SKrzysztof Grobelny if (offsetInKiB != nullptr) 654ac6a4445SGunnar Mills { 655c1343bf6SKrzysztof Grobelny partition["OffsetMiB"] = (*offsetInKiB >> 10); 656ac6a4445SGunnar Mills } 657ac6a4445SGunnar Mills 658c1343bf6SKrzysztof Grobelny if (partitionId != nullptr) 659ac6a4445SGunnar Mills { 660c1343bf6SKrzysztof Grobelny partition["RegionId"] = *partitionId; 661c1343bf6SKrzysztof Grobelny } 662c1343bf6SKrzysztof Grobelny 663c1343bf6SKrzysztof Grobelny if (passphraseState != nullptr) 664ac6a4445SGunnar Mills { 665c1343bf6SKrzysztof Grobelny partition["PassphraseEnabled"] = *passphraseState; 666ac6a4445SGunnar Mills } 667c1343bf6SKrzysztof Grobelny 668c1343bf6SKrzysztof Grobelny if (sizeInKiB != nullptr) 669ac6a4445SGunnar Mills { 670c1343bf6SKrzysztof Grobelny partition["SizeMiB"] = (*sizeInKiB >> 10); 671ac6a4445SGunnar Mills } 672c1343bf6SKrzysztof Grobelny 673d7f04fd9SNan Zhou aResp->res.jsonValue[regionPtr].emplace_back(std::move(partition)); 674ef00d7d4SNan Zhou } 675ef00d7d4SNan Zhou 676ef00d7d4SNan Zhou inline void getDimmPartitionData(std::shared_ptr<bmcweb::AsyncResp> aResp, 677ef00d7d4SNan Zhou const std::string& service, 678ef00d7d4SNan Zhou const std::string& path) 679ef00d7d4SNan Zhou { 680c1343bf6SKrzysztof Grobelny sdbusplus::asio::getAllProperties( 681c1343bf6SKrzysztof Grobelny *crow::connections::systemBus, service, path, 682c1343bf6SKrzysztof Grobelny "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition", 683ef00d7d4SNan Zhou [aResp{std::move(aResp)}]( 684ef00d7d4SNan Zhou const boost::system::error_code ec, 685ef00d7d4SNan Zhou const dbus::utility::DBusPropertiesMap& properties) { 686ef00d7d4SNan Zhou if (ec) 687ef00d7d4SNan Zhou { 688ef00d7d4SNan Zhou BMCWEB_LOG_DEBUG << "DBUS response error"; 689ef00d7d4SNan Zhou messages::internalError(aResp->res); 690ef00d7d4SNan Zhou 691ef00d7d4SNan Zhou return; 692ef00d7d4SNan Zhou } 693d7f04fd9SNan Zhou nlohmann::json::json_pointer regionPtr = "/Regions"_json_pointer; 694d7f04fd9SNan Zhou assembleDimmPartitionData(aResp, properties, regionPtr); 695c1343bf6SKrzysztof Grobelny } 696ac6a4445SGunnar Mills 697c1343bf6SKrzysztof Grobelny ); 698ac6a4445SGunnar Mills } 699ac6a4445SGunnar Mills 7008d1b46d7Szhanghch05 inline void getDimmData(std::shared_ptr<bmcweb::AsyncResp> aResp, 701ac6a4445SGunnar Mills const std::string& dimmId) 702ac6a4445SGunnar Mills { 703ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "Get available system dimm resources."; 704ac6a4445SGunnar Mills crow::connections::systemBus->async_method_call( 705ac6a4445SGunnar Mills [dimmId, aResp{std::move(aResp)}]( 706ac6a4445SGunnar Mills const boost::system::error_code ec, 707b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 708ac6a4445SGunnar Mills if (ec) 709ac6a4445SGunnar Mills { 710ac6a4445SGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error"; 711ac6a4445SGunnar Mills messages::internalError(aResp->res); 712ac6a4445SGunnar Mills 713ac6a4445SGunnar Mills return; 714ac6a4445SGunnar Mills } 715ac6a4445SGunnar Mills bool found = false; 71676686dccSNan Zhou for (const auto& [rawPath, object] : subtree) 717ac6a4445SGunnar Mills { 71876686dccSNan Zhou sdbusplus::message::object_path path(rawPath); 719ac6a4445SGunnar Mills for (const auto& [service, interfaces] : object) 720ac6a4445SGunnar Mills { 721b9d36b47SEd Tanous for (const auto& interface : interfaces) 722ac6a4445SGunnar Mills { 723b9d36b47SEd Tanous if (interface == 72476686dccSNan Zhou "xyz.openbmc_project.Inventory.Item.Dimm" && 72576686dccSNan Zhou path.filename() == dimmId) 726b9d36b47SEd Tanous { 72776686dccSNan Zhou getDimmDataByService(aResp, dimmId, service, rawPath); 728ac6a4445SGunnar Mills found = true; 729ac6a4445SGunnar Mills } 730ac6a4445SGunnar Mills 731b9d36b47SEd Tanous // partitions are separate as there can be multiple 732b9d36b47SEd Tanous // per 733ac6a4445SGunnar Mills // device, i.e. 734ac6a4445SGunnar Mills // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition1 735ac6a4445SGunnar Mills // /xyz/openbmc_project/Inventory/Item/Dimm1/Partition2 736b9d36b47SEd Tanous if (interface == 73776686dccSNan Zhou "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition" && 73876686dccSNan Zhou path.parent_path().filename() == dimmId) 739ac6a4445SGunnar Mills { 74076686dccSNan Zhou getDimmPartitionData(aResp, service, rawPath); 741ac6a4445SGunnar Mills } 742ac6a4445SGunnar Mills } 743ac6a4445SGunnar Mills } 744b9d36b47SEd Tanous } 745ac6a4445SGunnar Mills // Object not found 746ac6a4445SGunnar Mills if (!found) 747ac6a4445SGunnar Mills { 748ac6a4445SGunnar Mills messages::resourceNotFound(aResp->res, "Memory", dimmId); 7491a1d5d6dSNan Zhou return; 750ac6a4445SGunnar Mills } 7511a1d5d6dSNan Zhou // Set @odata only if object is found 7521a1d5d6dSNan Zhou aResp->res.jsonValue["@odata.type"] = "#Memory.v1_11_0.Memory"; 7531a1d5d6dSNan Zhou aResp->res.jsonValue["@odata.id"] = 7541a1d5d6dSNan Zhou "/redfish/v1/Systems/system/Memory/" + dimmId; 755ac6a4445SGunnar Mills return; 756ac6a4445SGunnar Mills }, 757ac6a4445SGunnar Mills "xyz.openbmc_project.ObjectMapper", 758ac6a4445SGunnar Mills "/xyz/openbmc_project/object_mapper", 759ac6a4445SGunnar Mills "xyz.openbmc_project.ObjectMapper", "GetSubTree", 760ac6a4445SGunnar Mills "/xyz/openbmc_project/inventory", 0, 761ac6a4445SGunnar Mills std::array<const char*, 2>{ 762ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.Dimm", 763ac6a4445SGunnar Mills "xyz.openbmc_project.Inventory.Item.PersistentMemory.Partition"}); 764ac6a4445SGunnar Mills } 765ac6a4445SGunnar Mills 7667e860f15SJohn Edward Broadbent inline void requestRoutesMemoryCollection(App& app) 767ac6a4445SGunnar Mills { 768ac6a4445SGunnar Mills /** 769ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 770ac6a4445SGunnar Mills */ 7717e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Memory/") 772ed398213SEd Tanous .privileges(redfish::privileges::getMemoryCollection) 7737e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 77445ca1b86SEd Tanous [&app](const crow::Request& req, 7757e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 7763ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 77745ca1b86SEd Tanous { 77845ca1b86SEd Tanous return; 77945ca1b86SEd Tanous } 7808d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 7818d1b46d7Szhanghch05 "#MemoryCollection.MemoryCollection"; 7828d1b46d7Szhanghch05 asyncResp->res.jsonValue["Name"] = "Memory Module Collection"; 7838d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = 7848d1b46d7Szhanghch05 "/redfish/v1/Systems/system/Memory"; 785ac6a4445SGunnar Mills 78605030b8eSGunnar Mills collection_util::getCollectionMembers( 78705030b8eSGunnar Mills asyncResp, "/redfish/v1/Systems/system/Memory", 78805030b8eSGunnar Mills {"xyz.openbmc_project.Inventory.Item.Dimm"}); 7897e860f15SJohn Edward Broadbent }); 790ac6a4445SGunnar Mills } 791ac6a4445SGunnar Mills 7927e860f15SJohn Edward Broadbent inline void requestRoutesMemory(App& app) 7937e860f15SJohn Edward Broadbent { 794ac6a4445SGunnar Mills /** 795ac6a4445SGunnar Mills * Functions triggers appropriate requests on DBus 796ac6a4445SGunnar Mills */ 7977e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Memory/<str>/") 798ed398213SEd Tanous .privileges(redfish::privileges::getMemory) 7997e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 80045ca1b86SEd Tanous [&app](const crow::Request& req, 8017e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 8027e860f15SJohn Edward Broadbent const std::string& dimmId) { 8033ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 80445ca1b86SEd Tanous { 80545ca1b86SEd Tanous return; 80645ca1b86SEd Tanous } 807ac6a4445SGunnar Mills getDimmData(asyncResp, dimmId); 8087e860f15SJohn Edward Broadbent }); 809ac6a4445SGunnar Mills } 810ac6a4445SGunnar Mills 811ac6a4445SGunnar Mills } // namespace redfish 812