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
diff --git a/attn/attn_handler.hpp b/attn/attn_handler.hpp
new file mode 100644
index 0000000..2be6b07
--- /dev/null
+++ b/attn/attn_handler.hpp
@@ -0,0 +1,21 @@
+#pragma once
+
+/**
+ * @brief The main attention handler logic
+ *
+ * Check each processor for active attentions of type SBE Vital (vital),
+ * System Checkstop (checkstop) and Special Attention (special) and handle
+ * each as follows:
+ *
+ * checkstop: TBD
+ * vital: TBD
+ * special: Determine if the special attention is a Breakpoint (BP),
+ * Terminate Immediately (TI) or CoreCodeToSp (corecode). For each
+ * special attention type, do the following:
+ *
+ * BP: Notify Cronus
+ * TI: TBD
+ * Corecode: TBD
+ * Recoverable: TBD
+ */
+void attnHandler();
diff --git a/attn/attn_main.cpp b/attn/attn_main.cpp
new file mode 100644
index 0000000..dda1fc8
--- /dev/null
+++ b/attn/attn_main.cpp
@@ -0,0 +1,21 @@
+#include <libpdbg.h>
+
+#include <attn_handler.hpp>
+
+/**
+ * @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.
+ *
+ * @return 0 = success
+ */
+int main()
+{
+ int rc = 0; // return code
+
+ // initialize pdbg targets
+ pdbg_targets_init(nullptr);
+
+ return rc;
+}
diff --git a/attn/meson.build b/attn/meson.build
new file mode 100644
index 0000000..d215067
--- /dev/null
+++ b/attn/meson.build
@@ -0,0 +1,18 @@
+# needed to find external libraries not registered with package manager
+cmplr = meson.get_compiler('cpp')
+
+# dependency to link dbus support
+sdbusplus = dependency('sdbusplus', version : '>=1.0')
+
+# dependency to link libpdbg support
+libpdbg = cmplr.find_library('pdbg')
+
+# libpdbg requires linking with "whole-archive" option
+whole_archive = declare_dependency(link_args : '-Wl,--whole-archive')
+no_whole_archive = declare_dependency(link_args : '-Wl,--no-whole-archive')
+
+executable('attn_handler',
+ 'attn_main.cpp', 'attn_handler.cpp',
+ dependencies : [whole_archive, libpdbg,
+ no_whole_archive, sdbusplus],
+ install : true)
diff --git a/meson.build b/meson.build
index b28887d..9dc0caa 100644
--- a/meson.build
+++ b/meson.build
@@ -7,6 +7,7 @@
])
subdir('src')
+subdir('attn')
build_tests = get_option('tests')