Enable/disable logic for each attention type
Allow the handler for each attention type to be enabled or
disabled. The default is all attention handlers are enabled.
Signed-off-by: Ben Tyner <ben.tyner@ibm.com>
Change-Id: Ibe2e7848a7064ae164f70aa5ea5bfca486c4036b
diff --git a/attn/attention.cpp b/attn/attention.cpp
index c13bf64..0806ef2 100644
--- a/attn/attention.cpp
+++ b/attn/attention.cpp
@@ -1,21 +1,16 @@
#include <attention.hpp>
+#include <attn_config.hpp>
namespace attn
{
/** @brief Main constructor. */
Attention::Attention(AttentionType i_type, int (*i_handler)(Attention*),
- pdbg_target* i_target, bool i_breakpoints) :
+ pdbg_target* i_target, Config* i_config) :
iv_type(i_type),
- iv_handler(i_handler), iv_target(i_target)
+ iv_handler(i_handler), iv_target(i_target), iv_config(i_config)
-{
- // set attention handler configuration flags
- if (true == i_breakpoints)
- {
- iv_flags |= enableBreakpoints;
- }
-}
+{}
/** @brief Get attention priority */
int Attention::getPriority() const
@@ -23,16 +18,10 @@
return iv_type;
}
-/** @brief Get configuration flags */
-uint32_t Attention::getFlags() const
+/* @brief Get config object */
+Config* Attention::getConfig() const
{
- return iv_flags;
-}
-
-/** @brief Set configuration flags */
-void Attention::setFlags(uint32_t i_flags)
-{
- iv_flags = i_flags;
+ return iv_config;
}
/* @brief Call attention handler function */
@@ -41,7 +30,7 @@
return iv_handler(this);
}
-/** @brief less than operator */
+/** @brief less than operator, for heap creation */
bool Attention::operator<(const Attention& right) const
{
return (getPriority() < right.getPriority());
diff --git a/attn/attention.hpp b/attn/attention.hpp
index 28e7c76..a4d3461 100644
--- a/attn/attention.hpp
+++ b/attn/attention.hpp
@@ -2,6 +2,10 @@
#include <libpdbg.h>
+#include <attn/attn_config.hpp>
+
+#include <bitset>
+
namespace attn
{
@@ -34,7 +38,7 @@
/** @brief Main constructors */
Attention(AttentionType i_type, int (*i_handler)(Attention*),
- pdbg_target* i_target, bool i_breakpoints);
+ pdbg_target* i_target, Config* i_config);
/** @brief Destructor */
~Attention() = default;
@@ -42,11 +46,8 @@
/** @brief Get attention priority */
int getPriority() const;
- /** @brief Get configuration flags */
- uint32_t getFlags() const;
-
- /** @brief Set configuration flags */
- void setFlags(uint32_t i_flags);
+ /* @brief Get config object */
+ Config* getConfig() const;
/* @brief Call attention handler function */
int handle();
@@ -64,7 +65,7 @@
AttentionType iv_type; // attention type
int (*iv_handler)(Attention*); // handler function
pdbg_target* iv_target; // handler function target
- uint32_t iv_flags = 0; // configuration flags
+ Config* iv_config; // configuration flags
};
} // namespace attn
diff --git a/attn/attn_config.cpp b/attn/attn_config.cpp
new file mode 100644
index 0000000..caee221
--- /dev/null
+++ b/attn/attn_config.cpp
@@ -0,0 +1,47 @@
+#include <attn/attn_config.hpp>
+
+namespace attn
+{
+
+/** @brief Main constructor */
+Config::Config(bool i_vital, bool i_checkstop, bool i_terminate,
+ bool i_breakpoints)
+{
+ setConfig(i_vital, i_checkstop, i_terminate, i_breakpoints);
+}
+
+/** @brief Get state of flag */
+bool Config::getFlag(AttentionFlag i_flag) const
+{
+ return (iv_flags.test(i_flag));
+}
+
+/** @brief Set configuration flag */
+void Config::setFlag(AttentionFlag i_flag)
+{
+ iv_flags.set(i_flag);
+}
+
+/** @brief Clear configuration flag */
+void Config::clearFlag(AttentionFlag i_flag)
+{
+ iv_flags.reset(i_flag);
+}
+
+/** @brief Set state of all configuration data */
+void Config::setConfig(bool i_vital, bool i_checkstop, bool i_terminate,
+ bool i_breakpoints)
+{
+ (true == i_vital) ? iv_flags.set(enVital) : iv_flags.reset(enVital);
+
+ (true == i_checkstop) ? iv_flags.set(enCheckstop)
+ : iv_flags.reset(enCheckstop);
+
+ (true == i_terminate) ? iv_flags.set(enTerminate)
+ : iv_flags.reset(enTerminate);
+
+ (true == i_breakpoints) ? iv_flags.set(enBreakpoints)
+ : iv_flags.reset(enBreakpoints);
+}
+
+} // namespace attn
diff --git a/attn/attn_config.hpp b/attn/attn_config.hpp
new file mode 100644
index 0000000..ec8013b
--- /dev/null
+++ b/attn/attn_config.hpp
@@ -0,0 +1,57 @@
+#pragma once
+#include <bitset>
+
+namespace attn
+{
+
+/** @brief configuration flags */
+enum AttentionFlag
+{
+ enVital = 0,
+ enCheckstop = 1,
+ enTerminate = 2,
+ enBreakpoints = 3,
+ lastFlag
+};
+
+/** @brief Objhects to hold configuration data */
+class Config
+{
+ public: // methods
+ /** @brief Default constructor */
+ Config() = delete;
+
+ /** @brief Crate configuration object
+ *
+ * Create a configuration object to hold the attention handler
+ * configuration data
+ *
+ * @param i_vital Enable vital attention handling
+ * @param i_checkstop Enable checkstop attention handling
+ * @param i_terminate Enable TI attention handling
+ * @param i_+breakpoint Enable breakpoint attention handling
+ */
+ Config(bool i_vital, bool i_checkstop, bool i_terminate,
+ bool i_breakpoints);
+
+ /** @brief Default destructor */
+ ~Config() = default;
+
+ /** @brief Get state of flag */
+ bool getFlag(AttentionFlag i_flag) const;
+
+ /** @brief Set configuration flag */
+ void setFlag(AttentionFlag i_flag);
+
+ /** @brief Clear configuration flag */
+ void clearFlag(AttentionFlag i_flag);
+
+ /** @brief Set state of all configuration data */
+ void setConfig(bool i_vital, bool i_checkstop, bool i_terminate,
+ bool i_breakpoints);
+
+ private:
+ std::bitset<lastFlag> iv_flags; // configuration flags
+};
+
+} // namespace attn
diff --git a/attn/attn_handler.cpp b/attn/attn_handler.cpp
index 65d980a..a6bd469 100644
--- a/attn/attn_handler.cpp
+++ b/attn/attn_handler.cpp
@@ -1,5 +1,6 @@
#include <analyzer/analyzer_main.hpp>
#include <attention.hpp>
+#include <attn_config.hpp>
#include <bp_handler.hpp>
#include <logging.hpp>
#include <ti_handler.hpp>
@@ -20,7 +21,8 @@
* @brief Handle SBE vital attention
*
* @param i_attention Attention object
- * @return 0 = success
+ * @return 0 indicates that the vital attention was successfully handled
+ * 1 indicates that the vital attention was NOT successfully handled
*/
int handleVital(Attention* i_attention);
@@ -28,7 +30,9 @@
* @brief Handle checkstop attention
*
* @param i_attention Attention object
- * @return 0 = success
+ * @return 0 indicates that the checkstop attention was successfully handled
+ * 1 indicates that the checkstop attention was NOT successfully
+ * handled.
*/
int handleCheckstop(Attention* i_attention);
@@ -36,7 +40,8 @@
* @brief Handle special attention
*
* @param i_attention Attention object
- * @return 0 = success
+ * @return 0 indicates that the special attention was successfully handled
+ * 1 indicates that the special attention was NOT successfully handled
*/
int handleSpecial(Attention* i_attention);
@@ -45,7 +50,7 @@
*
* @param i_breakpoints true = breakpoint special attn handling enabled
*/
-void attnHandler(const bool i_breakpoints)
+void attnHandler(Config* i_config)
{
// Vector of active attentions to be handled
std::vector<Attention> active_attentions;
@@ -94,9 +99,8 @@
// bit 0 on "left": bit 30 = SBE vital attention
if (isr_val & isr_mask & 0x00000002)
{
- active_attentions.emplace_back(Attention::Vital,
- handleVital, target,
- i_breakpoints);
+ active_attentions.emplace_back(
+ Attention::Vital, handleVital, target, i_config);
}
// bit 0 on "left": bit 1 = checkstop
@@ -104,7 +108,7 @@
{
active_attentions.emplace_back(Attention::Checkstop,
handleCheckstop, target,
- i_breakpoints);
+ i_config);
}
// bit 0 on "left": bit 2 = special attention
@@ -112,7 +116,7 @@
{
active_attentions.emplace_back(Attention::Special,
handleSpecial, target,
- i_breakpoints);
+ i_config);
}
} // cfam 0x100d valid
} // cfam 0x1007 valid
@@ -144,16 +148,25 @@
/**
* @brief Handle SBE vital attention
+ *
+ * @param i_attention Attention object
+ * @return 0 indicates that the vital attention was successfully handled
+ * 1 indicates that the vital attention was NOT successfully handled
*/
int handleVital(Attention* i_attention)
{
- int rc = RC_NOT_SUCCESS; // vital attention handling not yet supported
+ int rc = RC_SUCCESS; // assume vital handled
- log<level::INFO>("vital");
-
- if (RC_SUCCESS != rc)
+ // if vital handling enabled, handle vital attention
+ if (false == (i_attention->getConfig()->getFlag(enVital)))
+ {
+ log<level::INFO>("vital handling disabled");
+ rc = RC_NOT_SUCCESS;
+ }
+ else
{
log<level::INFO>("vital NOT handled");
+ rc = RC_NOT_SUCCESS;
}
return rc;
@@ -161,50 +174,71 @@
/**
* @brief Handle checkstop attention
+ *
+ * @param i_attention Attention object
+ * @return 0 indicates that the checkstop attention was successfully handled
+ * 1 indicates that the checkstop attention was NOT successfully
+ * handled.
*/
int handleCheckstop(Attention* i_attention)
{
- int rc = RC_SUCCESS; // checkstop handling supported
+ int rc = RC_SUCCESS; // assume checkstop handled
- log<level::INFO>("checkstop");
-
- analyzer::analyzeHardware();
+ // if checkstop handling enabled, handle checkstop attention
+ if (false == (i_attention->getConfig()->getFlag(enCheckstop)))
+ {
+ log<level::INFO>("Checkstop handling disabled");
+ rc = RC_NOT_SUCCESS;
+ }
+ else
+ {
+ analyzer::analyzeHardware();
+ rc = RC_SUCCESS;
+ }
return rc;
}
/**
* @brief Handle special attention
+ *
+ * @param i_attention Attention object
+ * @return 0 indicates that the special attention was successfully handled
+ * 1 indicates that the special attention was NOT successfully handled
*/
int handleSpecial(Attention* i_attention)
{
- int rc = RC_SUCCESS; // special attention handling supported
+ int rc = RC_NOT_SUCCESS; // assume special attention handling disabled
- log<level::INFO>("special");
+ // Until the special attention chipop is availabe we will treat the special
+ // attention as a TI. If TI handling is disabled we will treat the special
+ // attention as a breakpopint.
- // 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 (0 != (i_attention->getFlags() & enableBreakpoints))
- {
- log<level::INFO>("breakpoint");
-
- // Call the breakpoint special attention handler
- bpHandler();
- }
- // 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
+ // TI attention gets priority over breakpoints, if enabled then handle
+ if (true == (i_attention->getConfig()->getFlag(enTerminate)))
{
log<level::INFO>("TI (terminate immediately)");
// Call TI special attention handler
tiHandler();
+ rc = RC_SUCCESS;
+ }
+ else
+ {
+ if (true == (i_attention->getConfig()->getFlag(enBreakpoints)))
+ {
+ log<level::INFO>("breakpoint");
+
+ // Call the breakpoint special attention handler
+ bpHandler();
+ rc = RC_SUCCESS;
+ }
}
- // TODO recoverable errors?
+ if (RC_SUCCESS != rc)
+ {
+ log<level::INFO>("Special attn handling disabled");
+ }
return rc;
}
diff --git a/attn/attn_handler.hpp b/attn/attn_handler.hpp
index 5bfe995..f81a9e7 100644
--- a/attn/attn_handler.hpp
+++ b/attn/attn_handler.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include <attn/attn_config.hpp>
+
namespace attn
{
@@ -10,19 +12,18 @@
* System Checkstop (checkstop) and Special Attention (special) and handle
* each as follows:
*
- * checkstop: TBD
+ * checkstop: Call hardware error analyzer
* 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
+ * TI: Start host diagnostics mode systemd unit
* Corecode: TBD
- * Recoverable: TBD
*
- * @param i_breakpoints true = breakpoint special attn handling enabled
+ * @param i_config pointer to attention handler configuration object
*/
-void attnHandler(const bool i_breakpoints);
+void attnHandler(Config* i_config);
} // namespace attn
diff --git a/attn/attn_main.cpp b/attn/attn_main.cpp
index 492531b..46455b3 100644
--- a/attn/attn_main.cpp
+++ b/attn/attn_main.cpp
@@ -6,7 +6,7 @@
/**
* @brief Attention handler application main()
*/
-int attnDaemon(bool i_breakpoints)
+int attnDaemon(Config* i_config)
{
int rc = 0; // assume success
@@ -31,8 +31,8 @@
{
// 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,
- i_breakpoints));
+ gpios.push_back(
+ std::make_unique<attn::AttnMonitor>(line, config, io, i_config));
io.run(); // start GPIO monitor
}
diff --git a/attn/attn_main.hpp b/attn/attn_main.hpp
index 4403b45..b0b954b 100644
--- a/attn/attn_main.hpp
+++ b/attn/attn_main.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include <attn/attn_config.hpp>
+
namespace attn
{
@@ -9,10 +11,10 @@
* Request the attention gpio for monitoring and attach the attention handler
* as the gpio event handler.
*
- * @param i_breakpoints enables breakpoint special attn handling
+ * @param i_config pointer to attention handler configuration object
*
* @return 0 == success
*/
-int attnDaemon(bool i_breakpoints);
+int attnDaemon(Config* i_config);
} // namespace attn
diff --git a/attn/attn_monitor.cpp b/attn/attn_monitor.cpp
index eb46978..13b7f15 100644
--- a/attn/attn_monitor.cpp
+++ b/attn/attn_monitor.cpp
@@ -50,7 +50,7 @@
{
// active attention when gpio == 0
case 0:
- attnHandler(iv_breakpoints);
+ attnHandler(iv_config);
break;
// gpio == 1, GPIO handler should not be executing
diff --git a/attn/attn_monitor.hpp b/attn/attn_monitor.hpp
index 251857b..7b70316 100644
--- a/attn/attn_monitor.hpp
+++ b/attn/attn_monitor.hpp
@@ -2,6 +2,7 @@
#include <gpiod.h>
+#include <attn/attn_config.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/asio/posix/stream_descriptor.hpp>
@@ -22,16 +23,16 @@
* The AttnMonitor constructor will create a new object and start
* the objects associated GPIO listener.
*
- * @param line GPIO line handle
- * @param config configuration of line
- * @param io io service
- * @param i_breakpoints true = breakpoint special attn handling enabled
+ * @param line GPIO line handle
+ * @param config configuration of line
+ * @param io io service
+ * @param i_attnConfig poiner to attention handler configuration object
*/
AttnMonitor(gpiod_line* line, gpiod_line_request_config& config,
- boost::asio::io_service& io, bool i_breakpoints) :
+ boost::asio::io_service& io, Config* i_attnConfig) :
iv_gpioLine(line),
iv_gpioConfig(config), iv_gpioEventDescriptor(io),
- iv_breakpoints(i_breakpoints)
+ iv_config(i_attnConfig)
{
requestGPIOEvent(); // registers the event handler
@@ -59,6 +60,9 @@
/** @brief GPIO event descriptor */
boost::asio::posix::stream_descriptor iv_gpioEventDescriptor;
+ /** @brief attention handler configuration object pointer */
+ Config* iv_config;
+
private: // class methods
/** @brief schedule a gpio event handler */
void scheduleGPIOEvent();
@@ -68,9 +72,6 @@
/** @brief register for a gpio event */
void requestGPIOEvent();
-
- /** @brief enable breakpoint special attn handling */
- bool iv_breakpoints;
};
} // namespace attn
diff --git a/attn/meson.build b/attn/meson.build
index 40a3875..6a0bcc2 100644
--- a/attn/meson.build
+++ b/attn/meson.build
@@ -40,7 +40,7 @@
# gather attention sources to be used here and elsewhere if needed
attn_src = files('attn_main.cpp', 'attn_handler.cpp', 'attn_monitor.cpp',
'bp_handler.cpp', 'ti_handler.cpp', logging_src,
- 'attention.cpp')
+ 'attention.cpp', 'attn_config.cpp')
# Create attention handler library
attn = static_library('attn_handler',
diff --git a/main.cpp b/main.cpp
index bb43990..4e73e03 100644
--- a/main.cpp
+++ b/main.cpp
@@ -14,9 +14,21 @@
*
* Command line arguments:
*
- * analyze analyze hardware
- * --daemon load application as a daemon
- * --breakpoints enable breakpoint special attn handling (in daemon mode)
+ * commands:
+ *
+ * analyze analyze hardware
+ *
+ * options:
+ *
+ * --daemon load application as a daemon
+ * --vital off disable vital attention handling (daemon mode)
+ * --checkstop off disable checkstop attention handling (daemon mode)
+ * --terminate off disable TI attention handling (daemon mode)
+ * --breakpoints off disable breakpoint attention handling (daemon mode)
+ *
+ * example:
+ *
+ * openpower-hw-diags --daemon --terminate off
*
* @return 0 = success
*/
@@ -24,22 +36,29 @@
{
int rc = 0; // return code
+ // attention handler configuration flags
+ bool vital_enable = true;
+ bool checkstop_enable = true;
+ bool ti_enable = true;
+ bool bp_enable = true;
+
// initialize pdbg targets
pdbg_targets_init(nullptr);
- // TODO Handle target init fail
+ // get configuration options
+ parseConfig(argv, argv + argc, vital_enable, checkstop_enable, ti_enable,
+ bp_enable);
// check if we are being loaded as a daemon
if (true == getCliOption(argv, argv + argc, "--daemon"))
{
- // Check command line args for breakpoint handling enable option
- bool bp_enable = getCliOption(argv, argv + argc, "--breakpoints");
+ attn::Config config(vital_enable, checkstop_enable, ti_enable,
+ bp_enable);
// Configure and start attention monitor
- attn::attnDaemon(bp_enable);
+ attn::attnDaemon(&config);
}
- // We are being loaded as an application, so parse the command line
- // arguments to determine what operation is being requested.
+ // we are being loaded as an application
else
{
// Request to analyze the hardware for error conditions
diff --git a/test/end2end/main.cpp b/test/end2end/main.cpp
index 3232903..fe637f6 100644
--- a/test/end2end/main.cpp
+++ b/test/end2end/main.cpp
@@ -1,18 +1,32 @@
#include <libpdbg.h>
+#include <attn/attn_config.hpp>
#include <attn/attn_handler.hpp>
+#include <cli.hpp>
-// The attnHandler() function is called when the an attention GPIO event is
-// triggered. We call it here directly to simulatea a GPIO event.
-int main()
+/** @brief Attention handler test application */
+int main(int argc, char* argv[])
{
int rc = 0; // return code
+ // attention handler configuration flags
+ bool vital_enable = true;
+ bool checkstop_enable = true;
+ bool ti_enable = true;
+ bool bp_enable = true;
+
// initialize pdbg targets
pdbg_targets_init(nullptr);
+ // convert cmd line args to config values
+ parseConfig(argv, argv + argc, vital_enable, checkstop_enable, ti_enable,
+ bp_enable);
+
+ // create attention handler config object
+ attn::Config config(vital_enable, checkstop_enable, ti_enable, bp_enable);
+
// exercise attention gpio event path
- attn::attnHandler(false); // false = breakpoint handling disabled
+ attn::attnHandler(&config);
return rc;
}
diff --git a/test/end2end/meson.build b/test/end2end/meson.build
index f2031d6..e672d98 100644
--- a/test/end2end/meson.build
+++ b/test/end2end/meson.build
@@ -1,7 +1,7 @@
# create openpower-hw-diags executable for local testing
executable('openpower-hw-diags-test',
'main.cpp', 'logging.cpp', 'bp_handler.cpp', 'ti_handler.cpp',
- 'analyzer_main.cpp',
+ 'analyzer_main.cpp', '../../cli.cpp',
link_with : [analyzer, attn],
include_directories : incdir,
dependencies : libhei_dep,