Add command line interface to attention handler

Allows configuring attention handler before starting attention
GPIO monitor.

Signed-off-by: Ben Tyner <ben.tyner@ibm.com>
Change-Id: I7a8d91703c14ce6d8eb3efddb135f11bf6baf06e
diff --git a/attn/attn_handler.cpp b/attn/attn_handler.cpp
index 8f43459..0463837 100644
--- a/attn/attn_handler.cpp
+++ b/attn/attn_handler.cpp
@@ -27,9 +27,10 @@
 /**
  * @brief Handle special attention
  *
+ * @param i_breakpoints true = breakpoint special attn handling enabled
  * @return 0 = success
  */
-int handleSpecial();
+int handleSpecial(bool i_breakpoints);
 
 /**
  * @brief Notify Cronus over dbus interface
@@ -49,8 +50,10 @@
 
 /**
  * @brief The main attention handler logic
+ *
+ * @param i_breakpoints true = breakpoint special attn handling enabled
  */
-void attnHandler()
+void attnHandler(bool i_breakpoints)
 {
     uint32_t isr_val, isr_mask;
     uint32_t proc;
@@ -112,7 +115,7 @@
                     // bit 0 on "left": bit 2 = special attention
                     if (isr_val & isr_mask & 0x20000000)
                     {
-                        handleSpecial();
+                        handleSpecial(i_breakpoints);
                     }
                 } // cfam 0x100d valid
             }     // cfam 0x1007 valid
@@ -168,8 +171,10 @@
 
 /**
  * @brief Handle special attention
+ *
+ * @param i_breakpoints true = breakpoint special attn handling enabled
  */
-int handleSpecial()
+int handleSpecial(bool i_breakpoints)
 {
     int rc = 0; // special attention handling supported
 
@@ -177,17 +182,29 @@
 
     ss << "[ATTN] special" << std::endl;
 
-    // Currently we are only handling Cronus breakpoints
-    // ss << "[ATTN] breakpoint" << std::endl;
-    // log<level::INFO>(ss.str().c_str());
+    // Right now we always handle breakpoint special attentions if breakpoint
+    // attn handling is enabled. This will eventually check if breakpoint attn
+    // handing is enabled AND there is a breakpoint pending.
+    if (true == i_breakpoints)
+    {
+        ss << "[ATTN] breakpoint" << std::endl;
+        log<level::INFO>(ss.str().c_str());
 
-    // Cronus will determine proc, core and thread so just notify
-    // notifyCronus(0, 0, 0); // proc-0, core-0, thread-0
+        // Cronus will determine proc, core and thread so just notify
+        notifyCronus(0, 0, 0); // proc-0, core-0, thread-0
+    }
+    // Right now if breakpoint attn handling is not enabled we will treat the
+    // special attention as a TI. This will eventually be changed to check
+    // whether a TI is active and handle it regardless of whether breakpoint
+    // handling is enbaled or not.
+    else
+    {
+        ss << "[ATTN] TI (terminate immediately)" << std::endl;
+        log<level::INFO>(ss.str().c_str());
 
-    // For TI special attention start host diagnostic mode
-    ss << "[ATTN] TI (terminate immediately)" << std::endl;
-    log<level::INFO>(ss.str().c_str());
-    startHostDiagnosticMode();
+        // Start host diagnostic mode
+        startHostDiagnosticMode();
+    }
 
     // TODO recoverable errors?
 
diff --git a/attn/attn_handler.hpp b/attn/attn_handler.hpp
index e8fb312..256145b 100644
--- a/attn/attn_handler.hpp
+++ b/attn/attn_handler.hpp
@@ -20,7 +20,9 @@
  *            TI:          TBD
  *            Corecode:    TBD
  *            Recoverable: TBD
+ *
+ * @param i_breakpoints true = breakpoint special attn handling enabled
  */
-void attnHandler();
+void attnHandler(bool i_breakpoints);
 
 } // namespace attn
