blob: db82ef5d15e56c1eba7cad956669f933254f83f4 [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>
5#include <attn/attn_config.hpp>
6#include <attn/attn_handler.hpp>
7#include <attn/attn_logging.hpp>
8#include <attn/bp_handler.hpp>
9#include <attn/ti_handler.hpp>
Ben Tyneref320152020-01-09 10:31:23 -060010
Ben Tynerb481d902020-03-05 10:24:23 -060011#include <algorithm>
Ben Tyneref320152020-01-09 10:31:23 -060012#include <iomanip>
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050013#include <map>
Ben Tyner9ae5ca42020-02-28 13:13:50 -060014#include <sstream>
Ben Tynerb481d902020-03-05 10:24:23 -060015#include <vector>
Ben Tyneref320152020-01-09 10:31:23 -060016
17namespace attn
18{
19
20/**
21 * @brief Handle SBE vital attention
22 *
Ben Tynerb481d902020-03-05 10:24:23 -060023 * @param i_attention Attention object
Ben Tyner3fb52e52020-03-31 10:10:07 -050024 * @return 0 indicates that the vital attention was successfully handled
25 * 1 indicates that the vital attention was NOT successfully handled
Ben Tyneref320152020-01-09 10:31:23 -060026 */
Ben Tynerb481d902020-03-05 10:24:23 -060027int handleVital(Attention* i_attention);
Ben Tyneref320152020-01-09 10:31:23 -060028
29/**
30 * @brief Handle checkstop attention
31 *
Ben Tynerb481d902020-03-05 10:24:23 -060032 * @param i_attention Attention object
Ben Tyner3fb52e52020-03-31 10:10:07 -050033 * @return 0 indicates that the checkstop attention was successfully handled
34 * 1 indicates that the checkstop attention was NOT successfully
35 * handled.
Ben Tyneref320152020-01-09 10:31:23 -060036 */
Ben Tynerb481d902020-03-05 10:24:23 -060037int handleCheckstop(Attention* i_attention);
Ben Tyneref320152020-01-09 10:31:23 -060038
39/**
40 * @brief Handle special attention
41 *
Ben Tynerb481d902020-03-05 10:24:23 -060042 * @param i_attention Attention object
Ben Tyner3fb52e52020-03-31 10:10:07 -050043 * @return 0 indicates that the special attention was successfully handled
44 * 1 indicates that the special attention was NOT successfully handled
Ben Tyneref320152020-01-09 10:31:23 -060045 */
Ben Tynerb481d902020-03-05 10:24:23 -060046int handleSpecial(Attention* i_attention);
Ben Tyneref320152020-01-09 10:31:23 -060047
Ben Tynerfb190542020-11-06 09:27:56 -060048/** @brief Determine if attention is active and not masked */
49bool activeAttn(uint32_t i_val, uint32_t i_mask, uint32_t i_attn,
50 uint32_t i_proc);
51
Ben Tyneref320152020-01-09 10:31:23 -060052/**
Ben Tyneref320152020-01-09 10:31:23 -060053 * @brief The main attention handler logic
Ben Tyner970fd4f2020-02-19 13:46:42 -060054 *
55 * @param i_breakpoints true = breakpoint special attn handling enabled
Ben Tyneref320152020-01-09 10:31:23 -060056 */
Ben Tyner3fb52e52020-03-31 10:10:07 -050057void attnHandler(Config* i_config)
Ben Tyneref320152020-01-09 10:31:23 -060058{
Ben Tynerb481d902020-03-05 10:24:23 -060059 // Vector of active attentions to be handled
60 std::vector<Attention> active_attentions;
61
Ben Tyneref320152020-01-09 10:31:23 -060062 uint32_t isr_val, isr_mask;
63 uint32_t proc;
64
65 // loop through processors looking for active attentions
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050066 trace<level::INFO>("Attention handler started");
Ben Tyner117af992020-05-22 13:32:11 -050067
Ben Tyneref320152020-01-09 10:31:23 -060068 pdbg_target* target;
Ben Tyner5e622d82020-09-11 10:10:24 -050069 pdbg_for_each_class_target("proc", target)
Ben Tyneref320152020-01-09 10:31:23 -060070 {
71 if (PDBG_TARGET_ENABLED == pdbg_target_probe(target))
72 {
73 proc = pdbg_target_index(target); // get processor number
74
Ben Tyner5e622d82020-09-11 10:10:24 -050075 // The processor FSI target is required for CFAM read
76 char path[16];
Ben Tynerfb190542020-11-06 09:27:56 -060077 sprintf(path, "/proc%d/fsi", proc);
Ben Tyner5e622d82020-09-11 10:10:24 -050078 pdbg_target* attnTarget = pdbg_target_from_path(nullptr, path);
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050079
Ben Tyner5e622d82020-09-11 10:10:24 -050080 if (PDBG_TARGET_ENABLED == pdbg_target_probe(attnTarget))
Ben Tyneref320152020-01-09 10:31:23 -060081 {
Ben Tyner5e622d82020-09-11 10:10:24 -050082 // get active attentions on processor
83 if (RC_SUCCESS != fsi_read(attnTarget, 0x1007, &isr_val))
Ben Tyneref320152020-01-09 10:31:23 -060084 {
Ben Tynerfb190542020-11-06 09:27:56 -060085 // log cfam read error
Ben Tyner5e622d82020-09-11 10:10:24 -050086 trace<level::INFO>("Error! cfam read 0x1007 FAILED");
Ben Tynerfb190542020-11-06 09:27:56 -060087 eventAttentionFail(RC_CFAM_ERROR);
Ben Tyneref320152020-01-09 10:31:23 -060088 }
89 else
90 {
Ben Tyner5e622d82020-09-11 10:10:24 -050091 // get interrupt enabled special attentions mask
92 if (RC_SUCCESS != fsi_read(attnTarget, 0x100d, &isr_mask))
Ben Tyneref320152020-01-09 10:31:23 -060093 {
Ben Tynerfb190542020-11-06 09:27:56 -060094 // log cfam read error
Ben Tyner5e622d82020-09-11 10:10:24 -050095 trace<level::INFO>("Error! cfam read 0x100d FAILED");
Ben Tynerfb190542020-11-06 09:27:56 -060096 eventAttentionFail(RC_CFAM_ERROR);
Ben Tyneref320152020-01-09 10:31:23 -060097 }
Ben Tyner5e622d82020-09-11 10:10:24 -050098 else
99 {
Ben Tynerfb190542020-11-06 09:27:56 -0600100 // SBE vital attention active and not masked?
101 if (true ==
102 activeAttn(isr_val, isr_mask, SBE_ATTN, proc))
Ben Tyner5e622d82020-09-11 10:10:24 -0500103 {
104 active_attentions.emplace_back(Attention::Vital,
105 handleVital, target,
106 i_config);
107 }
108
Ben Tynerfb190542020-11-06 09:27:56 -0600109 // Checkstop attention active and not masked?
110 if (true ==
111 activeAttn(isr_val, isr_mask, CHECKSTOP_ATTN, proc))
Ben Tyner5e622d82020-09-11 10:10:24 -0500112 {
113 active_attentions.emplace_back(Attention::Checkstop,
114 handleCheckstop,
115 target, i_config);
116 }
117
Ben Tynerfb190542020-11-06 09:27:56 -0600118 // Special attention active and not masked?
119 if (true ==
120 activeAttn(isr_val, isr_mask, SPECIAL_ATTN, proc))
Ben Tyner5e622d82020-09-11 10:10:24 -0500121 {
122 active_attentions.emplace_back(Attention::Special,
123 handleSpecial,
124 target, i_config);
125 }
126 } // cfam 0x100d valid
127 } // cfam 0x1007 valid
128 } // proc target enabled
129 } // fsi target enabled
130 } // next processor
Ben Tyneref320152020-01-09 10:31:23 -0600131
Ben Tynerb481d902020-03-05 10:24:23 -0600132 // convert to heap, highest priority is at front
133 if (!std::is_heap(active_attentions.begin(), active_attentions.end()))
134 {
135 std::make_heap(active_attentions.begin(), active_attentions.end());
136 }
137
138 // call the attention handler until one is handled or all were attempted
139 while (false == active_attentions.empty())
140 {
141 // handle highest priority attention, done if successful
142 if (RC_SUCCESS == active_attentions.front().handle())
143 {
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500144 // an attention was handled so we are done
Ben Tynerb481d902020-03-05 10:24:23 -0600145 break;
146 }
147
148 // move attention to back of vector
149 std::pop_heap(active_attentions.begin(), active_attentions.end());
150
151 // remove attention from vector
152 active_attentions.pop_back();
153 }
Ben Tyneref320152020-01-09 10:31:23 -0600154}
155
156/**
157 * @brief Handle SBE vital attention
Ben Tyner3fb52e52020-03-31 10:10:07 -0500158 *
159 * @param i_attention Attention object
160 * @return 0 indicates that the vital attention was successfully handled
161 * 1 indicates that the vital attention was NOT successfully handled
Ben Tyneref320152020-01-09 10:31:23 -0600162 */
Ben Tynerb481d902020-03-05 10:24:23 -0600163int handleVital(Attention* i_attention)
Ben Tyneref320152020-01-09 10:31:23 -0600164{
Ben Tyner3fb52e52020-03-31 10:10:07 -0500165 int rc = RC_SUCCESS; // assume vital handled
Ben Tyneref320152020-01-09 10:31:23 -0600166
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500167 trace<level::INFO>("vital handler started");
168
Ben Tyner3fb52e52020-03-31 10:10:07 -0500169 // if vital handling enabled, handle vital attention
170 if (false == (i_attention->getConfig()->getFlag(enVital)))
171 {
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500172 trace<level::INFO>("vital handling disabled");
Ben Tyner792f32f2020-06-02 08:50:47 -0500173 rc = RC_NOT_HANDLED;
Ben Tyner3fb52e52020-03-31 10:10:07 -0500174 }
175 else
Ben Tyneref320152020-01-09 10:31:23 -0600176 {
Ben Tyner792f32f2020-06-02 08:50:47 -0500177 eventVital();
Ben Tyneref320152020-01-09 10:31:23 -0600178 }
179
180 return rc;
181}
182
183/**
184 * @brief Handle checkstop attention
Ben Tyner3fb52e52020-03-31 10:10:07 -0500185 *
186 * @param i_attention Attention object
187 * @return 0 indicates that the checkstop attention was successfully handled
188 * 1 indicates that the checkstop attention was NOT successfully
189 * handled.
Ben Tyneref320152020-01-09 10:31:23 -0600190 */
Ben Tynerb481d902020-03-05 10:24:23 -0600191int handleCheckstop(Attention* i_attention)
Ben Tyneref320152020-01-09 10:31:23 -0600192{
Ben Tyner3fb52e52020-03-31 10:10:07 -0500193 int rc = RC_SUCCESS; // assume checkstop handled
Ben Tyneref320152020-01-09 10:31:23 -0600194
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500195 trace<level::INFO>("checkstop handler started");
196
Ben Tyner3fb52e52020-03-31 10:10:07 -0500197 // if checkstop handling enabled, handle checkstop attention
198 if (false == (i_attention->getConfig()->getFlag(enCheckstop)))
199 {
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500200 trace<level::INFO>("Checkstop handling disabled");
Ben Tyner3fb52e52020-03-31 10:10:07 -0500201 }
202 else
203 {
Zane Shelley9fb73932020-09-15 13:34:57 -0500204 // Look for any attentions found in hardware. This will generate and
205 // comment a PEL if any errors are found.
206 if (true != analyzer::analyzeHardware())
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500207 {
208 rc = RC_ANALYZER_ERROR;
209 }
Ben Tyner3fb52e52020-03-31 10:10:07 -0500210 }
Ben Tyneref320152020-01-09 10:31:23 -0600211
Ben Tyneref320152020-01-09 10:31:23 -0600212 return rc;
213}
214
215/**
216 * @brief Handle special attention
Ben Tyner3fb52e52020-03-31 10:10:07 -0500217 *
218 * @param i_attention Attention object
219 * @return 0 indicates that the special attention was successfully handled
220 * 1 indicates that the special attention was NOT successfully handled
Ben Tyneref320152020-01-09 10:31:23 -0600221 */
Ben Tynerb481d902020-03-05 10:24:23 -0600222int handleSpecial(Attention* i_attention)
Ben Tyneref320152020-01-09 10:31:23 -0600223{
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500224 int rc = RC_SUCCESS; // assume special attention handled
Ben Tyneref320152020-01-09 10:31:23 -0600225
Ben Tynerfb190542020-11-06 09:27:56 -0600226 // The TI info chipop will give us a pointer to the TI info data
Ben Tyner98430b32020-08-19 19:14:02 -0500227 uint8_t* tiInfo = nullptr; // ptr to TI info data
228 uint32_t tiInfoLen = 0; // length of TI info data
229 pdbg_target* attnProc = i_attention->getTarget(); // proc with attention
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500230
Ben Tyner98430b32020-08-19 19:14:02 -0500231 if (attnProc != nullptr)
Ben Tyner89c0a7a2020-08-07 12:07:35 -0500232 {
Ben Tyner98430b32020-08-19 19:14:02 -0500233 // The processor PIB target is required for get TI info chipop
234 char path[16];
235 sprintf(path, "/proc%d/pib", pdbg_target_index(attnProc));
236 pdbg_target* tiInfoTarget = pdbg_target_from_path(nullptr, path);
237
238 if (nullptr != tiInfoTarget)
Ben Tyner89c0a7a2020-08-07 12:07:35 -0500239 {
Ben Tyner98430b32020-08-19 19:14:02 -0500240 if (PDBG_TARGET_ENABLED == pdbg_target_probe(tiInfoTarget))
241 {
Ben Tyner98430b32020-08-19 19:14:02 -0500242 sbe_mpipl_get_ti_info(tiInfoTarget, &tiInfo, &tiInfoLen);
243 if (tiInfo == nullptr)
244 {
245 trace<level::INFO>("TI info data ptr is null after call");
246 }
247 }
Ben Tyner89c0a7a2020-08-07 12:07:35 -0500248 }
249 }
Ben Tyneref320152020-01-09 10:31:23 -0600250
Ben Tyner792f32f2020-06-02 08:50:47 -0500251 // If TI area exists and is marked valid we can assume TI occurred
252 if ((nullptr != tiInfo) && (0 != tiInfo[0]))
Ben Tyner970fd4f2020-02-19 13:46:42 -0600253 {
Ben Tyner792f32f2020-06-02 08:50:47 -0500254 TiDataArea* tiDataArea = (TiDataArea*)tiInfo;
Ben Tyner7e6611f2020-02-13 16:42:56 -0600255
Ben Tyner792f32f2020-06-02 08:50:47 -0500256 // trace a few known TI data area values
Ben Tyner8c5e4f42020-10-28 11:11:55 -0500257 std::stringstream ss;
258 ss << std::hex << std::showbase;
Ben Tyner40717722020-09-23 09:43:20 -0500259
260 ss << "TI data command = " << (int)tiDataArea->command;
Ben Tyner792f32f2020-06-02 08:50:47 -0500261 trace<level::INFO>(ss.str().c_str());
Ben Tyner40717722020-09-23 09:43:20 -0500262 ss.str(std::string());
263
Ben Tyner8c5e4f42020-10-28 11:11:55 -0500264 ss << "TI data hb_terminate_type = "
265 << (int)tiDataArea->hbTerminateType;
266 trace<level::INFO>(ss.str().c_str());
267 ss.str(std::string());
268
Ben Tyner40717722020-09-23 09:43:20 -0500269 ss << "TI data SRC format = " << (int)tiDataArea->srcFormat;
Ben Tyner792f32f2020-06-02 08:50:47 -0500270 trace<level::INFO>(ss.str().c_str());
Ben Tyner40717722020-09-23 09:43:20 -0500271 ss.str(std::string());
272
Ben Tyner8c5e4f42020-10-28 11:11:55 -0500273 ss << "TI data source = " << (int)tiDataArea->source;
Ben Tyner792f32f2020-06-02 08:50:47 -0500274 trace<level::INFO>(ss.str().c_str());
Ben Tyner40717722020-09-23 09:43:20 -0500275 ss.str(std::string());
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500276
Ben Tyner792f32f2020-06-02 08:50:47 -0500277 if (true == (i_attention->getConfig()->getFlag(enTerminate)))
278 {
Ben Tyner792f32f2020-06-02 08:50:47 -0500279 // Call TI special attention handler
280 rc = tiHandler(tiDataArea);
281 }
Ben Tyner3fb52e52020-03-31 10:10:07 -0500282 }
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500283 // TI area not valid or not available
Ben Tyner3fb52e52020-03-31 10:10:07 -0500284 else
285 {
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500286 trace<level::INFO>("TI info NOT available");
Ben Tyner98430b32020-08-19 19:14:02 -0500287
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500288 // if configured to handle breakpoint as default special attention
289 if (i_attention->getConfig()->getFlag(dfltBreakpoint))
Ben Tyner3fb52e52020-03-31 10:10:07 -0500290 {
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500291 if (true == (i_attention->getConfig()->getFlag(enBreakpoints)))
292 {
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500293 // Call the breakpoint special attention handler
294 bpHandler();
295 }
296 }
297 // if configured to handle TI as default special attention
298 else
299 {
300 trace<level::INFO>("assuming TI");
301
302 if (true == (i_attention->getConfig()->getFlag(enTerminate)))
303 {
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500304 // Call TI special attention handler
305 rc = tiHandler(nullptr);
306 }
Ben Tyner3fb52e52020-03-31 10:10:07 -0500307 }
Ben Tyner970fd4f2020-02-19 13:46:42 -0600308 }
Ben Tyneref320152020-01-09 10:31:23 -0600309
Ben Tyner792f32f2020-06-02 08:50:47 -0500310 // release TI data buffer
311 if (nullptr != tiInfo)
312 {
313 free(tiInfo);
314 }
315
Ben Tyner3fb52e52020-03-31 10:10:07 -0500316 if (RC_SUCCESS != rc)
317 {
Ben Tyner792f32f2020-06-02 08:50:47 -0500318 trace<level::INFO>("Special attn not handled");
Ben Tyner3fb52e52020-03-31 10:10:07 -0500319 }
Ben Tyneref320152020-01-09 10:31:23 -0600320
321 return rc;
322}
323
Ben Tynerfb190542020-11-06 09:27:56 -0600324/**
325 * @brief Determine if attention is active and not masked
326 *
327 * Determine whether an attention needs to be handled and trace details of
328 * attention type and whether it is masked or not.
329 *
330 * @param i_val attention status register
331 * @param i_mask attention true mask register
332 * @param i_attn attention type
333 * @param i_proc processor associated with registers
334 *
335 * @return true if attention is active and not masked, otherwise false
336 */
337bool activeAttn(uint32_t i_val, uint32_t i_mask, uint32_t i_attn,
338 uint32_t i_proc)
339{
340 bool rc = false; // assume attn masked and/or inactive
341 bool validAttn = true; // known attention type
342
343 // if attention active
344 if (0 != (i_val & i_attn))
345 {
346 // trace proc with attn
347 std::stringstream ss;
348 ss << "Attn: proc " << i_proc;
349 trace<level::INFO>(ss.str().c_str());
350
351 // trace isr
352 ss.str(std::string()); // clear stream
353 ss << std::hex << std::showbase; // trace as hex vals
354 ss << "cfam 0x1007 = " << std::setw(8) << std::setfill('0') << i_val;
355 trace<level::INFO>(ss.str().c_str());
356
357 // trace true-mask
358 ss.str(std::string()); // clear stream
359 ss << std::hex << std::showbase; // trace as hex vals
360 ss << "cfam 0x100d = " << std::setw(8) << std::setfill('0') << i_mask;
361 trace<level::INFO>(ss.str().c_str());
362
363 ss.str(std::string()); // clear stream
364
365 switch (i_attn)
366 {
367 case SBE_ATTN:
368 ss << "SBE attn";
369 break;
370 case CHECKSTOP_ATTN:
371 ss << "Checkstop attn";
372 break;
373 case SPECIAL_ATTN:
374 ss << "Special attn";
375 break;
376 default:
377 ss << "Unknown attn";
378 validAttn = false;
379 }
380
381 // see if attention is masked
382 if (true == validAttn)
383 {
384 if (0 != (i_mask & i_attn))
385 {
386 rc = true; // attention active and not masked
387 }
388 else
389 {
390 ss << " masked";
391 }
392 }
393
394 trace<level::INFO>(ss.str().c_str()); // commit trace stream
395 }
396
397 return rc;
398}
399
Ben Tyneref320152020-01-09 10:31:23 -0600400} // namespace attn