blob: 8a5042d3efefec002d7abb81585b79e4da4c4e9f [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>
7#include <attn/attn_handler.hpp>
8#include <attn/attn_logging.hpp>
9#include <attn/bp_handler.hpp>
10#include <attn/ti_handler.hpp>
Ben Tynerbcf65a82020-12-01 08:46:36 -060011#include <attn/vital_handler.hpp>
Ben Tyneref320152020-01-09 10:31:23 -060012
Ben Tynerb481d902020-03-05 10:24:23 -060013#include <algorithm>
Ben Tyneref320152020-01-09 10:31:23 -060014#include <iomanip>
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050015#include <map>
Ben Tyner9ae5ca42020-02-28 13:13:50 -060016#include <sstream>
Ben Tynerb481d902020-03-05 10:24:23 -060017#include <vector>
Ben Tyneref320152020-01-09 10:31:23 -060018
19namespace attn
20{
21
22/**
Ben Tyneref320152020-01-09 10:31:23 -060023 * @brief Handle checkstop attention
24 *
Ben Tynerb481d902020-03-05 10:24:23 -060025 * @param i_attention Attention object
Ben Tyner3fb52e52020-03-31 10:10:07 -050026 * @return 0 indicates that the checkstop attention was successfully handled
27 * 1 indicates that the checkstop attention was NOT successfully
28 * handled.
Ben Tyneref320152020-01-09 10:31:23 -060029 */
Ben Tynerb481d902020-03-05 10:24:23 -060030int handleCheckstop(Attention* i_attention);
Ben Tyneref320152020-01-09 10:31:23 -060031
32/**
33 * @brief Handle special attention
34 *
Ben Tynerb481d902020-03-05 10:24:23 -060035 * @param i_attention Attention object
Ben Tyner3fb52e52020-03-31 10:10:07 -050036 * @return 0 indicates that the special attention was successfully handled
37 * 1 indicates that the special attention was NOT successfully handled
Ben Tyneref320152020-01-09 10:31:23 -060038 */
Ben Tynerb481d902020-03-05 10:24:23 -060039int handleSpecial(Attention* i_attention);
Ben Tyneref320152020-01-09 10:31:23 -060040
Ben Tynerfb190542020-11-06 09:27:56 -060041/** @brief Determine if attention is active and not masked */
Ben Tyner1965e502020-11-20 10:32:24 -060042bool activeAttn(uint32_t i_val, uint32_t i_mask, uint32_t i_attn);
Ben Tynerfb190542020-11-06 09:27:56 -060043
Ben Tyneref320152020-01-09 10:31:23 -060044/**
Ben Tyneref320152020-01-09 10:31:23 -060045 * @brief The main attention handler logic
Ben Tyner970fd4f2020-02-19 13:46:42 -060046 *
47 * @param i_breakpoints true = breakpoint special attn handling enabled
Ben Tyneref320152020-01-09 10:31:23 -060048 */
Ben Tyner3fb52e52020-03-31 10:10:07 -050049void attnHandler(Config* i_config)
Ben Tyneref320152020-01-09 10:31:23 -060050{
Ben Tynerb481d902020-03-05 10:24:23 -060051 // Vector of active attentions to be handled
52 std::vector<Attention> active_attentions;
53
Ben Tyneref320152020-01-09 10:31:23 -060054 uint32_t isr_val, isr_mask;
55 uint32_t proc;
56
Ben Tyner1965e502020-11-20 10:32:24 -060057 std::stringstream ss; // for trace messages
58
Ben Tyneref320152020-01-09 10:31:23 -060059 // loop through processors looking for active attentions
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050060 trace<level::INFO>("Attention handler started");
Ben Tyner117af992020-05-22 13:32:11 -050061
Ben Tyneref320152020-01-09 10:31:23 -060062 pdbg_target* target;
Ben Tyner5e622d82020-09-11 10:10:24 -050063 pdbg_for_each_class_target("proc", target)
Ben Tyneref320152020-01-09 10:31:23 -060064 {
65 if (PDBG_TARGET_ENABLED == pdbg_target_probe(target))
66 {
67 proc = pdbg_target_index(target); // get processor number
68
Ben Tynerb83c8522020-11-20 10:45:26 -060069 // Use PIB target to determine if a processor is enabled
Ben Tyner5e622d82020-09-11 10:10:24 -050070 char path[16];
Ben Tynerb83c8522020-11-20 10:45:26 -060071 sprintf(path, "/proc%d/pib", proc);
Ben Tyner5e622d82020-09-11 10:10:24 -050072 pdbg_target* attnTarget = pdbg_target_from_path(nullptr, path);
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050073
Ben Tynerb83c8522020-11-20 10:45:26 -060074 // sanity check
75 if (nullptr == attnTarget)
76 {
77 trace<level::INFO>("pib path or target not found");
78 continue;
79 }
80
Ben Tyner5e622d82020-09-11 10:10:24 -050081 if (PDBG_TARGET_ENABLED == pdbg_target_probe(attnTarget))
Ben Tyneref320152020-01-09 10:31:23 -060082 {
Ben Tynerb83c8522020-11-20 10:45:26 -060083 // The processor FSI target is required for CFAM read
84 sprintf(path, "/proc%d/fsi", proc);
85 attnTarget = pdbg_target_from_path(nullptr, path);
86
87 // sanity check
88 if (nullptr == attnTarget)
89 {
90 trace<level::INFO>("fsi path or target not found");
91 continue;
92 }
93
Ben Tyner1965e502020-11-20 10:32:24 -060094 // trace fsi path
95 ss.str(std::string()); // clear stream
96 ss << "target - " << path;
97 trace<level::INFO>(ss.str().c_str());
98
Ben Tyner5adc96e2020-11-20 10:54:12 -060099 isr_val = 0xffffffff; // invalid isr value
100
Ben Tyner5e622d82020-09-11 10:10:24 -0500101 // get active attentions on processor
102 if (RC_SUCCESS != fsi_read(attnTarget, 0x1007, &isr_val))
Ben Tyneref320152020-01-09 10:31:23 -0600103 {
Ben Tynerfb190542020-11-06 09:27:56 -0600104 // log cfam read error
Ben Tyner5e622d82020-09-11 10:10:24 -0500105 trace<level::INFO>("Error! cfam read 0x1007 FAILED");
Ben Tynerfb190542020-11-06 09:27:56 -0600106 eventAttentionFail(RC_CFAM_ERROR);
Ben Tyneref320152020-01-09 10:31:23 -0600107 }
Ben Tyner5adc96e2020-11-20 10:54:12 -0600108 else if (0xffffffff == isr_val)
109 {
110 trace<level::INFO>("Error! cfam read 0x1007 INVALID");
111 continue;
112 }
Ben Tyneref320152020-01-09 10:31:23 -0600113 else
114 {
Ben Tyner1965e502020-11-20 10:32:24 -0600115 // trace isr
116 ss.str(std::string()); // clear stream
117 ss << std::hex << std::showbase; // trace as hex vals
118 ss << "cfam 0x1007 = " << std::setw(8) << std::setfill('0')
119 << isr_val;
120 trace<level::INFO>(ss.str().c_str());
121
Ben Tyner5adc96e2020-11-20 10:54:12 -0600122 isr_mask = 0xffffffff; // invalid isr mask
123
Ben Tyner5e622d82020-09-11 10:10:24 -0500124 // get interrupt enabled special attentions mask
125 if (RC_SUCCESS != fsi_read(attnTarget, 0x100d, &isr_mask))
Ben Tyneref320152020-01-09 10:31:23 -0600126 {
Ben Tynerfb190542020-11-06 09:27:56 -0600127 // log cfam read error
Ben Tyner5e622d82020-09-11 10:10:24 -0500128 trace<level::INFO>("Error! cfam read 0x100d FAILED");
Ben Tynerfb190542020-11-06 09:27:56 -0600129 eventAttentionFail(RC_CFAM_ERROR);
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 Tyner1965e502020-11-20 10:32:24 -0600138 // trace true-mask
139 ss.str(std::string()); // clear stream
140 ss << std::hex << std::showbase; // trace as hex vals
141 ss << "cfam 0x100d = " << std::setw(8)
142 << std::setfill('0') << isr_mask;
143 trace<level::INFO>(ss.str().c_str());
144
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
171 } // proc target enabled
172 } // fsi target enabled
173 } // 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 Tyner98430b32020-08-19 19:14:02 -0500247 if (attnProc != nullptr)
Ben Tyner89c0a7a2020-08-07 12:07:35 -0500248 {
Ben Tyner98430b32020-08-19 19:14:02 -0500249 // The processor PIB target is required for get TI info chipop
250 char path[16];
251 sprintf(path, "/proc%d/pib", pdbg_target_index(attnProc));
252 pdbg_target* tiInfoTarget = pdbg_target_from_path(nullptr, path);
253
254 if (nullptr != tiInfoTarget)
Ben Tyner89c0a7a2020-08-07 12:07:35 -0500255 {
Ben Tyner98430b32020-08-19 19:14:02 -0500256 if (PDBG_TARGET_ENABLED == pdbg_target_probe(tiInfoTarget))
257 {
Ben Tyner98430b32020-08-19 19:14:02 -0500258 sbe_mpipl_get_ti_info(tiInfoTarget, &tiInfo, &tiInfoLen);
259 if (tiInfo == nullptr)
260 {
261 trace<level::INFO>("TI info data ptr is null after call");
262 }
263 }
Ben Tyner89c0a7a2020-08-07 12:07:35 -0500264 }
265 }
Ben Tyneref320152020-01-09 10:31:23 -0600266
Ben Tyner0fe5df42020-12-03 08:57:17 -0600267 bool tiInfoValid = false; // TI area data not valid or not available
268
Ben Tyner792f32f2020-06-02 08:50:47 -0500269 // If TI area exists and is marked valid we can assume TI occurred
270 if ((nullptr != tiInfo) && (0 != tiInfo[0]))
Ben Tyner970fd4f2020-02-19 13:46:42 -0600271 {
Ben Tyner792f32f2020-06-02 08:50:47 -0500272 TiDataArea* tiDataArea = (TiDataArea*)tiInfo;
Ben Tyner7e6611f2020-02-13 16:42:56 -0600273
Ben Tyner792f32f2020-06-02 08:50:47 -0500274 // trace a few known TI data area values
Ben Tyner8c5e4f42020-10-28 11:11:55 -0500275 std::stringstream ss;
276 ss << std::hex << std::showbase;
Ben Tyner40717722020-09-23 09:43:20 -0500277
278 ss << "TI data command = " << (int)tiDataArea->command;
Ben Tyner792f32f2020-06-02 08:50:47 -0500279 trace<level::INFO>(ss.str().c_str());
Ben Tyner40717722020-09-23 09:43:20 -0500280 ss.str(std::string());
281
Ben Tyner0fe5df42020-12-03 08:57:17 -0600282 // Another check for valid TI Info since it has been seen that
283 // tiInfo[0] != 0 but TI info is not valid
284 if (0xa1 == tiDataArea->command)
Ben Tyner792f32f2020-06-02 08:50:47 -0500285 {
Ben Tyner0fe5df42020-12-03 08:57:17 -0600286 tiInfoValid = true;
287
288 // trace some more data since TI info appears valid
289 ss << "TI data hb_terminate_type = "
290 << (int)tiDataArea->hbTerminateType;
291 trace<level::INFO>(ss.str().c_str());
292 ss.str(std::string());
293
294 ss << "TI data SRC format = " << (int)tiDataArea->srcFormat;
295 trace<level::INFO>(ss.str().c_str());
296 ss.str(std::string());
297
298 ss << "TI data source = " << (int)tiDataArea->source;
299 trace<level::INFO>(ss.str().c_str());
300 ss.str(std::string());
301
302 if (true == (i_attention->getConfig()->getFlag(enTerminate)))
303 {
304 // Call TI special attention handler
305 rc = tiHandler(tiDataArea);
306 }
Ben Tyner792f32f2020-06-02 08:50:47 -0500307 }
Ben Tyner3fb52e52020-03-31 10:10:07 -0500308 }
Ben Tyner0fe5df42020-12-03 08:57:17 -0600309
310 // If TI area not valid or not available
311 if (false == tiInfoValid)
Ben Tyner3fb52e52020-03-31 10:10:07 -0500312 {
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500313 trace<level::INFO>("TI info NOT available");
Ben Tyner98430b32020-08-19 19:14:02 -0500314
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500315 // if configured to handle breakpoint as default special attention
316 if (i_attention->getConfig()->getFlag(dfltBreakpoint))
Ben Tyner3fb52e52020-03-31 10:10:07 -0500317 {
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500318 if (true == (i_attention->getConfig()->getFlag(enBreakpoints)))
319 {
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500320 // Call the breakpoint special attention handler
321 bpHandler();
322 }
323 }
324 // if configured to handle TI as default special attention
325 else
326 {
327 trace<level::INFO>("assuming TI");
328
329 if (true == (i_attention->getConfig()->getFlag(enTerminate)))
330 {
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500331 // Call TI special attention handler
332 rc = tiHandler(nullptr);
333 }
Ben Tyner3fb52e52020-03-31 10:10:07 -0500334 }
Ben Tyner970fd4f2020-02-19 13:46:42 -0600335 }
Ben Tyneref320152020-01-09 10:31:23 -0600336
Ben Tyner792f32f2020-06-02 08:50:47 -0500337 // release TI data buffer
338 if (nullptr != tiInfo)
339 {
340 free(tiInfo);
341 }
342
Ben Tyner3fb52e52020-03-31 10:10:07 -0500343 if (RC_SUCCESS != rc)
344 {
Ben Tyner792f32f2020-06-02 08:50:47 -0500345 trace<level::INFO>("Special attn not handled");
Ben Tyner3fb52e52020-03-31 10:10:07 -0500346 }
Ben Tyneref320152020-01-09 10:31:23 -0600347
348 return rc;
349}
350
Ben Tynerfb190542020-11-06 09:27:56 -0600351/**
352 * @brief Determine if attention is active and not masked
353 *
354 * Determine whether an attention needs to be handled and trace details of
355 * attention type and whether it is masked or not.
356 *
357 * @param i_val attention status register
358 * @param i_mask attention true mask register
359 * @param i_attn attention type
360 * @param i_proc processor associated with registers
361 *
362 * @return true if attention is active and not masked, otherwise false
363 */
Ben Tyner1965e502020-11-20 10:32:24 -0600364bool activeAttn(uint32_t i_val, uint32_t i_mask, uint32_t i_attn)
Ben Tynerfb190542020-11-06 09:27:56 -0600365{
366 bool rc = false; // assume attn masked and/or inactive
367 bool validAttn = true; // known attention type
368
369 // if attention active
370 if (0 != (i_val & i_attn))
371 {
Ben Tynerfb190542020-11-06 09:27:56 -0600372 std::stringstream ss;
Ben Tynerfb190542020-11-06 09:27:56 -0600373
374 switch (i_attn)
375 {
376 case SBE_ATTN:
377 ss << "SBE attn";
378 break;
379 case CHECKSTOP_ATTN:
380 ss << "Checkstop attn";
381 break;
382 case SPECIAL_ATTN:
383 ss << "Special attn";
384 break;
385 default:
386 ss << "Unknown attn";
387 validAttn = false;
388 }
389
390 // see if attention is masked
391 if (true == validAttn)
392 {
393 if (0 != (i_mask & i_attn))
394 {
395 rc = true; // attention active and not masked
396 }
397 else
398 {
399 ss << " masked";
400 }
401 }
402
403 trace<level::INFO>(ss.str().c_str()); // commit trace stream
404 }
405
406 return rc;
407}
408
Ben Tyneref320152020-01-09 10:31:23 -0600409} // namespace attn