Guard: Guarded DIMMS/CPU are not enabled back after factory reset

User not able to enable some of the guarded dimm/cpu after host
factory reset even though host cleared the guards in the guard
partition.

BMC will not know that host took a factory reset for it to clear the
disabled flag for the earlier guarded dimm/cpu.

Modified to force enable all the cpu/dimm during host factory reset.
Test result:
openpower-update-manager[2001]:ItemUpdaterMMC::reset
openpower-update-manager[2001]:GardResetMMC::reset
openpower-update-manager[2001]:GardResetMMC::enableInventoryItems
openpower-update-manager[2001]:GardResetMMC::enableInventoryItemsHelper
openpower-update-manager[2001]:enable specified inventory items
OBJ(/xyz/openbmc_project/inventory/system/chassis/motherboard/dcm0/cpu0/core13)
openpower-update-manager[2001]:enable specified inventory items
OBJ(/xyz/openbmc_project/inventory/system/chassis/motherboard/dcm0/cpu0/core14)
openpower-update-manager[2001]:GardResetMMC::enableInventoryItemsHelper
openpower-update-manager[2001]:enable specified inventory items
OBJ(/xyz/openbmc_project/inventory/system/chassis/motherboard/dimm0)

Signed-off-by: Marri Devender Rao <devenrao@in.ibm.com>`
Change-Id: I7f7d3981d38cdc6cc7dda4e3ee49403c772dc5ef
diff --git a/item_updater.hpp b/item_updater.hpp
index 0b880c7..c8b414d 100644
--- a/item_updater.hpp
+++ b/item_updater.hpp
@@ -56,16 +56,16 @@
     virtual ~GardReset()
     {}
 
+    /**
+     * @brief GARD factory reset - clears the PNOR GARD partition.
+     */
+    virtual void reset() = 0;
+
   protected:
     // TODO Remove once openbmc/openbmc#1975 is resolved
     static constexpr auto interface = "xyz.openbmc_project.Common.FactoryReset";
     sdbusplus::bus_t& bus;
     std::string path;
-
-    /**
-     * @brief GARD factory reset - clears the PNOR GARD partition.
-     */
-    virtual void reset() = 0;
 };
 
 /** @class ItemUpdater
diff --git a/mmc/item_updater_mmc.cpp b/mmc/item_updater_mmc.cpp
index c99a3c4..3872b96 100644
--- a/mmc/item_updater_mmc.cpp
+++ b/mmc/item_updater_mmc.cpp
@@ -6,6 +6,10 @@
 #include "utils.hpp"
 #include "version.hpp"
 
+#include <fmt/core.h>
+
+#include <phosphor-logging/log.hpp>
+
 #include <filesystem>
 #include <iostream>
 #include <thread>
@@ -17,6 +21,8 @@
 namespace updater
 {
 
+using ::phosphor::logging::level;
+using ::phosphor::logging::log;
 // These functions are just a stub (empty) because the current eMMC
 // implementation uses the BMC updater (repo phosphor-bmc-code-mgmt) to write
 // the new host FW to flash since it's delivered as a "System" image in the
@@ -78,6 +84,9 @@
     // Set attribute to clear hypervisor NVRAM
     utils::setClearNvram(bus);
 
+    // reset the enabled property of dimms/cpu after factory reset
+    gardReset->reset();
+
     // Remove files related to the Hardware Management Console / BMC web app
     utils::clearHMCManaged(bus);
     std::filesystem::path consolePath("/var/lib/bmcweb/ibm-management-console");
@@ -140,9 +149,63 @@
 
 void ItemUpdaterMMC::updateFunctionalAssociation(const std::string&)
 {}
+void GardResetMMC::enableInventoryItems()
+{
+    (void)enableInventoryItemsHelper(
+        "xyz.openbmc_project.PLDM",
+        "xyz.openbmc_project.Inventory.Item.CpuCore",
+        "/xyz/openbmc_project/inventory/system/chassis/motherboard");
+
+    (void)enableInventoryItemsHelper("xyz.openbmc_project.Inventory.Manager",
+                                     "xyz.openbmc_project.Inventory.Item.Dimm",
+                                     "/xyz/openbmc_project/inventory");
+}
+
+void GardResetMMC::enableInventoryItemsHelper(const std::string& service,
+                                              const std::string& intf,
+                                              const std::string& objPath)
+{
+    const std::vector<std::string> intflist{intf};
+
+    std::vector<std::string> objs;
+    try
+    {
+        auto mapperCall = bus.new_method_call(
+            "xyz.openbmc_project.ObjectMapper",
+            "/xyz/openbmc_project/object_mapper",
+            "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths");
+        mapperCall.append(objPath);
+        mapperCall.append(0);
+        mapperCall.append(intflist);
+
+        auto response = bus.call(mapperCall);
+        response.read(objs);
+        for (auto& obj : objs)
+        {
+            auto method =
+                bus.new_method_call(service.c_str(), obj.c_str(),
+                                    "org.freedesktop.DBus.Properties", "Set");
+            std::variant<bool> propertyVal{true};
+            method.append("xyz.openbmc_project.Object.Enable", "Enabled",
+                          propertyVal);
+            bus.call_noreply(method);
+        }
+    }
+    catch (const sdbusplus::exception_t& e)
+    {
+        log<level::ERR>(
+            fmt::format("Failed to enable specified inventory items ex({}) "
+                        "intf({}) objpath({})",
+                        e.what(), intf, objPath)
+                .c_str());
+    }
+}
 
 void GardResetMMC::reset()
-{}
+{
+    log<level::INFO>("GardResetMMC::reset");
+    (void)enableInventoryItems();
+}
 
 } // namespace updater
 } // namespace software
diff --git a/mmc/item_updater_mmc.hpp b/mmc/item_updater_mmc.hpp
index a8b495b..47ebd5d 100644
--- a/mmc/item_updater_mmc.hpp
+++ b/mmc/item_updater_mmc.hpp
@@ -15,11 +15,32 @@
     using GardReset::GardReset;
     virtual ~GardResetMMC() = default;
 
-  protected:
     /**
      * @brief GARD factory reset - clears the PNOR GARD partition.
      */
     void reset() override;
+
+  private:
+    /**
+     * @brief During host factory reset, host clears the guard records in the
+     * guard partition. BMC is not notified about host factory reset so
+     * it continues to disable the guarded items. Now modified to enable
+     * back CpuCore and DIMM items during factory reset.
+     */
+    void enableInventoryItems();
+
+    /**
+     * @brief Helper function to set enable flag for all the subtree objects
+     * implementing the specified interface.
+     *
+     * @param[in] - service D-Bus service name
+     * @param[in] - intf find objects that implement this interface
+     * @param[in] - objPath find subtree objects from this object path
+     * @return none
+     */
+    void enableInventoryItemsHelper(const std::string& service,
+                                    const std::string& intf,
+                                    const std::string& objPath);
 };
 
 /** @class ItemUpdaterMMC