Move SMI monitor to the new architecture

Add an error monitor for SMI that polls to check if it is
asserted through the timeout and logs the event.  If it is ever
not asserted, it will wait for an interrupt to start polling
again.

Change-Id: Ic000f8c8d3a1acd06a76f47484f3cd2f06670835
Signed-off-by: Jason M. Bills <jason.m.bills@intel.com>
diff --git a/include/error_monitors/smi_monitor.hpp b/include/error_monitors/smi_monitor.hpp
new file mode 100644
index 0000000..5c3d07c
--- /dev/null
+++ b/include/error_monitors/smi_monitor.hpp
@@ -0,0 +1,94 @@
+/*
+// Copyright (c) 2021 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.
+*/
+#pragma once
+#include <systemd/sd-journal.h>
+
+#include <error_monitors/base_gpio_poll_monitor.hpp>
+#include <host_error_monitor.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+
+#include <iostream>
+
+namespace host_error_monitor::smi_monitor
+{
+static constexpr bool debug = false;
+
+class SMIMonitor :
+    public host_error_monitor::base_gpio_poll_monitor::BaseGPIOPollMonitor
+{
+    const static host_error_monitor::base_gpio_poll_monitor::AssertValue
+        assertValue =
+            host_error_monitor::base_gpio_poll_monitor::AssertValue::lowAssert;
+    const static constexpr size_t smiPollingTimeMs = 1000;
+    const static constexpr size_t smiTimeoutMs = 90000;
+
+    void logEvent() override
+    {
+        sd_journal_send("MESSAGE=HostError: SMI Timeout", "PRIORITY=%i",
+                        LOG_INFO, "REDFISH_MESSAGE_ID=%s",
+                        "OpenBMC.0.1.CPUError", "REDFISH_MESSAGE_ARGS=%s",
+                        "SMI Timeout", NULL);
+    }
+
+    void assertHandler() override
+    {
+        BaseGPIOPollMonitor::assertHandler();
+
+        conn->async_method_call(
+            [this](boost::system::error_code ec,
+                   const std::variant<bool>& property) {
+                if (ec)
+                {
+                    return;
+                }
+                const bool* reset = std::get_if<bool>(&property);
+                if (reset == nullptr)
+                {
+                    std::cerr << "Unable to read reset on " << signalName
+                              << " value\n";
+                    return;
+                }
+#ifdef HOST_ERROR_CRASHDUMP_ON_SMI_TIMEOUT
+                startCrashdumpAndRecovery(conn, *reset, "SMI Timeout");
+#else
+                if (*reset)
+                {
+                    std::cout << "Recovering the system\n";
+                    startWarmReset(conn);
+                }
+#endif
+            },
+            "xyz.openbmc_project.Settings",
+            "/xyz/openbmc_project/control/bmc_reset_disables",
+            "org.freedesktop.DBus.Properties", "Get",
+            "xyz.openbmc_project.Control.ResetDisables", "ResetOnSMI");
+    }
+
+  public:
+    SMIMonitor(boost::asio::io_service& io,
+               std::shared_ptr<sdbusplus::asio::connection> conn,
+               const std::string& signalName) :
+        BaseGPIOPollMonitor(io, conn, signalName, assertValue, smiPollingTimeMs,
+                            smiTimeoutMs)
+
+    {
+        if (valid)
+        {
+            startPolling();
+        }
+    }
+};
+} // namespace host_error_monitor::smi_monitor
diff --git a/src/host_error_monitor.cpp b/src/host_error_monitor.cpp
index 4f88b88..ddfb54a 100644
--- a/src/host_error_monitor.cpp
+++ b/src/host_error_monitor.cpp
@@ -49,7 +49,6 @@
 static size_t caterrTimeoutMs = 2000;
 const static constexpr size_t caterrTimeoutMsMax = 600000; // 10 minutes maximum
 const static constexpr size_t errTimeoutMs = 90000;
-const static constexpr size_t smiTimeoutMs = 90000;
 
 // Timers
 // Timer for CATERR asserted
@@ -60,8 +59,6 @@
 static boost::asio::steady_timer err1AssertTimer(io);
 // Timer for ERR2 asserted
 static boost::asio::steady_timer err2AssertTimer(io);
-// Timer for SMI asserted
-static boost::asio::steady_timer smiAssertTimer(io);
 
 // GPIO Lines and Event Descriptors
 static gpiod::line caterrLine;
@@ -72,8 +69,6 @@
 static boost::asio::posix::stream_descriptor err1Event(io);
 static gpiod::line err2Line;
 static boost::asio::posix::stream_descriptor err2Event(io);
