mmc: Set clear NVRAM bios attribute during factory reset

During factory reset, instead of calling the PLDM services to delete the
PHYP NVRAM files, set the pvm_clear_nvram bios attribute to Enabled to
signal the hypervisor to clear NVRAM when it starts up.

Add the nvram hostfw directory to the list of directories to preserve
during a factory reset because the NVRAM files would now be cleared by
the hypervisor after reading the bios attribute.

Tested: Verified the pvm_clar_nvram bios attribute was set to Enabled as
part of factory reset. Verified a journal error message was logged if
the attribute did not exist and the rest of the factory reset actions
were executed.

Change-Id: Ia3c0f707e8fb8208b5e2bc1edb9a8aef3bb36a89
Signed-off-by: Adriana Kobylak <anoo@us.ibm.com>
diff --git a/mmc/item_updater_mmc.cpp b/mmc/item_updater_mmc.cpp
index c806252..2b83305 100644
--- a/mmc/item_updater_mmc.cpp
+++ b/mmc/item_updater_mmc.cpp
@@ -57,8 +57,9 @@
 void ItemUpdaterMMC::reset()
 {
     // Do not reset read-only files needed for reset or ext4 default files
-    const std::vector<std::string> exclusionList = {
-        "alternate", "hostfw-a", "hostfw-b", "lost+found", "running-ro"};
+    const std::vector<std::string> exclusionList = {"alternate", "hostfw-a",
+                                                    "hostfw-b",  "lost+found",
+                                                    "nvram",     "running-ro"};
     std::filesystem::path dirPath(std::string(MEDIA_DIR "hostfw/"));
     // Delete all files in /media/hostfw/ except for those on exclusionList
     for (const auto& p : std::filesystem::directory_iterator(dirPath))
@@ -73,16 +74,16 @@
     // Delete all BMC error logs to avoid discrepancies with the host error logs
     utils::deleteAllErrorLogs(bus);
 
+    // Set attribute to clear hypervisor NVRAM
+    utils::setClearNvram(bus);
+
     // Remove files related to the Hardware Management Console / BMC web app
-
     utils::clearHMCManaged(bus);
-
     std::filesystem::path consolePath("/var/lib/bmcweb/ibm-management-console");
     if (std::filesystem::exists(consolePath))
     {
         std::filesystem::remove_all(consolePath);
     }
-
     std::filesystem::path bmcdataPath("/home/root/bmcweb_persistent_data.json");
     if (std::filesystem::exists(bmcdataPath))
     {
@@ -96,8 +97,6 @@
         {"StartUnit", "obmc-flash-bios-patch.service"},
         {"StartUnit", "openpower-process-host-firmware.service"},
         {"StartUnit", "openpower-update-bios-attr-table.service"},
-        {"StartUnit", "pldm-reset-phyp-nvram.service"},
-        {"StartUnit", "pldm-reset-phyp-nvram-cksum.service"},
         {"RestartUnit", "org.open_power.HardwareIsolation.service"}};
 
     for (const auto& service : services)
diff --git a/utils.cpp b/utils.cpp
index a1ae101..f7a1194 100644
--- a/utils.cpp
+++ b/utils.cpp
@@ -112,19 +112,19 @@
     }
 }
 
-void clearHMCManaged(sdbusplus::bus::bus& bus)
+void setPendingAttributes(sdbusplus::bus::bus& bus, const std::string& attrName,
+                          const std::string& attrValue)
 {
     constexpr auto biosConfigPath = "/xyz/openbmc_project/bios_config/manager";
     constexpr auto biosConfigIntf = "xyz.openbmc_project.BIOSConfig.Manager";
     constexpr auto dbusAttrType =
         "xyz.openbmc_project.BIOSConfig.Manager.AttributeType.Enumeration";
-    constexpr auto dbusAttrName = "pvm_hmc_managed";
 
     using PendingAttributesType = std::vector<std::pair<
         std::string, std::tuple<std::string, std::variant<std::string>>>>;
     PendingAttributesType pendingAttributes;
-    pendingAttributes.emplace_back(std::make_pair(
-        dbusAttrName, std::make_tuple(dbusAttrType, "Disabled")));
+    pendingAttributes.emplace_back(
+        std::make_pair(attrName, std::make_tuple(dbusAttrType, attrValue)));
 
     try
     {
@@ -139,11 +139,22 @@
     {
         log<level::ERR>("Error setting the bios attribute",
                         entry("ERROR=%s", e.what()),
-                        entry("ATTRIBUTE=%s", dbusAttrName));
+                        entry("ATTRIBUTE=%s", attrName.c_str()),
+                        entry("ATTRIBUTE_VALUE=%s", attrValue.c_str()));
         return;
     }
 }
 
+void clearHMCManaged(sdbusplus::bus::bus& bus)
+{
+    setPendingAttributes(bus, "pvm_hmc_managed", "Disabled");
+}
+
+void setClearNvram(sdbusplus::bus::bus& bus)
+{
+    setPendingAttributes(bus, "pvm_clear_nvram", "Enabled");
+}
+
 void deleteAllErrorLogs(sdbusplus::bus::bus& bus)
 {
     constexpr auto loggingPath = "/xyz/openbmc_project/logging";
diff --git a/utils.hpp b/utils.hpp
index 7588039..97b5e59 100644
--- a/utils.hpp
+++ b/utils.hpp
@@ -52,6 +52,13 @@
  */
 void clearHMCManaged(sdbusplus::bus::bus& bus);
 
+/** @brief Set the Clear hypervisor NVRAM bios attribute to Enabled to indicate
+ *         to the hypervisor to clear its NVRAM.
+ *
+ * @param[in] bus - The D-Bus bus object.
+ */
+void setClearNvram(sdbusplus::bus::bus& bus);
+
 /** @brief DeleteAll error logs
  *
  * @param[in] bus - The D-Bus bus object.