PLDM: System specific BIOS attributes
This commit adds code to populate BIOS attributes
based on the system type that is the platform.
The BIOS Jsons are installed based on the platform/
system type. The system type is populated by entity
manager.
TESTED on hardware across different platform/system type.
On systems where the compatible system interface is not
implemented or entity manager not running, then the BIOS
Jsons with default values are installed.
Signed-off-by: Sagar Srinivas <sagar.srinivas@ibm.com>
Change-Id: I179dad34537ed0d1fb263584d687a1b8cb64c335
diff --git a/oem/ibm/libpldmresponder/bios_oem_ibm.cpp b/oem/ibm/libpldmresponder/bios_oem_ibm.cpp
new file mode 100644
index 0000000..308eac1
--- /dev/null
+++ b/oem/ibm/libpldmresponder/bios_oem_ibm.cpp
@@ -0,0 +1,103 @@
+#include "bios_oem_ibm.hpp"
+
+namespace pldm
+{
+namespace responder
+{
+namespace oem::ibm::bios
+{
+/** @brief Method to get the system type information
+ *
+ * @return - the system type information
+ */
+std::optional<std::string>
+ pldm::responder::oem::ibm::bios::Handler::getPlatformName()
+{
+ if (!systemType.empty())
+ {
+ return systemType;
+ }
+
+ static constexpr auto searchpath = "/xyz/openbmc_project/";
+ int depth = 0;
+ std::vector<std::string> ibmCompatible = {compatibleInterface};
+ pldm::utils::GetSubTreeResponse response;
+ try
+ {
+ response = pldm::utils::DBusHandler().getSubtree(searchpath, depth,
+ ibmCompatible);
+ }
+ catch (const sdbusplus::exception_t& e)
+ {
+ error(
+ " getSubtree call failed with, ERROR={ERROR} PATH={PATH} INTERFACE={INTERFACE}",
+ "ERROR", e.what(), "PATH", searchpath, "INTERFACE",
+ ibmCompatible[0]);
+ return std::nullopt;
+ }
+
+ for (const auto& [objectPath, serviceMap] : response)
+ {
+ try
+ {
+ auto value = pldm::utils::DBusHandler()
+ .getDbusProperty<std::vector<std::string>>(
+ objectPath.c_str(), namesProperty,
+ ibmCompatible[0].c_str());
+ return value[0];
+ }
+ catch (const sdbusplus::exception_t& e)
+ {
+ error(
+ " Error getting Names property, ERROR={ERROR} PATH={PATH} INTERFACE={INTERFACE}",
+ "ERROR", e.what(), "PATH", searchpath, "INTERFACE",
+ ibmCompatible[0]);
+ }
+ }
+ return std::nullopt;
+}
+
+/** @brief callback function invoked when interfaces get added from
+ * Entity manager
+ *
+ * @param[in] msg - Data associated with subscribed signal
+ */
+void pldm::responder::oem::ibm::bios::Handler::ibmCompatibleAddedCallback(
+ sdbusplus::message::message& msg)
+{
+ sdbusplus::message::object_path path;
+
+ pldm::utils::InterfaceMap interfaceMap;
+
+ msg.read(path, interfaceMap);
+
+ if (!interfaceMap.contains(compatibleInterface))
+ {
+ return;
+ }
+ // Get the "Name" property value of the
+ // "xyz.openbmc_project.Configuration.IBMCompatibleSystem" interface
+ const auto& properties = interfaceMap.at(compatibleInterface);
+
+ if (!properties.contains(namesProperty))
+ {
+ return;
+ }
+ auto names =
+ std::get<pldm::utils::Interfaces>(properties.at(namesProperty));
+
+ // get only the first system type
+ if (!names.empty())
+ {
+ systemType = names.front();
+ }
+
+ if (!systemType.empty())
+ {
+ ibmCompatibleMatchConfig.reset();
+ }
+}
+
+} // namespace oem::ibm::bios
+} // namespace responder
+} // namespace pldm
diff --git a/oem/ibm/libpldmresponder/bios_oem_ibm.hpp b/oem/ibm/libpldmresponder/bios_oem_ibm.hpp
new file mode 100644
index 0000000..242241b
--- /dev/null
+++ b/oem/ibm/libpldmresponder/bios_oem_ibm.hpp
@@ -0,0 +1,60 @@
+#pragma once
+#include "common/utils.hpp"
+#include "libpldmresponder/bios.hpp"
+#include "libpldmresponder/oem_handler.hpp"
+
+#include <filesystem>
+
+namespace pldm
+{
+namespace responder
+{
+namespace oem::ibm::bios
+{
+static constexpr auto compatibleInterface =
+ "xyz.openbmc_project.Configuration.IBMCompatibleSystem";
+static constexpr auto namesProperty = "Names";
+namespace fs = std::filesystem;
+class Handler : public oem_bios::Handler
+{
+ public:
+ Handler(const pldm::utils::DBusHandler* dBusIntf) :
+ oem_bios::Handler(dBusIntf)
+ {
+ ibmCompatibleMatchConfig = std::make_unique<sdbusplus::bus::match_t>(
+ dBusIntf->getBus(),
+ sdbusplus::bus::match::rules::interfacesAdded() +
+ sdbusplus::bus::match::rules::sender(
+ "xyz.openbmc_project.EntityManager"),
+ std::bind_front(&Handler::ibmCompatibleAddedCallback, this));
+ }
+
+ /** @brief Method to get the system type information
+ *
+ * @return - the system type information
+ */
+ std::optional<std::string> getPlatformName();
+
+ private:
+ /** @brief system type/model */
+ std::string systemType;
+
+ pldm::responder::bios::Handler* biosHandler;
+
+ /** @brief D-Bus Interface added signal match for Entity Manager */
+ std::unique_ptr<sdbusplus::bus::match::match> ibmCompatibleMatchConfig;
+
+ /** @brief D-Bus Interface object*/
+ const pldm::utils::DBusHandler* dBusIntf;
+
+ /** @brief callback function invoked when interfaces get added from
+ * Entity manager
+ *
+ * @param[in] msg - Data associated with subscribed signal
+ */
+ void ibmCompatibleAddedCallback(sdbusplus::message::message& msg);
+};
+
+} // namespace oem::ibm::bios
+} // namespace responder
+} // namespace pldm