-static gpiod::line smiLine;
-static boost::asio::posix::stream_descriptor smiEvent(io);
 static gpiod::line cpu1FIVRFaultLine;
 static gpiod::line cpu1ThermtripLine;
 static boost::asio::posix::stream_descriptor cpu1ThermtripEvent(io);
@@ -174,13 +169,6 @@
                     "REDFISH_MESSAGE_ARGS=%s", msg.c_str(), NULL);
 }
 
-static void smiTimeoutLog()
-{
-    sd_journal_send("MESSAGE=HostError: SMI Timeout", "PRIORITY=%i", LOG_INFO,
-                    "REDFISH_MESSAGE_ID=%s", "OpenBMC.0.1.CPUError",
-                    "REDFISH_MESSAGE_ARGS=%s", "SMI Timeout", NULL);
-}
-
 static void cpuBootFIVRFaultLog(const int cpuNum)
 {
     std::string msg = "Boot FIVR Fault on CPU " + std::to_string(cpuNum);
@@ -330,7 +318,6 @@
                 err0AssertTimer.cancel();
                 err1AssertTimer.cancel();
                 err2AssertTimer.cancel();
-                smiAssertTimer.cancel();
             }
             else
             {
@@ -1331,83 +1318,6 @@
                          });
 }
 
-static void smiAssertHandler()
-{
-    smiAssertTimer.expires_after(std::chrono::milliseconds(smiTimeoutMs));
-    smiAssertTimer.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 << "smi timeout async_wait failed: " << ec.message()
-                          << "\n";
-            }
-            return;
-        }
-        std::cerr << "SMI asserted for " << std::to_string(smiTimeoutMs)
-                  << " ms\n";
-        smiTimeoutLog();
-        conn->async_method_call(
-            [](boost::system::error_code ec,
-               const std::variant<bool>& property) {
-                if (ec)
-                {
-                    return;
-                }
-                const bool* reset = std::get_if<bool>(&property);
-                if (reset == nullptr)
-                {
-                    std::cerr << "Unable to read reset on SMI value\n";
-                    return;
-                }
-#ifdef HOST_ERROR_CRASHDUMP_ON_SMI_TIMEOUT
-                startCrashdumpAndRecovery(*reset, "SMI Timeout");
-#else
-                if (*reset)
-                {
-                    std::cerr << "Recovering the system\n";
-                    startWarmReset(conn);
-                }
-#endif
-            },
-            "xyz.openbmc_project.Settings",
-            "/xyz/openbmc_project/control/bmc_reset_disables",
-            "org.freedesktop.DBus.Properties", "Get",
-            "xyz.openbmc_project.Control.ResetDisables", "ResetOnSMI");
-    });
-}
-
-static void smiHandler()
-{
-    if (!hostOff)
-    {
-        gpiod::line_event gpioLineEvent = smiLine.event_read();
-
-        bool smi = gpioLineEvent.event_type == gpiod::line_event::FALLING_EDGE;
-        if (smi)
-        {
-            smiAssertHandler();
-        }
-        else
-        {
-            smiAssertTimer.cancel();
-        }
-    }
-    smiEvent.async_wait(boost::asio::posix::stream_descriptor::wait_read,
-                        [](const boost::system::error_code ec) {
-                            if (ec)
-                            {
-                                std::cerr
-                                    << "smi handler error: " << ec.message()
-                                    << "\n";
-                                return;
-                            }
-                            smiHandler();
-                        });
-}
-
 static void initializeErrorState()
 {
     // Handle CPU1_MISMATCH if it's asserted now
@@ -1452,12 +1362,6 @@
         err2AssertHandler();
     }
 
-    // Handle SMI if it's asserted now
-    if (smiLine.get_value() == 0)
-    {
-        smiAssertHandler();
-    }
-
     // Handle CPU1_THERMTRIP if it's asserted now
     if (cpu1ThermtripLine.get_value() == 0)
     {
@@ -1635,14 +1539,6 @@
         return -1;
     }
 
-    // Request SMI GPIO events
-    if (!host_error_monitor::requestGPIOEvents(
-            "SMI", host_error_monitor::smiHandler, host_error_monitor::smiLine,
-            host_error_monitor::smiEvent))
-    {
-        return -1;
-    }
-
     // Request CPU1_FIVR_FAULT GPIO input
     if (!host_error_monitor::requestGPIOInput(
             "CPU1_FIVR_FAULT", host_error_monitor::cpu1FIVRFaultLine))