oem-ibm: Support bios attributes for boot types

This commit adds support to two bios attributes, boot
initiator and boot type, which lets the host know who
initiated the boot through boot initiator, and what type of
boot(boot or reboot) through the boot type attribute

Change-Id: Iec4bc4ceec3a48ffd3f59b4d31f419c8806187ac
Signed-off-by: Archana Kakani <archana.kakani@ibm.com>
diff --git a/oem/ibm/libpldmresponder/oem_ibm_handler.cpp b/oem/ibm/libpldmresponder/oem_ibm_handler.cpp
index 567d14f..86fc0d8 100644
--- a/oem/ibm/libpldmresponder/oem_ibm_handler.cpp
+++ b/oem/ibm/libpldmresponder/oem_ibm_handler.cpp
@@ -11,6 +11,7 @@
 
 #include <phosphor-logging/lg2.hpp>
 #include <xyz/openbmc_project/State/BMC/client.hpp>
+#include <xyz/openbmc_project/State/Host/common.hpp>
 
 PHOSPHOR_LOG2_USING;
 
@@ -864,6 +865,88 @@
     }
 }
 
+void pldm::responder::oem_ibm_platform::Handler::handleBootTypesAtPowerOn()
+{
+    PendingAttributesList biosAttrList;
+    auto bootInitiator =
+        getBiosAttrValue<std::string>("pvm_boot_initiator_current")
+            .value_or("");
+    std::string restartCause;
+    if (((bootInitiator != "HMC") || (bootInitiator != "Host")) &&
+        !bootInitiator.empty())
+    {
+        try
+        {
+            restartCause =
+                pldm::utils::DBusHandler().getDbusProperty<std::string>(
+                    "/xyz/openbmc_project/state/host0", "RestartCause",
+                    sdbusplus::common::xyz::openbmc_project::state::Host::
+                        interface);
+            setBootTypesBiosAttr(restartCause);
+        }
+        catch (const std::exception& e)
+        {
+            error(
+                "Failed to set the D-bus property for the Host restart reason ERROR={ERR}",
+                "ERR", e);
+        }
+    }
+}
+
+void pldm::responder::oem_ibm_platform::Handler::setBootTypesBiosAttr(
+    const std::string& restartCause)
+{
+    PendingAttributesList biosAttrList;
+    if (restartCause ==
+        "xyz.openbmc_project.State.Host.RestartCause.ScheduledPowerOn")
+    {
+        biosAttrList.emplace_back(std::make_pair(
+            "pvm_boot_initiator", std::make_tuple(EnumAttribute, "Host")));
+        setBiosAttr(biosAttrList);
+    }
+    else if (
+        (restartCause ==
+         "xyz.openbmc_project.State.Host.RestartCause.PowerPolicyAlwaysOn") ||
+        (restartCause ==
+         "xyz.openbmc_project.State.Host.RestartCause.PowerPolicyPreviousState"))
+    {
+        biosAttrList.emplace_back(std::make_pair(
+            "pvm_boot_initiator", std::make_tuple(EnumAttribute, "Auto")));
+        setBiosAttr(biosAttrList);
+    }
+    else if (restartCause ==
+             "xyz.openbmc_project.State.Host.RestartCause.HostCrash")
+    {
+        biosAttrList.emplace_back(std::make_pair(
+            "pvm_boot_initiator", std::make_tuple(EnumAttribute, "Auto")));
+        biosAttrList.emplace_back(std::make_pair(
+            "pvm_boot_type", std::make_tuple(EnumAttribute, "ReIPL")));
+        setBiosAttr(biosAttrList);
+    }
+}
+
+void pldm::responder::oem_ibm_platform::Handler::handleBootTypesAtChassisOff()
+{
+    PendingAttributesList biosAttrList;
+    auto bootInitiator =
+        getBiosAttrValue<std::string>("pvm_boot_initiator").value_or("");
+    auto bootType = getBiosAttrValue<std::string>("pvm_boot_type").value_or("");
+    if (bootInitiator.empty() || bootType.empty())
+    {
+        error(
+            "ERROR in fetching the pvm_boot_initiator and pvm_boot_type BIOS attribute values");
+        return;
+    }
+    else if (bootInitiator != "Host")
+    {
+        biosAttrList.emplace_back(std::make_pair(
+            "pvm_boot_initiator", std::make_tuple(EnumAttribute, "User")));
+        biosAttrList.emplace_back(std::make_pair(
+            "pvm_boot_type", std::make_tuple(EnumAttribute, "IPL")));
+        setBiosAttr(biosAttrList);
+    }
+}
+
 } // namespace oem_ibm_platform
 } // namespace responder
 } // namespace pldm