diff --git a/subprojects/hsbp-manager/.gitignore b/subprojects/hsbp-manager/.gitignore
new file mode 100644
index 0000000..a007fea
--- /dev/null
+++ b/subprojects/hsbp-manager/.gitignore
@@ -0,0 +1 @@
+build/*
diff --git a/subprojects/hsbp-manager/LICENCE b/subprojects/hsbp-manager/LICENCE
new file mode 100644
index 0000000..729f4d4
--- /dev/null
+++ b/subprojects/hsbp-manager/LICENCE
@@ -0,0 +1,13 @@
+Copyright 2019 Intel Corporation
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/subprojects/hsbp-manager/include/utils.hpp b/subprojects/hsbp-manager/include/utils.hpp
new file mode 100644
index 0000000..304ea5b
--- /dev/null
+++ b/subprojects/hsbp-manager/include/utils.hpp
@@ -0,0 +1,219 @@
+/*
+// Copyright (c) 2019 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#include <systemd/sd-journal.h>
+
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/steady_timer.hpp>
+#include <boost/container/flat_map.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/bus/match.hpp>
+
+#include <cstdint>
+#include <iostream>
+#include <string>
+#include <variant>
+#include <vector>
+
+using GetSubTreeType = std::vector<
+    std::pair<std::string,
+              std::vector<std::pair<std::string, std::vector<std::string>>>>>;
+using BasicVariantType =
+    std::variant<std::vector<std::string>, std::string, int64_t, uint64_t,
+                 double, int32_t, uint32_t, int16_t, uint16_t, uint8_t, bool>;
+using Association = std::tuple<std::string, std::string, std::string>;
+
+constexpr const char* assetTag =
+    "xyz.openbmc_project.Inventory.Decorator.Asset";
+
+namespace mapper
+{
+constexpr const char* busName = "xyz.openbmc_project.ObjectMapper";
+constexpr const char* path = "/xyz/openbmc_project/object_mapper";
+constexpr const char* interface = "xyz.openbmc_project.ObjectMapper";
+constexpr const char* subtree = "GetSubTree";
+} // namespace mapper
+
+namespace entityManager
+{
+constexpr const char* busName = "xyz.openbmc_project.EntityManager";
+} // namespace entityManager
+
+namespace inventory
+{
+constexpr const char* interface = "xyz.openbmc_project.Inventory.Item";
+} // namespace inventory
+
+namespace ledGroup
+{
+constexpr const char* interface = "xyz.openbmc_project.Led.Group";
+constexpr const char* asserted = "Asserted";
+} // namespace ledGroup
+
+namespace properties
+{
+constexpr const char* interface = "org.freedesktop.DBus.Properties";
+constexpr const char* get = "Get";
+} // namespace properties
+
+namespace power
+{
+const static constexpr char* busname = "xyz.openbmc_project.State.Host";
+const static constexpr char* interface = "xyz.openbmc_project.State.Host";
+const static constexpr char* path = "/xyz/openbmc_project/state/host0";
+const static constexpr char* property = "CurrentHostState";
+} // namespace power
+
+namespace association
+{
+const static constexpr char* interface =
+    "xyz.openbmc_project.Association.Definitions";
+} // namespace association
+
+namespace hsbp
+{
+enum class registers : uint8_t
+{
+    fpgaIdH = 0x0,
+    fpgaIdL = 0x1,
+    typeId = 0x2,
+    bootVer = 0x3,
+    fpgaVer = 0x4,
+    securityRev = 0x5,
+    funSupported = 0x6,
+    numDisks = 0x7,
+    presence = 0x8,
+    ssdIFDET = 0x9,
+    ifdetPart = 0xA,
+    statusLocate = 0xB,
+    statusFail = 0xC,
+    statusRebuild = 0xD,
+    ledOverride = 0xE,
+    ledStatus = 0xF,
+    ledPattern0 = 0x10,
+    ledPattern1 = 0x11,
+    ledPattern2 = 0x12,
+    ledPattern3 = 0x13,
+    ledPattern4 = 0x14,
+    ledPattern5 = 0x15,
+    ledPattern6 = 0x16,
+    ledPattern7 = 0x17,
+};
+
+} // namespace hsbp
+
+static std::unique_ptr<sdbusplus::bus::match_t> powerMatch = nullptr;
+static bool powerStatusOn = false;
+
+bool isPowerOn(void)
+{
+    if (!powerMatch)
+    {
+        throw std::runtime_error("Power Match Not Created");
+    }
+    return powerStatusOn;
+}
+
+void setupPowerMatch(const std::shared_ptr<sdbusplus::asio::connection>& conn)
+{
+    static boost::asio::steady_timer timer(conn->get_io_context());
+    // create a match for powergood changes, first time do a method call to
+    // cache the correct value
+    if (powerMatch)
+    {
+        return;
+    }
+
+    powerMatch = std::make_unique<sdbusplus::bus::match_t>(
+        static_cast<sdbusplus::bus_t&>(*conn),
+        "type='signal',interface='" + std::string(properties::interface) +
+            "',path='" + std::string(power::path) + "',arg0='" +
+            std::string(power::interface) + "'",
+        [](sdbusplus::message_t& message) {
+            std::string objectName;
+            boost::container::flat_map<std::string, std::variant<std::string>>
+                values;
+            message.read(objectName, values);
+            auto findState = values.find(power::property);
+            if (findState != values.end())
+            {
+                bool on = boost::ends_with(
+                    std::get<std::string>(findState->second), "Running");
+                if (!on)
+                {
+                    timer.cancel();
+                    powerStatusOn = false;
+                    return;
+                }
+                // on comes too quickly
+                timer.expires_after(std::chrono::seconds(10));
+                timer.async_wait([](boost::system::error_code ec) {
+                    if (ec == boost::asio::error::operation_aborted)
+                    {
+                        return;
+                    }
+                    else if (ec)
+                    {
+                        std::cerr << "Timer error " << ec.message() << "\n";
+                        return;
+                    }
+                    powerStatusOn = true;
+                });
+            }
+        });
+
+    conn->async_method_call(
+        [](boost::system::error_code ec,
+           const std::variant<std::string>& state) {
+            if (ec)
+            {
+                // we commonly come up before power control, we'll capture the
+                // property change later
+                return;
+            }
+            powerStatusOn =
+                boost::ends_with(std::get<std::string>(state), "Running");
+        },
+        power::busname, power::path, properties::interface, properties::get,
+        power::interface, power::property);
+}
+
+inline void logDeviceAdded(const std::string& model, const std::string& type,
+                           const std::string& sn)
+{
+    sd_journal_send("MESSAGE=%s", "Inventory Added", "PRIORITY=%i", LOG_ERR,
+                    "REDFISH_MESSAGE_ID=%s", "OpenBMC.0.1.InventoryAdded",
+                    "REDFISH_MESSAGE_ARGS=%s,%s,%s", model.c_str(),
+                    type.c_str(), sn.c_str(), NULL);
+}
+
+inline void logDeviceRemoved(const std::string& model, const std::string& type,
+                             const std::string& sn)
+{
+    sd_journal_send("MESSAGE=%s", "Inventory Removed", "PRIORITY=%i", LOG_ERR,
+                    "REDFISH_MESSAGE_ID=%s", "OpenBMC.0.1.InventoryRemoved",
+                    "REDFISH_MESSAGE_ARGS=%s,%s,%s", model.c_str(),
+                    type.c_str(), sn.c_str(), NULL);
+}
+
+inline void logDriveError(const std::string& name)
+{
+    sd_journal_send("MESSAGE=%s", "Drive Error", "PRIORITY=%i", LOG_ERR,
+                    "REDFISH_MESSAGE_ID=%s", "OpenBMC.0.1.DriveError",
+                    "REDFISH_MESSAGE_ARGS=%s", name.c_str(), NULL);
+}
diff --git a/subprojects/hsbp-manager/meson.build b/subprojects/hsbp-manager/meson.build
new file mode 100644
index 0000000..c757d26
--- /dev/null
+++ b/subprojects/hsbp-manager/meson.build
@@ -0,0 +1,70 @@
+project(
+    'hsbp-manager',
+    'cpp',
+    version: '1.1.1',
+    meson_version: '>=1.1.1',
+    default_options: ['cpp_std=c++23'],
+)
+
+# Compiler flags
+cpp_args = [
+    '-lstdc++fs',
+    '-Werror',
+    '-Wall',
+    '-Wextra',
+    '-Wshadow',
+    '-Wnon-virtual-dtor',
+    '-Wold-style-cast',
+    '-Wcast-align',
+    '-Wunused',
+    '-Woverloaded-virtual',
+    '-Wpedantic',
+    '-Wconversion',
+    '-Wmisleading-indentation',
+    '-Wduplicated-cond',
+    '-Wduplicated-branches',
+    '-Wlogical-op',
+    '-Wnull-dereference',
+    '-Wuseless-cast',
+    '-Wdouble-promotion',
+    '-Wformat=2',
+    '-fno-rtti',
+]
+
+# Definitions
+add_project_arguments(
+    '-DBOOST_ERROR_CODE_HEADER_ONLY',
+    '-DBOOST_SYSTEM_NO_DEPRECATED',
+    '-DBOOST_ALL_NO_LIB',
+    '-DBOOST_NO_RTTI',
+    '-DBOOST_NO_TYPEID',
+    '-DBOOST_ASIO_DISABLE_THREADS',
+    language: 'cpp',
+)
+
+# Include directories
+inc = include_directories('include')
+
+cpp = meson.get_compiler('cpp')
+boost = dependency('boost', version: '1.86.0', required: false)
+sdbusplus = dependency('sdbusplus', required: true)
+i2c_dep = cpp.find_library('i2c')
+gpiodcxx = dependency('libgpiodcxx', default_options: ['bindings=cxx'])
+
+incdir = include_directories('include')
+
+executable(
+    'hsbp-manager',
+    'src/hsbp_manager.cpp',
+    include_directories: incdir,
+    dependencies: [boost, i2c_dep, sdbusplus, gpiodcxx],
+)
+# Systemd service files
+systemd_system_unit_dir = dependency('systemd').get_variable(
+    'systemdsystemunitdir',
+)
+
+install_data(
+    'service_files/hsbp-manager.service',
+    install_dir: systemd_system_unit_dir,
+)
diff --git a/subprojects/hsbp-manager/service_files/hsbp-manager.service b/subprojects/hsbp-manager/service_files/hsbp-manager.service
new file mode 100644
index 0000000..b9637d0
--- /dev/null
+++ b/subprojects/hsbp-manager/service_files/hsbp-manager.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=HSBP Manager
+
+[Service]
+Type=dbus
+BusName=xyz.openbmc_project.HsbpManager
+Restart=always
+RestartSec=5
+ExecStart=/usr/bin/hsbp-manager
+
+[Install]
+WantedBy=multi-user.target
diff --git a/subprojects/hsbp-manager/src/hsbp_manager.cpp b/subprojects/hsbp-manager/src/hsbp_manager.cpp
new file mode 100644
index 0000000..6e22d2d
--- /dev/null
+++ b/subprojects/hsbp-manager/src/hsbp_manager.cpp
@@ -0,0 +1,2914 @@
+/*
+// Copyright (c) 2019 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+
+#include "utils.hpp"
+
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/asio/posix/stream_descriptor.hpp>
+#include <boost/asio/steady_timer.hpp>
+#include <boost/container/flat_set.hpp>
+#include <gpiod.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+#include <sdbusplus/bus/match.hpp>
+
+#include <algorithm>
+#include <bitset>
+#include <filesystem>
+#include <forward_list>
+#include <fstream>
+#include <iostream>
+#include <list>
+#include <string>
+#include <utility>
+
+extern "C"
+{
+#include <i2c/smbus.h>
+#include <linux/i2c-dev.h>
+}
+
+/****************************************************************************/
+/******************** Global Constants/Type Declarations ********************/
+/****************************************************************************/
+constexpr const char* hsbpCpldInft =
+    "xyz.openbmc_project.Configuration.Intel_HSBP_CPLD";
+constexpr const char* hsbpConfigIntf =
+    "xyz.openbmc_project.Configuration.HSBPConfiguration";
+constexpr const char* nvmeIntf = "xyz.openbmc_project.Inventory.Item.NVMe";
+constexpr const char* busName = "xyz.openbmc_project.HsbpManager";
+
+constexpr size_t scanRateSeconds = 5;
+constexpr size_t maxDrives = 8; // only 1 byte alloted
+
+using NvmeMapping = std::vector<std::string>;
+/***************************** End of Section *******************************/
+
+/****************************************************************************/
+/**************************** Enums Definitions *****************************/
+/****************************************************************************/
+enum class AppState : uint8_t
+{
+    idle,
+    loadingHsbpConfig,
+    hsbpConfigLoaded,
+    loadingComponents,
+    componentsLoaded,
+    loadingBackplanes,
+    backplanesLoaded,
+    loadingDrives,
+    drivesLoaded
+};
+
+enum class BlinkPattern : uint8_t
+{
+    off = 0x0,
+    error = 0x2,
+    terminate = 0x3
+};
+/***************************** End of Section *******************************/
+
+/****************************************************************************/
+/************ HSBP Configuration related struct/class Definitions ***********/
+/****************************************************************************/
+struct HsbpConfig
+{
+    size_t rootBus;
+    std::vector<std::string> supportedHsbps;
+    std::unordered_map<std::string, NvmeMapping> hsbpNvmeMap;
+    std::vector<std::string> clockBufferTypes;
+    std::vector<std::string> ioExpanderTypes;
+
+    void clearConfig()
+    {
+        rootBus = -1;
+        supportedHsbps.clear();
+        hsbpNvmeMap.clear();
+        clockBufferTypes.clear();
+        ioExpanderTypes.clear();
+    }
+};
+
+class ClockBuffer
+{
+    size_t bus;
+    size_t address;
+    std::string modeOfOperation;
+    size_t outCtrlBaseAddr;
+    size_t outCtrlByteCount;
+    std::unordered_map<std::string, std::vector<std::string>> byteMap;
+    std::string name;
+    std::string type;
+
+    int file = -1;
+    bool initialized = false;
+
+    void initialize()
+    {
+        /* Execute below operation only when mode of operation is SMBus. By
+         * default the clock buffer is configured to follow OE pin output, so we
+         * need to set the output value to 0 to disable the clock outputs and 1
+         * to enable clock output. If mode of operation is IO, then the IO value
+         * will determine the disable/enable of clock output */
+        if (modeOfOperation == "SMBus")
+        {
+            if (file < 0)
+            {
+                file = open(("/dev/i2c-" + std::to_string(bus)).c_str(),
+                            O_RDWR | O_CLOEXEC);
+                if (file < 0)
+                {
+                    std::cerr << "ClockBuffer : \"" << name
+                              << "\" - Unable to open bus : " << bus << "\n";
+                    return;
+                }
+            }
+
+            if (ioctl(file, I2C_SLAVE_FORCE, address) < 0)
+            {
+                std::cerr << "ClockBuffer : \"" << name
+                          << "\" - Unable to set address to " << address
+                          << "\n";
+                return;
+            }
+
+            for (uint8_t i = 0; i < outCtrlByteCount; i++)
+            {
+                std::string byteName = "Byte" + std::to_string(i);
+
+                auto byte = byteMap.find(byteName);
+                if (byte == byteMap.end())
+                {
+                    std::cerr << "ClockBuffer : \"" << name
+                              << "\" - Byte map error ! Unable to find "
+                              << byteName << "\n";
+                    return;
+                }
+
+                /* Get current value of output control register */
+                int read = i2c_smbus_read_byte_data(
+                    file, static_cast<uint8_t>(outCtrlBaseAddr + i));
+                if (read < 0)
+                {
+                    std::cerr << "ClockBuffer : \"" << name
+                              << "\" - Error: Unable to read data from clock "
+                                 "buffer register\n";
+                    return;
+                }
+
+                std::bitset<8> currByte(read);
+                bool writeRequired = false;
+
+                /* Set 0/1 only at bit position that we have a NVMe drive (i.e.
+                 * ignore where byteMap is "-"). We do not want to touch other
+                 * bits */
+                for (uint8_t bit = 0; bit < 8; bit++)
+                {
+                    if (byte->second.at(bit) != "-")
+                    {
+                        writeRequired = true;
+                        /* Default to enabling the clock output and once the
+                         * HSBP's are detected the clocks will be
+                         * enabled/disabled depending on the drive status */
+                        /* TODO: This code might require a re-visit in case of
+                         * any signal integrity issues in the future */
+                        currByte.set(bit);
+                    }
+                }
+
+                if (writeRequired)
+                {
+                    int ret = i2c_smbus_write_byte_data(
+                        file, static_cast<uint8_t>(outCtrlBaseAddr + i),
+                        static_cast<uint8_t>(currByte.to_ulong()));
+
+                    if (ret < 0)
+                    {
+                        std::cerr
+                            << "ClockBuffer : \"" << name
+                            << "\" - Error: Unable to write data to clock "
+                               "buffer register\n";
+                        return;
+                    }
+                }
+            }
+        }
+        initialized = true;
+        std::cerr << "ClockBuffer : \"" << name << "\" initialized\n";
+    }
+
+  public:
+    ClockBuffer(
+        size_t busIn, size_t addressIn, std::string& modeOfOperationIn,
+        size_t outCtrlBaseAddrIn, size_t outCtrlByteCountIn,
+        std::unordered_map<std::string, std::vector<std::string>>& byteMapIn,
+        std::string& nameIn, std::string& typeIn) :
+        bus(busIn), address(addressIn),
+        modeOfOperation(std::move(modeOfOperationIn)),
+        outCtrlBaseAddr(outCtrlBaseAddrIn),
+        outCtrlByteCount(outCtrlByteCountIn), byteMap(std::move(byteMapIn)),
+        name(std::move(nameIn)), type(std::move(typeIn))
+    {
+        initialize();
+    }
+
+    bool isInitialized()
+    {
+        if (!initialized)
+        {
+            /* There was an issue with the initialization of this component. Try
+             * to invoke initialization again */
+            initialize();
+        }
+        return initialized;
+    }
+
+    std::string getName()
+    {
+        return name;
+    }
+
+    bool enableDisableClock(std::forward_list<std::string>& nvmeDrivesInserted,
+                            std::forward_list<std::string>& nvmeDrivesRemoved)
+    {
+        if (modeOfOperation != "SMBus")
+        {
+            /* The clock is enabled using IO expander. No action needed from
+             * here */
+            return true;
+        }
+
+        if (nvmeDrivesInserted.empty() && nvmeDrivesRemoved.empty())
+        {
+            /* There are no drives to update */
+            return true;
+        }
+
+        for (uint8_t i = 0; i < outCtrlByteCount; i++)
+        {
+            std::string byteName = "Byte" + std::to_string(i);
+
+            auto byte = byteMap.find(byteName);
+            if (byte == byteMap.end())
+            {
+                std::cerr << "ClockBuffer : \"" << name
+                          << "\" - Byte map error ! Unable to find " << byteName
+                          << "\n";
+                return false;
+            }
+
+            /* Get current value of output control register */
+            int read = i2c_smbus_read_byte_data(
+                file, static_cast<uint8_t>(outCtrlBaseAddr + i));
+            if (read < 0)
+            {
+                std::cerr << "ClockBuffer : \"" << name
+                          << "\" - Error: Unable to read data from clock "
+                             "buffer register\n";
+                return false;
+            }
+
+            std::bitset<8> currByte(read);
+            bool writeRequired = false;
+
+            /* Set the bit if the NVMe drive is found in nvmeDrivesInserted, and
+             * reset the bit if found in nvmeDrivesRemoved */
+            for (uint8_t bit = 0; bit < 8; bit++)
+            {
+                /* The remove function returns number of elements removed from
+                 * list indicating the presence of the drive and also removing
+                 * it form the list */
+                if (nvmeDrivesInserted.remove(byte->second.at(bit)))
+                {
+                    writeRequired = true;
+                    currByte.set(bit);
+                    continue;
+                }
+
+                if (nvmeDrivesRemoved.remove(byte->second.at(bit)))
+                {
+                    writeRequired = true;
+                    currByte.reset(bit);
+                }
+            }
+
+            if (!writeRequired)
+            {
+                /* No Write is required as there are no changes */
+                continue;
+            }
+
+            int ret = i2c_smbus_write_byte_data(
+                file, static_cast<uint8_t>(outCtrlBaseAddr + i),
+                static_cast<uint8_t>(currByte.to_ulong()));
+            if (ret < 0)
+            {
+                std::cerr << "ClockBuffer : \"" << name
+                          << "\" - Error: Unable to write data to clock "
+                             "buffer register\n";
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    ~ClockBuffer()
+    {
+        if (file >= 0)
+        {
+            close(file);
+        }
+    }
+};
+
+class IoExpander
+{
+    size_t bus;
+    size_t address;
+    size_t confIORegAddr;
+    size_t outCtrlBaseAddr;
+    size_t outCtrlByteCount;
+    std::unordered_map<std::string, std::vector<std::string>> ioMap;
+    std::string name;
+    std::string type;
+
+    int file = -1;
+    bool initialized = false;
+
+    void initialize()
+    {
+        /* Initialize the IO expander Control register to configure the IO ports
+         * as outputs and set the output*/
+        if (file < 0)
+        {
+            file = open(("/dev/i2c-" + std::to_string(bus)).c_str(),
+                        O_RDWR | O_CLOEXEC);
+            if (file < 0)
+            {
+                std::cerr << "IoExpander : " << name
+                          << " - Unable to open bus : " << bus << "\n";
+                return;
+            }
+        }
+
+        if (ioctl(file, I2C_SLAVE_FORCE, address) < 0)
+        {
+            std::cerr << "IoExpander : \"" << name
+                      << "\" - Unable to set address to " << address << "\n";
+            return;
+        }
+
+        for (uint8_t i = 0; i < outCtrlByteCount; i++)
+        {
+            std::string ioName = "IO" + std::to_string(i);
+
+            auto io = ioMap.find(ioName);
+            if (io == ioMap.end())
+            {
+                std::cerr << "IoExpander : \"" << name
+                          << "\" - IO map error ! Unable to find " << ioName
+                          << "\n";
+                return;
+            }
+
+            /* Get current value of IO configuration register */
+            int read1 = i2c_smbus_read_byte_data(
+                file, static_cast<uint8_t>(confIORegAddr + i));
+            if (read1 < 0)
+            {
+                std::cerr << "IoExpander : \"" << name
+                          << "\" - Error: Unable to read data from io expander "
+                             "IO control register\n";
+                return;
+            }
+
+            /* Get current value of IO Ouput register */
+            int read2 = i2c_smbus_read_byte_data(
+                file, static_cast<uint8_t>(confIORegAddr + i));
+            if (read2 < 0)
+            {
+                std::cerr << "IoExpander : \"" << name
+                          << "\" - Error: Unable to read data from io expander "
+                             "IO output register\n";
+                return;
+            }
+
+            bool writeRequired = false;
+            std::bitset<8> currCtrlVal(read1);
+            std::bitset<8> currOutVal(read2);
+
+            /* Set 0/1 only at bit position that we have a NVMe drive (i.e.
+             * ignore where ioMap is "-"). We do not want to touch other
+             * bits */
+            for (uint8_t bit = 0; bit < 8; bit++)
+            {
+                if (io->second.at(bit) != "-")
+                {
+                    writeRequired = true;
+                    currCtrlVal.reset(bit);
+                    /* Set the output register to drive the OE pin high thereby
+                     * enabling the clock. Default to enabling the clock output
+                     * and once the HSBP's are detected the clocks will be
+                     * enabled/disabled depending on the drive status */
+                    currOutVal.set(bit);
+                }
+            }
+
+            if (writeRequired)
+            {
+                int ret1 = i2c_smbus_write_byte_data(
+                    file, static_cast<uint8_t>(confIORegAddr + i),
+                    static_cast<uint8_t>(currCtrlVal.to_ulong()));
+                if (ret1 < 0)
+                {
+                    std::cerr
+                        << "IoExpander : \"" << name
+                        << "\" - Error: Unable to write data to IO expander "
+                           "IO control register\n";
+                    return;
+                }
+
+                int ret2 = i2c_smbus_write_byte_data(
+                    file, static_cast<uint8_t>(outCtrlBaseAddr + i),
+                    static_cast<uint8_t>(currOutVal.to_ulong()));
+                if (ret2 < 0)
+                {
+                    std::cerr
+                        << "IoExpander : \"" << name
+                        << "\" - Error: Unable to write data to IO expander "
+                           "IO output register\n";
+                    return;
+                }
+            }
+        }
+        initialized = true;
+        std::cerr << "IoExpander : \"" << name << "\" initialized\n";
+    }
+
+  public:
+    IoExpander(
+        size_t busIn, size_t addressIn, size_t confIORegAddrIn,
+        size_t outCtrlBaseAddrIn, size_t outCtrlByteCountIn,
+        std::unordered_map<std::string, std::vector<std::string>>& ioMapIn,
+        std::string& nameIn, std::string& typeIn) :
+        bus(busIn), address(addressIn), confIORegAddr(confIORegAddrIn),
+        outCtrlBaseAddr(outCtrlBaseAddrIn),
+        outCtrlByteCount(outCtrlByteCountIn), ioMap(std::move(ioMapIn)),
+        name(std::move(nameIn)), type(std::move(typeIn))
+    {
+        initialize();
+    }
+
+    bool isInitialized()
+    {
+        if (!initialized)
+        {
+            /* There was an issue with the initialization of this component. Try
+             * to invoke initialization again */
+            initialize();
+        }
+        return initialized;
+    }
+
+    std::string getName()
+    {
+        return name;
+    }
+
+    bool enableDisableOuput(std::forward_list<std::string>& nvmeDrivesInserted,
+                            std::forward_list<std::string>& nvmeDrivesRemoved)
+    {
+        if (nvmeDrivesInserted.empty() && nvmeDrivesRemoved.empty())
+        {
+            /* There are no drives to update */
+            return true;
+        }
+
+        for (uint8_t i = 0; i < outCtrlByteCount; i++)
+        {
+            std::string ioName = "IO" + std::to_string(i);
+
+            auto io = ioMap.find(ioName);
+            if (io == ioMap.end())
+            {
+                std::cerr << "IoExpander : \"" << name
+                          << "\" - IO map error ! Unable to find " << ioName
+                          << "\n";
+                return false;
+            }
+
+            /* Get current value of IO output register */
+            int read = i2c_smbus_read_byte_data(
+                file, static_cast<uint8_t>(outCtrlBaseAddr + i));
+            if (read < 0)
+            {
+                std::cerr << "IoExpander : \"" << name
+                          << "\" - Error: Unable to read data from io expander "
+                             "register\n";
+                return false;
+            }
+
+            std::bitset<8> currVal(read);
+            bool writeRequired = false;
+
+            /* Set the bit if the NVMe drive is found in nvmeDrivesInserted, and
+             * reset the bit if found in nvmeDrivesRemoved */
+            for (uint8_t bit = 0; bit < 8; bit++)
+            {
+                /* The remove function returns number of elements removed from
+                 * list indicating the presence of the drive and also removing
+                 * it form the list */
+                if (nvmeDrivesInserted.remove(io->second.at(bit)))
+                {
+                    writeRequired = true;
+                    currVal.set(bit);
+                    continue;
+                }
+
+                if (nvmeDrivesRemoved.remove(io->second.at(bit)))
+                {
+                    writeRequired = true;
+                    currVal.reset(bit);
+                }
+            }
+
+            if (!writeRequired)
+            {
+                /* No Write is required as there are no changes */
+                continue;
+            }
+
+            int ret = i2c_smbus_write_byte_data(
+                file, static_cast<uint8_t>(outCtrlBaseAddr + i),
+                static_cast<uint8_t>(currVal.to_ulong()));
+            if (ret < 0)
+            {
+                std::cerr << "IoExpander : \"" << name
+                          << "\" - Error: Unable to write data to IO expander "
+                             "register\n";
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    ~IoExpander()
+    {
+        if (file >= 0)
+        {
+            close(file);
+        }
+    }
+};
+/***************************** End of Section *******************************/
+
+/****************************************************************************/
+/*********************** Global Variables Declarations **********************/
+/****************************************************************************/
+/* State os Application */
+static AppState appState = AppState::idle;
+
+/* Configuration and Components */
+static HsbpConfig hsbpConfig;
+std::forward_list<ClockBuffer> clockBuffers;
+std::forward_list<IoExpander> ioExpanders;
+
+/* Boost IO context and Dbus variables */
+boost::asio::io_context io;
+auto conn = std::make_shared<sdbusplus::asio::connection>(io);
+sdbusplus::asio::object_server objServer(conn);
+
+/* GPIO Lines and GPIO Event Descriptors */
+static gpiod::line nvmeLvc3AlertLine;
+static boost::asio::posix::stream_descriptor nvmeLvc3AlertEvent(io);
+/***************************** End of Section *******************************/
+
+/****************************************************************************/
+/********** HSBP Backplane related struct and Global definitions ************/
+/****************************************************************************/
+struct Mux
+{
+    Mux(size_t busIn, size_t addressIn, size_t channelsIn, size_t indexIn) :
+        bus(busIn), address(addressIn), channels(channelsIn), index(indexIn)
+    {}
+    size_t bus;
+    size_t address;
+    size_t channels;
+    size_t index;
+
+    // to sort in the flat set
+    bool operator<(const Mux& rhs) const
+    {
+        return index < rhs.index;
+    }
+};
+
+struct Led : std::enable_shared_from_this<Led>
+{
+    // led pattern addresses start at 0x10
+    Led(const std::string& path, size_t index, int fd) :
+        address(static_cast<uint8_t>(index + 0x10)), file(fd),
+        ledInterface(objServer.add_interface(path, ledGroup::interface))
+    {
+        if (index >= maxDrives)
+        {
+            throw std::runtime_error("Invalid drive index");
+        }
+
+        if (!set(BlinkPattern::off))
+        {
+            std::cerr << "Cannot initialize LED " << path << "\n";
+        }
+    }
+
+    // this has to be called outside the constructor for shared_from_this to
+    // work
+    void createInterface(void)
+    {
+        ledInterface->register_property(
+            ledGroup::asserted, false,
+            [weakRef{weak_from_this()}](const bool req, bool& val) {
+                auto self = weakRef.lock();
+                if (!self)
+                {
+                    return 0;
+                }
+                if (req == val)
+                {
+                    return 1;
+                }
+
+                if (!isPowerOn())
+                {
+                    std::cerr << "Can't change blink state when power is off\n";
+                    throw std::runtime_error(
+                        "Can't change blink state when power is off");
+                }
+                BlinkPattern pattern =
+                    req ? BlinkPattern::error : BlinkPattern::terminate;
+                if (!self->set(pattern))
+                {
+                    std::cerr << "Can't change blink pattern\n";
+                    throw std::runtime_error("Cannot set blink pattern");
+                }
+                val = req;
+                return 1;
+            });
+        ledInterface->initialize();
+    }
+
+    virtual ~Led()
+    {
+        objServer.remove_interface(ledInterface);
+    }
+
+    bool set(BlinkPattern pattern)
+    {
+        int ret = i2c_smbus_write_byte_data(file, address,
+                                            static_cast<uint8_t>(pattern));
+        return ret >= 0;
+    }
+
+    uint8_t address;
+    int file;
+    std::shared_ptr<sdbusplus::asio::dbus_interface> ledInterface;
+};
+
+struct Drive
+{
+    Drive(std::string driveName, bool present, bool isOperational, bool nvme,
+          bool rebuilding) : isNvme(nvme), isPresent(present), name(driveName)
+    {
+        constexpr const char* basePath =
+            "/xyz/openbmc_project/inventory/item/drive/";
+        itemIface =
+            objServer.add_interface(basePath + driveName, inventory::interface);
+        itemIface->register_property("Present", isPresent);
+        itemIface->register_property("PrettyName", driveName);
+        itemIface->initialize();
+        operationalIface = objServer.add_interface(
+            itemIface->get_object_path(),
+            "xyz.openbmc_project.State.Decorator.OperationalStatus");
+
+        operationalIface->register_property(
+            "Functional", isOperational,
+            [this](const bool req, bool& property) {
+                if (!isPresent)
+                {
+                    return 0;
+                }
+                if (property == req)
+                {
+                    return 1;
+                }
+                property = req;
+                if (req)
+                {
+                    clearFailed();
+                    return 1;
+                }
+                markFailed();
+                return 1;
+            });
+
+        operationalIface->initialize();
+        rebuildingIface = objServer.add_interface(
+            itemIface->get_object_path(), "xyz.openbmc_project.State.Drive");
+        rebuildingIface->register_property("Rebuilding", rebuilding);
+        rebuildingIface->initialize();
+        driveIface =
+            objServer.add_interface(itemIface->get_object_path(),
+                                    "xyz.openbmc_project.Inventory.Item.Drive");
+        driveIface->initialize();
+        associations = objServer.add_interface(itemIface->get_object_path(),
+                                               association::interface);
+        associations->register_property("Associations",
+                                        std::vector<Association>{});
+        associations->initialize();
+
+        if (isPresent && (!isOperational || rebuilding))
+        {
+            markFailed();
+        }
+    }
+    virtual ~Drive()
+    {
+        objServer.remove_interface(itemIface);
+        objServer.remove_interface(operationalIface);
+        objServer.remove_interface(rebuildingIface);
+        objServer.remove_interface(assetIface);
+        objServer.remove_interface(driveIface);
+        objServer.remove_interface(associations);
+    }
+
+    void removeAsset()
+    {
+        objServer.remove_interface(assetIface);
+        assetIface = nullptr;
+    }
+
+    void createAsset(
+        const boost::container::flat_map<std::string, std::string>& data)
+    {
+        if (assetIface != nullptr)
+        {
+            return;
+        }
+        assetIface = objServer.add_interface(
+            itemIface->get_object_path(),
+            "xyz.openbmc_project.Inventory.Decorator.Asset");
+        for (const auto& [key, value] : data)
+        {
+            assetIface->register_property(key, value);
+            if (key == "SerialNumber")
+            {
+                serialNumber = value;
+                serialNumberInitialized = true;
+            }
+        }
+        assetIface->initialize();
+    }
+
+    void markFailed(void)
+    {
+        // todo: maybe look this up via mapper
+        constexpr const char* globalInventoryPath =
+            "/xyz/openbmc_project/CallbackManager";
+
+        if (!isPresent)
+        {
+            return;
+        }
+
+        operationalIface->set_property("Functional", false);
+        std::vector<Association> warning = {
+            {"", "warning", globalInventoryPath}};
+        associations->set_property("Associations", warning);
+        logDriveError("Drive " + name);
+    }
+
+    void clearFailed(void)
+    {
+        operationalIface->set_property("Functional", true);
+        associations->set_property("Associations", std::vector<Association>{});
+    }
+
+    void setPresent(bool set)
+    {
+        // nvme drives get detected by their fru
+        if (set == isPresent)
+        {
+            return;
+        }
+        itemIface->set_property("Present", set);
+        isPresent = set;
+    }
+
+    void logPresent()
+    {
+        if (isNvme && !serialNumberInitialized)
+        {
+            // wait until NVMe asset is updated to include the serial number
+            // from the NVMe drive
+            return;
+        }
+
+        if (!isPresent && loggedPresent)
+        {
+            loggedPresent = false;
+            logDeviceRemoved("Drive", name, serialNumber);
+            serialNumber = "N/A";
+            serialNumberInitialized = false;
+            removeAsset();
+        }
+        else if (isPresent && !loggedPresent)
+        {
+            loggedPresent = true;
+            logDeviceAdded("Drive", name, serialNumber);
+        }
+    }
+
+    std::shared_ptr<sdbusplus::asio::dbus_interface> itemIface;
+    std::shared_ptr<sdbusplus::asio::dbus_interface> operationalIface;
+    std::shared_ptr<sdbusplus::asio::dbus_interface> rebuildingIface;
+    std::shared_ptr<sdbusplus::asio::dbus_interface> assetIface;
+    std::shared_ptr<sdbusplus::asio::dbus_interface> driveIface;
+    std::shared_ptr<sdbusplus::asio::dbus_interface> associations;
+
+    bool isNvme;
+    bool isPresent;
+    std::string name;
+    std::string serialNumber = "N/A";
+    bool serialNumberInitialized = false;
+    bool loggedPresent = false;
+};
+
+struct Backplane : std::enable_shared_from_this<Backplane>
+{
+    Backplane(size_t busIn, size_t addressIn, size_t backplaneIndexIn,
+              const std::string& nameIn) :
+        bus(busIn), address(addressIn), backplaneIndex(backplaneIndexIn - 1),
+        name(nameIn), timer(boost::asio::steady_timer(io)),
+        muxes(std::make_shared<boost::container::flat_set<Mux>>())
+    {}
+    void populateAsset(const std::string& rootPath, const std::string& busname)
+    {
+        conn->async_method_call(
+            [assetIface{assetInterface}](
+                const boost::system::error_code ec,
+                const boost::container::flat_map<
+                    std::string, std::variant<std::string>>& values) mutable {
+                if (ec)
+                {
+                    std::cerr
+                        << "Error getting asset tag from HSBP configuration\n";
+
+                    return;
+                }
+                for (const auto& [key, value] : values)
+                {
+                    const std::string* ptr = std::get_if<std::string>(&value);
+                    if (ptr == nullptr)
+                    {
+                        std::cerr << key << " Invalid type!\n";
+                        continue;
+                    }
+                    assetIface->register_property(key, *ptr);
+                }
+                assetIface->initialize();
+            },
+            busname, rootPath, "org.freedesktop.DBus.Properties", "GetAll",
+            assetTag);
+    }
+
+    static std::string zeroPad(const uint8_t val)
+    {
+        std::ostringstream version;
+        version << std::setw(2) << std::setfill('0')
+                << static_cast<size_t>(val);
+        return version.str();
+    }
+
+    void run(const std::string& rootPath, const std::string& busname)
+    {
+        file = open(("/dev/i2c-" + std::to_string(bus)).c_str(),
+                    O_RDWR | O_CLOEXEC);
+        if (file < 0)
+        {
+            std::cerr << "unable to open bus " << bus << "\n";
+            return;
+        }
+
+        if (ioctl(file, I2C_SLAVE_FORCE, address) < 0)
+        {
+            std::cerr << "unable to set address to " << address << "\n";
+            return;
+        }
+
+        if (!getPresent())
+        {
+            std::cerr << "Cannot detect CPLD\n";
+            return;
+        }
+
+        getBootVer(bootVer);
+        getFPGAVer(fpgaVer);
+        getSecurityRev(securityRev);
+        std::string dbusName = boost::replace_all_copy(name, " ", "_");
+        hsbpItemIface = objServer.add_interface(
+            "/xyz/openbmc_project/inventory/item/hsbp/" + dbusName,
+            inventory::interface);
+        hsbpItemIface->register_property("Present", true);
+        hsbpItemIface->register_property("PrettyName", name);
+        hsbpItemIface->initialize();
+
+        storageInterface = objServer.add_interface(
+            hsbpItemIface->get_object_path(),
+            "xyz.openbmc_project.Inventory.Item.StorageController");
+        storageInterface->initialize();
+
+        assetInterface =
+            objServer.add_interface(hsbpItemIface->get_object_path(), assetTag);
+
+        versionIface =
+            objServer.add_interface("/xyz/openbmc_project/software/" + dbusName,
+                                    "xyz.openbmc_project.Software.Version");
+        versionIface->register_property(
+            "Version", zeroPad(bootVer) + "." + zeroPad(fpgaVer) + "." +
+                           zeroPad(securityRev));
+        versionIface->register_property(
+            "Purpose",
+            std::string(
+                "xyz.openbmc_project.Software.Version.VersionPurpose.HSBP"));
+        versionIface->initialize();
+
+        activationIface =
+            objServer.add_interface("/xyz/openbmc_project/software/" + dbusName,
+                                    "xyz.openbmc_project.Software.Activation");
+        activationIface->register_property(
+            "Activation",
+            std::string(
+                "xyz.openbmc_project.Software.Activation.Activations.Active"));
+        activationIface->register_property(
+            "RequestedActivation",
+            std::string("xyz.openbmc_project.Software.Activation."
+                        "RequestedActivations.None"));
+        activationIface->initialize();
+
+        getPresence(presence);
+        getIFDET(ifdet);
+
+        populateAsset(rootPath, busname);
+
+        createDrives();
+
+        runTimer();
+    }
+
+    void runTimer()
+    {
+        timer.expires_after(std::chrono::seconds(scanRateSeconds));
+        timer.async_wait([weak{std::weak_ptr<Backplane>(shared_from_this())}](
+                             boost::system::error_code ec) {
+            auto self = weak.lock();
+            if (!self)
+            {
+                return;
+            }
+            if (ec == boost::asio::error::operation_aborted)
+            {
+                // we're being destroyed
+                return;
+            }
+            else if (ec)
+            {
+                std::cerr << "timer error " << ec.message() << "\n";
+                return;
+            }
+
+            if (!isPowerOn())
+            {
+                // can't access hsbp when power is off
+                self->runTimer();
+                return;
+            }
+
+            self->getPresence(self->presence);
+            self->getIFDET(self->ifdet);
+            self->getFailed(self->failed);
+            self->getRebuild(self->rebuilding);
+
+            self->updateDrives();
+            self->runTimer();
+        });
+    }
+
+    void createDrives()
+    {
+        for (size_t ii = 0; ii < maxDrives; ii++)
+        {
+            uint8_t driveSlot = (1 << ii);
+            bool isNvme = ((ifdet & driveSlot) && !(presence & driveSlot));
+            bool isPresent = isNvme || (presence & driveSlot);
+            bool isFailed = !isPresent || failed & driveSlot;
+            bool isRebuilding = !isPresent && (rebuilding & driveSlot);
+
+            // +1 to convert from 0 based to 1 based
+            std::string driveName = boost::replace_all_copy(name, " ", "_") +
+                                    "_Drive_" + std::to_string(ii + 1);
+            Drive& drive = drives.emplace_back(driveName, isPresent, !isFailed,
+                                               isNvme, isRebuilding);
+            std::shared_ptr<Led> led = leds.emplace_back(std::make_shared<Led>(
+                drive.itemIface->get_object_path(), ii, file));
+            led->createInterface();
+        }
+    }
+
+    void updateDrives()
+    {
+        size_t ii = 0;
+
+        for (auto it = drives.begin(); it != drives.end(); it++, ii++)
+        {
+            uint8_t driveSlot = (1 << ii);
+            bool isNvme = ((ifdet & driveSlot) && !(presence & driveSlot));
+            bool isPresent = isNvme || (presence & driveSlot);
+            bool isFailed = !isPresent || (failed & driveSlot);
+            bool isRebuilding = isPresent && (rebuilding & driveSlot);
+
+            it->isNvme = isNvme;
+            it->setPresent(isPresent);
+            it->logPresent();
+
+            it->rebuildingIface->set_property("Rebuilding", isRebuilding);
+            if (isFailed || isRebuilding)
+            {
+                it->markFailed();
+            }
+            else
+            {
+                it->clearFailed();
+            }
+        }
+    }
+
+    bool getPresent()
+    {
+        present = i2c_smbus_read_byte(file) >= 0;
+        return present;
+    }
+
+    bool getTypeID(uint8_t& val)
+    {
+        constexpr uint8_t addr = 2;
+        int ret = i2c_smbus_read_byte_data(file, addr);
+        if (ret < 0)
+        {
+            std::cerr << "Error " << __FUNCTION__ << "\n";
+            return false;
+        }
+        val = static_cast<uint8_t>(ret);
+        return true;
+    }
+
+    bool getBootVer(uint8_t& val)
+    {
+        constexpr uint8_t addr = 3;
+        int ret = i2c_smbus_read_byte_data(file, addr);
+        if (ret < 0)
+        {
+            std::cerr << "Error " << __FUNCTION__ << "\n";
+            return false;
+        }
+        val = static_cast<uint8_t>(ret);
+        return true;
+    }
+
+    bool getFPGAVer(uint8_t& val)
+    {
+        constexpr uint8_t addr = 4;
+        int ret = i2c_smbus_read_byte_data(file, addr);
+        if (ret < 0)
+        {
+            std::cerr << "Error " << __FUNCTION__ << "\n";
+            return false;
+        }
+        val = static_cast<uint8_t>(ret);
+        return true;
+    }
+
+    bool getSecurityRev(uint8_t& val)
+    {
+        constexpr uint8_t addr = 5;
+        int ret = i2c_smbus_read_byte_data(file, addr);
+        if (ret < 0)
+        {
+            std::cerr << "Error " << __FUNCTION__ << "\n";
+            return false;
+        }
+        val = static_cast<uint8_t>(ret);
+        return true;
+    }
+
+    bool getPresence(uint8_t& val)
+    {
+        // NVMe drives do not assert PRSNTn, and as such do not get reported as
+        // PRESENT in this register
+
+        constexpr uint8_t addr = 8;
+
+        int ret = i2c_smbus_read_byte_data(file, addr);
+        if (ret < 0)
+        {
+            std::cerr << "Error " << __FUNCTION__ << "\n";
+            return false;
+        }
+        // presence is inverted
+        val = static_cast<uint8_t>(~ret);
+        return true;
+    }
+
+    bool getIFDET(uint8_t& val)
+    {
+        // This register is a bitmap of parallel GPIO pins connected to the
+        // IFDETn pin of a drive slot. SATA, SAS, and NVMe drives all assert
+        // IFDETn low when they are inserted into the HSBP.This register, in
+        // combination with the PRESENCE register, are used by the BMC to detect
+        // the presence of NVMe drives.
+
+        constexpr uint8_t addr = 9;
+
+        int ret = i2c_smbus_read_byte_data(file, addr);
+        if (ret < 0)
+        {
+            std::cerr << "Error " << __FUNCTION__ << "\n";
+            return false;
+        }
+        // ifdet is inverted
+        val = static_cast<uint8_t>(~ret);
+        return true;
+    }
+
+    bool getFailed(uint8_t& val)
+    {
+        constexpr uint8_t addr = 0xC;
+        int ret = i2c_smbus_read_byte_data(file, addr);
+        if (ret < 0)
+        {
+            std::cerr << "Error " << __FUNCTION__ << "\n";
+            return false;
+        }
+        val = static_cast<uint8_t>(ret);
+        return true;
+    }
+
+    bool getRebuild(uint8_t& val)
+    {
+        constexpr uint8_t addr = 0xD;
+        int ret = i2c_smbus_read_byte_data(file, addr);
+        if (ret < 0)
+        {
+            std::cerr << "Error " << __FUNCTION__ << " " << strerror(ret)
+                      << "\n";
+            return false;
+        }
+        val = static_cast<uint8_t>(ret);
+        return true;
+    }
+
+    bool getInsertedAndRemovedNvmeDrives(
+        std::forward_list<std::string>& nvmeDrivesInserted,
+        std::forward_list<std::string>& nvmeDrivesRemoved)
+    {
+        /* Get the current drives status */
+        std::bitset<8> currDriveStatus;
+        uint8_t nPresence;
+        uint8_t nIfdet;
+
+        if (!getPresence(nPresence) || !getIFDET(nIfdet))
+        {
+            /* Error getting value. Return */
+            std::cerr << "Backplane " << name
+                      << " failed to get drive status\n";
+            return false;
+        }
+
+        std::string dbusHsbpName = boost::replace_all_copy(name, " ", "_");
+        auto nvmeMap = hsbpConfig.hsbpNvmeMap.find(dbusHsbpName);
+        if (nvmeMap == hsbpConfig.hsbpNvmeMap.end())
+        {
+            std::cerr << "Couldn't get the NVMe Map for the backplane : "
+                      << name << "\n";
+            return false;
+        }
+
+        /* NVMe drives do not assert PRSNTn, and as such do not get reported in
+         * "presence" register, but assert ifdet low. This implies for a NVMe
+         * drive to be present, corresponding precense bit has to be 0 and idfet
+         * has to be 1 (as the values of these regosters are negated: check
+         * getPresence() and getIfdet() functions) */
+        for (uint8_t bit = 0; bit < 8; bit++)
+        {
+            if ((nPresence & (1U << bit)) == 0)
+            {
+                if (nIfdet & (1U << bit))
+                {
+                    currDriveStatus.set(bit);
+                }
+            }
+        }
+
+        /* Determine Inserted and Removed Drives
+         * Prev Bit | Curr Bit | Status
+         *    0     |    0     | No Change
+         *    0     |    1     | Inserted
+         *    1     |    0     | Removed
+         *    1     |    1     | No Change
+         */
+        for (uint8_t index = 0; index < 8; index++)
+        {
+            /* Inserted */
+            if (!prevDriveStatus.test(index) && currDriveStatus.test(index))
+            {
+                nvmeDrivesInserted.emplace_front(nvmeMap->second.at(index));
+                std::cerr << name << " : " << nvmeDrivesInserted.front()
+                          << " Inserted !\n";
+            }
+
+            /* Removed */
+            else if (prevDriveStatus.test(index) &&
+                     !currDriveStatus.test(index))
+            {
+                nvmeDrivesRemoved.emplace_front(nvmeMap->second.at(index));
+                std::cerr << name << " : " << nvmeDrivesRemoved.front()
+                          << " Removed !\n";
+            }
+        }
+
+        prevDriveStatus = currDriveStatus;
+        return true;
+    }
+
+    virtual ~Backplane()
+    {
+        timer.cancel();
+        objServer.remove_interface(hsbpItemIface);
+        objServer.remove_interface(versionIface);
+        objServer.remove_interface(storageInterface);
+        objServer.remove_interface(assetInterface);
+        objServer.remove_interface(activationIface);
+        if (file >= 0)
+        {
+            close(file);
+        }
+    }
+
+    size_t bus;
+    size_t address;
+    size_t backplaneIndex;
+    std::string name;
+    boost::asio::steady_timer timer;
+    bool present = false;
+    uint8_t typeId = 0;
+    uint8_t bootVer = 0;
+    uint8_t fpgaVer = 0;
+    uint8_t securityRev = 0;
+    uint8_t funSupported = 0;
+    uint8_t presence = 0;
+    uint8_t ifdet = 0;
+    uint8_t failed = 0;
+    uint8_t rebuilding = 0;
+    std::bitset<8> prevDriveStatus;
+
+    int file = -1;
+
+    std::string type;
+
+    std::shared_ptr<sdbusplus::asio::dbus_interface> hsbpItemIface;
+    std::shared_ptr<sdbusplus::asio::dbus_interface> versionIface;
+    std::shared_ptr<sdbusplus::asio::dbus_interface> storageInterface;
+    std::shared_ptr<sdbusplus::asio::dbus_interface> assetInterface;
+    std::shared_ptr<sdbusplus::asio::dbus_interface> activationIface;
+    std::list<Drive> drives;
+    std::vector<std::shared_ptr<Led>> leds;
+    std::shared_ptr<boost::container::flat_set<Mux>> muxes;
+};
+
+/* Global HSBP backplanes and NVMe drives collection */
+std::unordered_map<std::string, std::shared_ptr<Backplane>> backplanes;
+std::list<Drive> ownerlessDrives; // drives without a backplane
+/***************************** End of Section *******************************/
+
+/****************************************************************************/
+/***************** Miscellaneous Class/Function Definitions *****************/
+/****************************************************************************/
+/* The purpose of this class is to sync the code flow. Often times there could
+ * be multiple dbus calls which are async, and upon completely finishing all
+ * Dbus calls, we need to call next function, or handle the error.
+ * When an object of this class goes out of scope, the respective handlers
+ * will be called */
+class AsyncCallbackHandler
+{
+    bool errorOccurred = false;
+    std::function<void()> onSuccess = nullptr;
+    std::function<void()> onError = nullptr;
+
+  public:
+    explicit AsyncCallbackHandler(std::function<void()> onSuccessIn,
+                                  std::function<void()> onErrorIn) :
+        onSuccess(std::move(onSuccessIn)), onError(std::move(onErrorIn))
+    {}
+
+    void setError()
+    {
+        errorOccurred = true;
+    }
+
+    ~AsyncCallbackHandler()
+    {
+        /* If error occurred flag was set, execute the error handler */
+        if (errorOccurred)
+        {
+            /* Check if Error Handler is defined */
+            if (onError)
+            {
+                onError();
+            }
+
+            return;
+        }
+
+        /* If Success Handler is present, execute Success Handler */
+        if (onSuccess)
+        {
+            onSuccess();
+        }
+    }
+};
+
+void stopHsbpManager()
+{
+    std::cerr << __FUNCTION__ << ": Stopping hsbp-manager\n";
+    appState = AppState::idle;
+    hsbpConfig.clearConfig();
+    clockBuffers.clear();
+    ioExpanders.clear();
+    backplanes.clear();
+
+    io.stop();
+}
+/***************************** End of Section *******************************/
+
+/****************************************************************************/
+/********* HSBP clock enable/disable related Function Definitions ***********/
+/****************************************************************************/
+void updateHsbpClocks(std::forward_list<std::string>& nvmeDrivesInserted,
+                      std::forward_list<std::string>& nvmeDrivesRemoved)
+{
+    if (appState < AppState::backplanesLoaded)
+    {
+        std::cerr << "HSBP not initialized ! Cancelling Clock Update ! \n";
+        return;
+    }
+
+    std::cerr << "Updating HSBP drive clocks ...\n";
+
+    /* Loop through all clock buffers and try to update the clocks (this will be
+     * done if the mode of operation of the clock buffer is SMBus) */
+    for (auto& clockBuffer : clockBuffers)
+    {
+        if (!clockBuffer.enableDisableClock(nvmeDrivesInserted,
+                                            nvmeDrivesRemoved))
+        {
+            std::cerr << "Error Occurred while setting the clock in \""
+                      << clockBuffer.getName() << "\"\n";
+        }
+    }
+
+    /* If there are drives yet to be updated, check all the IO Expanders in case
+     * they are mapped to the drives and enable the respective IO */
+    if (!nvmeDrivesInserted.empty() || !nvmeDrivesRemoved.empty())
+    {
+        for (auto& ioExpander : ioExpanders)
+        {
+            if (!ioExpander.enableDisableOuput(nvmeDrivesInserted,
+                                               nvmeDrivesRemoved))
+            {
+                std::cerr << "Error Occurred while setting the IO in \""
+                          << ioExpander.getName() << "\"\n";
+            }
+        }
+    }
+
+    /* If there are drives still left, then one or more drives clock
+     * enable/diable failed. There is a possibility of improper mapping or
+     * current communication with the device failed */
+    if (!nvmeDrivesInserted.empty() || !nvmeDrivesRemoved.empty())
+    {
+        std::cerr << "Critical Error !!!\nMapping issue detected !\n";
+
+        if (!nvmeDrivesInserted.empty())
+        {
+            std::cerr << "The clock enable failed for : ";
+            for (auto& nvme1 : nvmeDrivesInserted)
+            {
+                std::cerr << nvme1 << ", ";
+            }
+            std::cerr << "\n";
+        }
+
+        if (!nvmeDrivesRemoved.empty())
+        {
+            std::cerr << "The clock disable failed for : ";
+            for (auto& nvme1 : nvmeDrivesRemoved)
+            {
+                std::cerr << nvme1 << ", ";
+            }
+            std::cerr << "\n";
+        }
+    }
+}
+
+void scanHsbpDrives(bool& hsbpDriveScanInProgress)
+{
+    std::cerr << __FUNCTION__ << ": Scanning HSBP drives status ...\n";
+
+    /* List variables to store the drives Inserted/Removed */
+    std::forward_list<std::string> nvmeDrivesInserted;
+    std::forward_list<std::string> nvmeDrivesRemoved;
+
+    /* Loop through each backplane present and get the list of inserted/removed
+     * drives */
+    for (auto& [name, backplane] : backplanes)
+    {
+        backplane->getInsertedAndRemovedNvmeDrives(nvmeDrivesInserted,
+                                                   nvmeDrivesRemoved);
+    }
+
+    if (!nvmeDrivesInserted.empty() || !nvmeDrivesRemoved.empty())
+    {
+        updateHsbpClocks(nvmeDrivesInserted, nvmeDrivesRemoved);
+    }
+
+    std::cerr << __FUNCTION__ << ": Scanning HSBP drives Completed\n";
+
+    hsbpDriveScanInProgress = false;
+}
+
+void checkHsbpDrivesStatus()
+{
+    static bool hsbpDriveScanInProgress = false;
+    static bool hsbpDriveRescanInQueue = false;
+
+    if (appState < AppState::backplanesLoaded)
+    {
+        std::cerr << __FUNCTION__
+                  << ": HSBP not initialized ! Cancelling scan of HSBP drives "
+                     "status ! \n";
+        return;
+    }
+
+    if (hsbpDriveScanInProgress)
+    {
+        /* Scan and Clock Update already in progress. Try again after sometime.
+         * This event can occur due to the GPIO interrupt */
+        std::cerr << __FUNCTION__
+                  << ": HSBP Drives Scan is already in progress\n";
+        if (hsbpDriveRescanInQueue)
+        {
+            /* There is already a Re-Scan in queue. No need to create multiple
+             * rescans */
+            return;
+        }
+
+        hsbpDriveRescanInQueue = true;
+
+        std::cerr << __FUNCTION__ << ": Queuing the Scan \n";
+
+        auto driveScanTimer = std::make_shared<boost::asio::steady_timer>(io);
+        driveScanTimer->expires_after(std::chrono::seconds(1));
+        driveScanTimer->async_wait(
+            [driveScanTimer](const boost::system::error_code ec) {
+                if (ec == boost::asio::error::operation_aborted)
+                {
+                    // Timer was Aborted
+                    return;
+                }
+                else if (ec)
+                {
+                    std::cerr << "driveScanTimer: Timer error" << ec.message()
+                              << "\n";
+                    return;
+                }
+                hsbpDriveRescanInQueue = false;
+                checkHsbpDrivesStatus();
+            });
+
+        return;
+    }
+
+    hsbpDriveScanInProgress = true;
+
+    /* Post the scan to IO queue and return from here. This enables capturing
+     * next GPIO event if any */
+    boost::asio::post(io, []() { scanHsbpDrives(hsbpDriveScanInProgress); });
+}
+/***************************** End of Section *******************************/
+
+/****************************************************************************/
+/********** Backplanes and NVMe drives related Function Definitions *********/
+/****************************************************************************/
+static size_t getDriveCount()
+{
+    size_t count = 0;
+    for (const auto& [key, backplane] : backplanes)
+    {
+        count += backplane->drives.size();
+    }
+    return count + ownerlessDrives.size();
+}
+
+void updateAssets()
+{
+    appState = AppState::loadingDrives;
+
+    /* Setup a callback to be called once the assets are populated completely or
+     * fallback to error handler */
+    auto drivesLoadedCallback = std::make_shared<AsyncCallbackHandler>(
+        []() {
+            appState = AppState::drivesLoaded;
+            std::cerr << "Drives Updated !\n";
+        },
+        []() {
+            // TODO: Handle this error if needed
+            appState = AppState::backplanesLoaded;
+            std::cerr << "An error occured ! Drives load failed \n";
+        });
+
+    conn->async_method_call(
+        [drivesLoadedCallback](const boost::system::error_code ec,
+                               const GetSubTreeType& subtree) {
+            if (ec)
+            {
+                std::cerr << __FUNCTION__ << ": Error contacting mapper "
+                          << ec.message() << "\n";
+                drivesLoadedCallback->setError();
+                return;
+            }
+
+            // drives may get an owner during this, or we might disover more
+            // drives
+            ownerlessDrives.clear();
+            for (const auto& [path, objDict] : subtree)
+            {
+                if (objDict.empty())
+                {
+                    continue;
+                }
+
+                const std::string& owner = objDict.begin()->first;
+                // we export this interface too
+                if (owner == busName)
+                {
+                    continue;
+                }
+                if (std::find(objDict.begin()->second.begin(),
+                              objDict.begin()->second.end(), assetTag) ==
+                    objDict.begin()->second.end())
+                {
+                    // no asset tag to associate to
+                    continue;
+                }
+
+                conn->async_method_call(
+                    [path, drivesLoadedCallback](
+                        const boost::system::error_code ec2,
+                        const boost::container::flat_map<
+                            std::string, std::variant<uint64_t, std::string>>&
+                            values) {
+                        if (ec2)
+                        {
+                            std::cerr
+                                << __FUNCTION__ << ": Error Getting Config "
+                                << ec2.message() << " "
+                                << "\n";
+                            drivesLoadedCallback->setError();
+                            return;
+                        }
+                        auto findBus = values.find("Bus");
+
+                        if (findBus == values.end())
+                        {
+                            std::cerr
+                                << __FUNCTION__ << ": Illegal interface at "
+                                << path << "\n";
+                            drivesLoadedCallback->setError();
+                            return;
+                        }
+
+                        // find the mux bus and addr
+                        size_t muxBus = static_cast<size_t>(
+                            std::get<uint64_t>(findBus->second));
+                        std::filesystem::path muxPath =
+                            "/sys/bus/i2c/devices/i2c-" +
+                            std::to_string(muxBus) + "/mux_device";
+                        if (!std::filesystem::is_symlink(muxPath))
+                        {
+                            std::cerr << path << " mux does not exist\n";
+                            drivesLoadedCallback->setError();
+                            return;
+                        }
+
+                        // we should be getting something of the form 7-0052
+                        // for bus 7 addr 52
+                        std::string fname =
+                            std::filesystem::read_symlink(muxPath).filename();
+                        auto findDash = fname.find('-');
+
+                        if (findDash == std::string::npos ||
+                            findDash + 1 >= fname.size())
+                        {
+                            std::cerr << path << " mux path invalid\n";
+                            drivesLoadedCallback->setError();
+                            return;
+                        }
+
+                        std::string busStr = fname.substr(0, findDash);
+                        std::string muxStr = fname.substr(findDash + 1);
+
+                        size_t bus = static_cast<size_t>(std::stoi(busStr));
+                        size_t addr =
+                            static_cast<size_t>(std::stoi(muxStr, nullptr, 16));
+                        size_t muxIndex = 0;
+
+                        // find the channel of the mux the drive is on
+                        std::ifstream nameFile(
+                            "/sys/bus/i2c/devices/i2c-" +
+                            std::to_string(muxBus) + "/name");
+                        if (!nameFile)
+                        {
+                            std::cerr << __FUNCTION__
+                                      << ": Unable to open name file of bus "
+                                      << muxBus << "\n";
+                            drivesLoadedCallback->setError();
+                            return;
+                        }
+
+                        std::string nameStr;
+                        std::getline(nameFile, nameStr);
+
+                        // file is of the form "i2c-4-mux (chan_id 1)", get chan
+                        // assume single digit chan
+                        const std::string prefix = "chan_id ";
+                        size_t findId = nameStr.find(prefix);
+                        if (findId == std::string::npos ||
+                            findId + 1 >= nameStr.size())
+                        {
+                            std::cerr
+                                << __FUNCTION__ << ": Illegal name file on bus "
+                                << muxBus << "\n";
+                        }
+
+                        std::string indexStr =
+                            nameStr.substr(findId + prefix.size(), 1);
+
+                        size_t driveIndex = std::stoi(indexStr);
+
+                        boost::container::flat_map<std::string, std::string>
+                            assetInventory;
+                        const std::array<const char*, 4> assetKeys = {
+                            "PartNumber", "SerialNumber", "Manufacturer",
+                            "Model"};
+                        for (const auto& [key, value] : values)
+                        {
+                            if (std::find(assetKeys.begin(), assetKeys.end(),
+                                          key) == assetKeys.end())
+                            {
+                                continue;
+                            }
+                            if (std::holds_alternative<std::string>(value))
+                            {
+                                assetInventory[key] =
+                                    std::get<std::string>(value);
+                            }
+                        }
+
+                        Backplane* parent = nullptr;
+                        for (auto& [name, backplane] : backplanes)
+                        {
+                            muxIndex = 0;
+                            for (const Mux& mux : *(backplane->muxes))
+                            {
+                                if (bus == mux.bus && addr == mux.address)
+                                {
+                                    parent = backplane.get();
+                                    break;
+                                }
+                                muxIndex += mux.channels;
+                            }
+                            if (parent)
+                            {
+                                /* Found the backplane. No need to proceed
+                                 * further */
+                                break;
+                            }
+                        }
+
+                        // assume its a M.2 or something without a hsbp
+                        if (parent == nullptr)
+                        {
+                            std::string driveName =
+                                "Drive_" + std::to_string(getDriveCount() + 1);
+                            auto& drive = ownerlessDrives.emplace_back(
+                                driveName, true, true, true, false);
+                            drive.createAsset(assetInventory);
+                            return;
+                        }
+
+                        driveIndex += muxIndex;
+
+                        if (parent->drives.size() <= driveIndex)
+                        {
+                            std::cerr
+                                << __FUNCTION__ << ": Illegal drive index at "
+                                << path << " " << driveIndex << "\n";
+                            drivesLoadedCallback->setError();
+                            return;
+                        }
+                        auto it = parent->drives.begin();
+                        std::advance(it, driveIndex);
+
+                        it->createAsset(assetInventory);
+                    },
+                    owner, path, "org.freedesktop.DBus.Properties", "GetAll",
+                    "" /*all interface items*/);
+            }
+        },
+        mapper::busName, mapper::path, mapper::interface, mapper::subtree, "/",
+        0, std::array<const char*, 1>{nvmeIntf});
+}
+
+void populateMuxes(std::shared_ptr<boost::container::flat_set<Mux>> muxes,
+                   std::string& rootPath)
+{
+    const static std::array<const std::string, 4> muxTypes = {
+        "xyz.openbmc_project.Configuration.PCA9543Mux",
+        "xyz.openbmc_project.Configuration.PCA9544Mux",
+        "xyz.openbmc_project.Configuration.PCA9545Mux",
+        "xyz.openbmc_project.Configuration.PCA9546Mux"};
+
+    conn->async_method_call(
+        [muxes](const boost::system::error_code ec,
+                const GetSubTreeType& subtree) {
+            if (ec)
+            {
+                std::cerr << __FUNCTION__ << ": Error contacting mapper "
+                          << ec.message() << "\n";
+                return;
+            }
+            size_t index = 0; // as we use a flat map, these are sorted
+            for (const auto& [path, objDict] : subtree)
+            {
+                if (objDict.empty() || objDict.begin()->second.empty())
+                {
+                    continue;
+                }
+
+                const std::string& owner = objDict.begin()->first;
+                const std::vector<std::string>& interfaces =
+                    objDict.begin()->second;
+
+                const std::string* interface = nullptr;
+                for (const std::string& iface : interfaces)
+                {
+                    if (std::find(muxTypes.begin(), muxTypes.end(), iface) !=
+                        muxTypes.end())
+                    {
+                        interface = &iface;
+                        break;
+                    }
+                }
+
+                if (interface == nullptr)
+                {
+                    std::cerr << __FUNCTION__ << ": Cannot get mux type\n";
+                    continue;
+                }
+
+                conn->async_method_call(
+                    [path, muxes, index](
+                        const boost::system::error_code ec2,
+                        const boost::container::flat_map<
+                            std::string,
+                            std::variant<uint64_t, std::vector<std::string>>>&
+                            values) {
+                        if (ec2)
+                        {
+                            std::cerr
+                                << __FUNCTION__ << ": Error Getting Config "
+                                << ec2.message() << "\n";
+                            return;
+                        }
+                        auto findBus = values.find("Bus");
+                        auto findAddress = values.find("Address");
+                        auto findChannelNames = values.find("ChannelNames");
+                        if (findBus == values.end() ||
+                            findAddress == values.end())
+                        {
+                            std::cerr
+                                << __FUNCTION__ << ": Illegal configuration at "
+                                << path << "\n";
+                            return;
+                        }
+                        size_t bus = static_cast<size_t>(
+                            std::get<uint64_t>(findBus->second));
+                        size_t address = static_cast<size_t>(
+                            std::get<uint64_t>(findAddress->second));
+                        std::vector<std::string> channels =
+                            std::get<std::vector<std::string>>(
+                                findChannelNames->second);
+                        muxes->emplace(bus, address, channels.size(), index);
+                    },
+                    owner, path, "org.freedesktop.DBus.Properties", "GetAll",
+                    *interface);
+                index++;
+            }
+        },
+        mapper::busName, mapper::path, mapper::interface, mapper::subtree,
+        rootPath, 1, muxTypes);
+}
+
+void populateHsbpBackplanes(
+    const std::shared_ptr<AsyncCallbackHandler>& backplanesLoadedCallback)
+{
+    std::cerr << __FUNCTION__ << ": Scanning Backplanes ...\n";
+    appState = AppState::loadingBackplanes;
+    backplanes.clear();
+
+    conn->async_method_call(
+        [backplanesLoadedCallback](const boost::system::error_code ec,
+                                   const GetSubTreeType& subtree) {
+            if (ec)
+            {
+                std::cerr << __FUNCTION__ << ": Error contacting mapper "
+                          << ec.message() << "\n";
+                backplanesLoadedCallback->setError();
+                return;
+            }
+
+            if (subtree.empty())
+            {
+                /* There wer no HSBP's detected. set teh state back to
+                 * componentsLoaded so that on backplane match event, the
+                 * process can start again */
+                appState = AppState::componentsLoaded;
+                std::cerr << __FUNCTION__ << ": No HSBPs Detected....\n";
+                return;
+            }
+
+            for (const auto& [path, objDict] : subtree)
+            {
+                if (objDict.empty())
+                {
+                    std::cerr << __FUNCTION__
+                              << ": Subtree data "
+                                 "corrupted !\n";
+                    backplanesLoadedCallback->setError();
+                    return;
+                }
+
+                const std::string& owner = objDict.begin()->first;
+                conn->async_method_call(
+                    [backplanesLoadedCallback, path,
+                     owner](const boost::system::error_code ec2,
+                            const boost::container::flat_map<
+                                std::string, BasicVariantType>& resp) {
+                        if (ec2)
+                        {
+                            std::cerr
+                                << __FUNCTION__ << ": Error Getting Config "
+                                << ec2.message() << "\n";
+                            backplanesLoadedCallback->setError();
+                            return;
+                        }
+                        std::optional<size_t> bus;
+                        std::optional<size_t> address;
+                        std::optional<size_t> backplaneIndex;
+                        std::optional<std::string> name;
+                        for (const auto& [key, value] : resp)
+                        {
+                            if (key == "Bus")
+                            {
+                                bus = std::get<uint64_t>(value);
+                            }
+                            else if (key == "Address")
+                            {
+                                address = std::get<uint64_t>(value);
+                            }
+                            else if (key == "Index")
+                            {
+                                backplaneIndex = std::get<uint64_t>(value);
+                            }
+                            else if (key == "Name")
+                            {
+                                name = std::get<std::string>(value);
+                            }
+                        }
+                        if (!bus || !address || !name || !backplaneIndex)
+                        {
+                            std::cerr
+                                << __FUNCTION__ << ": Illegal configuration at "
+                                << path << "\n";
+                            backplanesLoadedCallback->setError();
+                            return;
+                        }
+                        std::string parentPath =
+                            std::filesystem::path(path).parent_path();
+                        const auto& [backplane, status] = backplanes.emplace(
+                            *name, std::make_shared<Backplane>(
+                                       *bus, *address, *backplaneIndex, *name));
+                        backplane->second->run(parentPath, owner);
+                        populateMuxes(backplane->second->muxes, parentPath);
+                    },
+                    owner, path, "org.freedesktop.DBus.Properties", "GetAll",
+                    hsbpCpldInft);
+            }
+        },
+        mapper::busName, mapper::path, mapper::interface, mapper::subtree, "/",
+        0, std::array<const char*, 1>{hsbpCpldInft});
+}
+
+void setUpBackplanesAndDrives()
+{
+    static bool backplanesScanInProgress = false;
+    static bool backplanesRescanInQueue = false;
+
+    if (appState < AppState::componentsLoaded)
+    {
+        std::cerr << __FUNCTION__
+                  << ": Components are not initialized ! Cancelling scan of "
+                     "Backplanes ! \n";
+        return;
+    }
+
+    if (backplanesScanInProgress)
+    {
+        std::cerr << __FUNCTION__
+                  << ": Backplanes Scan is already in progress\n";
+        if (backplanesRescanInQueue)
+        {
+            /* There is already a Re-Scan in queue. No need to create multiple
+             * rescans */
+            return;
+        }
+
+        backplanesRescanInQueue = true;
+
+        std::cerr << __FUNCTION__ << ": Queuing the Backplane Scan \n";
+
+        auto backplaneScanTimer =
+            std::make_shared<boost::asio::steady_timer>(io);
+        backplaneScanTimer->expires_after(std::chrono::seconds(1));
+        backplaneScanTimer->async_wait(
+            [backplaneScanTimer](const boost::system::error_code ec) {
+                if (ec == boost::asio::error::operation_aborted)
+                {
+                    // Timer was Aborted
+                    return;
+                }
+                else if (ec)
+                {
+                    std::cerr << "backplaneScanTimer: Timer error"
+                              << ec.message() << "\n";
+                    return;
+                }
+                backplanesRescanInQueue = false;
+                setUpBackplanesAndDrives();
+            });
+
+        return;
+    }
+
+    backplanesScanInProgress = true;
+
+    /* Set Callback to be called once backplanes are populated to call
+     * updateAssets() and checkHsbpDrivesStatus() or handle error scnenario */
+    auto backplanesLoadedCallback = std::make_shared<AsyncCallbackHandler>(
+        []() {
+            /* If no HSBP's were detected, the state changes to
+             * componentsLoaded. Proceed further only if state was
+             * loadingBackplanes */
+            if (appState != AppState::loadingBackplanes)
+            {
+                backplanesScanInProgress = false;
+                return;
+            }
+
+            /* If there is a ReScan in the Queue, dont proceed further. Load the
+             * Backplanes again and then proceed further */
+            if (backplanesRescanInQueue)
+            {
+                backplanesScanInProgress = false;
+                return;
+            }
+
+            appState = AppState::backplanesLoaded;
+            std::cerr << __FUNCTION__ << ": Backplanes Loaded...\n";
+
+            checkHsbpDrivesStatus();
+            updateAssets();
+            backplanesScanInProgress = false;
+        },
+        []() {
+            /* Loading Backplanes is an important step. If the load failed due
+             * to an error, stop the app so that restart cant be triggerred */
+            std::cerr << "Backplanes couldn't be loaded due to an error !...\n";
+            appState = AppState::idle;
+            backplanesScanInProgress = false;
+            stopHsbpManager();
+        });
+
+    populateHsbpBackplanes(backplanesLoadedCallback);
+}
+
+void setupBackplanesAndDrivesMatch()
+{
+    static auto backplaneMatch = std::make_unique<sdbusplus::bus::match_t>(
+        *conn,
+        "sender='xyz.openbmc_project.EntityManager', type='signal', "
+        "member='PropertiesChanged', "
+        "interface='org.freedesktop.DBus.Properties', "
+        "path_namespace='/xyz/openbmc_project/inventory/system/board', arg0='" +
+            std::string(hsbpCpldInft) + "'",
+        [](sdbusplus::message_t& msg) {
+            std::string intfName;
+            boost::container::flat_map<std::string, BasicVariantType> values;
+            msg.read(intfName, values);
+
+            /* This match will be triggered for each of the property being set
+             * under the hsbpCpldInft interface. Call the loader only on one
+             * property say "name". This will avoid multiple calls to populate
+             * function
+             */
+            for (const auto& [key, value] : values)
+            {
+                if (key == "Name")
+                {
+                    /* This match will be triggered when ever there is a
+                     * addition/removal of HSBP backplane. At this stage, all
+                     * the HSBP's need to be populated again and also assets
+                     * have to be re-discovered. So, setting state to
+                     * componentsLoaded and calling setUpBackplanesAndDrives()
+                     * only if configuration and components loading was
+                     * completed */
+                    if (appState < AppState::componentsLoaded)
+                    {
+                        /* Configuration is not loaded yet. Backplanes will be
+                         * loaded
+                         * once configuration and components are loaded. */
+                        std::cerr
+                            << __FUNCTION__ << ": Discarding Backplane match\n";
+                        return;
+                    }
+
+                    appState = AppState::componentsLoaded;
+
+                    /* We will call the function after a small delay to let all
+                     * the properties to be intialized */
+                    auto backplaneTimer =
+                        std::make_shared<boost::asio::steady_timer>(io);
+                    backplaneTimer->expires_after(std::chrono::seconds(2));
+                    backplaneTimer->async_wait(
+                        [backplaneTimer](const boost::system::error_code ec) {
+                            if (ec == boost::asio::error::operation_aborted)
+                            {
+                                return;
+                            }
+                            else if (ec)
+                            {
+                                std::cerr << "backplaneTimer: Timer error"
+                                          << ec.message() << "\n";
+                                return;
+                            }
+                            setUpBackplanesAndDrives();
+                        });
+                }
+            }
+        });
+
+    static auto drivesMatch = std::make_unique<sdbusplus::bus::match_t>(
+        *conn,
+        "sender='xyz.openbmc_project.EntityManager', type='signal', "
+        "member='PropertiesChanged', "
+        "interface='org.freedesktop.DBus.Properties', arg0='" +
+            std::string(nvmeIntf) + "'",
+        [](sdbusplus::message_t& msg) {
+            std::string intfName;
+            boost::container::flat_map<std::string, BasicVariantType> values;
+            msg.read(intfName, values);
+
+            /* This match will be triggered for each of the property being set
+             * under the nvmeIntf interface. Call the loader only on one
+             * property say "name". This will avoid multiple calls to populate
+             * function
+             */
+            for (const auto& [key, value] : values)
+            {
+                if (key == "Name")
+                {
+                    /* This match will be triggered when ever there is a
+                     * addition/removal of drives. At this stage only assets
+                     * have to be re-discovered. So, setting state to
+                     * backplanesLoaded and calling updateAssets() only if all
+                     * previous states are completed */
+                    if (appState < AppState::backplanesLoaded)
+                    {
+                        /* Configuration is not loaded yet. Drives will be
+                         * loaded once
+                         * configuration, components and backplanes are loaded.
+                         */
+                        std::cerr
+                            << __FUNCTION__ << ": Discarding Drive match\n";
+                        return;
+                    }
+
+                    appState = AppState::backplanesLoaded;
+
+                    /* We will call the function after a small delay to let all
+                     * the properties to be intialized */
+                    auto driveTimer =
+                        std::make_shared<boost::asio::steady_timer>(io);
+                    driveTimer->expires_after(std::chrono::seconds(2));
+                    driveTimer->async_wait(
+                        [driveTimer](const boost::system::error_code ec) {
+                            if (ec == boost::asio::error::operation_aborted)
+                            {
+                                return;
+                            }
+                            else if (ec)
+                            {
+                                std::cerr << "driveTimer: Timer error"
+                                          << ec.message() << "\n";
+                                return;
+                            }
+                            updateAssets();
+                        });
+                }
+            }
+        });
+}
+/***************************** End of Section *******************************/
+
+/****************************************************************************/
+/******************* Components related Function Definitions ****************/
+/****************************************************************************/
+bool verifyComponentsLoaded()
+{
+    std::cerr << __FUNCTION__ << ": Verifying all Components...\n";
+
+    /* Loop through all clock buffers */
+    for (auto& clockBuffer : clockBuffers)
+    {
+        if (!clockBuffer.isInitialized())
+        {
+            std::cerr << "Critical Error: Initializing \""
+                      << clockBuffer.getName() << "\" failed\n";
+            return false;
+        }
+    }
+
+    /* Loop through all IO Expanders */
+    for (auto& ioExpander : ioExpanders)
+    {
+        if (!ioExpander.isInitialized())
+        {
+            std::cerr << "Critical Error: Initializing \""
+                      << ioExpander.getName() << "\" failed\n";
+            return false;
+        }
+    }
+
+    std::cerr << __FUNCTION__ << ": Verifying Components Complete\n";
+
+    return true;
+}
+/***************************** End of Section *******************************/
+
+/****************************************************************************/
+/****************** IO expander related Function Definitions ****************/
+/****************************************************************************/
+void loadIoExpanderInfo(
+    const std::shared_ptr<AsyncCallbackHandler>& componentsLoadedCallback)
+{
+    appState = AppState::loadingComponents;
+
+    /* Clear global ioExpanders to start off */
+    ioExpanders.clear();
+
+    conn->async_method_call(
+        [componentsLoadedCallback](const boost::system::error_code ec,
+                                   const GetSubTreeType& subtree) {
+            if (ec)
+            {
+                std::cerr << __FUNCTION__ << ": Error contacting mapper "
+                          << ec.message() << "\n";
+                componentsLoadedCallback->setError();
+                return;
+            }
+
+            for (auto& [path, objDict] : subtree)
+            {
+                if (objDict.empty())
+                {
+                    std::cerr << __FUNCTION__ << ": Subtree data corrupted !\n";
+                    componentsLoadedCallback->setError();
+                    return;
+                }
+
+                /* Ideally there would be only one element in objDict as only
+                 * one service exposes it and there would be only one interface
+                 * so it is safe to directly read them without loop */
+                const std::string& service = objDict.begin()->first;
+                const std::string& intf = objDict.begin()->second.front();
+
+                conn->async_method_call(
+                    [componentsLoadedCallback](
+                        const boost::system::error_code er,
+                        const boost::container::flat_map<
+                            std::string, BasicVariantType>& resp) {
+                        if (er)
+                        {
+                            std::cerr << __FUNCTION__
+                                      << ": Error Getting "
+                                         "Config "
+                                      << er.message() << "\n";
+                            componentsLoadedCallback->setError();
+                            return;
+                        }
+
+                        std::optional<uint64_t> bus;
+                        std::optional<uint64_t> address;
+                        std::optional<uint64_t> confIORegAddr;
+                        std::optional<uint64_t> outCtrlBaseAddr;
+                        std::optional<uint64_t> outCtrlByteCount;
+                        std::unordered_map<std::string,
+                                           std::vector<std::string>>
+                            ioMap;
+                        std::optional<std::string> name;
+                        std::optional<std::string> type;
+
+                        /* Loop through to get all IO Expander properties */
+                        for (const auto& [key, value] : resp)
+                        {
+                            if (key == "Bus")
+                            {
+                                bus = std::get<uint64_t>(value);
+                            }
+                            else if (key == "Address")
+                            {
+                                address = std::get<uint64_t>(value);
+                            }
+                            else if (key == "ConfIORegAddr")
+                            {
+                                confIORegAddr = std::get<uint64_t>(value);
+                            }
+                            else if (key == "OutCtrlBaseAddr")
+                            {
+                                outCtrlBaseAddr = std::get<uint64_t>(value);
+                            }
+                            else if (key == "OutCtrlByteCount")
+                            {
+                                outCtrlByteCount = std::get<uint64_t>(value);
+                            }
+                            else if (key == "Name")
+                            {
+                                name = std::get<std::string>(value);
+                            }
+                            else if (key == "Type")
+                            {
+                                type = std::get<std::string>(value);
+                            }
+                            else if (key.starts_with("IO"))
+                            {
+                                std::optional<std::vector<std::string>> outList;
+                                outList = std::get<NvmeMapping>(value);
+                                if (!outList)
+                                {
+                                    break;
+                                }
+                                ioMap.try_emplace(key, *outList);
+                            }
+                        }
+
+                        /* Verify if all properties were defined */
+                        if (!bus || !address || !confIORegAddr ||
+                            !outCtrlBaseAddr || !outCtrlByteCount || !name)
+                        {
+                            std::cerr << __FUNCTION__
+                                      << ": Incomplete "
+                                         "Clock Buffer definition !! \n";
+                            componentsLoadedCallback->setError();
+                            return;
+                        }
+
+                        /* Check if we were able to get byteMap correctly */
+                        if ((*outCtrlByteCount) != ioMap.size())
+                        {
+                            std::cerr << "loadIoExpanderInfo(): Incomplete "
+                                         "IO Map !! \n";
+                            componentsLoadedCallback->setError();
+                            return;
+                        }
+
+                        /* Create IO expander object and add it to global
+                         * ioExpanders vector */
+                        ioExpanders.emplace_front(
+                            *bus, *address, *confIORegAddr, *outCtrlBaseAddr,
+                            *outCtrlByteCount, ioMap, *name, *type);
+                    },
+                    service, path, "org.freedesktop.DBus.Properties", "GetAll",
+                    intf);
+            }
+        },
+        mapper::busName, mapper::path, mapper::interface, mapper::subtree, "/",
+        0, hsbpConfig.ioExpanderTypes);
+}
+/***************************** End of Section *******************************/
+
+/****************************************************************************/
+/***************** Clock buffer related Function Definitions ****************/
+/****************************************************************************/
+void loadClockBufferInfo(
+    const std::shared_ptr<AsyncCallbackHandler>& componentsLoadedCallback)
+{
+    appState = AppState::loadingComponents;
+
+    /* Clear global clockBuffers to start off */
+    clockBuffers.clear();
+
+    conn->async_method_call(
+        [componentsLoadedCallback](const boost::system::error_code ec,
+                                   const GetSubTreeType& subtree) {
+            if (ec)
+            {
+                std::cerr << __FUNCTION__ << ": Error contacting mapper "
+                          << ec.message() << "\n";
+                componentsLoadedCallback->setError();
+                return;
+            }
+
+            for (auto& [path, objDict] : subtree)
+            {
+                if (objDict.empty())
+                {
+                    std::cerr << __FUNCTION__ << ": Subtree data corrupted !\n";
+                    componentsLoadedCallback->setError();
+                    return;
+                }
+
+                /* Ideally there would be only one element in objDict as only
+                 * one service exposes it and there would be only one interface
+                 * so it is safe to directly read them without loop */
+                const std::string& service = objDict.begin()->first;
+                const std::string& intf = objDict.begin()->second.front();
+
+                conn->async_method_call(
+                    [componentsLoadedCallback](
+                        const boost::system::error_code er,
+                        const boost::container::flat_map<
+                            std::string, BasicVariantType>& resp) {
+                        if (er)
+                        {
+                            std::cerr << __FUNCTION__
+                                      << ": Error Getting "
+                                         "Config "
+                                      << er.message() << "\n";
+                            componentsLoadedCallback->setError();
+                            return;
+                        }
+
+                        std::optional<uint64_t> bus;
+                        std::optional<uint64_t> address;
+                        std::optional<std::string> mode;
+                        std::optional<uint64_t> outCtrlBaseAddr;
+                        std::optional<uint64_t> outCtrlByteCount;
+                        std::unordered_map<std::string,
+                                           std::vector<std::string>>
+                            byteMap;
+                        std::optional<std::string> name;
+                        std::optional<std::string> type;
+
+                        /* Loop through to get all Clock Buffer properties */
+                        for (const auto& [key, value] : resp)
+                        {
+                            if (key == "Bus")
+                            {
+                                bus = std::get<uint64_t>(value);
+                            }
+                            else if (key == "Address")
+                            {
+                                address = std::get<uint64_t>(value);
+                            }
+                            else if (key == "Mode")
+                            {
+                                mode = std::get<std::string>(value);
+                            }
+                            else if (key == "OutCtrlBaseAddr")
+                            {
+                                outCtrlBaseAddr = std::get<uint64_t>(value);
+                            }
+                            else if (key == "OutCtrlByteCount")
+                            {
+                                outCtrlByteCount = std::get<uint64_t>(value);
+                            }
+                            else if (key == "Name")
+                            {
+                                name = std::get<std::string>(value);
+                            }
+                            else if (key == "Type")
+                            {
+                                type = std::get<std::string>(value);
+                            }
+                            else if (key.starts_with("Byte"))
+                            {
+                                std::optional<std::vector<std::string>>
+                                    byteList;
+                                byteList = std::get<NvmeMapping>(value);
+                                if (!byteList)
+                                {
+                                    break;
+                                }
+                                byteMap.try_emplace(key, *byteList);
+                            }
+                        }
+
+                        /* Verify if all properties were defined */
+                        if (!bus || !address || !mode || !outCtrlBaseAddr ||
+                            !outCtrlByteCount || !name)
+                        {
+                            std::cerr << __FUNCTION__
+                                      << ": Incomplete "
+                                         "Clock Buffer definition !! \n";
+                            componentsLoadedCallback->setError();
+                            return;
+                        }
+
+                        /* Check if we were able to get byteMap correctly */
+                        if ((*outCtrlByteCount) != byteMap.size())
+                        {
+                            std::cerr << __FUNCTION__
+                                      << ": Incomplete "
+                                         "Byte Map !! \n";
+                            componentsLoadedCallback->setError();
+                            return;
+                        }
+
+                        /* Create clock buffer object and add it to global
+                         * clockBuffers vector */
+                        clockBuffers.emplace_front(
+                            *bus, *address, *mode, *outCtrlBaseAddr,
+                            *outCtrlByteCount, byteMap, *name, *type);
+                    },
+                    service, path, "org.freedesktop.DBus.Properties", "GetAll",
+                    intf);
+            }
+        },
+        mapper::busName, mapper::path, mapper::interface, mapper::subtree, "/",
+        0, hsbpConfig.clockBufferTypes);
+}
+/***************************** End of Section *******************************/
+
+/****************************************************************************/
+/***************** HSBP Config related Function Definitions *****************/
+/****************************************************************************/
+void loadHsbpConfig()
+{
+    appState = AppState::loadingHsbpConfig;
+
+    conn->async_method_call(
+        [](const boost::system::error_code ec, const GetSubTreeType& subtree) {
+            if (ec)
+            {
+                std::cerr << __FUNCTION__ << ": Error contacting mapper "
+                          << ec.message() << "\n";
+                return;
+            }
+
+            if (subtree.empty())
+            {
+                /* Entity manager is either still loading the configuration or
+                 * failed to load. In either way, return from here as the dbus
+                 * match will take care */
+                std::cerr << __FUNCTION__ << ": No configuration detected !!\n";
+                return;
+            }
+
+            /* There should be only one HSBP Configureation exposed */
+            if (subtree.size() != 1)
+            {
+                std::cerr << __FUNCTION__
+                          << ": Multiple configurations "
+                             "detected !!\n";
+                /* Critical Error. Stop Application */
+                stopHsbpManager();
+                return;
+            }
+
+            auto& path = subtree.begin()->first;
+            auto& objDict = subtree.begin()->second;
+
+            if (objDict.empty())
+            {
+                /* Critical Error. Stop Application */
+                std::cerr << __FUNCTION__ << ": Subtree data corrupted !\n";
+                stopHsbpManager();
+                return;
+            }
+
+            const std::string& service = objDict.begin()->first;
+
+            conn->async_method_call(
+                [](const boost::system::error_code er,
+                   const boost::container::flat_map<std::string,
+                                                    BasicVariantType>& resp) {
+                    if (er)
+                    {
+                        std::cerr << __FUNCTION__ << ": Error Getting Config "
+                                  << er.message() << "\n";
+                        /* Critical Error. Stop Application */
+                        stopHsbpManager();
+                        return;
+                    }
+
+                    std::optional<uint64_t> rootI2cBus;
+                    std::optional<std::vector<std::string>> supportedHsbps;
+                    std::optional<std::vector<std::string>> clockBufferTypes;
+                    std::optional<std::vector<std::string>> ioExpanderTypes;
+
+                    /* Loop through to get root i2c bus and list of supported
+                     * HSBPs */
+                    for (const auto& [key, value] : resp)
+                    {
+                        if (key == "HsbpSupported")
+                        {
+                            supportedHsbps =
+                                std::get<std::vector<std::string>>(value);
+                        }
+                        else if (key == "RootI2cBus")
+                        {
+                            rootI2cBus = std::get<uint64_t>(value);
+                        }
+                        else if (key == "ClockBuffer")
+                        {
+                            clockBufferTypes =
+                                std::get<std::vector<std::string>>(value);
+                        }
+                        else if (key == "IoExpander")
+                        {
+                            ioExpanderTypes =
+                                std::get<std::vector<std::string>>(value);
+                        }
+                    }
+
+                    /* Verify if i2c bus, supported HSBP's and clock buffers
+                     * were defined (IO Expanders are optional) */
+                    if (!rootI2cBus || !supportedHsbps || !clockBufferTypes)
+                    {
+                        std::cerr << __FUNCTION__
+                                  << ": Incomplete HSBP "
+                                     "configuration !! \n";
+                        /* Critical Error. Stop Application */
+                        stopHsbpManager();
+                        return;
+                    }
+
+                    /* Clear and Load all details to global hsbp configuration
+                     * variable */
+                    hsbpConfig.clearConfig();
+                    hsbpConfig.rootBus = *rootI2cBus;
+                    hsbpConfig.supportedHsbps = std::move(*supportedHsbps);
+
+                    for (auto& clkBuffType : *clockBufferTypes)
+                    {
+                        hsbpConfig.clockBufferTypes.emplace_back(
+                            "xyz.openbmc_project.Configuration." + clkBuffType);
+                    }
+
+                    if (ioExpanderTypes)
+                    {
+                        for (auto& ioCntrType : *ioExpanderTypes)
+                        {
+                            hsbpConfig.ioExpanderTypes.emplace_back(
+                                "xyz.openbmc_project.Configuration." +
+                                ioCntrType);
+                        }
+                    }
+
+                    /* Loop through to get HSBP-NVME map and Components map
+                     * details */
+                    uint8_t hsbpMapCount = 0;
+                    for (const auto& [key, value] : resp)
+                    {
+                        if (std::find(hsbpConfig.supportedHsbps.begin(),
+                                      hsbpConfig.supportedHsbps.end(), key) !=
+                            hsbpConfig.supportedHsbps.end())
+                        {
+                            std::optional<std::vector<std::string>> hsbpMap;
+                            hsbpMap = std::get<NvmeMapping>(value);
+                            if (!hsbpMap)
+                            {
+                                break;
+                            }
+                            hsbpConfig.hsbpNvmeMap.try_emplace(key, *hsbpMap);
+                            hsbpMapCount++;
+                        }
+                    }
+
+                    /* Check if we were able to get all the HSBP-NVMe maps */
+                    if (hsbpConfig.supportedHsbps.size() != hsbpMapCount)
+                    {
+                        std::cerr << __FUNCTION__
+                                  << ": Incomplete HSBP Map "
+                                     "details !! \n";
+                        /* Critical Error. Stop Application */
+                        stopHsbpManager();
+                        return;
+                    }
+
+                    /* HSBP configuration is loaded */
+                    appState = AppState::hsbpConfigLoaded;
+                    std::cerr << "HSBP Config loaded !\n";
+
+                    /* Get Clock buffers and IO expander details. Create shared
+                     * object of AsyncCallbackHandler with success and error
+                     * callback */
+                    auto componentsLoadedCallback = std::make_shared<
+                        AsyncCallbackHandler>(
+                        []() {
+                            /* Verify if all components were initialized without
+                             * errors */
+                            if (!verifyComponentsLoaded())
+                            {
+                                /* The application cannot proceed further as
+                                 * components initialization failed. App needs
+                                 * Restart */
+                                appState = AppState::idle;
+                                std::cerr
+                                    << "One or more Componenets initialization "
+                                       "failed !! Restart Required !\n";
+                                stopHsbpManager();
+                            }
+
+                            appState = AppState::componentsLoaded;
+                            setUpBackplanesAndDrives();
+                        },
+                        []() {
+                            /* The application cannot proceed further as
+                             * components load failed. App needs Restart */
+                            appState = AppState::idle;
+                            std::cerr << "Loading Componenets failed !! "
+                                         "Restart Required !\n";
+                            stopHsbpManager();
+                        });
+
+                    loadClockBufferInfo(componentsLoadedCallback);
+
+                    if (ioExpanderTypes)
+                    {
+                        loadIoExpanderInfo(componentsLoadedCallback);
+                    }
+                },
+                service, path, "org.freedesktop.DBus.Properties", "GetAll",
+                hsbpConfigIntf);
+        },
+        mapper::busName, mapper::path, mapper::interface, mapper::subtree, "/",
+        0, std::array<const char*, 1>{hsbpConfigIntf});
+}
+
+void setupHsbpConfigMatch()
+{
+    static auto hsbpConfigMatch = std::make_unique<sdbusplus::bus::match_t>(
+        *conn,
+        "sender='xyz.openbmc_project.EntityManager', type='signal', "
+        "member='PropertiesChanged', "
+        "interface='org.freedesktop.DBus.Properties', "
+        "path_namespace='/xyz/openbmc_project/inventory/system/board', arg0='" +
+            std::string(hsbpConfigIntf) + "'",
+        [](sdbusplus::message_t& msg) {
+            std::string intfName;
+            boost::container::flat_map<std::string, BasicVariantType> values;
+            msg.read(intfName, values);
+
+            /* This match will be triggered for each of the property being set
+             * under the hsbpConfig interface. "HsbpSupported" is one of the
+             * important property which will enable us to read other properties.
+             * So, when the match event occurs for "HsbpSupported" property
+             * being set, we will call "loadHsbpConfig()" If the control has
+             * come here, its either the first initialization or entity-manager
+             * reload. So, we will reset the state to uninitialized
+             */
+            for (const auto& [key, value] : values)
+            {
+                if (key == "HsbpSupported")
+                {
+                    /* Configuration change detected, change the state to stop
+                     * other processing */
+                    appState = AppState::idle;
+
+                    /* We will call the function after a small delay to let all
+                     * the properties to be intialized */
+                    auto loadTimer =
+                        std::make_shared<boost::asio::steady_timer>(io);
+                    loadTimer->expires_after(std::chrono::seconds(1));
+                    loadTimer->async_wait(
+                        [loadTimer](const boost::system::error_code ec) {
+                            if (ec == boost::asio::error::operation_aborted)
+                            {
+                                return;
+                            }
+                            else if (ec)
+                            {
+                                std::cerr << __FUNCTION__ << ": Timer error"
+                                          << ec.message() << "\n";
+                                if (hsbpConfig.supportedHsbps.empty())
+                                {
+                                    /* Critical Error as none of the
+                                     * configuration was loaded and timer
+                                     * failed. Stop the application */
+                                    stopHsbpManager();
+                                }
+                                return;
+                            }
+                            loadHsbpConfig();
+                        });
+                }
+            }
+        });
+}
+/***************************** End of Section *******************************/
+
+/****************************************************************************/
+/***************** GPIO Events related Function Definitions *****************/
+/****************************************************************************/
+static void nvmeLvc3AlertHandler()
+{
+    /* If the state is not backplanesLoaded, we ignore the GPIO event as we
+     * cannot communicate to the backplanes yet */
+    if (appState < AppState::backplanesLoaded)
+    {
+        std::cerr << __FUNCTION__
+                  << ": HSBP not initialized ! Dropping the interrupt ! \n";
+        return;
+    }
+
+    /* This GPIO event only indicates the addition or removal of drive to either
+     * of CPU. The backplanes detected need to be scanned and detect which drive
+     * has been added/removed and enable/diable clock accordingly */
+    gpiod::line_event gpioLineEvent = nvmeLvc3AlertLine.event_read();
+
+    if (gpioLineEvent.event_type == gpiod::line_event::FALLING_EDGE)
+    {
+        /* Check for HSBP Drives status to determine if any new drive has been
+         * added/removed and update clocks accordingly */
+        checkHsbpDrivesStatus();
+    }
+
+    nvmeLvc3AlertEvent.async_wait(
+        boost::asio::posix::stream_descriptor::wait_read,
+        [](const boost::system::error_code ec) {
+            if (ec)
+            {
+                std::cerr << __FUNCTION__ << ": nvmealert event error: "
+                          << ec.message() << "\n";
+            }
+            nvmeLvc3AlertHandler();
+        });
+}
+
+static bool hsbpRequestAlertGpioEvents(
+    const std::string& name, const std::function<void()>& handler,
+    gpiod::line& gpioLine,
+    boost::asio::posix::stream_descriptor& gpioEventDescriptor)
+{
+    // Find the GPIO line
+    gpioLine = gpiod::find_line(name);
+    if (!gpioLine)
+    {
+        std::cerr << __FUNCTION__ << ": Failed to find the " << name
+                  << " line\n";
+        return false;
+    }
+
+    try
+    {
+        gpioLine.request(
+            {"hsbp-manager", gpiod::line_request::EVENT_BOTH_EDGES, 0});
+    }
+    catch (std::exception&)
+    {
+        std::cerr << __FUNCTION__ << ": Failed to request events for " << name
+                  << "\n";
+        return false;
+    }
+
+    int gpioLineFd = gpioLine.event_get_fd();
+    if (gpioLineFd < 0)
+    {
+        std::cerr << __FUNCTION__ << ": Failed to get " << name << " fd\n";
+        return false;
+    }
+
+    gpioEventDescriptor.assign(gpioLineFd);
+
+    gpioEventDescriptor.async_wait(
+        boost::asio::posix::stream_descriptor::wait_read,
+        [&name, handler](const boost::system::error_code ec) {
+            if (ec)
+            {
+                std::cerr << __FUNCTION__ << ": " << name
+                          << " fd handler error: " << ec.message() << "\n";
+                return;
+            }
+            handler();
+        });
+    return true;
+}
+/***************************** End of Section *******************************/
+
+int main()
+{
+    std::cerr << "******* Starting hsbp-manager *******\n";
+
+    /* Set the Dbus name */
+    conn->request_name(busName);
+
+    std::shared_ptr<sdbusplus::asio::dbus_interface> storageIface;
+
+    /* Add interface for storage inventory */
+    storageIface = objServer.add_interface(
+        "/xyz/openbmc_project/inventory/item/storage/hsbp/1",
+        "xyz.openbmc_project.Inventory.Item.Storage");
+
+    storageIface->initialize();
+
+    /* HSBP initializtion flow:
+     * 1. Register GPIO event callback on FM_SMB_BMC_NVME_LVC3_ALERT_N line
+     * 2. Set up Dbus match for power - determine if host is up and running
+     *    or powered off
+     * 3. Set up Dbus match for HSBP backplanes and Drives
+     * 4. Load HSBP config exposed by entity manager
+     *    - Also setup a match to capture HSBP configuation in case
+     *      entity-manager restarts
+     * 5. Load Clock buffer and IO expander (and other peripherals if any
+     *    related to HSBP functionality)
+     *    - Reload the info each time HSBP configuration is changed
+     * 6. Populate all Backpanes (HSBP's)
+     * 7. Load all NVMe drive's and associate with HSBP Backpane
+     */
+
+    /* Register GPIO Events on FM_SMB_BMC_NVME_LVC3_ALERT_N */
+    if (!hsbpRequestAlertGpioEvents("FM_SMB_BMC_NVME_LVC3_ALERT_N",
+                                    nvmeLvc3AlertHandler, nvmeLvc3AlertLine,
+                                    nvmeLvc3AlertEvent))
+    {
+        std::cerr << __FUNCTION__
+                  << ": error: Unable to monitor events on HSBP "
+                     "Alert line\n";
+        return -1;
+    }
+
+    /* Setup Dbus-match for power */
+    setupPowerMatch(conn);
+
+    /* Setup Dbus-match for HSBP backplanes and Drives */
+    setupBackplanesAndDrivesMatch();
+
+    /* Setup HSBP Config match and load config
+     * In the event of entity-manager reboot, the match will help catch new
+     * configuration.
+     * In the event of hsbp-manager reboot, loadHsbpConfig will get all
+     * config details and will take care of remaining config's to be
+     * loaded
+     */
+    setupHsbpConfigMatch();
+    loadHsbpConfig();
+
+    io.run();
+    std::cerr << __FUNCTION__ << ": Aborting hsbp-manager !\n";
+    return -1;
+}
