diff --git a/power-control-x86/src/power_control.cpp b/power-control-x86/src/power_control.cpp
new file mode 100644
index 0000000..dce3440
--- /dev/null
+++ b/power-control-x86/src/power_control.cpp
@@ -0,0 +1,2145 @@
+/*
+// Copyright (c) 2018-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 "i2c.hpp"
+
+#include <sys/sysinfo.h>
+#include <systemd/sd-journal.h>
+
+#include <boost/asio/posix/stream_descriptor.hpp>
+#include <boost/container/flat_map.hpp>
+#include <filesystem>
+#include <fstream>
+#include <gpiod.hpp>
+#include <iostream>
+#include <sdbusplus/asio/object_server.hpp>
+#include <string_view>
+
+namespace power_control
+{
+static boost::asio::io_service io;
+std::shared_ptr<sdbusplus::asio::connection> conn;
+static std::shared_ptr<sdbusplus::asio::dbus_interface> hostIface;
+static std::shared_ptr<sdbusplus::asio::dbus_interface> chassisIface;
+static std::shared_ptr<sdbusplus::asio::dbus_interface> powerButtonIface;
+static std::shared_ptr<sdbusplus::asio::dbus_interface> resetButtonIface;
+static std::shared_ptr<sdbusplus::asio::dbus_interface> nmiButtonIface;
+static std::shared_ptr<sdbusplus::asio::dbus_interface> osIface;
+static std::shared_ptr<sdbusplus::asio::dbus_interface> idButtonIface;
+
+static gpiod::line powerButtonMask;
+static gpiod::line resetButtonMask;
+static bool nmiButtonMasked = false;
+static bool resetInProgress = false;
+
+const static constexpr int powerPulseTimeMs = 200;
+const static constexpr int forceOffPulseTimeMs = 15000;
+const static constexpr int resetPulseTimeMs = 500;
+const static constexpr int powerCycleTimeMs = 1000;
+const static constexpr int sioPowerGoodWatchdogTimeMs = 1000;
+const static constexpr int psPowerOKWatchdogTimeMs = 8000;
+const static constexpr int gracefulPowerOffTimeMs = 60000;
+const static constexpr int buttonMaskTimeMs = 60000;
+const static constexpr int powerOffSaveTimeMs = 7000;
+
+const static std::filesystem::path powerControlDir = "/var/lib/power-control";
+const static constexpr std::string_view powerStateFile = "power-state";
+
+static bool nmiEnabled = true;
+static constexpr const char* nmiOutName = "NMI_OUT";
+
+// Timers
+// Time holding GPIOs asserted
+static boost::asio::steady_timer gpioAssertTimer(io);
+// Time between off and on during a power cycle
+static boost::asio::steady_timer powerCycleTimer(io);
+// Time OS gracefully powering off
+static boost::asio::steady_timer gracefulPowerOffTimer(io);
+// Time power supply power OK assertion on power-on
+static boost::asio::steady_timer psPowerOKWatchdogTimer(io);
+// Time SIO power good assertion on power-on
+static boost::asio::steady_timer sioPowerGoodWatchdogTimer(io);
+// Time power-off state save for power loss tracking
+static boost::asio::steady_timer powerStateSaveTimer(io);
+// POH timer
+static boost::asio::steady_timer pohCounterTimer(io);
+
+// GPIO Lines and Event Descriptors
+static gpiod::line psPowerOKLine;
+static boost::asio::posix::stream_descriptor psPowerOKEvent(io);
+static gpiod::line sioPowerGoodLine;
+static boost::asio::posix::stream_descriptor sioPowerGoodEvent(io);
+static gpiod::line sioOnControlLine;
+static boost::asio::posix::stream_descriptor sioOnControlEvent(io);
+static gpiod::line sioS5Line;
+static boost::asio::posix::stream_descriptor sioS5Event(io);
+static gpiod::line powerButtonLine;
+static boost::asio::posix::stream_descriptor powerButtonEvent(io);
+static gpiod::line resetButtonLine;
+static boost::asio::posix::stream_descriptor resetButtonEvent(io);
+static gpiod::line nmiButtonLine;
+static boost::asio::posix::stream_descriptor nmiButtonEvent(io);
+static gpiod::line idButtonLine;
+static boost::asio::posix::stream_descriptor idButtonEvent(io);
+static gpiod::line postCompleteLine;
+static boost::asio::posix::stream_descriptor postCompleteEvent(io);
+static gpiod::line nmiOutLine;
+
+static constexpr uint8_t beepPowerFail = 8;
+
+static void beep(const uint8_t& beepPriority)
+{
+    std::cerr << "Beep with priority: " << (unsigned)beepPriority << "\n";
+
+    conn->async_method_call(
+        [](boost::system::error_code ec) {
+            if (ec)
+            {
+                std::cerr << "beep returned error with "
+                             "async_method_call (ec = "
+                          << ec << ")\n";
+                return;
+            }
+        },
+        "xyz.openbmc_project.BeepCode", "/xyz/openbmc_project/BeepCode",
+        "xyz.openbmc_project.BeepCode", "Beep", uint8_t(beepPriority));
+}
+
+enum class PowerState
+{
+    on,
+    waitForPSPowerOK,
+    waitForSIOPowerGood,
+    failedTransitionToOn,
+    off,
+    transitionToOff,
+    gracefulTransitionToOff,
+    cycleOff,
+    transitionToCycleOff,
+    gracefulTransitionToCycleOff,
+};
+static PowerState powerState;
+static std::string getPowerStateName(PowerState state)
+{
+    switch (state)
+    {
+        case PowerState::on:
+            return "On";
+            break;
+        case PowerState::waitForPSPowerOK:
+            return "Wait for Power Supply Power OK";
+            break;
+        case PowerState::waitForSIOPowerGood:
+            return "Wait for SIO Power Good";
+            break;
+        case PowerState::failedTransitionToOn:
+            return "Failed Transition to On";
+            break;
+        case PowerState::off:
+            return "Off";
+            break;
+        case PowerState::transitionToOff:
+            return "Transition to Off";
+            break;
+        case PowerState::gracefulTransitionToOff:
+            return "Graceful Transition to Off";
+            break;
+        case PowerState::cycleOff:
+            return "Power Cycle Off";
+            break;
+        case PowerState::transitionToCycleOff:
+            return "Transition to Power Cycle Off";
+            break;
+        case PowerState::gracefulTransitionToCycleOff:
+            return "Graceful Transition to Power Cycle Off";
+            break;
+        default:
+            return "unknown state: " + std::to_string(static_cast<int>(state));
+            break;
+    }
+}
+static void logStateTransition(const PowerState state)
+{
+    std::cerr << "Moving to \"" << getPowerStateName(state) << "\" state.\n";
+}
+
+enum class Event
+{
+    psPowerOKAssert,
+    psPowerOKDeAssert,
+    sioPowerGoodAssert,
+    sioPowerGoodDeAssert,
+    sioS5Assert,
+    sioS5DeAssert,
+    powerButtonPressed,
+    powerCycleTimerExpired,
+    psPowerOKWatchdogTimerExpired,
+    sioPowerGoodWatchdogTimerExpired,
+    gracefulPowerOffTimerExpired,
+    powerOnRequest,
+    powerOffRequest,
+    powerCycleRequest,
+    resetRequest,
+    gracefulPowerOffRequest,
+    gracefulPowerCycleRequest,
+};
+static std::string getEventName(Event event)
+{
+    switch (event)
+    {
+        case Event::psPowerOKAssert:
+            return "power supply power OK assert";
+            break;
+        case Event::psPowerOKDeAssert:
+            return "power supply power OK de-assert";
+            break;
+        case Event::sioPowerGoodAssert:
+            return "SIO power good assert";
+            break;
+        case Event::sioPowerGoodDeAssert:
+            return "SIO power good de-assert";
+            break;
+        case Event::sioS5Assert:
+            return "SIO S5 assert";
+            break;
+        case Event::sioS5DeAssert:
+            return "SIO S5 de-assert";
+            break;
+        case Event::powerButtonPressed:
+            return "power button pressed";
+            break;
+        case Event::powerCycleTimerExpired:
+            return "power cycle timer expired";
+            break;
+        case Event::psPowerOKWatchdogTimerExpired:
+            return "power supply power OK watchdog timer expired";
+            break;
+        case Event::sioPowerGoodWatchdogTimerExpired:
+            return "SIO power good watchdog timer expired";
+            break;
+        case Event::gracefulPowerOffTimerExpired:
+            return "graceful power-off timer expired";
+            break;
+        case Event::powerOnRequest:
+            return "power-on request";
+            break;
+        case Event::powerOffRequest:
+            return "power-off request";
+            break;
+        case Event::powerCycleRequest:
+            return "power-cycle request";
+            break;
+        case Event::resetRequest:
+            return "reset request";
+            break;
+        case Event::gracefulPowerOffRequest:
+            return "graceful power-off request";
+            break;
+        case Event::gracefulPowerCycleRequest:
+            return "graceful power-cycle request";
+            break;
+        default:
+            return "unknown event: " + std::to_string(static_cast<int>(event));
+            break;
+    }
+}
+static void logEvent(const std::string_view stateHandler, const Event event)
+{
+    std::cerr << stateHandler << ": " << getEventName(event)
+              << " event received.\n";
+}
+
+// Power state handlers
+static void powerStateOn(const Event event);
+static void powerStateWaitForPSPowerOK(const Event event);
+static void powerStateWaitForSIOPowerGood(const Event event);
+static void powerStateFailedTransitionToOn(const Event event);
+static void powerStateOff(const Event event);
+static void powerStateTransitionToOff(const Event event);
+static void powerStateGracefulTransitionToOff(const Event event);
+static void powerStateCycleOff(const Event event);
+static void powerStateTransitionToCycleOff(const Event event);
+static void powerStateGracefulTransitionToCycleOff(const Event event);
+
+static std::function<void(const Event)> getPowerStateHandler(PowerState state)
+{
+    switch (state)
+    {
+        case PowerState::on:
+            return powerStateOn;
+            break;
+        case PowerState::waitForPSPowerOK:
+            return powerStateWaitForPSPowerOK;
+            break;
+        case PowerState::waitForSIOPowerGood:
+            return powerStateWaitForSIOPowerGood;
+            break;
+        case PowerState::failedTransitionToOn:
+            return powerStateFailedTransitionToOn;
+            break;
+        case PowerState::off:
+            return powerStateOff;
+            break;
+        case PowerState::transitionToOff:
+            return powerStateTransitionToOff;
+            break;
+        case PowerState::gracefulTransitionToOff:
+            return powerStateGracefulTransitionToOff;
+            break;
+        case PowerState::cycleOff:
+            return powerStateCycleOff;
+            break;
+        case PowerState::transitionToCycleOff:
+            return powerStateTransitionToCycleOff;
+            break;
+        case PowerState::gracefulTransitionToCycleOff:
+            return powerStateGracefulTransitionToCycleOff;
+            break;
+        default:
+            return std::function<void(const Event)>{};
+            break;
+    }
+};
+
+static void sendPowerControlEvent(const Event event)
+{
+    std::function<void(const Event)> handler = getPowerStateHandler(powerState);
+    if (handler == nullptr)
+    {
+        std::cerr << "Failed to find handler for power state: "
+                  << static_cast<int>(powerState) << "\n";
+        return;
+    }
+    handler(event);
+}
+
+static uint64_t getCurrentTimeMs()
+{
+    struct timespec time = {};
+
+    if (clock_gettime(CLOCK_REALTIME, &time) < 0)
+    {
+        return 0;
+    }
+    uint64_t currentTimeMs = static_cast<uint64_t>(time.tv_sec) * 1000;
+    currentTimeMs += static_cast<uint64_t>(time.tv_nsec) / 1000 / 1000;
+
+    return currentTimeMs;
+}
+
+static constexpr std::string_view getHostState(const PowerState state)
+{
+    switch (state)
+    {
+        case PowerState::on:
+        case PowerState::transitionToOff:
+        case PowerState::gracefulTransitionToOff:
+        case PowerState::transitionToCycleOff:
+        case PowerState::gracefulTransitionToCycleOff:
+            return "xyz.openbmc_project.State.Host.HostState.Running";
+            break;
+        case PowerState::waitForPSPowerOK:
+        case PowerState::waitForSIOPowerGood:
+        case PowerState::failedTransitionToOn:
+        case PowerState::off:
+        case PowerState::cycleOff:
+            return "xyz.openbmc_project.State.Host.HostState.Off";
+            break;
+        default:
+            return "";
+            break;
+    }
+};
+static constexpr std::string_view getChassisState(const PowerState state)
+{
+    switch (state)
+    {
+        case PowerState::on:
+        case PowerState::transitionToOff:
+        case PowerState::gracefulTransitionToOff:
+        case PowerState::transitionToCycleOff:
+        case PowerState::gracefulTransitionToCycleOff:
+            return "xyz.openbmc_project.State.Chassis.PowerState.On";
+            break;
+        case PowerState::waitForPSPowerOK:
+        case PowerState::waitForSIOPowerGood:
+        case PowerState::failedTransitionToOn:
+        case PowerState::off:
+        case PowerState::cycleOff:
+            return "xyz.openbmc_project.State.Chassis.PowerState.Off";
+            break;
+        default:
+            return "";
+            break;
+    }
+};
+static void savePowerState(const PowerState state)
+{
+    powerStateSaveTimer.expires_after(
+        std::chrono::milliseconds(powerOffSaveTimeMs));
+    powerStateSaveTimer.async_wait([state](const boost::system::error_code ec) {
+        if (ec)
+        {
+            // operation_aborted is expected if timer is canceled before
+            // completion.
+            if (ec != boost::asio::error::operation_aborted)
+            {
+                std::cerr << "Power-state save async_wait failed: "
+                          << ec.message() << "\n";
+            }
+            return;
+        }
+        std::ofstream powerStateStream(powerControlDir / powerStateFile);
+        powerStateStream << getChassisState(state);
+    });
+}
+static void setPowerState(const PowerState state)
+{
+    powerState = state;
+    logStateTransition(state);
+
+    hostIface->set_property("CurrentHostState",
+                            std::string(getHostState(powerState)));
+
+    chassisIface->set_property("CurrentPowerState",
+                               std::string(getChassisState(powerState)));
+    chassisIface->set_property("LastStateChangeTime", getCurrentTimeMs());
+
+    // Save the power state for the restore policy
+    savePowerState(state);
+}
+
+enum class RestartCause
+{
+    command,
+    resetButton,
+    powerButton,
+    powerPolicyOn,
+    powerPolicyRestore,
+    softReset,
+};
+static std::string getRestartCause(RestartCause cause)
+{
+    switch (cause)
+    {
+        case RestartCause::command:
+            return "xyz.openbmc_project.State.Host.RestartCause.IpmiCommand";
+            break;
+        case RestartCause::resetButton:
+            return "xyz.openbmc_project.State.Host.RestartCause.ResetButton";
+            break;
+        case RestartCause::powerButton:
+            return "xyz.openbmc_project.State.Host.RestartCause.PowerButton";
+            break;
+        case RestartCause::powerPolicyOn:
+            return "xyz.openbmc_project.State.Host.RestartCause."
+                   "PowerPolicyAlwaysOn";
+            break;
+        case RestartCause::powerPolicyRestore:
+            return "xyz.openbmc_project.State.Host.RestartCause."
+                   "PowerPolicyPreviousState";
+            break;
+        case RestartCause::softReset:
+            return "xyz.openbmc_project.State.Host.RestartCause.SoftReset";
+            break;
+        default:
+            return "xyz.openbmc_project.State.Host.RestartCause.Unknown";
+            break;
+    }
+}
+static void setRestartCause(const RestartCause cause)
+{
+    conn->async_method_call(
+        [](boost::system::error_code ec) {
+            if (ec)
+            {
+                std::cerr << "failed to set RestartCause\n";
+            }
+        },
+        "xyz.openbmc_project.Settings",
+        "/xyz/openbmc_project/control/host0/restart_cause",
+        "org.freedesktop.DBus.Properties", "Set",
+        "xyz.openbmc_project.Common.RestartCause", "RestartCause",
+        std::variant<std::string>(getRestartCause(cause)));
+}
+
+static void powerRestorePolicyLog()
+{
+    sd_journal_send("MESSAGE=PowerControl: power restore policy applied",
+                    "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s",
+                    "OpenBMC.0.1.PowerRestorePolicyApplied", NULL);
+}
+
+static void powerButtonPressLog()
+{
+    sd_journal_send("MESSAGE=PowerControl: power button pressed", "PRIORITY=%i",
+                    LOG_INFO, "REDFISH_MESSAGE_ID=%s",
+                    "OpenBMC.0.1.PowerButtonPressed", NULL);
+}
+
+static void resetButtonPressLog()
+{
+    sd_journal_send("MESSAGE=PowerControl: reset button pressed", "PRIORITY=%i",
+                    LOG_INFO, "REDFISH_MESSAGE_ID=%s",
+                    "OpenBMC.0.1.ResetButtonPressed", NULL);
+}
+
+static void nmiButtonPressLog()
+{
+    sd_journal_send("MESSAGE=PowerControl: NMI button pressed", "PRIORITY=%i",
+                    LOG_INFO, "REDFISH_MESSAGE_ID=%s",
+                    "OpenBMC.0.1.NMIButtonPressed", NULL);
+}
+
+static void nmiDiagIntLog()
+{
+    sd_journal_send("MESSAGE=PowerControl: NMI Diagnostic Interrupt",
+                    "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s",
+                    "OpenBMC.0.1.NMIDiagnosticInterrupt", NULL);
+}
+
+static int initializePowerStateStorage()
+{
+    // create the power control directory if it doesn't exist
+    std::error_code ec;
+    if (!(std::filesystem::create_directories(powerControlDir, ec)))
+    {
+        if (ec.value() != 0)
+        {
+            std::cerr << "failed to create " << powerControlDir << ": "
+                      << ec.message() << "\n";
+            return -1;
+        }
+    }
+    // Create the power state file if it doesn't exist
+    if (!std::filesystem::exists(powerControlDir / powerStateFile))
+    {
+        std::ofstream powerStateStream(powerControlDir / powerStateFile);
+        powerStateStream << getChassisState(powerState);
+    }
+    return 0;
+}
+
+static bool wasPowerDropped()
+{
+    std::ifstream powerStateStream(powerControlDir / powerStateFile);
+    if (!powerStateStream.is_open())
+    {
+        std::cerr << "Failed to open power state file\n";
+        return false;
+    }
+
+    std::string state;
+    std::getline(powerStateStream, state);
+    return state == "xyz.openbmc_project.State.Chassis.PowerState.On";
+}
+
+static void invokePowerRestorePolicy(const std::string& policy)
+{
+    // Async events may call this twice, but we only want to run once
+    static bool policyInvoked = false;
+    if (policyInvoked)
+    {
+        return;
+    }
+    policyInvoked = true;
+
+    std::cerr << "Power restore delay expired, invoking " << policy << "\n";
+    if (policy ==
+        "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
+    {
+        sendPowerControlEvent(Event::powerOnRequest);
+        setRestartCause(RestartCause::powerPolicyOn);
+    }
+    else if (policy == "xyz.openbmc_project.Control.Power.RestorePolicy."
+                       "Policy.Restore")
+    {
+        if (wasPowerDropped())
+        {
+            std::cerr << "Power was dropped, restoring Host On state\n";
+            sendPowerControlEvent(Event::powerOnRequest);
+            setRestartCause(RestartCause::powerPolicyRestore);
+        }
+        else
+        {
+            std::cerr << "No power drop, restoring Host Off state\n";
+        }
+    }
+}
+
+static void powerRestorePolicyDelay(int delay)
+{
+    // Async events may call this twice, but we only want to run once
+    static bool delayStarted = false;
+    if (delayStarted)
+    {
+        return;
+    }
+    delayStarted = true;
+    // Calculate the delay from now to meet the requested delay
+    // Subtract the approximate uboot time
+    static constexpr const int ubootSeconds = 20;
+    delay -= ubootSeconds;
+    // Subtract the time since boot
+    struct sysinfo info = {};
+    if (sysinfo(&info) == 0)
+    {
+        delay -= info.uptime;
+    }
+    // 0 is the minimum delay
+    delay = std::max(delay, 0);
+
+    static boost::asio::steady_timer powerRestorePolicyTimer(io);
+    powerRestorePolicyTimer.expires_after(std::chrono::seconds(delay));
+    std::cerr << "Power restore delay of " << delay << " seconds started\n";
+    powerRestorePolicyTimer.async_wait([](const boost::system::error_code ec) {
+        if (ec)
+        {
+            // operation_aborted is expected if timer is canceled before
+            // completion.
+            if (ec != boost::asio::error::operation_aborted)
+            {
+                std::cerr << "power restore policy async_wait failed: "
+                          << ec.message() << "\n";
+            }
+            return;
+        }
+        // Get Power Restore Policy
+        // In case PowerRestorePolicy is not available, set a match for it
+        static std::unique_ptr<sdbusplus::bus::match::match>
+            powerRestorePolicyMatch = std::make_unique<
+                sdbusplus::bus::match::match>(
+                *conn,
+                "type='signal',interface='org.freedesktop.DBus.Properties',"
+                "member='PropertiesChanged',arg0namespace='xyz.openbmc_"
+                "project.Control.Power.RestorePolicy'",
+                [](sdbusplus::message::message& msg) {
+                    std::string interfaceName;
+                    boost::container::flat_map<std::string,
+                                               std::variant<std::string>>
+                        propertiesChanged;
+                    std::string policy;
+                    try
+                    {
+                        msg.read(interfaceName, propertiesChanged);
+                        policy = std::get<std::string>(
+                            propertiesChanged.begin()->second);
+                    }
+                    catch (std::exception& e)
+                    {
+                        std::cerr
+                            << "Unable to read power restore policy value\n";
+                        powerRestorePolicyMatch.reset();
+                        return;
+                    }
+                    invokePowerRestorePolicy(policy);
+                    powerRestorePolicyMatch.reset();
+                });
+
+        // Check if it's already on DBus
+        conn->async_method_call(
+            [](boost::system::error_code ec,
+               const std::variant<std::string>& policyProperty) {
+                if (ec)
+                {
+                    return;
+                }
+                powerRestorePolicyMatch.reset();
+                const std::string* policy =
+                    std::get_if<std::string>(&policyProperty);
+                if (policy == nullptr)
+                {
+                    std::cerr << "Unable to read power restore policy value\n";
+                    return;
+                }
+                invokePowerRestorePolicy(*policy);
+            },
+            "xyz.openbmc_project.Settings",
+            "/xyz/openbmc_project/control/host0/power_restore_policy",
+            "org.freedesktop.DBus.Properties", "Get",
+            "xyz.openbmc_project.Control.Power.RestorePolicy",
+            "PowerRestorePolicy");
+    });
+}
+
+static void powerRestorePolicyStart()
+{
+    std::cerr << "Power restore policy started\n";
+    powerRestorePolicyLog();
+
+    // Get the desired delay time
+    // In case PowerRestoreDelay is not available, set a match for it
+    static std::unique_ptr<sdbusplus::bus::match::match>
+        powerRestoreDelayMatch = std::make_unique<sdbusplus::bus::match::match>(
+            *conn,
+            "type='signal',interface='org.freedesktop.DBus.Properties',member='"
+            "PropertiesChanged',arg0namespace='xyz.openbmc_project.Control."
+            "Power.RestoreDelay'",
+            [](sdbusplus::message::message& msg) {
+                std::string interfaceName;
+                boost::container::flat_map<std::string, std::variant<uint16_t>>
+                    propertiesChanged;
+                int delay = 0;
+                try
+                {
+                    msg.read(interfaceName, propertiesChanged);
+                    delay =
+                        std::get<uint16_t>(propertiesChanged.begin()->second);
+                }
+                catch (std::exception& e)
+                {
+                    std::cerr << "Unable to read power restore delay value\n";
+                    powerRestoreDelayMatch.reset();
+                    return;
+                }
+                powerRestorePolicyDelay(delay);
+                powerRestoreDelayMatch.reset();
+            });
+
+    // Check if it's already on DBus
+    conn->async_method_call(
+        [](boost::system::error_code ec,
+           const std::variant<uint16_t>& delayProperty) {
+            if (ec)
+            {
+                return;
+            }
+            powerRestoreDelayMatch.reset();
+            const uint16_t* delay = std::get_if<uint16_t>(&delayProperty);
+            if (delay == nullptr)
+            {
+                std::cerr << "Unable to read power restore delay value\n";
+                return;
+            }
+            powerRestorePolicyDelay(*delay);
+        },
+        "xyz.openbmc_project.Settings",
+        "/xyz/openbmc_project/control/power_restore_delay",
+        "org.freedesktop.DBus.Properties", "Get",
+        "xyz.openbmc_project.Control.Power.RestoreDelay", "PowerRestoreDelay");
+}
+
+static void powerRestorePolicyCheck()
+{
+    // In case ACBoot is not available, set a match for it
+    static std::unique_ptr<sdbusplus::bus::match::match> acBootMatch =
+        std::make_unique<sdbusplus::bus::match::match>(
+            *conn,
+            "type='signal',interface='org.freedesktop.DBus.Properties',member='"
+            "PropertiesChanged',arg0namespace='xyz.openbmc_project.Common."
+            "ACBoot'",
+            [](sdbusplus::message::message& msg) {
+                std::string interfaceName;
+                boost::container::flat_map<std::string,
+                                           std::variant<std::string>>
+                    propertiesChanged;
+                std::string acBoot;
+                try
+                {
+                    msg.read(interfaceName, propertiesChanged);
+                    acBoot = std::get<std::string>(
+                        propertiesChanged.begin()->second);
+                }
+                catch (std::exception& e)
+                {
+                    std::cerr << "Unable to read AC Boot status\n";
+                    acBootMatch.reset();
+                    return;
+                }
+                if (acBoot == "Unknown")
+                {
+                    return;
+                }
+                if (acBoot == "True")
+                {
+                    // Start the Power Restore policy
+                    powerRestorePolicyStart();
+                }
+                acBootMatch.reset();
+            });
+
+    // Check if it's already on DBus
+    conn->async_method_call(
+        [](boost::system::error_code ec,
+           const std::variant<std::string>& acBootProperty) {
+            if (ec)
+            {
+                return;
+            }
+            const std::string* acBoot =
+                std::get_if<std::string>(&acBootProperty);
+            if (acBoot == nullptr)
+            {
+                std::cerr << "Unable to read AC Boot status\n";
+                return;
+            }
+            if (*acBoot == "Unknown")
+            {
+                return;
+            }
+            if (*acBoot == "True")
+            {
+                // Start the Power Restore policy
+                powerRestorePolicyStart();
+            }
+            acBootMatch.reset();
+        },
+        "xyz.openbmc_project.Settings",
+        "/xyz/openbmc_project/control/host0/ac_boot",
+        "org.freedesktop.DBus.Properties", "Get",
+        "xyz.openbmc_project.Common.ACBoot", "ACBoot");
+}
+
+static bool requestGPIOEvents(
+    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 << "Failed to find the " << name << " line\n";
+        return false;
+    }
+
+    try
+    {
+        gpioLine.request(
+            {"power-control", gpiod::line_request::EVENT_BOTH_EDGES});
+    }
+    catch (std::exception&)
+    {
+        std::cerr << "Failed to request events for " << name << "\n";
+        return false;
+    }
+
+    int gpioLineFd = gpioLine.event_get_fd();
+    if (gpioLineFd < 0)
+    {
+        std::cerr << "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 << name << " fd handler error: " << ec.message()
+                          << "\n";
+                // TODO: throw here to force power-control to restart?
+                return;
+            }
+            handler();
+        });
+    return true;
+}
+
+static bool setGPIOOutput(const std::string& name, const int value,
+                          gpiod::line& gpioLine)
+{
+    // Find the GPIO line
+    gpioLine = gpiod::find_line(name);
+    if (!gpioLine)
+    {
+        std::cerr << "Failed to find the " << name << " line.\n";
+        return false;
+    }
+
+    // Request GPIO output to specified value
+    try
+    {
+        gpioLine.request({__FUNCTION__, gpiod::line_request::DIRECTION_OUTPUT},
+                         value);
+    }
+    catch (std::exception&)
+    {
+        std::cerr << "Failed to request " << name << " output\n";
+        return false;
+    }
+
+    std::cerr << name << " set to " << std::to_string(value) << "\n";
+    return true;
+}
+
+static int setMaskedGPIOOutputForMs(gpiod::line& maskedGPIOLine,
+                                    const std::string& name, const int value,
+                                    const int durationMs)
+{
+    // Set the masked GPIO line to the specified value
+    maskedGPIOLine.set_value(value);
+    std::cerr << name << " set to " << std::to_string(value) << "\n";
+    gpioAssertTimer.expires_after(std::chrono::milliseconds(durationMs));
+    gpioAssertTimer.async_wait(
+        [maskedGPIOLine, value, name](const boost::system::error_code ec) {
+            // Set the masked GPIO line back to the opposite value
+            maskedGPIOLine.set_value(!value);
+            std::cerr << name << " released\n";
+            if (ec)
+            {
+                // operation_aborted is expected if timer is canceled before
+                // completion.
+                if (ec != boost::asio::error::operation_aborted)
+                {
+                    std::cerr << name << " async_wait failed: " + ec.message()
+                              << "\n";
+                }
+            }
+        });
+    return 0;
+}
+
+static int setGPIOOutputForMs(const std::string& name, const int value,
+                              const int durationMs)
+{
+    // If the requested GPIO is masked, use the mask line to set the output
+    if (powerButtonMask && name == "POWER_OUT")
+    {
+        return setMaskedGPIOOutputForMs(powerButtonMask, name, value,
+                                        durationMs);
+    }
+    if (resetButtonMask && name == "RESET_OUT")
+    {
+        return setMaskedGPIOOutputForMs(resetButtonMask, name, value,
+                                        durationMs);
+    }
+
+    // No mask set, so request and set the GPIO normally
+    gpiod::line gpioLine;
+    if (!setGPIOOutput(name, value, gpioLine))
+    {
+        return -1;
+    }
+    gpioAssertTimer.expires_after(std::chrono::milliseconds(durationMs));
+    gpioAssertTimer.async_wait(
+        [gpioLine, name](const boost::system::error_code ec) {
+            std::cerr << name << " released\n";
+            if (ec)
+            {
+                // operation_aborted is expected if timer is canceled before
+                // completion.
+                if (ec != boost::asio::error::operation_aborted)
+                {
+                    std::cerr << name << " async_wait failed: " << ec.message()
+                              << "\n";
+                }
+            }
+        });
+    return 0;
+}
+
+static void powerOn()
+{
+    setGPIOOutputForMs("POWER_OUT", 0, powerPulseTimeMs);
+}
+
+static void gracefulPowerOff()
+{
+    setGPIOOutputForMs("POWER_OUT", 0, powerPulseTimeMs);
+}
+
+static void forcePowerOff()
+{
+    if (setGPIOOutputForMs("POWER_OUT", 0, forceOffPulseTimeMs) < 0)
+    {
+        return;
+    }
+
+    // If the force off timer expires, then the PCH power-button override
+    // failed, so attempt the Unconditional Powerdown SMBus command.
+    gpioAssertTimer.async_wait([](const boost::system::error_code ec) {
+        if (ec)
+        {
+            // operation_aborted is expected if timer is canceled before
+            // completion.
+            if (ec != boost::asio::error::operation_aborted)
+            {
+                std::cerr << "Force power off async_wait failed: "
+                          << ec.message() << "\n";
+            }
+            return;
+        }
+        std::cerr << "PCH Power-button override failed. Issuing Unconditional "
+                     "Powerdown SMBus command.\n";
+        const static constexpr size_t pchDevBusAddress = 3;
+        const static constexpr size_t pchDevSlaveAddress = 0x44;
+        const static constexpr size_t pchCmdReg = 0;
+        const static constexpr size_t pchPowerDownCmd = 0x02;
+        if (i2cSet(pchDevBusAddress, pchDevSlaveAddress, pchCmdReg,
+                   pchPowerDownCmd) < 0)
+        {
+            std::cerr << "Unconditional Powerdown command failed! Not sure "
+                         "what to do now.\n";
+        }
+    });
+}
+
+static void reset()
+{
+    setGPIOOutputForMs("RESET_OUT", 0, resetPulseTimeMs);
+}
+
+static void gracefulPowerOffTimerStart()
+{
+    std::cerr << "Graceful power-off timer started\n";
+    gracefulPowerOffTimer.expires_after(
+        std::chrono::milliseconds(gracefulPowerOffTimeMs));
+    gracefulPowerOffTimer.async_wait([](const boost::system::error_code ec) {
+        if (ec)
+        {
+            // operation_aborted is expected if timer is canceled before
+            // completion.
+            if (ec != boost::asio::error::operation_aborted)
+            {
+                std::cerr << "Graceful power-off async_wait failed: "
+                          << ec.message() << "\n";
+            }
+            std::cerr << "Graceful power-off timer canceled\n";
+            return;
+        }
+        std::cerr << "Graceful power-off timer completed\n";
+        sendPowerControlEvent(Event::gracefulPowerOffTimerExpired);
+    });
+}
+
+static void powerCycleTimerStart()
+{
+    std::cerr << "Power-cycle timer started\n";
+    powerCycleTimer.expires_after(std::chrono::milliseconds(powerCycleTimeMs));
+    powerCycleTimer.async_wait([](const boost::system::error_code ec) {
+        if (ec)
+        {
+            // operation_aborted is expected if timer is canceled before
+            // completion.
+            if (ec != boost::asio::error::operation_aborted)
+            {
+                std::cerr << "Power-cycle async_wait failed: " << ec.message()
+                          << "\n";
+            }
+            std::cerr << "Power-cycle timer canceled\n";
+            return;
+        }
+        std::cerr << "Power-cycle timer completed\n";
+        sendPowerControlEvent(Event::powerCycleTimerExpired);
+    });
+}
+
+static void psPowerOKWatchdogTimerStart()
+{
+    std::cerr << "power supply power OK watchdog timer started\n";
+    psPowerOKWatchdogTimer.expires_after(
+        std::chrono::milliseconds(psPowerOKWatchdogTimeMs));
+    psPowerOKWatchdogTimer.async_wait(
+        [](const boost::system::error_code ec) {
+            if (ec)
+            {
+                // operation_aborted is expected if timer is canceled before
+                // completion.
+                if (ec != boost::asio::error::operation_aborted)
+                {
+                    std::cerr
+                        << "power supply power OK watchdog async_wait failed: "
+                        << ec.message() << "\n";
+                }
+                std::cerr << "power supply power OK watchdog timer canceled\n";
+                return;
+            }
+            std::cerr << "power supply power OK watchdog timer expired\n";
+            sendPowerControlEvent(Event::psPowerOKWatchdogTimerExpired);
+        });
+}
+
+static void pohCounterTimerStart()
+{
+    std::cerr << "POH timer started\n";
+    // Set the time-out as 1 hour, to align with POH command in ipmid
+    pohCounterTimer.expires_after(std::chrono::hours(1));
+    pohCounterTimer.async_wait([](const boost::system::error_code& ec) {
+        if (ec)
+        {
+            // operation_aborted is expected if timer is canceled before
+            // completion.
+            if (ec != boost::asio::error::operation_aborted)
+            {
+                std::cerr << "POH timer async_wait failed: " << ec.message()
+                          << "\n";
+            }
+            std::cerr << "POH timer canceled\n";
+            return;
+        }
+
+        if (getHostState(powerState) !=
+            "xyz.openbmc_project.State.Host.HostState.Running")
+        {
+            return;
+        }
+
+        conn->async_method_call(
+            [](boost::system::error_code ec,
+               const std::variant<uint32_t>& pohCounterProperty) {
+                if (ec)
+                {
+                    std::cerr << "error to get poh counter\n";
+                    return;
+                }
+                const uint32_t* pohCounter =
+                    std::get_if<uint32_t>(&pohCounterProperty);
+                if (pohCounter == nullptr)
+                {
+                    std::cerr << "unable to read poh counter\n";
+                    return;
+                }
+
+                conn->async_method_call(
+                    [](boost::system::error_code ec) {
+                        if (ec)
+                        {
+                            std::cerr << "failed to set poh counter\n";
+                        }
+                    },
+                    "xyz.openbmc_project.Settings",
+                    "/xyz/openbmc_project/state/chassis0",
+                    "org.freedesktop.DBus.Properties", "Set",
+                    "xyz.openbmc_project.State.PowerOnHours", "POHCounter",
+                    std::variant<uint32_t>(*pohCounter + 1));
+            },
+            "xyz.openbmc_project.Settings",
+            "/xyz/openbmc_project/state/chassis0",
+            "org.freedesktop.DBus.Properties", "Get",
+            "xyz.openbmc_project.State.PowerOnHours", "POHCounter");
+
+        pohCounterTimerStart();
+    });
+}
+
+static void currentHostStateMonitor()
+{
+    static auto match = sdbusplus::bus::match::match(
+        *conn,
+        "type='signal',member='PropertiesChanged', "
+        "interface='org.freedesktop.DBus.Properties', "
+        "arg0namespace='xyz.openbmc_project.State.Host'",
+        [](sdbusplus::message::message& message) {
+            std::string intfName;
+            std::map<std::string, std::variant<std::string>> properties;
+
+            message.read(intfName, properties);
+
+            std::variant<std::string> currentHostState;
+
+            try
+            {
+                currentHostState = properties.at("CurrentHostState");
+            }
+            catch (const std::out_of_range& e)
+            {
+                std::cerr << "Error in finding CurrentHostState property\n";
+
+                return;
+            }
+
+            if (std::get<std::string>(currentHostState) ==
+                "xyz.openbmc_project.State.Host.HostState.Running")
+            {
+                pohCounterTimerStart();
+            }
+            else
+            {
+                pohCounterTimer.cancel();
+            }
+        });
+}
+
+static void sioPowerGoodWatchdogTimerStart()
+{
+    std::cerr << "SIO power good watchdog timer started\n";
+    sioPowerGoodWatchdogTimer.expires_after(
+        std::chrono::milliseconds(sioPowerGoodWatchdogTimeMs));
+    sioPowerGoodWatchdogTimer.async_wait(
+        [](const boost::system::error_code ec) {
+            if (ec)
+            {
+                // operation_aborted is expected if timer is canceled before
+                // completion.
+                if (ec != boost::asio::error::operation_aborted)
+                {
+                    std::cerr << "SIO power good watchdog async_wait failed: "
+                              << ec.message() << "\n";
+                }
+                std::cerr << "SIO power good watchdog timer canceled\n";
+                return;
+            }
+            std::cerr << "SIO power good watchdog timer completed\n";
+            sendPowerControlEvent(Event::sioPowerGoodWatchdogTimerExpired);
+        });
+}
+
+static void powerStateOn(const Event event)
+{
+    logEvent(__FUNCTION__, event);
+    switch (event)
+    {
+        case Event::psPowerOKDeAssert:
+            setPowerState(PowerState::off);
+            // DC power is unexpectedly lost, beep
+            beep(beepPowerFail);
+            break;
+        case Event::sioS5Assert:
+            setPowerState(PowerState::transitionToOff);
+            setRestartCause(RestartCause::softReset);
+            break;
+        case Event::powerButtonPressed:
+            setPowerState(PowerState::gracefulTransitionToOff);
+            gracefulPowerOffTimerStart();
+            break;
+        case Event::powerOffRequest:
+            setPowerState(PowerState::transitionToOff);
+            forcePowerOff();
+            break;
+        case Event::gracefulPowerOffRequest:
+            setPowerState(PowerState::gracefulTransitionToOff);
+            gracefulPowerOffTimerStart();
+            gracefulPowerOff();
+            break;
+        case Event::powerCycleRequest:
+            setPowerState(PowerState::transitionToCycleOff);
+            forcePowerOff();
+            break;
+        case Event::gracefulPowerCycleRequest:
+            setPowerState(PowerState::gracefulTransitionToCycleOff);
+            gracefulPowerOffTimerStart();
+            gracefulPowerOff();
+            break;
+        case Event::resetRequest:
+            reset();
+            break;
+        default:
+            std::cerr << "No action taken.\n";
+            break;
+    }
+}
+
+static void powerStateWaitForPSPowerOK(const Event event)
+{
+    logEvent(__FUNCTION__, event);
+    switch (event)
+    {
+        case Event::psPowerOKAssert:
+            // Cancel any GPIO assertions held during the transition
+            gpioAssertTimer.cancel();
+            psPowerOKWatchdogTimer.cancel();
+            sioPowerGoodWatchdogTimerStart();
+            setPowerState(PowerState::waitForSIOPowerGood);
+            break;
+        case Event::psPowerOKWatchdogTimerExpired:
+            setPowerState(PowerState::failedTransitionToOn);
+            break;
+        default:
+            std::cerr << "No action taken.\n";
+            break;
+    }
+}
+
+static void powerStateWaitForSIOPowerGood(const Event event)
+{
+    logEvent(__FUNCTION__, event);
+    switch (event)
+    {
+        case Event::sioPowerGoodAssert:
+            sioPowerGoodWatchdogTimer.cancel();
+            setPowerState(PowerState::on);
+            break;
+        case Event::sioPowerGoodWatchdogTimerExpired:
+            setPowerState(PowerState::failedTransitionToOn);
+            forcePowerOff();
+            break;
+        default:
+            std::cerr << "No action taken.\n";
+            break;
+    }
+}
+
+static void powerStateFailedTransitionToOn(const Event event)
+{
+    logEvent(__FUNCTION__, event);
+    switch (event)
+    {
+        case Event::psPowerOKAssert:
+            // We're in a failure state, so don't allow the system to turn on
+            // without a user request
+            forcePowerOff();
+            break;
+        case Event::psPowerOKDeAssert:
+            // Cancel any GPIO assertions held during the transition
+            gpioAssertTimer.cancel();
+            break;
+        case Event::powerButtonPressed:
+            psPowerOKWatchdogTimerStart();
+            setPowerState(PowerState::waitForPSPowerOK);
+            break;
+        case Event::powerOnRequest:
+            psPowerOKWatchdogTimerStart();
+            setPowerState(PowerState::waitForPSPowerOK);
+            powerOn();
+            break;
+        default:
+            std::cerr << "No action taken.\n";
+            break;
+    }
+}
+
+static void powerStateOff(const Event event)
+{
+    logEvent(__FUNCTION__, event);
+    switch (event)
+    {
+        case Event::psPowerOKAssert:
+            setPowerState(PowerState::waitForSIOPowerGood);
+            break;
+        case Event::sioS5DeAssert:
+            setPowerState(PowerState::waitForPSPowerOK);
+            break;
+        case Event::powerButtonPressed:
+            psPowerOKWatchdogTimerStart();
+            setPowerState(PowerState::waitForPSPowerOK);
+            break;
+        case Event::powerOnRequest:
+            psPowerOKWatchdogTimerStart();
+            setPowerState(PowerState::waitForPSPowerOK);
+            powerOn();
+            break;
+        default:
+            std::cerr << "No action taken.\n";
+            break;
+    }
+}
+
+static void powerStateTransitionToOff(const Event event)
+{
+    logEvent(__FUNCTION__, event);
+    switch (event)
+    {
+        case Event::psPowerOKDeAssert:
+            // Cancel any GPIO assertions held during the transition
+            gpioAssertTimer.cancel();
+            setPowerState(PowerState::off);
+            break;
+        default:
+            std::cerr << "No action taken.\n";
+            break;
+    }
+}
+
+static void powerStateGracefulTransitionToOff(const Event event)
+{
+    logEvent(__FUNCTION__, event);
+    switch (event)
+    {
+        case Event::psPowerOKDeAssert:
+            gracefulPowerOffTimer.cancel();
+            setPowerState(PowerState::off);
+            break;
+        case Event::gracefulPowerOffTimerExpired:
+            setPowerState(PowerState::on);
+            break;
+        default:
+            std::cerr << "No action taken.\n";
+            break;
+    }
+}
+
+static void powerStateCycleOff(const Event event)
+{
+    logEvent(__FUNCTION__, event);
+    switch (event)
+    {
+        case Event::powerCycleTimerExpired:
+            psPowerOKWatchdogTimerStart();
+            setPowerState(PowerState::waitForPSPowerOK);
+            powerOn();
+            break;
+        default:
+            std::cerr << "No action taken.\n";
+            break;
+    }
+}
+
+static void powerStateTransitionToCycleOff(const Event event)
+{
+    logEvent(__FUNCTION__, event);
+    switch (event)
+    {
+        case Event::psPowerOKDeAssert:
+            // Cancel any GPIO assertions held during the transition
+            gpioAssertTimer.cancel();
+            setPowerState(PowerState::cycleOff);
+            powerCycleTimerStart();
+            break;
+        default:
+            std::cerr << "No action taken.\n";
+            break;
+    }
+}
+
+static void powerStateGracefulTransitionToCycleOff(const Event event)
+{
+    logEvent(__FUNCTION__, event);
+    switch (event)
+    {
+        case Event::psPowerOKDeAssert:
+            gracefulPowerOffTimer.cancel();
+            setPowerState(PowerState::cycleOff);
+            powerCycleTimerStart();
+            break;
+        case Event::gracefulPowerOffTimerExpired:
+            setPowerState(PowerState::on);
+            break;
+        default:
+            std::cerr << "No action taken.\n";
+            break;
+    }
+}
+
+static void psPowerOKHandler()
+{
+    gpiod::line_event gpioLineEvent = psPowerOKLine.event_read();
+
+    Event powerControlEvent =
+        gpioLineEvent.event_type == gpiod::line_event::RISING_EDGE
+            ? Event::psPowerOKAssert
+            : Event::psPowerOKDeAssert;
+
+    sendPowerControlEvent(powerControlEvent);
+    psPowerOKEvent.async_wait(
+        boost::asio::posix::stream_descriptor::wait_read,
+        [](const boost::system::error_code ec) {
+            if (ec)
+            {
+                std::cerr << "power supply power OK handler error: "
+                          << ec.message() << "\n";
+                return;
+            }
+            psPowerOKHandler();
+        });
+}
+
+static void sioPowerGoodHandler()
+{
+    gpiod::line_event gpioLineEvent = sioPowerGoodLine.event_read();
+
+    Event powerControlEvent =
+        gpioLineEvent.event_type == gpiod::line_event::RISING_EDGE
+            ? Event::sioPowerGoodAssert
+            : Event::sioPowerGoodDeAssert;
+
+    sendPowerControlEvent(powerControlEvent);
+    sioPowerGoodEvent.async_wait(
+        boost::asio::posix::stream_descriptor::wait_read,
+        [](const boost::system::error_code ec) {
+            if (ec)
+            {
+                std::cerr << "SIO power good handler error: " << ec.message()
+                          << "\n";
+                return;
+            }
+            sioPowerGoodHandler();
+        });
+}
+
+static void sioOnControlHandler()
+{
+    gpiod::line_event gpioLineEvent = sioOnControlLine.event_read();
+
+    bool sioOnControl =
+        gpioLineEvent.event_type == gpiod::line_event::RISING_EDGE;
+    std::cerr << "SIO_ONCONTROL value changed: " << sioOnControl << "\n";
+    sioOnControlEvent.async_wait(
+        boost::asio::posix::stream_descriptor::wait_read,
+        [](const boost::system::error_code ec) {
+            if (ec)
+            {
+                std::cerr << "SIO ONCONTROL handler error: " << ec.message()
+                          << "\n";
+                return;
+            }
+            sioOnControlHandler();
+        });
+}
+
+static void sioS5Handler()
+{
+    gpiod::line_event gpioLineEvent = sioS5Line.event_read();
+
+    Event powerControlEvent =
+        gpioLineEvent.event_type == gpiod::line_event::FALLING_EDGE
+            ? Event::sioS5Assert
+            : Event::sioS5DeAssert;
+
+    sendPowerControlEvent(powerControlEvent);
+    sioS5Event.async_wait(boost::asio::posix::stream_descriptor::wait_read,
+                          [](const boost::system::error_code ec) {
+                              if (ec)
+                              {
+                                  std::cerr << "SIO S5 handler error: "
+                                            << ec.message() << "\n";
+                                  return;
+                              }
+                              sioS5Handler();
+                          });
+}
+
+static void powerButtonHandler()
+{
+    gpiod::line_event gpioLineEvent = powerButtonLine.event_read();
+
+    if (gpioLineEvent.event_type == gpiod::line_event::FALLING_EDGE)
+    {
+        powerButtonPressLog();
+        powerButtonIface->set_property("ButtonPressed", true);
+        if (!powerButtonMask)
+        {
+            sendPowerControlEvent(Event::powerButtonPressed);
+            setRestartCause(RestartCause::powerButton);
+        }
+        else
+        {
+            std::cerr << "power button press masked\n";
+        }
+    }
+    else if (gpioLineEvent.event_type == gpiod::line_event::RISING_EDGE)
+    {
+        powerButtonIface->set_property("ButtonPressed", false);
+    }
+    powerButtonEvent.async_wait(
+        boost::asio::posix::stream_descriptor::wait_read,
+        [](const boost::system::error_code ec) {
+            if (ec)
+            {
+                std::cerr << "power button handler error: " << ec.message()
+                          << "\n";
+                return;
+            }
+            powerButtonHandler();
+        });
+}
+
+static void resetButtonHandler()
+{
+    gpiod::line_event gpioLineEvent = resetButtonLine.event_read();
+
+    if (gpioLineEvent.event_type == gpiod::line_event::FALLING_EDGE)
+    {
+        resetButtonPressLog();
+        resetButtonIface->set_property("ButtonPressed", true);
+        if (!resetButtonMask)
+        {
+            resetInProgress = true;
+            setRestartCause(RestartCause::resetButton);
+        }
+        else
+        {
+            std::cerr << "reset button press masked\n";
+        }
+    }
+    else if (gpioLineEvent.event_type == gpiod::line_event::RISING_EDGE)
+    {
+        resetButtonIface->set_property("ButtonPressed", false);
+    }
+    resetButtonEvent.async_wait(
+        boost::asio::posix::stream_descriptor::wait_read,
+        [](const boost::system::error_code ec) {
+            if (ec)
+            {
+                std::cerr << "reset button handler error: " << ec.message()
+                          << "\n";
+                return;
+            }
+            resetButtonHandler();
+        });
+}
+
+static void nmiSetEnablePorperty(bool value)
+{
+    conn->async_method_call(
+        [](boost::system::error_code ec) {
+            if (ec)
+            {
+                std::cerr << "failed to set NMI source\n";
+            }
+        },
+        "xyz.openbmc_project.Settings", "/com/intel/control/NMISource",
+        "org.freedesktop.DBus.Properties", "Set", "com.intel.Control.NMISource",
+        "Enabled", std::variant<bool>{value});
+}
+
+static void nmiReset(void)
+{
+    static constexpr const uint8_t value = 1;
+    const static constexpr int nmiOutPulseTimeMs = 200;
+
+    std::cerr << "NMI out action \n";
+    nmiOutLine.set_value(value);
+    std::cerr << nmiOutName << " set to " << std::to_string(value) << "\n";
+    gpioAssertTimer.expires_after(std::chrono::milliseconds(nmiOutPulseTimeMs));
+    gpioAssertTimer.async_wait([](const boost::system::error_code ec) {
+        // restore the NMI_OUT GPIO line back to the opposite value
+        nmiOutLine.set_value(!value);
+        std::cerr << nmiOutName << " released\n";
+        if (ec)
+        {
+            // operation_aborted is expected if timer is canceled before
+            // completion.
+            if (ec != boost::asio::error::operation_aborted)
+            {
+                std::cerr << nmiOutName << " async_wait failed: " + ec.message()
+                          << "\n";
+            }
+        }
+    });
+    // log to redfish
+    nmiDiagIntLog();
+    std::cerr << "NMI out action completed\n";
+    // reset Enable Property
+    nmiSetEnablePorperty(false);
+}
+
+static void nmiSourcePropertyMonitor(void)
+{
+    std::cerr << " NMI Source Property Monitor \n";
+
+    static std::unique_ptr<sdbusplus::bus::match::match> nmiSourceMatch =
+        std::make_unique<sdbusplus::bus::match::match>(
+            *conn,
+            "type='signal',interface='org.freedesktop.DBus.Properties',"
+            "member='PropertiesChanged',arg0namespace='com.intel.Control."
+            "NMISource'",
+            [](sdbusplus::message::message& msg) {
+                std::string interfaceName;
+                boost::container::flat_map<std::string,
+                                           std::variant<bool, std::string>>
+                    propertiesChanged;
+                std::string state;
+                bool value = true;
+                try
+                {
+                    msg.read(interfaceName, propertiesChanged);
+                    if (propertiesChanged.begin()->first == "Enabled")
+                    {
+                        value =
+                            std::get<bool>(propertiesChanged.begin()->second);
+                        std::cerr
+                            << " NMI Enabled propertiesChanged value: " << value
+                            << "\n";
+                        nmiEnabled = value;
+                        if (nmiEnabled)
+                        {
+                            nmiReset();
+                        }
+                    }
+                }
+                catch (std::exception& e)
+                {
+                    std::cerr << "Unable to read NMI source\n";
+                    return;
+                }
+            });
+}
+
+static void setNmiSource()
+{
+    conn->async_method_call(
+        [](boost::system::error_code ec) {
+            if (ec)
+            {
+                std::cerr << "failed to set NMI source\n";
+            }
+        },
+        "xyz.openbmc_project.Settings", "/com/intel/control/NMISource",
+        "org.freedesktop.DBus.Properties", "Set", "com.intel.Control.NMISource",
+        "BMCSource",
+        std::variant<std::string>{
+            "com.intel.Control.NMISource.BMCSourceSignal.FpBtn"});
+    // set Enable Property
+    nmiSetEnablePorperty(true);
+}
+
+static void nmiButtonHandler()
+{
+    gpiod::line_event gpioLineEvent = nmiButtonLine.event_read();
+
+    if (gpioLineEvent.event_type == gpiod::line_event::FALLING_EDGE)
+    {
+        nmiButtonPressLog();
+        nmiButtonIface->set_property("ButtonPressed", true);
+        if (nmiButtonMasked)
+        {
+            std::cerr << "NMI button press masked\n";
+        }
+        else
+        {
+            setNmiSource();
+        }
+    }
+    else if (gpioLineEvent.event_type == gpiod::line_event::RISING_EDGE)
+    {
+        nmiButtonIface->set_property("ButtonPressed", false);
+    }
+    nmiButtonEvent.async_wait(boost::asio::posix::stream_descriptor::wait_read,
+                              [](const boost::system::error_code ec) {
+                                  if (ec)
+                                  {
+                                      std::cerr << "NMI button handler error: "
+                                                << ec.message() << "\n";
+                                      return;
+                                  }
+                                  nmiButtonHandler();
+                              });
+}
+
+static void idButtonHandler()
+{
+    gpiod::line_event gpioLineEvent = idButtonLine.event_read();
+
+    if (gpioLineEvent.event_type == gpiod::line_event::FALLING_EDGE)
+    {
+        idButtonIface->set_property("ButtonPressed", true);
+    }
+    else if (gpioLineEvent.event_type == gpiod::line_event::RISING_EDGE)
+    {
+        idButtonIface->set_property("ButtonPressed", false);
+    }
+    idButtonEvent.async_wait(boost::asio::posix::stream_descriptor::wait_read,
+                             [](const boost::system::error_code& ec) {
+                                 if (ec)
+                                 {
+                                     std::cerr << "ID button handler error: "
+                                               << ec.message() << "\n";
+                                     return;
+                                 }
+                                 idButtonHandler();
+                             });
+}
+
+static void postCompleteHandler()
+{
+    gpiod::line_event gpioLineEvent = postCompleteLine.event_read();
+
+    bool postComplete =
+        gpioLineEvent.event_type == gpiod::line_event::FALLING_EDGE;
+    std::cerr << "POST complete value changed: " << postComplete << "\n";
+    if (postComplete)
+    {
+        osIface->set_property("OperatingSystemState", std::string("Standby"));
+        resetInProgress = false;
+    }
+    else
+    {
+        osIface->set_property("OperatingSystemState", std::string("Inactive"));
+        // Set the restart cause if POST complete de-asserted by host software
+        if (powerState == PowerState::on && !resetInProgress)
+        {
+            resetInProgress = true;
+            setRestartCause(RestartCause::softReset);
+        }
+    }
+    postCompleteEvent.async_wait(
+        boost::asio::posix::stream_descriptor::wait_read,
+        [](const boost::system::error_code ec) {
+            if (ec)
+            {
+                std::cerr << "POST complete handler error: " << ec.message()
+                          << "\n";
+                return;
+            }
+            postCompleteHandler();
+        });
+}
+} // namespace power_control
+
+int main(int argc, char* argv[])
+{
+    std::cerr << "Start Chassis power control service...\n";
+    power_control::conn =
+        std::make_shared<sdbusplus::asio::connection>(power_control::io);
+
+    // Request all the dbus names
+    power_control::conn->request_name("xyz.openbmc_project.State.Host");
+    power_control::conn->request_name("xyz.openbmc_project.State.Chassis");
+    power_control::conn->request_name(
+        "xyz.openbmc_project.State.OperatingSystem");
+    power_control::conn->request_name("xyz.openbmc_project.Chassis.Buttons");
+
+    // Request PS_PWROK GPIO events
+    if (!power_control::requestGPIOEvents(
+            "PS_PWROK", power_control::psPowerOKHandler,
+            power_control::psPowerOKLine, power_control::psPowerOKEvent))
+    {
+        return -1;
+    }
+
+    // Request SIO_POWER_GOOD GPIO events
+    if (!power_control::requestGPIOEvents(
+            "SIO_POWER_GOOD", power_control::sioPowerGoodHandler,
+            power_control::sioPowerGoodLine, power_control::sioPowerGoodEvent))
+    {
+        return -1;
+    }
+
+    // Request SIO_ONCONTROL GPIO events
+    if (!power_control::requestGPIOEvents(
+            "SIO_ONCONTROL", power_control::sioOnControlHandler,
+            power_control::sioOnControlLine, power_control::sioOnControlEvent))
+    {
+        return -1;
+    }
+
+    // Request SIO_S5 GPIO events
+    if (!power_control::requestGPIOEvents("SIO_S5", power_control::sioS5Handler,
+                                          power_control::sioS5Line,
+                                          power_control::sioS5Event))
+    {
+        return -1;
+    }
+
+    // Request POWER_BUTTON GPIO events
+    if (!power_control::requestGPIOEvents(
+            "POWER_BUTTON", power_control::powerButtonHandler,
+            power_control::powerButtonLine, power_control::powerButtonEvent))
+    {
+        return -1;
+    }
+
+    // Request RESET_BUTTON GPIO events
+    if (!power_control::requestGPIOEvents(
+            "RESET_BUTTON", power_control::resetButtonHandler,
+            power_control::resetButtonLine, power_control::resetButtonEvent))
+    {
+        return -1;
+    }
+
+    // Request NMI_BUTTON GPIO events
+    if (!power_control::requestGPIOEvents(
+            "NMI_BUTTON", power_control::nmiButtonHandler,
+            power_control::nmiButtonLine, power_control::nmiButtonEvent))
+    {
+        return -1;
+    }
+
+    // Request ID_BUTTON GPIO events
+    if (!power_control::requestGPIOEvents(
+            "ID_BUTTON", power_control::idButtonHandler,
+            power_control::idButtonLine, power_control::idButtonEvent))
+    {
+        return -1;
+    }
+
+    // Request POST_COMPLETE GPIO events
+    if (!power_control::requestGPIOEvents(
+            "POST_COMPLETE", power_control::postCompleteHandler,
+            power_control::postCompleteLine, power_control::postCompleteEvent))
+    {
+        return -1;
+    }
+
+    // initialize NMI_OUT GPIO.
+    if (!power_control::setGPIOOutput(power_control::nmiOutName, 0,
+                                      power_control::nmiOutLine))
+    {
+        return -1;
+    }
+
+    // Initialize the power state
+    power_control::powerState = power_control::PowerState::off;
+    // Check power good
+    if (power_control::psPowerOKLine.get_value() > 0)
+    {
+        power_control::powerState = power_control::PowerState::on;
+    }
+
+    // Initialize the power state storage
+    if (power_control::initializePowerStateStorage() < 0)
+    {
+        return -1;
+    }
+
+    // Check if we need to start the Power Restore policy
+    power_control::powerRestorePolicyCheck();
+
+    power_control::nmiSourcePropertyMonitor();
+
+    std::cerr << "Initializing power state. ";
+    power_control::logStateTransition(power_control::powerState);
+
+    // Power Control Service
+    sdbusplus::asio::object_server hostServer =
+        sdbusplus::asio::object_server(power_control::conn);
+
+    // Power Control Interface
+    power_control::hostIface = hostServer.add_interface(
+        "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host");
+
+    power_control::hostIface->register_property(
+        "RequestedHostTransition",
+        std::string("xyz.openbmc_project.State.Host.Transition.Off"),
+        [](const std::string& requested, std::string& resp) {
+            if (requested == "xyz.openbmc_project.State.Host.Transition.Off")
+            {
+                sendPowerControlEvent(
+                    power_control::Event::gracefulPowerOffRequest);
+            }
+            else if (requested ==
+                     "xyz.openbmc_project.State.Host.Transition.On")
+            {
+                sendPowerControlEvent(power_control::Event::powerOnRequest);
+                setRestartCause(power_control::RestartCause::command);
+            }
+            else if (requested ==
+                     "xyz.openbmc_project.State.Host.Transition.Reboot")
+            {
+                sendPowerControlEvent(
+                    power_control::Event::gracefulPowerCycleRequest);
+                setRestartCause(power_control::RestartCause::command);
+            }
+            else
+            {
+                std::cerr << "Unrecognized host state transition request.\n";
+                throw std::invalid_argument("Unrecognized Transition Request");
+                return 0;
+            }
+            resp = requested;
+            return 1;
+        });
+    power_control::hostIface->register_property(
+        "CurrentHostState",
+        std::string(power_control::getHostState(power_control::powerState)));
+
+    power_control::currentHostStateMonitor();
+
+    power_control::hostIface->initialize();
+
+    // Chassis Control Service
+    sdbusplus::asio::object_server chassisServer =
+        sdbusplus::asio::object_server(power_control::conn);
+
+    // Chassis Control Interface
+    power_control::chassisIface =
+        chassisServer.add_interface("/xyz/openbmc_project/state/chassis0",
+                                    "xyz.openbmc_project.State.Chassis");
+
+    power_control::chassisIface->register_property(
+        "RequestedPowerTransition",
+        std::string("xyz.openbmc_project.State.Chassis.Transition.Off"),
+        [](const std::string& requested, std::string& resp) {
+            if (requested == "xyz.openbmc_project.State.Chassis.Transition.Off")
+            {
+                sendPowerControlEvent(power_control::Event::powerOffRequest);
+            }
+            else if (requested ==
+                     "xyz.openbmc_project.State.Chassis.Transition.On")
+            {
+                sendPowerControlEvent(power_control::Event::powerOnRequest);
+                setRestartCause(power_control::RestartCause::command);
+            }
+            else if (requested ==
+                     "xyz.openbmc_project.State.Chassis.Transition.PowerCycle")
+            {
+                sendPowerControlEvent(power_control::Event::powerCycleRequest);
+                setRestartCause(power_control::RestartCause::command);
+            }
+            else if (requested ==
+                     "xyz.openbmc_project.State.Chassis.Transition.Reset")
+            {
+                setRestartCause(power_control::RestartCause::command);
+                sendPowerControlEvent(power_control::Event::resetRequest);
+            }
+            else
+            {
+                std::cerr << "Unrecognized chassis state transition request.\n";
+                throw std::invalid_argument("Unrecognized Transition Request");
+                return 0;
+            }
+            resp = requested;
+            return 1;
+        });
+    power_control::chassisIface->register_property(
+        "CurrentPowerState",
+        std::string(power_control::getChassisState(power_control::powerState)));
+    power_control::chassisIface->register_property(
+        "LastStateChangeTime", power_control::getCurrentTimeMs());
+
+    power_control::chassisIface->initialize();
+
+    // Buttons Service
+    sdbusplus::asio::object_server buttonsServer =
+        sdbusplus::asio::object_server(power_control::conn);
+
+    // Power Button Interface
+    power_control::powerButtonIface = buttonsServer.add_interface(
+        "/xyz/openbmc_project/chassis/buttons/power",
+        "xyz.openbmc_project.Chassis.Buttons");
+
+    power_control::powerButtonIface->register_property(
+        "ButtonMasked", false, [](const bool requested, bool& current) {
+            if (requested)
+            {
+                if (power_control::powerButtonMask)
+                {
+                    return 1;
+                }
+                if (!power_control::setGPIOOutput(
+                        "POWER_OUT", 1, power_control::powerButtonMask))
+                {
+                    throw std::runtime_error("Failed to request GPIO");
+                    return 0;
+                }
+                std::cerr << "Power Button Masked.\n";
+            }
+            else
+            {
+                if (!power_control::powerButtonMask)
+                {
+                    return 1;
+                }
+                std::cerr << "Power Button Un-masked\n";
+                power_control::powerButtonMask.reset();
+            }
+            // Update the mask setting
+            current = requested;
+            return 1;
+        });
+
+    // Check power button state
+    bool powerButtonPressed = power_control::powerButtonLine.get_value() == 0;
+    power_control::powerButtonIface->register_property("ButtonPressed",
+                                                       powerButtonPressed);
+
+    power_control::powerButtonIface->initialize();
+
+    // Reset Button Interface
+    power_control::resetButtonIface = buttonsServer.add_interface(
+        "/xyz/openbmc_project/chassis/buttons/reset",
+        "xyz.openbmc_project.Chassis.Buttons");
+
+    power_control::resetButtonIface->register_property(
+        "ButtonMasked", false, [](const bool requested, bool& current) {
+            if (requested)
+            {
+                if (power_control::resetButtonMask)
+                {
+                    return 1;
+                }
+                if (!power_control::setGPIOOutput(
+                        "RESET_OUT", 1, power_control::resetButtonMask))
+                {
+                    throw std::runtime_error("Failed to request GPIO");
+                    return 0;
+                }
+                std::cerr << "Reset Button Masked.\n";
+            }
+            else
+            {
+                if (!power_control::resetButtonMask)
+                {
+                    return 1;
+                }
+                std::cerr << "Reset Button Un-masked\n";
+                power_control::resetButtonMask.reset();
+            }
+            // Update the mask setting
+            current = requested;
+            return 1;
+        });
+
+    // Check reset button state
+    bool resetButtonPressed = power_control::resetButtonLine.get_value() == 0;
+    power_control::resetButtonIface->register_property("ButtonPressed",
+                                                       resetButtonPressed);
+
+    power_control::resetButtonIface->initialize();
+
+    // NMI Button Interface
+    power_control::nmiButtonIface =
+        buttonsServer.add_interface("/xyz/openbmc_project/chassis/buttons/nmi",
+                                    "xyz.openbmc_project.Chassis.Buttons");
+
+    power_control::nmiButtonIface->register_property(
+        "ButtonMasked", false, [](const bool requested, bool& current) {
+            if (power_control::nmiButtonMasked == requested)
+            {
+                // NMI button mask is already set as requested, so no change
+                return 1;
+            }
+            if (requested)
+            {
+                std::cerr << "NMI Button Masked.\n";
+                power_control::nmiButtonMasked = true;
+            }
+            else
+            {
+                std::cerr << "NMI Button Un-masked.\n";
+                power_control::nmiButtonMasked = false;
+            }
+            // Update the mask setting
+            current = power_control::nmiButtonMasked;
+            return 1;
+        });
+
+    // Check NMI button state
+    bool nmiButtonPressed = power_control::nmiButtonLine.get_value() == 0;
+    power_control::nmiButtonIface->register_property("ButtonPressed",
+                                                     nmiButtonPressed);
+
+    power_control::nmiButtonIface->initialize();
+
+    // ID Button Interface
+    power_control::idButtonIface =
+        buttonsServer.add_interface("/xyz/openbmc_project/chassis/buttons/id",
+                                    "xyz.openbmc_project.Chassis.Buttons");
+
+    // Check ID button state
+    bool idButtonPressed = power_control::idButtonLine.get_value() == 0;
+    power_control::idButtonIface->register_property("ButtonPressed",
+                                                    idButtonPressed);
+
+    power_control::idButtonIface->initialize();
+
+    // OS State Service
+    sdbusplus::asio::object_server osServer =
+        sdbusplus::asio::object_server(power_control::conn);
+
+    // OS State Interface
+    power_control::osIface = osServer.add_interface(
+        "/xyz/openbmc_project/state/os",
+        "xyz.openbmc_project.State.OperatingSystem.Status");
+
+    // Get the initial OS state based on POST complete
+    //      0: Asserted, OS state is "Standby" (ready to boot)
+    //      1: De-Asserted, OS state is "Inactive"
+    std::string osState = power_control::postCompleteLine.get_value() > 0
+                              ? "Inactive"
+                              : "Standby";
+
+    power_control::osIface->register_property("OperatingSystemState",
+                                              std::string(osState));
+
+    power_control::osIface->initialize();
+
+    power_control::io.run();
+
+    return 0;
+}
