pfr-manager: Get i2cBusNumber and i2cSlaveAddress from EntityManager.
Add support to pull i2cBusNumber and i2cSlaveAddress from EntityManager
service dynamically.
Tested:
i2cBusNumber and i2cSlaveAddress are read and updated.
Signed-off-by: Chalapathi Venkataramashetty <chalapathix.venkataramashetty@intel.com>
Change-Id: I90fc6f39cfffe609cfefe45fb1e17b9fd6d29f8a
diff --git a/libpfr/inc/pfr.hpp b/libpfr/inc/pfr.hpp
index e327b69..d088f4e 100644
--- a/libpfr/inc/pfr.hpp
+++ b/libpfr/inc/pfr.hpp
@@ -15,6 +15,10 @@
*/
#pragma once
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/asio.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+
#include <string>
namespace pfr
@@ -49,5 +53,7 @@
int readCpldReg(const ActionType& action, uint8_t& value);
std::string readCPLDVersion();
int setBMCBootCheckpoint(const uint8_t checkPoint);
+void init(std::shared_ptr<sdbusplus::asio::connection> conn,
+ bool& i2cConfigLoaded);
} // namespace pfr
diff --git a/libpfr/src/pfr.cpp b/libpfr/src/pfr.cpp
index 856a39c..b52ba22 100644
--- a/libpfr/src/pfr.cpp
+++ b/libpfr/src/pfr.cpp
@@ -27,11 +27,13 @@
namespace pfr
{
-// TODO: Dynamically pull these values from configuration
-// entity-manager, when needed
-static constexpr int i2cBusNumber = 4;
-// below given is 7bit address. Its 8bit addr is 0x70
-static constexpr int i2cSlaveAddress = 0x38;
+
+using GetSubTreeType = std::vector<
+ std::pair<std::string,
+ std::vector<std::pair<std::string, std::vector<std::string>>>>>;
+
+static int i2cBusNumber = 4;
+static int i2cSlaveAddress = 56;
// CPLD mailbox registers
static constexpr uint8_t pfrROTId = 0x00;
@@ -87,6 +89,79 @@
bool exceptionFlag = true;
+void init(std::shared_ptr<sdbusplus::asio::connection> conn,
+ bool& i2cConfigLoaded)
+{
+ conn->async_method_call(
+ [conn, &i2cConfigLoaded](const boost::system::error_code ec,
+ const GetSubTreeType& resp) {
+ if (ec || resp.size() != 1)
+ {
+ return;
+ }
+
+ const std::string& objPath = resp[0].first;
+ const std::string& serviceName = resp[0].second.begin()->first;
+ const std::string match = "Baseboard/PFR";
+ if (boost::ends_with(objPath, match))
+ {
+ // PFR object found.. check for PFR support
+ conn->async_method_call(
+ [objPath, serviceName, conn, &i2cConfigLoaded](
+ boost::system::error_code ec,
+ const std::vector<std::pair<
+ std::string, std::variant<std::string, uint64_t>>>&
+ propertiesList) {
+ if (ec)
+ {
+ phosphor::logging::log<
+ phosphor::logging::level::ERR>(
+ "Error to Get PFR properties.",
+ phosphor::logging::entry("MSG=%s",
+ ec.message().c_str()));
+ return;
+ }
+
+ const uint64_t* i2cBus = nullptr;
+ const uint64_t* address = nullptr;
+
+ for (const auto& [propName, propVariant] :
+ propertiesList)
+ {
+ if (propName == "Address")
+ {
+ address = std::get_if<uint64_t>(&propVariant);
+ }
+ else if (propName == "Bus")
+ {
+ i2cBus = std::get_if<uint64_t>(&propVariant);
+ }
+ }
+
+ if ((address == nullptr) || (i2cBus == nullptr))
+ {
+ phosphor::logging::log<
+ phosphor::logging::level::ERR>(
+ "Unable to read the pfr properties");
+ return;
+ }
+
+ i2cBusNumber = static_cast<int>(*i2cBus);
+ i2cSlaveAddress = static_cast<int>(*address);
+ i2cConfigLoaded = true;
+ },
+ serviceName, objPath, "org.freedesktop.DBus.Properties",
+ "GetAll", "xyz.openbmc_project.Configuration.PFR");
+ }
+ },
+ "xyz.openbmc_project.ObjectMapper",
+ "/xyz/openbmc_project/object_mapper",
+ "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+ "/xyz/openbmc_project/inventory/system", 0,
+ std::array<const char*, 1>{"xyz.openbmc_project.Configuration.PFR"});
+ return;
+}
+
std::string toHexString(const uint8_t val)
{
std::stringstream stream;
diff --git a/service/src/mainapp.cpp b/service/src/mainapp.cpp
index dfbf582..5cbe32c 100644
--- a/service/src/mainapp.cpp
+++ b/service/src/mainapp.cpp
@@ -32,6 +32,8 @@
static uint8_t lastMajorErr = 0;
static uint8_t lastMinorErr = 0;
+static bool i2cConfigLoaded = false;
+
static bool stateTimerRunning = false;
bool finishedSettingChkPoint = false;
static constexpr uint8_t bmcBootFinishedChkPoint = 0x09;
@@ -489,6 +491,7 @@
pfr::stateTimer = std::make_unique<boost::asio::steady_timer>(io);
pfr::initTimer = std::make_unique<boost::asio::steady_timer>(io);
auto server = sdbusplus::asio::object_server(conn, true);
+ pfr::init(conn, pfr::i2cConfigLoaded);
pfr::monitorSignals(server, conn);
// Update CPLD Version to cpld_active object in settings.