attn: Collect SBE FFDC on getTiInfo chip-op fail

If the PHAL library throws an exception during the call to
getTiInfo it may provide some SBE FFDC data which the attention
handler will collect and put into an event log entry.

Signed-off-by: Ben Tyner <ben.tyner@ibm.com>
Change-Id: I834719944ed646ab6478f554965cf976a7c606e0
diff --git a/attn/attn_handler.cpp b/attn/attn_handler.cpp
index 13f9af4..66eb2fc 100644
--- a/attn/attn_handler.cpp
+++ b/attn/attn_handler.cpp
@@ -21,6 +21,8 @@
 #include <attn/ti_handler.hpp>
 #include <attn/vital_handler.hpp>
 #include <util/dbus.hpp>
+#include <util/ffdc_file.hpp>
+#include <util/trace.hpp>
 
 #include <algorithm>
 #include <iomanip>
@@ -56,7 +58,7 @@
 #ifdef CONFIG_PHAL_API
 /** @brief Handle phal sbe exception */
 void phalSbeExceptionHandler(openpower::phal::exception::SbeError& e,
-                             uint32_t procNum);
+                             uint32_t chipPosition, uint32_t command);
 #endif
 
 /** @brief Get static TI info data based on host state */
@@ -298,11 +300,16 @@
                 // get dynamic TI info
                 openpower::phal::sbe::getTiInfo(attnProc, &tiInfo, &tiInfoLen);
             }
-            catch (openpower::phal::exception::SbeError& e)
+            catch (openpower::phal::exception::SbeError& sbeError)
             {
                 // library threw an exception
+                // note: phal::sbe::getTiInfo = command class | command ==
+                // 0xa900 | 0x04 = 0xa904. The sbe fifo command class and
+                // commands are defined in the sbefifo library source code but
+                // do not seem to be exported/installed for consumption
+                // externally.
                 uint32_t procNum = pdbg_target_index(attnProc);
-                phalSbeExceptionHandler(e, procNum);
+                phalSbeExceptionHandler(sbeError, procNum, 0xa904);
             }
         }
 #else
@@ -447,23 +454,42 @@
 }
 
 #ifdef CONFIG_PHAL_API
+
 /**
  * @brief Handle phal sbe exception
  *
  * @param[in] e - exception object
  * @param[in] procNum - processor number associated with sbe exception
  */
-void phalSbeExceptionHandler(openpower::phal::exception::SbeError& e,
-                             uint32_t procNum)
+void phalSbeExceptionHandler(openpower::phal::exception::SbeError& sbeError,
+                             uint32_t chipPosition, uint32_t command)
 {
-    // trace exception details
-    std::string traceMsg = std::string(e.what());
-    trace<level::ERROR>(traceMsg.c_str());
+    trace::err("Attention handler phal exception handler");
 
-    // Handle SBE chipop timeout error
-    if (e.errType() == openpower::phal::exception::SBE_CHIPOP_NOT_ALLOWED)
+    // Trace exception details
+    trace::err(sbeError.what());
+
+    // Create event log entry with SBE FFDC data if provided
+    auto fd = sbeError.getFd();
+    if (fd > 0)
     {
-        eventPhalSbeChipop(procNum);
+        trace::err("SBE FFDC data is available");
+
+        // FFDC parser expects chip position and command (command class |
+        // command) to be in the additional data.
+        std::map<std::string, std::string> additionalData = {
+            {"SRC6", std::to_string((chipPosition << 16) | command)}};
+
+        // See phosphor-logging/extensions/openpower-pels/README.md, "Self Boot
+        // Engine(SBE) First Failure Data Capture(FFDC)" - SBE FFDC file type
+        // is 0xCB, version is 0x01.
+        std::vector<util::FFDCTuple> ffdc{util::FFDCTuple{
+            util::FFDCFormat::Custom, static_cast<uint8_t>(0xCB),
+            static_cast<uint8_t>(0x01), fd}};
+
+        // Create event log entry with FFDC data
+        createPel("org.open_power.Processor.Error.SbeChipOpFailure",
+                  additionalData, ffdc);
     }
 }
 #endif
diff --git a/attn/attn_logging.cpp b/attn/attn_logging.cpp
index 9f0e531..94a54bd 100644
--- a/attn/attn_logging.cpp
+++ b/attn/attn_logging.cpp
@@ -382,10 +382,6 @@
             eventName  = "org.open_power.Attn.Error.Fail";
             eventValid = true;
             break;
-        case EventType::PhalSbeChipop:
-            eventName  = "org.open_power.Processor.Error.SbeChipOpFailure";
-            eventValid = true;
-            break;
         default:
             eventValid = false;
             break;
@@ -519,26 +515,6 @@
 }
 
 /**
- * Commit SBE timeout event to log
- *
- * Create an event log indicating an SBE operation timed out.
- *
- * @param proc - processor that encountered the error
- */
-void eventPhalSbeChipop(uint32_t proc)
-{
-    trace<level::ERROR>("SBE error while getting TI info");
-
-    // report proc number in event log entry
-    std::map<std::string, std::string> additionalData;
-    additionalData.emplace("SRC6", std::to_string(proc << 16));
-
-    // create event with additional data and no ffdc
-    event(EventType::PhalSbeChipop, additionalData,
-          createFFDCFiles(nullptr, 0));
-}
-
-/**
  * Parse systemd journal message field
  *
  * Parse the journal looking for the specified field and return the journal
diff --git a/attn/attn_logging.hpp b/attn/attn_logging.hpp
index 84c986b..f165aaa 100644
--- a/attn/attn_logging.hpp
+++ b/attn/attn_logging.hpp
@@ -51,7 +51,4 @@
 /** @brief Commit attention handler failure event to log */
 void eventAttentionFail(int i_error);
 
-/** @brief Commit sbe chipop event to log */
-void eventPhalSbeChipop(uint32_t proc);
-
 } // namespace attn