Enable MemoryLocation properties to be customized
-Enable MemoryLocation properties to be customized by a json table.
Example of memoryLocationTable.json:
{
"<MemoryDeviceLocator>": {
"MemoryController": 1,
"Socket":48,
"Slot":0,
"Channel":0
}
}
-Add attribute "memoryController", "slot", "channel", "socket" in
MemoryLocation.
Tested:
memoryLocationTable.json:
{
"DIMM4": {
"MemoryController": 1,
"Socket":48,
"Slot":0,
"Channel":0
}
}
with the change:
curl -k -X GET http://${bmc}/redfish/v1/Systems/system/Memory/dimm1
{
"@odata.id": "/redfish/v1/Systems/system/Memory/dimm1",
"@odata.type": "#Memory.v1_11_0.Memory",
"AllowedSpeedsMHz": [],
"BaseModuleType": "RDIMM",
"BusWidthBits": 80,
"CapacityMiB": 49152,
"DataWidthBits": 64,
"ErrorCorrection": "SingleBitECC",
"FirmwareRevision": "0",
"Id": "dimm1",
"Location": {
"PartLocation": {
"LocationType": "Slot",
"ServiceLabel": "DIMM4"
}
},
"Manufacturer": "",
"MemoryDeviceType": "DDR5",
"MemoryLocation": {
"Channel": 0,
"MemoryController": 1,
"Slot": 0,
"Socket": 48
}
without the change:
curl -k -X GET http://${bmc}/redfish/v1/Systems/system/Memory/dimm1
{
"@odata.id": "/redfish/v1/Systems/system/Memory/dimm1",
"@odata.type": "#Memory.v1_11_0.Memory",
"AllowedSpeedsMHz": [],
"BaseModuleType": "RDIMM",
"BusWidthBits": 80,
"CapacityMiB": 49152,
"DataWidthBits": 64,
"ErrorCorrection": "SingleBitECC",
"FirmwareRevision": "0",
"Id": "dimm1",
"Location": {
"PartLocation": {
"LocationType": "Slot",
"ServiceLabel": "DIMM4"
}
},
"Manufacturer": "",
"MemoryDeviceType": "DDR5",
"MemoryLocation": {
"Channel": 0,
"MemoryController": 0,
"Slot": 0,
"Socket": 0
}
Change-Id: Ic5ff09715a619907f06d06af33aa0d1755c8b4f3
Signed-off-by: Tony Lee <tony.lee@quantatw.com>
diff --git a/include/dimm.hpp b/include/dimm.hpp
index a3a48be..e848f42 100644
--- a/include/dimm.hpp
+++ b/include/dimm.hpp
@@ -17,6 +17,7 @@
#pragma once
#include "smbios_mdrv2.hpp"
+#include <nlohmann/json.hpp>
#include <xyz/openbmc_project/Association/Definitions/server.hpp>
#include <xyz/openbmc_project/Inventory/Connector/Slot/server.hpp>
#include <xyz/openbmc_project/Inventory/Decorator/Asset/server.hpp>
@@ -41,6 +42,8 @@
using MemoryTechType =
sdbusplus::server::xyz::openbmc_project::inventory::item::Dimm::MemoryTech;
+using Json = nlohmann::json;
+
class Dimm :
sdbusplus::server::object_t<
sdbusplus::server::xyz::openbmc_project::inventory::item::Dimm>,
@@ -119,9 +122,12 @@
MemoryTechType memoryMedia(MemoryTechType value) override;
uint8_t slot(uint8_t value) override;
uint8_t socket(uint8_t value) override;
+ uint8_t memoryController(uint8_t value) override;
+ uint8_t channel(uint8_t value) override;
uint16_t memoryConfiguredSpeedInMhz(uint16_t value) override;
bool functional(bool value) override;
EccType ecc(EccType value) override;
+ Json parseConfigFile();
private:
uint8_t dimmNum;
@@ -250,6 +256,14 @@
{0x5, MemoryTechType::NVDIMM_F}, {0x6, MemoryTechType::NVDIMM_P},
{0x7, MemoryTechType::IntelOptane}};
+struct memoryLocation
+{
+ uint8_t memoryController;
+ uint8_t socket;
+ uint8_t slot;
+ uint8_t channel;
+};
+
} // namespace smbios
} // namespace phosphor
diff --git a/src/dimm.cpp b/src/dimm.cpp
index b667179..dc8bb92 100644
--- a/src/dimm.cpp
+++ b/src/dimm.cpp
@@ -21,6 +21,8 @@
#include <boost/algorithm/string.hpp>
#include <phosphor-logging/elog-errors.hpp>
+#include <fstream>
+#include <iostream>
#include <regex>
namespace phosphor
@@ -41,6 +43,10 @@
sdbusplus::server::xyz::openbmc_project::inventory::item::Dimm::Ecc;
static constexpr uint16_t maxOldDimmSize = 0x7fff;
+
+static constexpr const char* filename =
+ "/usr/share/smbios-mdr/memoryLocationTable.json";
+
void Dimm::memoryInfoUpdate(uint8_t* smbiosTableStorage,
const std::string& motherboard)
{
@@ -215,21 +221,54 @@
const std::string substrCpu = "CPU";
auto cpuPos = deviceLocator.find(substrCpu);
- if (cpuPos != std::string::npos)
+ auto data = parseConfigFile();
+
+ if (!data.empty())
{
- std::string socketString =
- deviceLocator.substr(cpuPos + substrCpu.length(), 1);
- try
+ auto it = data.find(deviceLocator);
+
+ if (it != data.end())
{
- uint8_t socketNum =
- static_cast<uint8_t>(std::stoi(socketString) + 1);
- socket(socketNum);
+ uint8_t memoryControllerValue =
+ it.value()["MemoryController"].get<uint8_t>();
+ uint8_t socketValue = it.value()["Socket"].get<uint8_t>();
+ uint8_t slotValue = it.value()["Slot"].get<uint8_t>();
+ uint8_t channelValue = it.value()["Channel"].get<uint8_t>();
+
+ socket(memoryControllerValue);
+ memoryController(socketValue);
+ slot(slotValue);
+ channel(channelValue);
}
- catch (const sdbusplus::exception_t& ex)
+ else
{
+ socket(0);
+ memoryController(0);
+ slot(0);
+ channel(0);
phosphor::logging::log<phosphor::logging::level::ERR>(
- "std::stoi operation failed ",
- phosphor::logging::entry("ERROR=%s", ex.what()));
+ "Failed find the corresponding table for dimm ",
+ phosphor::logging::entry("DIMM:%s", deviceLocator.c_str()));
+ }
+ }
+ else
+ {
+ if (cpuPos != std::string::npos)
+ {
+ std::string socketString =
+ deviceLocator.substr(cpuPos + substrCpu.length(), 1);
+ try
+ {
+ uint8_t socketNum =
+ static_cast<uint8_t>(std::stoi(socketString) + 1);
+ socket(socketNum);
+ }
+ catch (const sdbusplus::exception_t& ex)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "std::stoi operation failed ",
+ phosphor::logging::entry("ERROR=%s", ex.what()));
+ }
}
}
@@ -398,6 +437,18 @@
MemoryLocation::slot(value);
}
+uint8_t Dimm::memoryController(uint8_t value)
+{
+ return sdbusplus::server::xyz::openbmc_project::inventory::item::dimm::
+ MemoryLocation::memoryController(value);
+}
+
+uint8_t Dimm::channel(uint8_t value)
+{
+ return sdbusplus::server::xyz::openbmc_project::inventory::item::dimm::
+ MemoryLocation::channel(value);
+}
+
uint8_t Dimm::socket(uint8_t value)
{
return sdbusplus::server::xyz::openbmc_project::inventory::item::dimm::
@@ -416,5 +467,28 @@
OperationalStatus::functional(value);
}
+Json Dimm::parseConfigFile()
+{
+ std::ifstream memoryLocationFile(filename);
+
+ if (!memoryLocationFile.is_open())
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "config JSON file not found, FILENAME ",
+ phosphor::logging::entry("%s", filename));
+ return {};
+ }
+
+ auto data = Json::parse(memoryLocationFile, nullptr, false);
+ if (data.is_discarded())
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "config readings JSON parser failure");
+ return {};
+ }
+
+ return data;
+}
+
} // namespace smbios
} // namespace phosphor