blob: c1a4b484b68c03953087b3460f4029fb047645ba [file] [log] [blame]
Jayanth Othayothb1eda6a2021-06-28 00:26:30 -05001extern "C"
2{
Ben Tyner792f32f2020-06-02 08:50:47 -05003#include <libpdbg.h>
Jayanth Othayothb1eda6a2021-06-28 00:26:30 -05004#include <libpdbg_sbe.h>
5}
Ben Tyner792f32f2020-06-02 08:50:47 -05006
Ben Tyner0205f3b2020-02-24 10:24:47 -06007#include <analyzer/analyzer_main.hpp>
Ben Tynerb797b3e2020-06-29 10:12:05 -05008#include <attn/attention.hpp>
Ben Tynerbcf65a82020-12-01 08:46:36 -06009#include <attn/attn_common.hpp>
Ben Tynerb797b3e2020-06-29 10:12:05 -050010#include <attn/attn_config.hpp>
Ben Tyner4bbcb382021-02-22 09:29:00 -060011#include <attn/attn_dbus.hpp>
Ben Tynerb797b3e2020-06-29 10:12:05 -050012#include <attn/attn_handler.hpp>
13#include <attn/attn_logging.hpp>
14#include <attn/bp_handler.hpp>
15#include <attn/ti_handler.hpp>
Ben Tynerbcf65a82020-12-01 08:46:36 -060016#include <attn/vital_handler.hpp>
Ben Tyneref320152020-01-09 10:31:23 -060017
Ben Tynerb481d902020-03-05 10:24:23 -060018#include <algorithm>
Ben Tyneref320152020-01-09 10:31:23 -060019#include <iomanip>
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050020#include <map>
Ben Tyner9ae5ca42020-02-28 13:13:50 -060021#include <sstream>
Ben Tynerb481d902020-03-05 10:24:23 -060022#include <vector>
Ben Tyneref320152020-01-09 10:31:23 -060023
24namespace attn
25{
26
27/**
Ben Tyneref320152020-01-09 10:31:23 -060028 * @brief Handle checkstop attention
29 *
Ben Tynerb481d902020-03-05 10:24:23 -060030 * @param i_attention Attention object
Ben Tyner3fb52e52020-03-31 10:10:07 -050031 * @return 0 indicates that the checkstop attention was successfully handled
32 * 1 indicates that the checkstop attention was NOT successfully
33 * handled.
Ben Tyneref320152020-01-09 10:31:23 -060034 */
Ben Tynerb481d902020-03-05 10:24:23 -060035int handleCheckstop(Attention* i_attention);
Ben Tyneref320152020-01-09 10:31:23 -060036
37/**
38 * @brief Handle special attention
39 *
Ben Tynerb481d902020-03-05 10:24:23 -060040 * @param i_attention Attention object
Ben Tyner3fb52e52020-03-31 10:10:07 -050041 * @return 0 indicates that the special attention was successfully handled
42 * 1 indicates that the special attention was NOT successfully handled
Ben Tyneref320152020-01-09 10:31:23 -060043 */
Ben Tynerb481d902020-03-05 10:24:23 -060044int handleSpecial(Attention* i_attention);
Ben Tyneref320152020-01-09 10:31:23 -060045
Ben Tynerfb190542020-11-06 09:27:56 -060046/** @brief Determine if attention is active and not masked */
Ben Tyner1965e502020-11-20 10:32:24 -060047bool activeAttn(uint32_t i_val, uint32_t i_mask, uint32_t i_attn);
Ben Tynerfb190542020-11-06 09:27:56 -060048
Ben Tyneref320152020-01-09 10:31:23 -060049/**
Ben Tyneref320152020-01-09 10:31:23 -060050 * @brief The main attention handler logic
Ben Tyner970fd4f2020-02-19 13:46:42 -060051 *
52 * @param i_breakpoints true = breakpoint special attn handling enabled
Ben Tyneref320152020-01-09 10:31:23 -060053 */
Ben Tyner3fb52e52020-03-31 10:10:07 -050054void attnHandler(Config* i_config)
Ben Tyneref320152020-01-09 10:31:23 -060055{
Ben Tynerb481d902020-03-05 10:24:23 -060056 // Vector of active attentions to be handled
57 std::vector<Attention> active_attentions;
58
Ben Tyneref320152020-01-09 10:31:23 -060059 uint32_t isr_val, isr_mask;
Ben Tyneref320152020-01-09 10:31:23 -060060
61 // loop through processors looking for active attentions
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050062 trace<level::INFO>("Attention handler started");
Ben Tyner117af992020-05-22 13:32:11 -050063
Ben Tyneref320152020-01-09 10:31:23 -060064 pdbg_target* target;
Ben Tyner5e622d82020-09-11 10:10:24 -050065 pdbg_for_each_class_target("proc", target)
Ben Tyneref320152020-01-09 10:31:23 -060066 {
67 if (PDBG_TARGET_ENABLED == pdbg_target_probe(target))
68 {
Zane Shelleya79f6c82021-01-12 16:38:49 -060069 auto proc = pdbg_target_index(target); // get processor number
Ben Tyneref320152020-01-09 10:31:23 -060070
Ben Tynerb83c8522020-11-20 10:45:26 -060071 // Use PIB target to determine if a processor is enabled
Ben Tyner5e622d82020-09-11 10:10:24 -050072 char path[16];
Ben Tynerb83c8522020-11-20 10:45:26 -060073 sprintf(path, "/proc%d/pib", proc);
Ben Tyner8882c322021-02-05 12:13:21 -060074 pdbg_target* pibTarget = pdbg_target_from_path(nullptr, path);
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050075
Ben Tynerb83c8522020-11-20 10:45:26 -060076 // sanity check
Ben Tyner8882c322021-02-05 12:13:21 -060077 if (nullptr == pibTarget)
Ben Tynerb83c8522020-11-20 10:45:26 -060078 {
79 trace<level::INFO>("pib path or target not found");
80 continue;
81 }
82
Ben Tyner8882c322021-02-05 12:13:21 -060083 // check if pib target is enabled
84 if (PDBG_TARGET_ENABLED == pdbg_target_probe(pibTarget))
Ben Tyneref320152020-01-09 10:31:23 -060085 {
Ben Tynerb83c8522020-11-20 10:45:26 -060086 // The processor FSI target is required for CFAM read
87 sprintf(path, "/proc%d/fsi", proc);
Ben Tyner8882c322021-02-05 12:13:21 -060088 pdbg_target* fsiTarget = pdbg_target_from_path(nullptr, path);
Ben Tynerb83c8522020-11-20 10:45:26 -060089
90 // sanity check
Ben Tyner8882c322021-02-05 12:13:21 -060091 if (nullptr == fsiTarget)
Ben Tynerb83c8522020-11-20 10:45:26 -060092 {
93 trace<level::INFO>("fsi path or target not found");
94 continue;
95 }
96
Ben Tyner8882c322021-02-05 12:13:21 -060097 // trace the proc number
98 std::string traceMsg = "proc: " + std::to_string(proc);
99 trace<level::INFO>(traceMsg.c_str());
Ben Tyner1965e502020-11-20 10:32:24 -0600100
Ben Tyner5adc96e2020-11-20 10:54:12 -0600101 isr_val = 0xffffffff; // invalid isr value
102
Ben Tyner5e622d82020-09-11 10:10:24 -0500103 // get active attentions on processor
Ben Tyner8882c322021-02-05 12:13:21 -0600104 if (RC_SUCCESS != fsi_read(fsiTarget, 0x1007, &isr_val))
Ben Tyneref320152020-01-09 10:31:23 -0600105 {
Ben Tynerfb190542020-11-06 09:27:56 -0600106 // log cfam read error
Ben Tyner5e622d82020-09-11 10:10:24 -0500107 trace<level::INFO>("Error! cfam read 0x1007 FAILED");
Ben Tyner7a0dd542021-02-12 09:33:44 -0600108 eventAttentionFail((int)AttnSection::attnHandler |
109 ATTN_PDBG_CFAM);
Ben Tyneref320152020-01-09 10:31:23 -0600110 }
Ben Tyner5adc96e2020-11-20 10:54:12 -0600111 else if (0xffffffff == isr_val)
112 {
113 trace<level::INFO>("Error! cfam read 0x1007 INVALID");
114 continue;
115 }
Ben Tyneref320152020-01-09 10:31:23 -0600116 else
117 {
Ben Tyner8882c322021-02-05 12:13:21 -0600118 // trace isr value
119 std::stringstream ssIsr;
120 ssIsr << "cfam 0x1007 = 0x" << std::setw(8)
121 << std::setfill('0') << std::hex << isr_val;
122 std::string strobjIsr = ssIsr.str();
123 trace<level::INFO>(strobjIsr.c_str());
Ben Tyner1965e502020-11-20 10:32:24 -0600124
Ben Tyner5adc96e2020-11-20 10:54:12 -0600125 isr_mask = 0xffffffff; // invalid isr mask
126
Ben Tyner5e622d82020-09-11 10:10:24 -0500127 // get interrupt enabled special attentions mask
Ben Tyner8882c322021-02-05 12:13:21 -0600128 if (RC_SUCCESS != fsi_read(fsiTarget, 0x100d, &isr_mask))
Ben Tyneref320152020-01-09 10:31:23 -0600129 {
Ben Tynerfb190542020-11-06 09:27:56 -0600130 // log cfam read error
Ben Tyner5e622d82020-09-11 10:10:24 -0500131 trace<level::INFO>("Error! cfam read 0x100d FAILED");
Ben Tyner7a0dd542021-02-12 09:33:44 -0600132 eventAttentionFail((int)AttnSection::attnHandler |
133 ATTN_PDBG_CFAM);
Ben Tyneref320152020-01-09 10:31:23 -0600134 }
Ben Tyner5adc96e2020-11-20 10:54:12 -0600135 else if (0xffffffff == isr_mask)
136 {
137 trace<level::INFO>("Error! cfam read 0x100d INVALID");
138 continue;
139 }
Ben Tyner5e622d82020-09-11 10:10:24 -0500140 else
141 {
Ben Tyner8882c322021-02-05 12:13:21 -0600142 // trace true mask
143 std::stringstream ssMask;
144 ssMask << "cfam 0x100d = 0x" << std::setw(8)
145 << std::setfill('0') << std::hex << isr_mask;
146 std::string strobjMask = ssMask.str();
147 trace<level::INFO>(strobjMask.c_str());
Ben Tyner1965e502020-11-20 10:32:24 -0600148
Ben Tynerfb190542020-11-06 09:27:56 -0600149 // SBE vital attention active and not masked?
Ben Tyner1965e502020-11-20 10:32:24 -0600150 if (true == activeAttn(isr_val, isr_mask, SBE_ATTN))
Ben Tyner5e622d82020-09-11 10:10:24 -0500151 {
152 active_attentions.emplace_back(Attention::Vital,
153 handleVital, target,
154 i_config);
155 }
156
Ben Tynerfb190542020-11-06 09:27:56 -0600157 // Checkstop attention active and not masked?
158 if (true ==
Ben Tyner1965e502020-11-20 10:32:24 -0600159 activeAttn(isr_val, isr_mask, CHECKSTOP_ATTN))
Ben Tyner5e622d82020-09-11 10:10:24 -0500160 {
161 active_attentions.emplace_back(Attention::Checkstop,
162 handleCheckstop,
163 target, i_config);
164 }
165
Ben Tynerfb190542020-11-06 09:27:56 -0600166 // Special attention active and not masked?
Ben Tyner1965e502020-11-20 10:32:24 -0600167 if (true == activeAttn(isr_val, isr_mask, SPECIAL_ATTN))
Ben Tyner5e622d82020-09-11 10:10:24 -0500168 {
169 active_attentions.emplace_back(Attention::Special,
170 handleSpecial,
171 target, i_config);
172 }
173 } // cfam 0x100d valid
174 } // cfam 0x1007 valid
Ben Tyner8882c322021-02-05 12:13:21 -0600175 } // fsi target enabled
176 } // pib target enabled
Ben Tyner5e622d82020-09-11 10:10:24 -0500177 } // next processor
Ben Tyneref320152020-01-09 10:31:23 -0600178
Ben Tynerb481d902020-03-05 10:24:23 -0600179 // convert to heap, highest priority is at front
180 if (!std::is_heap(active_attentions.begin(), active_attentions.end()))
181 {
182 std::make_heap(active_attentions.begin(), active_attentions.end());
183 }
184
185 // call the attention handler until one is handled or all were attempted
186 while (false == active_attentions.empty())
187 {
188 // handle highest priority attention, done if successful
189 if (RC_SUCCESS == active_attentions.front().handle())
190 {
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500191 // an attention was handled so we are done
Ben Tynerb481d902020-03-05 10:24:23 -0600192 break;
193 }
194
195 // move attention to back of vector
196 std::pop_heap(active_attentions.begin(), active_attentions.end());
197
198 // remove attention from vector
199 active_attentions.pop_back();
200 }
Ben Tyneref320152020-01-09 10:31:23 -0600201}
202
203/**
Ben Tyneref320152020-01-09 10:31:23 -0600204 * @brief Handle checkstop attention
Ben Tyner3fb52e52020-03-31 10:10:07 -0500205 *
206 * @param i_attention Attention object
207 * @return 0 indicates that the checkstop attention was successfully handled
208 * 1 indicates that the checkstop attention was NOT successfully
209 * handled.
Ben Tyneref320152020-01-09 10:31:23 -0600210 */
Ben Tynerb481d902020-03-05 10:24:23 -0600211int handleCheckstop(Attention* i_attention)
Ben Tyneref320152020-01-09 10:31:23 -0600212{
Ben Tyner3fb52e52020-03-31 10:10:07 -0500213 int rc = RC_SUCCESS; // assume checkstop handled
Ben Tyneref320152020-01-09 10:31:23 -0600214
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500215 trace<level::INFO>("checkstop handler started");
216
Ben Tynerb8335562021-07-16 12:43:52 -0500217 // capture some additional data for logs/traces
218 addHbStatusRegs();
219
Ben Tyner3fb52e52020-03-31 10:10:07 -0500220 // if checkstop handling enabled, handle checkstop attention
221 if (false == (i_attention->getConfig()->getFlag(enCheckstop)))
222 {
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500223 trace<level::INFO>("Checkstop handling disabled");
Ben Tyner3fb52e52020-03-31 10:10:07 -0500224 }
225 else
226 {
Zane Shelley9fb73932020-09-15 13:34:57 -0500227 // Look for any attentions found in hardware. This will generate and
Zane Shelley7ae9c8c2020-12-02 20:10:31 -0600228 // commit a PEL if any errors are found.
Zane Shelley9fb73932020-09-15 13:34:57 -0500229 if (true != analyzer::analyzeHardware())
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500230 {
231 rc = RC_ANALYZER_ERROR;
232 }
Ben Tyner3fb52e52020-03-31 10:10:07 -0500233 }
Ben Tyneref320152020-01-09 10:31:23 -0600234
Ben Tyneref320152020-01-09 10:31:23 -0600235 return rc;
236}
237
238/**
239 * @brief Handle special attention
Ben Tyner3fb52e52020-03-31 10:10:07 -0500240 *
241 * @param i_attention Attention object
242 * @return 0 indicates that the special attention was successfully handled
243 * 1 indicates that the special attention was NOT successfully handled
Ben Tyneref320152020-01-09 10:31:23 -0600244 */
Ben Tynerb481d902020-03-05 10:24:23 -0600245int handleSpecial(Attention* i_attention)
Ben Tyneref320152020-01-09 10:31:23 -0600246{
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500247 int rc = RC_SUCCESS; // assume special attention handled
Ben Tyneref320152020-01-09 10:31:23 -0600248
Ben Tynerfb190542020-11-06 09:27:56 -0600249 // The TI info chipop will give us a pointer to the TI info data
Ben Tyner98430b32020-08-19 19:14:02 -0500250 uint8_t* tiInfo = nullptr; // ptr to TI info data
251 uint32_t tiInfoLen = 0; // length of TI info data
252 pdbg_target* attnProc = i_attention->getTarget(); // proc with attention
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500253
Ben Tyner29651ef2021-02-08 10:51:03 -0600254 bool tiInfoStatic = false; // assume TI info was provided (not created)
255
Ben Tyner98430b32020-08-19 19:14:02 -0500256 if (attnProc != nullptr)
Ben Tyner89c0a7a2020-08-07 12:07:35 -0500257 {
Ben Tyner98430b32020-08-19 19:14:02 -0500258 // The processor PIB target is required for get TI info chipop
259 char path[16];
260 sprintf(path, "/proc%d/pib", pdbg_target_index(attnProc));
261 pdbg_target* tiInfoTarget = pdbg_target_from_path(nullptr, path);
262
263 if (nullptr != tiInfoTarget)
Ben Tyner89c0a7a2020-08-07 12:07:35 -0500264 {
Ben Tyner98430b32020-08-19 19:14:02 -0500265 if (PDBG_TARGET_ENABLED == pdbg_target_probe(tiInfoTarget))
266 {
Ben Tyner98430b32020-08-19 19:14:02 -0500267 sbe_mpipl_get_ti_info(tiInfoTarget, &tiInfo, &tiInfoLen);
Ben Tyner4bbcb382021-02-22 09:29:00 -0600268
269 // If TI info not available use default based on host state
270 if (nullptr == tiInfo)
Ben Tyner98430b32020-08-19 19:14:02 -0500271 {
Ben Tyner4bbcb382021-02-22 09:29:00 -0600272 trace<level::INFO>("TI info data ptr is invalid");
273
274 HostRunningState runningState = hostRunningState();
275 std::string stateString = "host state unknown";
276
277 if ((HostRunningState::Started == runningState) ||
278 (HostRunningState::Unknown == runningState))
279 {
280 if (HostRunningState::Started == runningState)
281 {
282 stateString = "host started";
283 }
284 tiInfo = (uint8_t*)defaultPhypTiInfo;
285 }
286 else
287 {
288 stateString = "host not started";
289 tiInfo = (uint8_t*)defaultHbTiInfo;
290 }
291
292 // trace host state
293 trace<level::INFO>(stateString.c_str());
294
Ben Tyner29651ef2021-02-08 10:51:03 -0600295 tiInfoStatic = true; // using our TI info
Ben Tyner98430b32020-08-19 19:14:02 -0500296 }
297 }
Ben Tyner89c0a7a2020-08-07 12:07:35 -0500298 }
299 }
Ben Tyneref320152020-01-09 10:31:23 -0600300
Ben Tyner0fe5df42020-12-03 08:57:17 -0600301 bool tiInfoValid = false; // TI area data not valid or not available
302
Ben Tyner792f32f2020-06-02 08:50:47 -0500303 // If TI area exists and is marked valid we can assume TI occurred
304 if ((nullptr != tiInfo) && (0 != tiInfo[0]))
Ben Tyner970fd4f2020-02-19 13:46:42 -0600305 {
Ben Tyner792f32f2020-06-02 08:50:47 -0500306 TiDataArea* tiDataArea = (TiDataArea*)tiInfo;
Ben Tyner7e6611f2020-02-13 16:42:56 -0600307
Ben Tyner8882c322021-02-05 12:13:21 -0600308 std::stringstream ss; // string stream object for tracing
309 std::string strobj; // string object for tracing
Ben Tyner40717722020-09-23 09:43:20 -0500310
Ben Tyner8882c322021-02-05 12:13:21 -0600311 // trace a few known TI data area values
312 ss.str(std::string()); // empty the stream
313 ss.clear(); // clear the stream
314 ss << "TI data command = 0x" << std::setw(2) << std::setfill('0')
315 << std::hex << (int)tiDataArea->command;
316 strobj = ss.str();
317 trace<level::INFO>(strobj.c_str());
Ben Tyner40717722020-09-23 09:43:20 -0500318
Ben Tyner0fe5df42020-12-03 08:57:17 -0600319 // Another check for valid TI Info since it has been seen that
320 // tiInfo[0] != 0 but TI info is not valid
321 if (0xa1 == tiDataArea->command)
Ben Tyner792f32f2020-06-02 08:50:47 -0500322 {
Ben Tyner0fe5df42020-12-03 08:57:17 -0600323 tiInfoValid = true;
324
325 // trace some more data since TI info appears valid
Ben Tyner8882c322021-02-05 12:13:21 -0600326 ss.str(std::string()); // empty the stream
327 ss.clear(); // clear the stream
Ben Tyner7a0dd542021-02-12 09:33:44 -0600328 ss << "TI data term-type = 0x" << std::setw(2) << std::setfill('0')
329 << std::hex << (int)tiDataArea->hbTerminateType;
Ben Tyner8882c322021-02-05 12:13:21 -0600330 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 SRC format = 0x" << std::setw(2) << std::setfill('0')
336 << std::hex << (int)tiDataArea->srcFormat;
337 strobj = ss.str();
338 trace<level::INFO>(strobj.c_str());
Ben Tyner0fe5df42020-12-03 08:57:17 -0600339
Ben Tyner8882c322021-02-05 12:13:21 -0600340 ss.str(std::string()); // empty the stream
341 ss.clear(); // clear the stream
342 ss << "TI data source = 0x" << std::setw(2) << std::setfill('0')
343 << std::hex << (int)tiDataArea->source;
344 strobj = ss.str();
345 trace<level::INFO>(strobj.c_str());
Ben Tyner0fe5df42020-12-03 08:57:17 -0600346
347 if (true == (i_attention->getConfig()->getFlag(enTerminate)))
348 {
349 // Call TI special attention handler
350 rc = tiHandler(tiDataArea);
351 }
Ben Tyner792f32f2020-06-02 08:50:47 -0500352 }
Ben Tyner3fb52e52020-03-31 10:10:07 -0500353 }
Ben Tyner0fe5df42020-12-03 08:57:17 -0600354
Ben Tynerfe156492021-04-08 07:28:13 -0500355 // TI area is available but was not valid data
Ben Tyner0fe5df42020-12-03 08:57:17 -0600356 if (false == tiInfoValid)
Ben Tyner3fb52e52020-03-31 10:10:07 -0500357 {
Ben Tynerfe156492021-04-08 07:28:13 -0500358 trace<level::INFO>("TI info NOT valid");
Ben Tyner98430b32020-08-19 19:14:02 -0500359
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500360 // if configured to handle TI as default special attention
Ben Tynerfe156492021-04-08 07:28:13 -0500361 if (i_attention->getConfig()->getFlag(dfltTi))
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500362 {
Ben Tynerfe156492021-04-08 07:28:13 -0500363 // TI handling may be disabled
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500364 if (true == (i_attention->getConfig()->getFlag(enTerminate)))
365 {
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500366 // Call TI special attention handler
367 rc = tiHandler(nullptr);
368 }
Ben Tyner3fb52e52020-03-31 10:10:07 -0500369 }
Ben Tynerfe156492021-04-08 07:28:13 -0500370 // breakpoint is default special attention when TI info NOT valid
371 else
372 {
373 // breakpoint handling may be disabled
374 if (true == (i_attention->getConfig()->getFlag(enBreakpoints)))
375 {
376 // Call the breakpoint special attention handler
377 rc = bpHandler();
378 }
379 }
Ben Tyner970fd4f2020-02-19 13:46:42 -0600380 }
Ben Tyneref320152020-01-09 10:31:23 -0600381
Ben Tyner792f32f2020-06-02 08:50:47 -0500382 // release TI data buffer
Ben Tyner29651ef2021-02-08 10:51:03 -0600383 if ((nullptr != tiInfo) && (false == tiInfoStatic))
Ben Tyner792f32f2020-06-02 08:50:47 -0500384 {
385 free(tiInfo);
386 }
387
Ben Tyner3fb52e52020-03-31 10:10:07 -0500388 if (RC_SUCCESS != rc)
389 {
Ben Tyner792f32f2020-06-02 08:50:47 -0500390 trace<level::INFO>("Special attn not handled");
Ben Tyner3fb52e52020-03-31 10:10:07 -0500391 }
Ben Tyneref320152020-01-09 10:31:23 -0600392
393 return rc;
394}
395
Ben Tynerfb190542020-11-06 09:27:56 -0600396/**
397 * @brief Determine if attention is active and not masked
398 *
399 * Determine whether an attention needs to be handled and trace details of
400 * attention type and whether it is masked or not.
401 *
402 * @param i_val attention status register
403 * @param i_mask attention true mask register
404 * @param i_attn attention type
405 * @param i_proc processor associated with registers
406 *
407 * @return true if attention is active and not masked, otherwise false
408 */
Ben Tyner1965e502020-11-20 10:32:24 -0600409bool activeAttn(uint32_t i_val, uint32_t i_mask, uint32_t i_attn)
Ben Tynerfb190542020-11-06 09:27:56 -0600410{
Zane Shelley9fb657f2021-01-12 15:30:58 -0600411 bool rc = false; // assume attn masked and/or inactive
Ben Tynerfb190542020-11-06 09:27:56 -0600412
413 // if attention active
414 if (0 != (i_val & i_attn))
415 {
Ben Tynerfb190542020-11-06 09:27:56 -0600416 std::stringstream ss;
Ben Tynerfb190542020-11-06 09:27:56 -0600417
Zane Shelley9fb657f2021-01-12 15:30:58 -0600418 bool validAttn = true; // known attention type
419
Ben Tynerfb190542020-11-06 09:27:56 -0600420 switch (i_attn)
421 {
422 case SBE_ATTN:
423 ss << "SBE attn";
424 break;
425 case CHECKSTOP_ATTN:
426 ss << "Checkstop attn";
427 break;
428 case SPECIAL_ATTN:
429 ss << "Special attn";
430 break;
431 default:
432 ss << "Unknown attn";
433 validAttn = false;
434 }
435
436 // see if attention is masked
437 if (true == validAttn)
438 {
439 if (0 != (i_mask & i_attn))
440 {
441 rc = true; // attention active and not masked
442 }
443 else
444 {
445 ss << " masked";
446 }
447 }
448
Ben Tyner8882c322021-02-05 12:13:21 -0600449 std::string strobj = ss.str(); // ss.str() is temporary
450 trace<level::INFO>(strobj.c_str()); // commit trace stream
Ben Tynerfb190542020-11-06 09:27:56 -0600451 }
452
453 return rc;
454}
Ben Tyneref320152020-01-09 10:31:23 -0600455} // namespace attn