Attention Handler base logic
Added base logic for the attention handler application (attn) as a starting point for further refinement. Attn will handle SBE vital, system checkstop and special attention events. These events will be handled through a combination local logic and external hardware and software interfaces.
Signed-off-by: Ben Tyner <ben.tyner@ibm.com>
Change-Id: I074fb86474761bf694644c71d93ede9c45673b79
diff --git a/attn/attn_handler.cpp b/attn/attn_handler.cpp
new file mode 100644
index 0000000..cac1f84
--- /dev/null
+++ b/attn/attn_handler.cpp
@@ -0,0 +1,207 @@
+#include <libpdbg.h>
+
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/bus.hpp>
+
+#include <iomanip>
+
+using namespace phosphor::logging;
+
+namespace attn
+{
+
+/**
+ * @brief Handle SBE vital attention
+ *
+ * @return 0 = success
+ */
+int handleVital();
+
+/**
+ * @brief Handle checkstop attention
+ *
+ * @return 0 = success
+ */
+int handleCheckstop();
+
+/**
+ * @brief Handle special attention
+ *
+ * @return 0 = success
+ */
+int handleSpecial();
+
+/**
+ * @brief Notify Cronus over dbus interface
+ *
+ * @param i_proc Processor number with Special attention
+ * @param i_core Core number with special attention
+ * @param i_thread Thread number with special attention
+ */
+void notifyCronus(uint32_t i_proc, uint32_t i_core, uint32_t i_thread);
+
+/**
+ * @brief The main attention handler logic
+ */
+void attnHandler()
+{
+ uint32_t isr_val, isr_mask;
+ uint32_t proc;
+
+ // loop through processors looking for active attentions
+ pdbg_target* target;
+ pdbg_for_each_class_target("fsi", target)
+ {
+ if (PDBG_TARGET_ENABLED == pdbg_target_probe(target))
+ {
+ proc = pdbg_target_index(target); // get processor number
+
+ std::stringstream ss; // log message stream
+ ss << "[ATTN] checking processor " << proc << std::endl;
+ log<level::INFO>(ss.str().c_str());
+
+ // get active attentions on processor
+ if (0 != fsi_read(target, 0x1007, &isr_val))
+ {
+ std::stringstream ss; // log message stream
+ ss << "[ATTN] Error! cfam read 0x1007 FAILED" << std::endl;
+ log<level::INFO>(ss.str().c_str());
+ }
+ else
+ {
+ std::stringstream ss; // log message stream
+ ss << "[ATTN] cfam 0x1007 = 0x";
+ ss << std::hex << std::setw(8) << std::setfill('0');
+ ss << isr_val << std::endl;
+ log<level::INFO>(ss.str().c_str());
+
+ // get interrupt enabled special attentions mask
+ if (0 != fsi_read(target, 0x100d, &isr_mask))
+ {
+ std::stringstream ss; // log message stream
+ ss << "[ATTN] Error! cfam read 0x100d FAILED" << std::endl;
+ log<level::INFO>(ss.str().c_str());
+ }
+ else
+ {
+ std::stringstream ss; // log message stream
+ ss << "[ATTN] cfam 0x100d = 0x";
+ ss << std::hex << std::setw(8) << std::setfill('0');
+ ss << isr_mask << std::endl;
+ log<level::INFO>(ss.str().c_str());
+
+ // bit 0 on "left": bit 30 = SBE vital attention
+ if (isr_val & isr_mask & 0x00000002)
+ {
+ handleVital();
+ }
+
+ // bit 0 on "left": bit 1 = checkstop
+ if (isr_val & isr_mask & 0x40000000)
+ {
+ handleCheckstop();
+ }
+
+ // bit 0 on "left": bit 2 = special attention
+ if (isr_val & isr_mask & 0x20000000)
+ {
+ handleSpecial();
+ }
+ } // cfam 0x100d valid
+ } // cfam 0x1007 valid
+ } // fsi target enabled
+ } // next processor
+
+ return; // checked all processors
+}
+
+/**
+ * @brief Handle SBE vital attention
+ */
+int handleVital()
+{
+ int rc = 1; // vital attention handling not yet supported
+
+ std::stringstream ss; // log message stream
+ ss << "[ATTN] vital" << std::endl;
+ log<level::INFO>(ss.str().c_str());
+
+ if (0 != rc)
+ {
+ std::stringstream ss; // log message stream
+ ss << "[ATTN] vital NOT handled" << std::endl;
+ log<level::INFO>(ss.str().c_str());
+ }
+
+ return rc;
+}
+
+/**
+ * @brief Handle checkstop attention
+ */
+int handleCheckstop()
+{
+ int rc = 1; // checkstop handling not yet supported
+
+ std::stringstream ss; // log message stream
+ ss << "[ATTN] checkstop" << std::endl;
+ log<level::INFO>(ss.str().c_str());
+
+ if (0 != rc)
+ {
+ std::stringstream ss; // log message stream
+ ss << "[ATTN] checkstop NOT handled" << std::endl;
+ log<level::INFO>(ss.str().c_str());
+ }
+
+ // TODO recoverable errors?
+
+ return rc;
+}
+
+/**
+ * @brief Handle special attention
+ */
+int handleSpecial()
+{
+ int rc = 0; // special attention handling supported
+
+ std::stringstream ss; // log message stream
+
+ ss << "[ATTN] special" << std::endl;
+
+ // Currently we are only handling Cronus 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
+
+ // TODO recoverable errors?
+
+ return rc;
+}
+
+/**
+ * @brief Notify Cronus over dbus interface
+ */
+void notifyCronus(uint32_t i_proc, uint32_t i_core, uint32_t i_thread)
+{
+ std::stringstream ss; // log message stream
+
+ // log status info
+ ss << "[ATTN] notify ";
+ ss << i_proc << ", " << i_core << ", " << i_thread << std::endl;
+ log<level::INFO>(ss.str().c_str());
+
+ // notify Cronus over dbus
+ auto bus = sdbusplus::bus::new_system();
+ auto msg = bus.new_signal("/", "org.openbmc.cronus", "Brkpt");
+
+ std::array<uint32_t, 3> params{i_proc, i_core, i_thread};
+ msg.append(params);
+
+ msg.signal_send();
+}
+
+} // namespace attn