blob: f4454cf30822062b7a10f653f524b35de5a3a22d [file] [log] [blame]
Ben Tyner792f32f2020-06-02 08:50:47 -05001#include <libpdbg.h>
2
Ben Tyner0205f3b2020-02-24 10:24:47 -06003#include <analyzer/analyzer_main.hpp>
Ben Tynerb797b3e2020-06-29 10:12:05 -05004#include <attn/attention.hpp>
Ben Tynerbcf65a82020-12-01 08:46:36 -06005#include <attn/attn_common.hpp>
Ben Tynerb797b3e2020-06-29 10:12:05 -05006#include <attn/attn_config.hpp>
Ben Tyner4bbcb382021-02-22 09:29:00 -06007#include <attn/attn_dbus.hpp>
Ben Tynerb797b3e2020-06-29 10:12:05 -05008#include <attn/attn_handler.hpp>
9#include <attn/attn_logging.hpp>
10#include <attn/bp_handler.hpp>
11#include <attn/ti_handler.hpp>
Ben Tynerbcf65a82020-12-01 08:46:36 -060012#include <attn/vital_handler.hpp>
Ben Tyneref320152020-01-09 10:31:23 -060013
Ben Tynerb481d902020-03-05 10:24:23 -060014#include <algorithm>
Ben Tyneref320152020-01-09 10:31:23 -060015#include <iomanip>
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050016#include <map>
Ben Tyner9ae5ca42020-02-28 13:13:50 -060017#include <sstream>
Ben Tynerb481d902020-03-05 10:24:23 -060018#include <vector>
Ben Tyneref320152020-01-09 10:31:23 -060019
20namespace attn
21{
22
23/**
Ben Tyneref320152020-01-09 10:31:23 -060024 * @brief Handle checkstop attention
25 *
Ben Tynerb481d902020-03-05 10:24:23 -060026 * @param i_attention Attention object
Ben Tyner3fb52e52020-03-31 10:10:07 -050027 * @return 0 indicates that the checkstop attention was successfully handled
28 * 1 indicates that the checkstop attention was NOT successfully
29 * handled.
Ben Tyneref320152020-01-09 10:31:23 -060030 */
Ben Tynerb481d902020-03-05 10:24:23 -060031int handleCheckstop(Attention* i_attention);
Ben Tyneref320152020-01-09 10:31:23 -060032
33/**
34 * @brief Handle special attention
35 *
Ben Tynerb481d902020-03-05 10:24:23 -060036 * @param i_attention Attention object
Ben Tyner3fb52e52020-03-31 10:10:07 -050037 * @return 0 indicates that the special attention was successfully handled
38 * 1 indicates that the special attention was NOT successfully handled
Ben Tyneref320152020-01-09 10:31:23 -060039 */
Ben Tynerb481d902020-03-05 10:24:23 -060040int handleSpecial(Attention* i_attention);
Ben Tyneref320152020-01-09 10:31:23 -060041
Ben Tynerfb190542020-11-06 09:27:56 -060042/** @brief Determine if attention is active and not masked */
Ben Tyner1965e502020-11-20 10:32:24 -060043bool activeAttn(uint32_t i_val, uint32_t i_mask, uint32_t i_attn);
Ben Tynerfb190542020-11-06 09:27:56 -060044
Ben Tyneref320152020-01-09 10:31:23 -060045/**
Ben Tyneref320152020-01-09 10:31:23 -060046 * @brief The main attention handler logic
Ben Tyner970fd4f2020-02-19 13:46:42 -060047 *
48 * @param i_breakpoints true = breakpoint special attn handling enabled
Ben Tyneref320152020-01-09 10:31:23 -060049 */
Ben Tyner3fb52e52020-03-31 10:10:07 -050050void attnHandler(Config* i_config)
Ben Tyneref320152020-01-09 10:31:23 -060051{
Ben Tynerb481d902020-03-05 10:24:23 -060052 // Vector of active attentions to be handled
53 std::vector<Attention> active_attentions;
54
Ben Tyneref320152020-01-09 10:31:23 -060055 uint32_t isr_val, isr_mask;
Ben Tyneref320152020-01-09 10:31:23 -060056
57 // loop through processors looking for active attentions
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050058 trace<level::INFO>("Attention handler started");
Ben Tyner117af992020-05-22 13:32:11 -050059
Ben Tyneref320152020-01-09 10:31:23 -060060 pdbg_target* target;
Ben Tyner5e622d82020-09-11 10:10:24 -050061 pdbg_for_each_class_target("proc", target)
Ben Tyneref320152020-01-09 10:31:23 -060062 {
63 if (PDBG_TARGET_ENABLED == pdbg_target_probe(target))
64 {
Zane Shelleya79f6c82021-01-12 16:38:49 -060065 auto proc = pdbg_target_index(target); // get processor number
Ben Tyneref320152020-01-09 10:31:23 -060066
Ben Tynerb83c8522020-11-20 10:45:26 -060067 // Use PIB target to determine if a processor is enabled
Ben Tyner5e622d82020-09-11 10:10:24 -050068 char path[16];
Ben Tynerb83c8522020-11-20 10:45:26 -060069 sprintf(path, "/proc%d/pib", proc);
Ben Tyner8882c322021-02-05 12:13:21 -060070 pdbg_target* pibTarget = pdbg_target_from_path(nullptr, path);
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050071
Ben Tynerb83c8522020-11-20 10:45:26 -060072 // sanity check
Ben Tyner8882c322021-02-05 12:13:21 -060073 if (nullptr == pibTarget)
Ben Tynerb83c8522020-11-20 10:45:26 -060074 {
75 trace<level::INFO>("pib path or target not found");
76 continue;
77 }
78
Ben Tyner8882c322021-02-05 12:13:21 -060079 // check if pib target is enabled
80 if (PDBG_TARGET_ENABLED == pdbg_target_probe(pibTarget))
Ben Tyneref320152020-01-09 10:31:23 -060081 {
Ben Tynerb83c8522020-11-20 10:45:26 -060082 // The processor FSI target is required for CFAM read
83 sprintf(path, "/proc%d/fsi", proc);
Ben Tyner8882c322021-02-05 12:13:21 -060084 pdbg_target* fsiTarget = pdbg_target_from_path(nullptr, path);
Ben Tynerb83c8522020-11-20 10:45:26 -060085
86 // sanity check
Ben Tyner8882c322021-02-05 12:13:21 -060087 if (nullptr == fsiTarget)
Ben Tynerb83c8522020-11-20 10:45:26 -060088 {
89 trace<level::INFO>("fsi path or target not found");
90 continue;
91 }
92
Ben Tyner8882c322021-02-05 12:13:21 -060093 // trace the proc number
94 std::string traceMsg = "proc: " + std::to_string(proc);
95 trace<level::INFO>(traceMsg.c_str());
Ben Tyner1965e502020-11-20 10:32:24 -060096
Ben Tyner5adc96e2020-11-20 10:54:12 -060097 isr_val = 0xffffffff; // invalid isr value
98
Ben Tyner5e622d82020-09-11 10:10:24 -050099 // get active attentions on processor
Ben Tyner8882c322021-02-05 12:13:21 -0600100 if (RC_SUCCESS != fsi_read(fsiTarget, 0x1007, &isr_val))
Ben Tyneref320152020-01-09 10:31:23 -0600101 {
Ben Tynerfb190542020-11-06 09:27:56 -0600102 // log cfam read error
Ben Tyner5e622d82020-09-11 10:10:24 -0500103 trace<level::INFO>("Error! cfam read 0x1007 FAILED");
Ben Tyner7a0dd542021-02-12 09:33:44 -0600104 eventAttentionFail((int)AttnSection::attnHandler |
105 ATTN_PDBG_CFAM);
Ben Tyneref320152020-01-09 10:31:23 -0600106 }
Ben Tyner5adc96e2020-11-20 10:54:12 -0600107 else if (0xffffffff == isr_val)
108 {
109 trace<level::INFO>("Error! cfam read 0x1007 INVALID");
110 continue;
111 }
Ben Tyneref320152020-01-09 10:31:23 -0600112 else
113 {
Ben Tyner8882c322021-02-05 12:13:21 -0600114 // trace isr value
115 std::stringstream ssIsr;
116 ssIsr << "cfam 0x1007 = 0x" << std::setw(8)
117 << std::setfill('0') << std::hex << isr_val;
118 std::string strobjIsr = ssIsr.str();
119 trace<level::INFO>(strobjIsr.c_str());
Ben Tyner1965e502020-11-20 10:32:24 -0600120
Ben Tyner5adc96e2020-11-20 10:54:12 -0600121 isr_mask = 0xffffffff; // invalid isr mask
122
Ben Tyner5e622d82020-09-11 10:10:24 -0500123 // get interrupt enabled special attentions mask
Ben Tyner8882c322021-02-05 12:13:21 -0600124 if (RC_SUCCESS != fsi_read(fsiTarget, 0x100d, &isr_mask))
Ben Tyneref320152020-01-09 10:31:23 -0600125 {
Ben Tynerfb190542020-11-06 09:27:56 -0600126 // log cfam read error
Ben Tyner5e622d82020-09-11 10:10:24 -0500127 trace<level::INFO>("Error! cfam read 0x100d FAILED");
Ben Tyner7a0dd542021-02-12 09:33:44 -0600128 eventAttentionFail((int)AttnSection::attnHandler |
129 ATTN_PDBG_CFAM);
Ben Tyneref320152020-01-09 10:31:23 -0600130 }
Ben Tyner5adc96e2020-11-20 10:54:12 -0600131 else if (0xffffffff == isr_mask)
132 {
133 trace<level::INFO>("Error! cfam read 0x100d INVALID");
134 continue;
135 }
Ben Tyner5e622d82020-09-11 10:10:24 -0500136 else
137 {
Ben Tyner8882c322021-02-05 12:13:21 -0600138 // trace true mask
139 std::stringstream ssMask;
140 ssMask << "cfam 0x100d = 0x" << std::setw(8)
141 << std::setfill('0') << std::hex << isr_mask;
142 std::string strobjMask = ssMask.str();
143 trace<level::INFO>(strobjMask.c_str());
Ben Tyner1965e502020-11-20 10:32:24 -0600144
Ben Tynerfb190542020-11-06 09:27:56 -0600145 // SBE vital attention active and not masked?
Ben Tyner1965e502020-11-20 10:32:24 -0600146 if (true == activeAttn(isr_val, isr_mask, SBE_ATTN))
Ben Tyner5e622d82020-09-11 10:10:24 -0500147 {
148 active_attentions.emplace_back(Attention::Vital,
149 handleVital, target,
150 i_config);
151 }
152
Ben Tynerfb190542020-11-06 09:27:56 -0600153 // Checkstop attention active and not masked?
154 if (true ==
Ben Tyner1965e502020-11-20 10:32:24 -0600155 activeAttn(isr_val, isr_mask, CHECKSTOP_ATTN))
Ben Tyner5e622d82020-09-11 10:10:24 -0500156 {
157 active_attentions.emplace_back(Attention::Checkstop,
158 handleCheckstop,
159 target, i_config);
160 }
161
Ben Tynerfb190542020-11-06 09:27:56 -0600162 // Special attention active and not masked?
Ben Tyner1965e502020-11-20 10:32:24 -0600163 if (true == activeAttn(isr_val, isr_mask, SPECIAL_ATTN))
Ben Tyner5e622d82020-09-11 10:10:24 -0500164 {
165 active_attentions.emplace_back(Attention::Special,
166 handleSpecial,
167 target, i_config);
168 }
169 } // cfam 0x100d valid
170 } // cfam 0x1007 valid
Ben Tyner8882c322021-02-05 12:13:21 -0600171 } // fsi target enabled
172 } // pib target enabled
Ben Tyner5e622d82020-09-11 10:10:24 -0500173 } // next processor
Ben Tyneref320152020-01-09 10:31:23 -0600174
Ben Tynerb481d902020-03-05 10:24:23 -0600175 // convert to heap, highest priority is at front
176 if (!std::is_heap(active_attentions.begin(), active_attentions.end()))
177 {
178 std::make_heap(active_attentions.begin(), active_attentions.end());
179 }
180
181 // call the attention handler until one is handled or all were attempted
182 while (false == active_attentions.empty())
183 {
184 // handle highest priority attention, done if successful
185 if (RC_SUCCESS == active_attentions.front().handle())
186 {
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500187 // an attention was handled so we are done
Ben Tynerb481d902020-03-05 10:24:23 -0600188 break;
189 }
190
191 // move attention to back of vector
192 std::pop_heap(active_attentions.begin(), active_attentions.end());
193
194 // remove attention from vector
195 active_attentions.pop_back();
196 }
Ben Tyneref320152020-01-09 10:31:23 -0600197}
198
199/**
Ben Tyneref320152020-01-09 10:31:23 -0600200 * @brief Handle checkstop attention
Ben Tyner3fb52e52020-03-31 10:10:07 -0500201 *
202 * @param i_attention Attention object
203 * @return 0 indicates that the checkstop attention was successfully handled
204 * 1 indicates that the checkstop attention was NOT successfully
205 * handled.
Ben Tyneref320152020-01-09 10:31:23 -0600206 */
Ben Tynerb481d902020-03-05 10:24:23 -0600207int handleCheckstop(Attention* i_attention)
Ben Tyneref320152020-01-09 10:31:23 -0600208{
Ben Tyner3fb52e52020-03-31 10:10:07 -0500209 int rc = RC_SUCCESS; // assume checkstop handled
Ben Tyneref320152020-01-09 10:31:23 -0600210
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500211 trace<level::INFO>("checkstop handler started");
212
Ben Tyner3fb52e52020-03-31 10:10:07 -0500213 // if checkstop handling enabled, handle checkstop attention
214 if (false == (i_attention->getConfig()->getFlag(enCheckstop)))
215 {
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500216 trace<level::INFO>("Checkstop handling disabled");
Ben Tyner3fb52e52020-03-31 10:10:07 -0500217 }
218 else
219 {
Zane Shelley9fb73932020-09-15 13:34:57 -0500220 // Look for any attentions found in hardware. This will generate and
Zane Shelley7ae9c8c2020-12-02 20:10:31 -0600221 // commit a PEL if any errors are found.
Zane Shelley9fb73932020-09-15 13:34:57 -0500222 if (true != analyzer::analyzeHardware())
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500223 {
224 rc = RC_ANALYZER_ERROR;
225 }
Ben Tyner3fb52e52020-03-31 10:10:07 -0500226 }
Ben Tyneref320152020-01-09 10:31:23 -0600227
Ben Tyneref320152020-01-09 10:31:23 -0600228 return rc;
229}
230
231/**
232 * @brief Handle special attention
Ben Tyner3fb52e52020-03-31 10:10:07 -0500233 *
234 * @param i_attention Attention object
235 * @return 0 indicates that the special attention was successfully handled
236 * 1 indicates that the special attention was NOT successfully handled
Ben Tyneref320152020-01-09 10:31:23 -0600237 */
Ben Tynerb481d902020-03-05 10:24:23 -0600238int handleSpecial(Attention* i_attention)
Ben Tyneref320152020-01-09 10:31:23 -0600239{
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500240 int rc = RC_SUCCESS; // assume special attention handled
Ben Tyneref320152020-01-09 10:31:23 -0600241
Ben Tynerfb190542020-11-06 09:27:56 -0600242 // The TI info chipop will give us a pointer to the TI info data
Ben Tyner98430b32020-08-19 19:14:02 -0500243 uint8_t* tiInfo = nullptr; // ptr to TI info data
244 uint32_t tiInfoLen = 0; // length of TI info data
245 pdbg_target* attnProc = i_attention->getTarget(); // proc with attention
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500246
Ben Tyner29651ef2021-02-08 10:51:03 -0600247 bool tiInfoStatic = false; // assume TI info was provided (not created)
248
Ben Tyner98430b32020-08-19 19:14:02 -0500249 if (attnProc != nullptr)
Ben Tyner89c0a7a2020-08-07 12:07:35 -0500250 {
Ben Tyner98430b32020-08-19 19:14:02 -0500251 // The processor PIB target is required for get TI info chipop
252 char path[16];
253 sprintf(path, "/proc%d/pib", pdbg_target_index(attnProc));
254 pdbg_target* tiInfoTarget = pdbg_target_from_path(nullptr, path);
255
256 if (nullptr != tiInfoTarget)
Ben Tyner89c0a7a2020-08-07 12:07:35 -0500257 {
Ben Tyner98430b32020-08-19 19:14:02 -0500258 if (PDBG_TARGET_ENABLED == pdbg_target_probe(tiInfoTarget))
259 {
Ben Tyner98430b32020-08-19 19:14:02 -0500260 sbe_mpipl_get_ti_info(tiInfoTarget, &tiInfo, &tiInfoLen);
Ben Tyner4bbcb382021-02-22 09:29:00 -0600261
262 // If TI info not available use default based on host state
263 if (nullptr == tiInfo)
Ben Tyner98430b32020-08-19 19:14:02 -0500264 {
Ben Tyner4bbcb382021-02-22 09:29:00 -0600265 trace<level::INFO>("TI info data ptr is invalid");
266
267 HostRunningState runningState = hostRunningState();
268 std::string stateString = "host state unknown";
269
270 if ((HostRunningState::Started == runningState) ||
271 (HostRunningState::Unknown == runningState))
272 {
273 if (HostRunningState::Started == runningState)
274 {
275 stateString = "host started";
276 }
277 tiInfo = (uint8_t*)defaultPhypTiInfo;
278 }
279 else
280 {
281 stateString = "host not started";
282 tiInfo = (uint8_t*)defaultHbTiInfo;
283 }
284
285 // trace host state
286 trace<level::INFO>(stateString.c_str());
287
Ben Tyner29651ef2021-02-08 10:51:03 -0600288 tiInfoStatic = true; // using our TI info
Ben Tyner98430b32020-08-19 19:14:02 -0500289 }
290 }
Ben Tyner89c0a7a2020-08-07 12:07:35 -0500291 }
292 }
Ben Tyneref320152020-01-09 10:31:23 -0600293
Ben Tyner0fe5df42020-12-03 08:57:17 -0600294 bool tiInfoValid = false; // TI area data not valid or not available
295
Ben Tyner792f32f2020-06-02 08:50:47 -0500296 // If TI area exists and is marked valid we can assume TI occurred
297 if ((nullptr != tiInfo) && (0 != tiInfo[0]))
Ben Tyner970fd4f2020-02-19 13:46:42 -0600298 {
Ben Tyner792f32f2020-06-02 08:50:47 -0500299 TiDataArea* tiDataArea = (TiDataArea*)tiInfo;
Ben Tyner7e6611f2020-02-13 16:42:56 -0600300
Ben Tyner8882c322021-02-05 12:13:21 -0600301 std::stringstream ss; // string stream object for tracing
302 std::string strobj; // string object for tracing
Ben Tyner40717722020-09-23 09:43:20 -0500303
Ben Tyner8882c322021-02-05 12:13:21 -0600304 // trace a few known TI data area values
305 ss.str(std::string()); // empty the stream
306 ss.clear(); // clear the stream
307 ss << "TI data command = 0x" << std::setw(2) << std::setfill('0')
308 << std::hex << (int)tiDataArea->command;
309 strobj = ss.str();
310 trace<level::INFO>(strobj.c_str());
Ben Tyner40717722020-09-23 09:43:20 -0500311
Ben Tyner0fe5df42020-12-03 08:57:17 -0600312 // Another check for valid TI Info since it has been seen that
313 // tiInfo[0] != 0 but TI info is not valid
314 if (0xa1 == tiDataArea->command)
Ben Tyner792f32f2020-06-02 08:50:47 -0500315 {
Ben Tyner0fe5df42020-12-03 08:57:17 -0600316 tiInfoValid = true;
317
318 // trace some more data since TI info appears valid
Ben Tyner8882c322021-02-05 12:13:21 -0600319 ss.str(std::string()); // empty the stream
320 ss.clear(); // clear the stream
Ben Tyner7a0dd542021-02-12 09:33:44 -0600321 ss << "TI data term-type = 0x" << std::setw(2) << std::setfill('0')
322 << std::hex << (int)tiDataArea->hbTerminateType;
Ben Tyner8882c322021-02-05 12:13:21 -0600323 strobj = ss.str();
324 trace<level::INFO>(strobj.c_str());
Ben Tyner0fe5df42020-12-03 08:57:17 -0600325
Ben Tyner8882c322021-02-05 12:13:21 -0600326 ss.str(std::string()); // empty the stream
327 ss.clear(); // clear the stream
328 ss << "TI data SRC format = 0x" << std::setw(2) << std::setfill('0')
329 << std::hex << (int)tiDataArea->srcFormat;
330 strobj = ss.str();
331 trace<level::INFO>(strobj.c_str());
Ben Tyner0fe5df42020-12-03 08:57:17 -0600332
Ben Tyner8882c322021-02-05 12:13:21 -0600333 ss.str(std::string()); // empty the stream
334 ss.clear(); // clear the stream
335 ss << "TI data source = 0x" << std::setw(2) << std::setfill('0')
336 << std::hex << (int)tiDataArea->source;
337 strobj = ss.str();
338 trace<level::INFO>(strobj.c_str());
Ben Tyner0fe5df42020-12-03 08:57:17 -0600339
340 if (true == (i_attention->getConfig()->getFlag(enTerminate)))
341 {
342 // Call TI special attention handler
343 rc = tiHandler(tiDataArea);
344 }
Ben Tyner792f32f2020-06-02 08:50:47 -0500345 }
Ben Tyner3fb52e52020-03-31 10:10:07 -0500346 }
Ben Tyner0fe5df42020-12-03 08:57:17 -0600347
348 // If TI area not valid or not available
349 if (false == tiInfoValid)
Ben Tyner3fb52e52020-03-31 10:10:07 -0500350 {
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500351 trace<level::INFO>("TI info NOT available");
Ben Tyner98430b32020-08-19 19:14:02 -0500352
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500353 // if configured to handle breakpoint as default special attention
354 if (i_attention->getConfig()->getFlag(dfltBreakpoint))
Ben Tyner3fb52e52020-03-31 10:10:07 -0500355 {
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500356 if (true == (i_attention->getConfig()->getFlag(enBreakpoints)))
357 {
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500358 // Call the breakpoint special attention handler
359 bpHandler();
360 }
361 }
362 // if configured to handle TI as default special attention
363 else
364 {
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500365 if (true == (i_attention->getConfig()->getFlag(enTerminate)))
366 {
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500367 // Call TI special attention handler
368 rc = tiHandler(nullptr);
369 }
Ben Tyner3fb52e52020-03-31 10:10:07 -0500370 }
Ben Tyner970fd4f2020-02-19 13:46:42 -0600371 }
Ben Tyneref320152020-01-09 10:31:23 -0600372
Ben Tyner792f32f2020-06-02 08:50:47 -0500373 // release TI data buffer
Ben Tyner29651ef2021-02-08 10:51:03 -0600374 if ((nullptr != tiInfo) && (false == tiInfoStatic))
Ben Tyner792f32f2020-06-02 08:50:47 -0500375 {
376 free(tiInfo);
377 }
378
Ben Tyner3fb52e52020-03-31 10:10:07 -0500379 if (RC_SUCCESS != rc)
380 {
Ben Tyner792f32f2020-06-02 08:50:47 -0500381 trace<level::INFO>("Special attn not handled");
Ben Tyner3fb52e52020-03-31 10:10:07 -0500382 }
Ben Tyneref320152020-01-09 10:31:23 -0600383
384 return rc;
385}
386
Ben Tynerfb190542020-11-06 09:27:56 -0600387/**
388 * @brief Determine if attention is active and not masked
389 *
390 * Determine whether an attention needs to be handled and trace details of
391 * attention type and whether it is masked or not.
392 *
393 * @param i_val attention status register
394 * @param i_mask attention true mask register
395 * @param i_attn attention type
396 * @param i_proc processor associated with registers
397 *
398 * @return true if attention is active and not masked, otherwise false
399 */
Ben Tyner1965e502020-11-20 10:32:24 -0600400bool activeAttn(uint32_t i_val, uint32_t i_mask, uint32_t i_attn)
Ben Tynerfb190542020-11-06 09:27:56 -0600401{
Zane Shelley9fb657f2021-01-12 15:30:58 -0600402 bool rc = false; // assume attn masked and/or inactive
Ben Tynerfb190542020-11-06 09:27:56 -0600403
404 // if attention active
405 if (0 != (i_val & i_attn))
406 {
Ben Tynerfb190542020-11-06 09:27:56 -0600407 std::stringstream ss;
Ben Tynerfb190542020-11-06 09:27:56 -0600408
Zane Shelley9fb657f2021-01-12 15:30:58 -0600409 bool validAttn = true; // known attention type
410
Ben Tynerfb190542020-11-06 09:27:56 -0600411 switch (i_attn)
412 {
413 case SBE_ATTN:
414 ss << "SBE attn";
415 break;
416 case CHECKSTOP_ATTN:
417 ss << "Checkstop attn";
418 break;
419 case SPECIAL_ATTN:
420 ss << "Special attn";
421 break;
422 default:
423 ss << "Unknown attn";
424 validAttn = false;
425 }
426
427 // see if attention is masked
428 if (true == validAttn)
429 {
430 if (0 != (i_mask & i_attn))
431 {
432 rc = true; // attention active and not masked
433 }
434 else
435 {
436 ss << " masked";
437 }
438 }
439
Ben Tyner8882c322021-02-05 12:13:21 -0600440 std::string strobj = ss.str(); // ss.str() is temporary
441 trace<level::INFO>(strobj.c_str()); // commit trace stream
Ben Tynerfb190542020-11-06 09:27:56 -0600442 }
443
444 return rc;
445}
446
Ben Tyneref320152020-01-09 10:31:23 -0600447} // namespace attn