DD2: Enable Dimms
This commit checks for the chip version , if it is DD2 or higher then bind the device driver
for all the Dimms(supported in vpd json)
Test-
Tested on HW with DD2 processor.
rain135bmc
root@rain135bmc:/sys/bus/i2c/drivers/at24# ls
0-0051 10-0050 6-0053 7-0050 8-0050 8-0051 9-0050 bind uevent unbind
===================after execution============================================================
root@rain135bmc:/sys/bus/i2c/drivers/at24# ls
0-0051 111-0050 311-0050 6-0053 8-0050 9-0050 uevent
10-0050 202-0050 402-0050 7-0050 8-0051 bind unbind
root@rain135bmc:/sys/bus/i2c/devices# ls
0-0020 11-0051 4-0049 5-0051 7-0040 8-0011 9-004d i2c-110 i2c-14 i2c-203 i2c-300 i2c-4 i2c-417
0-0051 13-0050 4-004a 6-0048 7-0048 8-0032 9-0050 i2c-111 i2c-15 i2c-210 i2c-301 i2c-402 i2c-5
10-004c 14-0050 4-0050 6-004a 7-0050 8-0048 i2c-0 i2c-112 i2c-16 i2c-211 i2c-310 i2c-403 i2c-6
10-004d 15-0050 4-0051 6-004b 7-0051 8-004a i2c-1 i2c-113 i2c-17 i2c-214 i2c-311 i2c-410 i2c-7
10-0050 3-0061 4-0052 6-0050 7-0052 8-0050 i2c-10 i2c-114 i2c-18 i2c-215 i2c-312 i2c-411 i2c-8
11-0048 3-0068 5-0048 6-0051 7-0061 8-0051 i2c-100 i2c-115 i2c-19 i2c-216 i2c-313 i2c-414 i2c-9
11-0049 3-0069 5-0049 6-0052 7-0076 8-0061 i2c-101 i2c-12 i2c-2 i2c-217 i2c-314 i2c-415
11-0050 4-0048 5-0050 6-0053 7-1062 9-004c i2c-11 i2c-13 i2c-202 i2c-3 i2c-315 i2c-416
root@rain135bmc:/sys/bus/i2c/devices#
===================Executing patch============================================================
root@rain135bmc:/tmp# ./ibm-read-vpd -f /sys/bus/spi/drivers/at25/spi12.0/eeprom
===================after execution============================================================
root@rain71bmc:/sys/bus/i2c/devices# ls
0-0020 111-0050 214-0050 313-0050 411-0050 6-0050 8-0011 i2c-10 i2c-14 i2c-215 i2c-4 i2c-8
0-0051 112-0050 215-0050 314-0050 414-0050 6-0051 8-0032 i2c-100 i2c-15 i2c-216 i2c-402 i2c-9
10-004c 113-0050 216-0050 315-0050 415-0050 6-0052 8-0048 i2c-101 i2c-16 i2c-217 i2c-403
10-004d 114-0050 217-0050 4-0048 416-0050 6-0053 8-004a i2c-11 i2c-17 i2c-3 i2c-410
10-0050 115-0050 3-0061 4-0049 417-0050 7-0040 8-0050 i2c-110 i2c-18 i2c-300 i2c-411
100-0050 13-0050 3-0068 4-004a 5-0048 7-0048 8-0051 i2c-111 i2c-19 i2c-301 i2c-414
101-0050 14-0050 3-0069 4-0050 5-0049 7-0050 8-0061 i2c-112 i2c-2 i2c-310 i2c-415
11-0048 15-0050 300-0050 4-0051 5-0050 7-0051 9-004c i2c-113 i2c-202 i2c-311 i2c-416
11-0049 202-0050 301-0050 4-0052 5-0051 7-0052 9-004d i2c-114 i2c-203 i2c-312 i2c-417
11-0050 203-0050 310-0050 402-0050 6-0048 7-0061 9-0050 i2c-115 i2c-210 i2c-313 i2c-5
11-0051 210-0050 311-0050 403-0050 6-004a 7-0076 i2c-0 i2c-12 i2c-211 i2c-314 i2c-6
110-0050 211-0050 312-0050 410-0050 6-004b 7-1062 i2c-1 i2c-13 i2c-214 i2c-315 i2c-7
root@rain135bmc:/sys/bus/i2c/devices#
Also, vpd got collected for all these Dimms-
root@rain135c:/tmp# busctl introspect xyz.openbmc_project.Inventory.Manager /xyz/openbmc_project/inventory/system/chassis/motherboard/dimm22| grep -e MemorySizeInKB -e Present -e PrettyName -e Model -e PartNumber -e SerialNumber
.Model property s "327A" emits-change writable
.PartNumber property s "78P6574" emits-change writable
.SerialNumber property s "YH30MS04N004" emits-change writable
.SparePartNumber property s "" emits-change writable
.SubModel property s "" emits-change writable
.Present property b true emits-change writable
.PrettyName property s "Memory DIMM" emits-change writable
.MemorySizeInKB property u 33554432 emits-change writable
root@rain135c:/tmp# busctl introspect xyz.openbmc_project.Inventory.Manager /xyz/openbmc_project/inventory/system/chassis/motherboard/dimm31| grep -e MemorySizeInKB -e Present -e PrettyName -e Model -e PartNumber -e SerialNumber
.Model property s "327A" emits-change writable
.PartNumber property s "78P6574" emits-change writable
.SerialNumber property s "YH301T9CH022" emits-change writable
.SparePartNumber property s "" emits-change writable
.SubModel property s "" emits-change writable
.Present property b true emits-change writable
.PrettyName property s "Memory DIMM" emits-change writable
.MemorySizeInKB property u 33554432 emits-change writable
root@rain135c:/tmp#
Change-Id: Iab1b099fe0352c08327e70aa8c2e33fc213cc40f
Signed-off-by: Alpana Kumari <alpankum@in.ibm.com>
diff --git a/ibm_vpd_app.cpp b/ibm_vpd_app.cpp
index bb0088f..b7de1a6 100644
--- a/ibm_vpd_app.cpp
+++ b/ibm_vpd_app.cpp
@@ -14,6 +14,7 @@
#include <CLI/CLI.hpp>
#include <algorithm>
+#include <boost/algorithm/string.hpp>
#include <cstdarg>
#include <exception>
#include <filesystem>
@@ -23,6 +24,7 @@
#include <iterator>
#include <nlohmann/json.hpp>
#include <phosphor-logging/log.hpp>
+#include <regex>
using namespace std;
using namespace openpower::vpd;
@@ -175,7 +177,6 @@
{
Binary vec(get_if<Binary>(&kwVal.second)->begin(),
get_if<Binary>(&kwVal.second)->end());
-
prop.emplace(move(kw), move(vec));
}
else
@@ -755,6 +756,107 @@
}
/**
+ * @brief This checks for is this FRU a processor
+ * And if yes, then checks for is this primary
+ *
+ * @param[in] js- vpd json to get the information about this FRU
+ * @param[in] filePath- FRU vpd
+ *
+ * @return true/false
+ */
+bool isThisPrimaryProcessor(nlohmann::json& js, const string& filePath)
+{
+ bool isProcessor = false;
+ bool isPrimary = false;
+
+ for (const auto& item : js["frus"][filePath])
+ {
+ if (item.find("extraInterfaces") != item.end())
+ {
+ for (const auto& eI : item["extraInterfaces"].items())
+ {
+ if (eI.key().find("Inventory.Item.Cpu") != string::npos)
+ {
+ isProcessor = true;
+ }
+ }
+ }
+
+ if (isProcessor)
+ {
+ string cpuType = item.value("cpuType", "");
+ if (cpuType == "primary")
+ {
+ isPrimary = true;
+ }
+ }
+ }
+
+ return (isProcessor && isPrimary);
+}
+
+/**
+ * @brief This finds DIMM vpd in vpd json and enables them by binding the device
+ * driver
+ * @param[in] js- vpd json to iterate through and take action if it is DIMM
+ */
+void doEnableAllDimms(nlohmann::json& js)
+{
+ // iterate over each fru
+ for (const auto& eachFru : js["frus"].items())
+ {
+ // skip the driver binding if eeprom already exists
+ if (fs::exists(eachFru.key()))
+ {
+ continue;
+ }
+
+ for (const auto& eachInventory : eachFru.value())
+ {
+ if (eachInventory.find("extraInterfaces") != eachInventory.end())
+ {
+ for (const auto& eI : eachInventory["extraInterfaces"].items())
+ {
+ if (eI.key().find("Inventory.Item.Dimm") != string::npos)
+ {
+ string dimmVpd = eachFru.key();
+ // fetch it from
+ // "/sys/bus/i2c/drivers/at24/414-0050/eeprom"
+
+ regex matchPatern("([0-9]+-[0-9]{4})");
+ smatch matchFound;
+ if (regex_search(dimmVpd, matchFound, matchPatern))
+ {
+ vector<string> i2cReg;
+ boost::split(i2cReg, matchFound.str(0),
+ boost::is_any_of("-"));
+
+ // remove 0s from begining
+ const regex pattern("^0+(?!$)");
+ for (auto& i : i2cReg)
+ {
+ i = regex_replace(i, pattern, "");
+ }
+
+ if (i2cReg.size() == 2)
+ {
+ // echo 24c32 0x50 >
+ // /sys/bus/i2c/devices/i2c-16/new_device
+ string cmnd = "echo 24c32 0x" + i2cReg[1] +
+ " > /sys/bus/i2c/devices/i2c-" +
+ i2cReg[0] + "/new_device";
+
+ executeCmd(cmnd);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/**
* @brief Populate Dbus.
* This method invokes all the populateInterface functions
* and notifies PIM about dbus object.
@@ -798,6 +900,23 @@
log<level::ERR>("No object path found");
}
}
+ else
+ {
+ // check if it is processor vpd.
+ auto isPrimaryCpu = isThisPrimaryProcessor(js, filePath);
+
+ if (isPrimaryCpu)
+ {
+ auto ddVersion = getKwVal(vpdMap, "CRP0", "DD");
+
+ auto chipVersion = atoi(ddVersion.substr(1, 2).c_str());
+
+ if (chipVersion >= 2)
+ {
+ doEnableAllDimms(js);
+ }
+ }
+ }
}
for (const auto& item : js["frus"][filePath])
diff --git a/ibm_vpd_utils.cpp b/ibm_vpd_utils.cpp
index 9b5530e..b8af0ed 100644
--- a/ibm_vpd_utils.cpp
+++ b/ibm_vpd_utils.cpp
@@ -543,5 +543,27 @@
badVpdFileStream.write(reinterpret_cast<const char*>(vpdVector.data()),
vpdVector.size());
}
+
+const string getKwVal(const Parsed& vpdMap, const string& rec,
+ const string& kwd)
+{
+ string kwVal{};
+
+ auto findRec = vpdMap.find(rec);
+
+ // check if record is found in map we got by parser
+ if (findRec != vpdMap.end())
+ {
+ auto findKwd = findRec->second.find(kwd);
+
+ if (findKwd != findRec->second.end())
+ {
+ kwVal = findKwd->second;
+ }
+ }
+
+ return kwVal;
+}
+
} // namespace vpd
} // namespace openpower
\ No newline at end of file
diff --git a/ibm_vpd_utils.hpp b/ibm_vpd_utils.hpp
index 8983985..8cedafb 100644
--- a/ibm_vpd_utils.hpp
+++ b/ibm_vpd_utils.hpp
@@ -209,5 +209,20 @@
* @param[in] vpdVector - bad vpd vector
*/
void dumpBadVpd(const std::string& file, const Binary& vpdVector);
+
+/*
+ * @brief This function fetches the value for given keyword in the given record
+ * from vpd data and returns this value.
+ *
+ * @param[in] vpdMap - vpd to find out the data
+ * @param[in] rec - Record under which desired keyword exists
+ * @param[in] kwd - keyword to read the data from
+ *
+ * @returns keyword value if record/keyword combination found
+ * empty string if record or keyword is not found.
+ */
+const string getKwVal(const Parsed& vpdMap, const string& rec,
+ const string& kwd);
+
} // namespace vpd
} // namespace openpower
\ No newline at end of file