util: add i2c->pcie map build method
Move method to util that handles creating a mapping between i2c-bus
numbers and their pci-e slot names. It's done as a list of tuples.
Tested: Only ran unit-tests.
Change-Id: Ie09d193add63245eebcf3806255311232a7c4c9a
Signed-off-by: Patrick Venture <venture@google.com>
diff --git a/util.cpp b/util.cpp
index 34b0f9b..eebc84e 100644
--- a/util.cpp
+++ b/util.cpp
@@ -1,17 +1,22 @@
#include "util.hpp"
+#include <cstdint>
#include <cstdio>
+#include <filesystem>
#include <fstream>
#include <nlohmann/json.hpp>
#include <phosphor-logging/elog-errors.hpp>
+#include <regex>
#include <string>
+#include <tuple>
+#include <vector>
#include <xyz/openbmc_project/Common/error.hpp>
namespace google
{
namespace ipmi
{
-
+namespace fs = std::filesystem;
using namespace phosphor::logging;
using InternalFailure =
sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
@@ -67,5 +72,60 @@
return "";
}
+std::vector<std::tuple<std::uint32_t, std::string>> buildPcieMap()
+{
+ std::vector<std::tuple<std::uint32_t, std::string>> pcie_i2c_map;
+
+ // Build a vector with i2c bus to pcie slot mapping.
+ // Iterate through all the devices under "/sys/bus/i2c/devices".
+ for (const auto& i2c_dev : fs::directory_iterator("/sys/bus/i2c/devices"))
+ {
+ std::string i2c_dev_path = i2c_dev.path();
+ std::smatch i2c_dev_string_number;
+ std::regex e("(i2c-)(\\d+)");
+
+ // Check if the device has "i2c-" in its path.
+ if (std::regex_search(i2c_dev_path, i2c_dev_string_number, e))
+ {
+ // Check if the i2c device has "pcie-slot" file under "of-node" dir.
+ std::string pcie_slot_path = i2c_dev_path + "/of_node/pcie-slot";
+ std::string pcie_slot;
+
+ // Read the "pcie-slot" name from the "pcie-slot" file.
+ pcie_slot = readPropertyFile(pcie_slot_path);
+ if (pcie_slot.empty())
+ {
+ continue;
+ }
+ std::string pcie_slot_name;
+ std::string pcie_slot_full_path;
+
+ // Append the "pcie-slot" name to dts base.
+ pcie_slot_full_path.append("/proc/device-tree");
+ pcie_slot_full_path.append(pcie_slot);
+
+ // Read the "label" which contains the pcie slot name.
+ pcie_slot_full_path.append("/label");
+ pcie_slot_name = readPropertyFile(pcie_slot_full_path);
+
+ if (pcie_slot_name.empty())
+ {
+ continue;
+ }
+
+ // Get the i2c bus number from the i2c device path.
+ std::uint32_t i2c_bus_number =
+ i2c_dev_string_number[2].matched
+ ? std::stoi(i2c_dev_string_number[2])
+ : 0;
+ // Store the i2c bus number and the pcie slot name in the vector.
+ pcie_i2c_map.push_back(
+ std::make_tuple(i2c_bus_number, pcie_slot_name));
+ }
+ }
+
+ return pcie_i2c_map;
+}
+
} // namespace ipmi
} // namespace google