diff --git a/attn/attn_main.cpp b/attn/attn_main.cpp
index e4766f0..c0e2451 100644
--- a/attn/attn_main.cpp
+++ b/attn/attn_main.cpp
@@ -3,15 +3,54 @@
 #include <attn_handler.hpp>
 #include <attn_monitor.hpp>
 
+#include <algorithm>
+
+/*
+ * @brief Search the command line arguments for an option
+ *
+ * @param i_begin   command line args vector begin
+ * @param i_end     command line args vector end
+ * @param i_option  configuration option to look for
+ *
+ * @return true = option found on command line
+ */
+bool getCliOption(char** i_begin, char** i_end, const std::string& i_option)
+{
+    return (i_end != std::find(i_begin, i_end, i_option));
+}
+
+/*
+ * @brief Search the command line arguments for a setting value
+ *
+ * @param i_begin   command line args vector begin
+ * @param i_end     command line args vectory end
+ * @param i_setting configuration setting to look for
+ *
+ * @return value of the setting or 0 if setting not found or value not given
+ */
+char* getCliSetting(char** i_begin, char** i_end, const std::string& i_setting)
+{
+    char** value = std::find(i_begin, i_end, i_setting);
+    if (value != i_end && ++value != i_end)
+    {
+        return *value;
+    }
+    return 0; // nullptr
+}
+
 /**
  * @brief Attention handler application main()
  *
  * This is the main interface to the Attention handler application, it will
  * initialize the libgpd targets and start a gpio mointor.
  *
+ * Command line arguments:
+ *
+ *  breakpoints - enables breakpoint special attn handling
+ *
  * @return 0 = success
  */
-int main()
+int main(int argc, char* argv[])
 {
     int rc = 0; // return code
 
@@ -37,9 +76,13 @@
     }
     else
     {
+        // Check command line args for breakpoint handling enable option
+        bool bp_enable = getCliOption(argv, argv + argc, "-breakpoints");
+
         // Creating a vector of one gpio to monitor
         std::vector<std::unique_ptr<attn::AttnMonitor>> gpios;
-        gpios.push_back(std::make_unique<attn::AttnMonitor>(line, config, io));
+        gpios.push_back(
+            std::make_unique<attn::AttnMonitor>(line, config, io, bp_enable));
 
         io.run(); // start GPIO monitor
     }
diff --git a/attn/attn_monitor.cpp b/attn/attn_monitor.cpp
index 2db8af1..15c924c 100644
--- a/attn/attn_monitor.cpp
+++ b/attn/attn_monitor.cpp
@@ -52,7 +52,7 @@
         {
             // active attention when gpio == 0
             case 0:
-                attnHandler();
+                attnHandler(iv_breakpoints);
                 break;
 
             // gpio == 1, GPIO handler should not be executing
diff --git a/attn/attn_monitor.hpp b/attn/attn_monitor.hpp
index 5231d7e..251857b 100644
--- a/attn/attn_monitor.hpp
+++ b/attn/attn_monitor.hpp
@@ -25,11 +25,13 @@
      * @param line     GPIO line handle
      * @param config   configuration of line
      * @param io       io service
+     * @param i_breakpoints true = breakpoint special attn handling enabled
      */
     AttnMonitor(gpiod_line* line, gpiod_line_request_config& config,
-                boost::asio::io_service& io) :
+                boost::asio::io_service& io, bool i_breakpoints) :
         iv_gpioLine(line),
-        iv_gpioConfig(config), iv_gpioEventDescriptor(io)
+        iv_gpioConfig(config), iv_gpioEventDescriptor(io),
+        iv_breakpoints(i_breakpoints)
     {
 
         requestGPIOEvent(); // registers the event handler
@@ -66,6 +68,9 @@
 
     /** @brief register for a gpio event */
     void requestGPIOEvent();
+
+    /** @brief enable breakpoint special attn handling */
+    bool iv_breakpoints;
 };
 
 } // namespace attn