Add ERR1 timeout monitoring and logging

This adds ERR1 timeout monitoring to the host error monitor.  When
the ERR1 signal is asserted for more than 90 seconds, the BMC will
log which CPU asserted the ERR1 signal.

Tested:
Manually triggered an ERR1 timeout and confirmed that the event is
logged correctly.

Change-Id: Ibed1faea7c80fc5ce0b1d5449ec4158d63ee3e0d
Signed-off-by: Jason M. Bills <jason.m.bills@intel.com>
diff --git a/src/host_error_monitor.cpp b/src/host_error_monitor.cpp
index 408acc9..52c34b4 100644
--- a/src/host_error_monitor.cpp
+++ b/src/host_error_monitor.cpp
@@ -40,6 +40,8 @@
 static boost::asio::steady_timer caterrAssertTimer(io);
 // Timer for ERR0 asserted
 static boost::asio::steady_timer err0AssertTimer(io);
+// Timer for ERR1 asserted
+static boost::asio::steady_timer err1AssertTimer(io);
 // Timer for ERR2 asserted
 static boost::asio::steady_timer err2AssertTimer(io);
 // Timer for SMI asserted
@@ -50,6 +52,8 @@
 static boost::asio::posix::stream_descriptor caterrEvent(io);
 static gpiod::line err0Line;
 static boost::asio::posix::stream_descriptor err0Event(io);
+static gpiod::line err1Line;
+static boost::asio::posix::stream_descriptor err1Event(io);
 static gpiod::line err2Line;
 static boost::asio::posix::stream_descriptor err2Event(io);
 static gpiod::line smiLine;
@@ -178,6 +182,7 @@
             {
                 caterrAssertTimer.cancel();
                 err0AssertTimer.cancel();
+                err1AssertTimer.cancel();
                 err2AssertTimer.cancel();
                 smiAssertTimer.cancel();
             }
@@ -774,6 +779,42 @@
                          });
 }
 
+static void err1AssertHandler()
+{
+    // Handle the standard ERR1 detection and logging
+    const static constexpr int err1 = 1;
+    errXAssertHandler(err1, err1AssertTimer);
+}
+
+static void err1Handler()
+{
+    if (!hostOff)
+    {
+        gpiod::line_event gpioLineEvent = err1Line.event_read();
+
+        bool err1 = gpioLineEvent.event_type == gpiod::line_event::FALLING_EDGE;
+        if (err1)
+        {
+            err1AssertHandler();
+        }
+        else
+        {
+            err1AssertTimer.cancel();
+        }
+    }
+    err1Event.async_wait(boost::asio::posix::stream_descriptor::wait_read,
+                         [](const boost::system::error_code ec) {
+                             if (ec)
+                             {
+                                 std::cerr
+                                     << "err1 handler error: " << ec.message()
+                                     << "\n";
+                                 return;
+                             }
+                             err1Handler();
+                         });
+}
+
 static void err2AssertHandler()
 {
     // Handle the standard ERR2 detection and logging
@@ -926,6 +967,12 @@
         err0AssertHandler();
     }
 
+    // Handle CPU_ERR1 if it's asserted now
+    if (err1Line.get_value() == 0)
+    {
+        err1AssertHandler();
+    }
+
     // Handle CPU_ERR2 if it's asserted now
     if (err2Line.get_value() == 0)
     {
@@ -981,6 +1028,14 @@
         return -1;
     }
 
+    // Request CPU_ERR1 GPIO events
+    if (!host_error_monitor::requestGPIOEvents(
+            "CPU_ERR1", host_error_monitor::err1Handler,
+            host_error_monitor::err1Line, host_error_monitor::err1Event))
+    {
+        return -1;
+    }
+
     // Request CPU_ERR2 GPIO events
     if (!host_error_monitor::requestGPIOEvents(
             "CPU_ERR2", host_error_monitor::err2Handler,