blob: d1f028d242df19236de86f03de4273cad04a4d94 [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 */
Ben Tyner1965e502020-11-20 10:32:24 -060049bool activeAttn(uint32_t i_val, uint32_t i_mask, uint32_t i_attn);
Ben Tynerfb190542020-11-06 09:27:56 -060050
Ben Tyneref320152020-01-09 10:31:23 -060051/**
Ben Tyneref320152020-01-09 10:31:23 -060052 * @brief The main attention handler logic
Ben Tyner970fd4f2020-02-19 13:46:42 -060053 *
54 * @param i_breakpoints true = breakpoint special attn handling enabled
Ben Tyneref320152020-01-09 10:31:23 -060055 */
Ben Tyner3fb52e52020-03-31 10:10:07 -050056void attnHandler(Config* i_config)
Ben Tyneref320152020-01-09 10:31:23 -060057{
Ben Tynerb481d902020-03-05 10:24:23 -060058 // Vector of active attentions to be handled
59 std::vector<Attention> active_attentions;
60
Ben Tyneref320152020-01-09 10:31:23 -060061 uint32_t isr_val, isr_mask;
62 uint32_t proc;
63
Ben Tyner1965e502020-11-20 10:32:24 -060064 std::stringstream ss; // for trace messages
65
Ben Tyneref320152020-01-09 10:31:23 -060066 // loop through processors looking for active attentions
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050067 trace<level::INFO>("Attention handler started");
Ben Tyner117af992020-05-22 13:32:11 -050068
Ben Tyneref320152020-01-09 10:31:23 -060069 pdbg_target* target;
Ben Tyner5e622d82020-09-11 10:10:24 -050070 pdbg_for_each_class_target("proc", target)
Ben Tyneref320152020-01-09 10:31:23 -060071 {
72 if (PDBG_TARGET_ENABLED == pdbg_target_probe(target))
73 {
74 proc = pdbg_target_index(target); // get processor number
75
Ben Tynerb83c8522020-11-20 10:45:26 -060076 // Use PIB target to determine if a processor is enabled
Ben Tyner5e622d82020-09-11 10:10:24 -050077 char path[16];
Ben Tynerb83c8522020-11-20 10:45:26 -060078 sprintf(path, "/proc%d/pib", proc);
Ben Tyner5e622d82020-09-11 10:10:24 -050079 pdbg_target* attnTarget = pdbg_target_from_path(nullptr, path);
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050080
Ben Tynerb83c8522020-11-20 10:45:26 -060081 // sanity check
82 if (nullptr == attnTarget)
83 {
84 trace<level::INFO>("pib path or target not found");
85 continue;
86 }
87
Ben Tyner5e622d82020-09-11 10:10:24 -050088 if (PDBG_TARGET_ENABLED == pdbg_target_probe(attnTarget))
Ben Tyneref320152020-01-09 10:31:23 -060089 {
Ben Tynerb83c8522020-11-20 10:45:26 -060090 // The processor FSI target is required for CFAM read
91 sprintf(path, "/proc%d/fsi", proc);
92 attnTarget = pdbg_target_from_path(nullptr, path);
93
94 // sanity check
95 if (nullptr == attnTarget)
96 {
97 trace<level::INFO>("fsi path or target not found");
98 continue;
99 }
100
Ben Tyner1965e502020-11-20 10:32:24 -0600101 // trace fsi path
102 ss.str(std::string()); // clear stream
103 ss << "target - " << path;
104 trace<level::INFO>(ss.str().c_str());
105
Ben Tyner5adc96e2020-11-20 10:54:12 -0600106 isr_val = 0xffffffff; // invalid isr value
107
Ben Tyner5e622d82020-09-11 10:10:24 -0500108 // get active attentions on processor
109 if (RC_SUCCESS != fsi_read(attnTarget, 0x1007, &isr_val))
Ben Tyneref320152020-01-09 10:31:23 -0600110 {
Ben Tynerfb190542020-11-06 09:27:56 -0600111 // log cfam read error
Ben Tyner5e622d82020-09-11 10:10:24 -0500112 trace<level::INFO>("Error! cfam read 0x1007 FAILED");
Ben Tynerfb190542020-11-06 09:27:56 -0600113 eventAttentionFail(RC_CFAM_ERROR);
Ben Tyneref320152020-01-09 10:31:23 -0600114 }
Ben Tyner5adc96e2020-11-20 10:54:12 -0600115 else if (0xffffffff == isr_val)
116 {
117 trace<level::INFO>("Error! cfam read 0x1007 INVALID");
118 continue;
119 }
Ben Tyneref320152020-01-09 10:31:23 -0600120 else
121 {
Ben Tyner1965e502020-11-20 10:32:24 -0600122 // trace isr
123 ss.str(std::string()); // clear stream
124 ss << std::hex << std::showbase; // trace as hex vals
125 ss << "cfam 0x1007 = " << std::setw(8) << std::setfill('0')
126 << isr_val;
127 trace<level::INFO>(ss.str().c_str());
128
Ben Tyner5adc96e2020-11-20 10:54:12 -0600129 isr_mask = 0xffffffff; // invalid isr mask
130
Ben Tyner5e622d82020-09-11 10:10:24 -0500131 // get interrupt enabled special attentions mask
132 if (RC_SUCCESS != fsi_read(attnTarget, 0x100d, &isr_mask))
Ben Tyneref320152020-01-09 10:31:23 -0600133 {
Ben Tynerfb190542020-11-06 09:27:56 -0600134 // log cfam read error
Ben Tyner5e622d82020-09-11 10:10:24 -0500135 trace<level::INFO>("Error! cfam read 0x100d FAILED");
Ben Tynerfb190542020-11-06 09:27:56 -0600136 eventAttentionFail(RC_CFAM_ERROR);
Ben Tyneref320152020-01-09 10:31:23 -0600137 }
Ben Tyner5adc96e2020-11-20 10:54:12 -0600138 else if (0xffffffff == isr_mask)
139 {
140 trace<level::INFO>("Error! cfam read 0x100d INVALID");
141 continue;
142 }
Ben Tyner5e622d82020-09-11 10:10:24 -0500143 else
144 {
Ben Tyner1965e502020-11-20 10:32:24 -0600145 // trace true-mask
146 ss.str(std::string()); // clear stream
147 ss << std::hex << std::showbase; // trace as hex vals
148 ss << "cfam 0x100d = " << std::setw(8)
149 << std::setfill('0') << isr_mask;
150 trace<level::INFO>(ss.str().c_str());
151
Ben Tynerfb190542020-11-06 09:27:56 -0600152 // SBE vital attention active and not masked?
Ben Tyner1965e502020-11-20 10:32:24 -0600153 if (true == activeAttn(isr_val, isr_mask, SBE_ATTN))
Ben Tyner5e622d82020-09-11 10:10:24 -0500154 {
155 active_attentions.emplace_back(Attention::Vital,
156 handleVital, target,
157 i_config);
158 }
159
Ben Tynerfb190542020-11-06 09:27:56 -0600160 // Checkstop attention active and not masked?
161 if (true ==
Ben Tyner1965e502020-11-20 10:32:24 -0600162 activeAttn(isr_val, isr_mask, CHECKSTOP_ATTN))
Ben Tyner5e622d82020-09-11 10:10:24 -0500163 {
164 active_attentions.emplace_back(Attention::Checkstop,
165 handleCheckstop,
166 target, i_config);
167 }
168
Ben Tynerfb190542020-11-06 09:27:56 -0600169 // Special attention active and not masked?
Ben Tyner1965e502020-11-20 10:32:24 -0600170 if (true == activeAttn(isr_val, isr_mask, SPECIAL_ATTN))
Ben Tyner5e622d82020-09-11 10:10:24 -0500171 {
172 active_attentions.emplace_back(Attention::Special,
173 handleSpecial,
174 target, i_config);
175 }
176 } // cfam 0x100d valid
177 } // cfam 0x1007 valid
178 } // proc target enabled
179 } // fsi target enabled
180 } // next processor
Ben Tyneref320152020-01-09 10:31:23 -0600181
Ben Tynerb481d902020-03-05 10:24:23 -0600182 // convert to heap, highest priority is at front
183 if (!std::is_heap(active_attentions.begin(), active_attentions.end()))
184 {
185 std::make_heap(active_attentions.begin(), active_attentions.end());
186 }
187
188 // call the attention handler until one is handled or all were attempted
189 while (false == active_attentions.empty())
190 {
191 // handle highest priority attention, done if successful
192 if (RC_SUCCESS == active_attentions.front().handle())
193 {
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500194 // an attention was handled so we are done
Ben Tynerb481d902020-03-05 10:24:23 -0600195 break;
196 }
197
198 // move attention to back of vector
199 std::pop_heap(active_attentions.begin(), active_attentions.end());
200
201 // remove attention from vector
202 active_attentions.pop_back();
203 }
Ben Tyneref320152020-01-09 10:31:23 -0600204}
205
206/**
207 * @brief Handle SBE vital attention
Ben Tyner3fb52e52020-03-31 10:10:07 -0500208 *
209 * @param i_attention Attention object
210 * @return 0 indicates that the vital attention was successfully handled
211 * 1 indicates that the vital attention was NOT successfully handled
Ben Tyneref320152020-01-09 10:31:23 -0600212 */
Ben Tynerb481d902020-03-05 10:24:23 -0600213int handleVital(Attention* i_attention)
Ben Tyneref320152020-01-09 10:31:23 -0600214{
Ben Tyner3fb52e52020-03-31 10:10:07 -0500215 int rc = RC_SUCCESS; // assume vital handled
Ben Tyneref320152020-01-09 10:31:23 -0600216
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500217 trace<level::INFO>("vital handler started");
218
Ben Tyner3fb52e52020-03-31 10:10:07 -0500219 // if vital handling enabled, handle vital attention
220 if (false == (i_attention->getConfig()->getFlag(enVital)))
221 {
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500222 trace<level::INFO>("vital handling disabled");
Ben Tyner792f32f2020-06-02 08:50:47 -0500223 rc = RC_NOT_HANDLED;
Ben Tyner3fb52e52020-03-31 10:10:07 -0500224 }
225 else
Ben Tyneref320152020-01-09 10:31:23 -0600226 {
Ben Tyner792f32f2020-06-02 08:50:47 -0500227 eventVital();
Ben Tyneref320152020-01-09 10:31:23 -0600228 }
229
230 return rc;
231}
232
233/**
234 * @brief Handle checkstop attention
Ben Tyner3fb52e52020-03-31 10:10:07 -0500235 *
236 * @param i_attention Attention object
237 * @return 0 indicates that the checkstop attention was successfully handled
238 * 1 indicates that the checkstop attention was NOT successfully
239 * handled.
Ben Tyneref320152020-01-09 10:31:23 -0600240 */
Ben Tynerb481d902020-03-05 10:24:23 -0600241int handleCheckstop(Attention* i_attention)
Ben Tyneref320152020-01-09 10:31:23 -0600242{
Ben Tyner3fb52e52020-03-31 10:10:07 -0500243 int rc = RC_SUCCESS; // assume checkstop handled
Ben Tyneref320152020-01-09 10:31:23 -0600244
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500245 trace<level::INFO>("checkstop handler started");
246
Ben Tyner3fb52e52020-03-31 10:10:07 -0500247 // if checkstop handling enabled, handle checkstop attention
248 if (false == (i_attention->getConfig()->getFlag(enCheckstop)))
249 {
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500250 trace<level::INFO>("Checkstop handling disabled");
Ben Tyner3fb52e52020-03-31 10:10:07 -0500251 }
252 else
253 {
Zane Shelley9fb73932020-09-15 13:34:57 -0500254 // Look for any attentions found in hardware. This will generate and
Zane Shelley7ae9c8c2020-12-02 20:10:31 -0600255 // commit a PEL if any errors are found.
Zane Shelley9fb73932020-09-15 13:34:57 -0500256 if (true != analyzer::analyzeHardware())
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500257 {
258 rc = RC_ANALYZER_ERROR;
259 }
Ben Tyner3fb52e52020-03-31 10:10:07 -0500260 }
Ben Tyneref320152020-01-09 10:31:23 -0600261
Ben Tyneref320152020-01-09 10:31:23 -0600262 return rc;
263}
264
265/**
266 * @brief Handle special attention
Ben Tyner3fb52e52020-03-31 10:10:07 -0500267 *
268 * @param i_attention Attention object
269 * @return 0 indicates that the special attention was successfully handled
270 * 1 indicates that the special attention was NOT successfully handled
Ben Tyneref320152020-01-09 10:31:23 -0600271 */
Ben Tynerb481d902020-03-05 10:24:23 -0600272int handleSpecial(Attention* i_attention)
Ben Tyneref320152020-01-09 10:31:23 -0600273{
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500274 int rc = RC_SUCCESS; // assume special attention handled
Ben Tyneref320152020-01-09 10:31:23 -0600275
Ben Tynerfb190542020-11-06 09:27:56 -0600276 // The TI info chipop will give us a pointer to the TI info data
Ben Tyner98430b32020-08-19 19:14:02 -0500277 uint8_t* tiInfo = nullptr; // ptr to TI info data
278 uint32_t tiInfoLen = 0; // length of TI info data
279 pdbg_target* attnProc = i_attention->getTarget(); // proc with attention
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500280
Ben Tyner98430b32020-08-19 19:14:02 -0500281 if (attnProc != nullptr)
Ben Tyner89c0a7a2020-08-07 12:07:35 -0500282 {
Ben Tyner98430b32020-08-19 19:14:02 -0500283 // The processor PIB target is required for get TI info chipop
284 char path[16];
285 sprintf(path, "/proc%d/pib", pdbg_target_index(attnProc));
286 pdbg_target* tiInfoTarget = pdbg_target_from_path(nullptr, path);
287
288 if (nullptr != tiInfoTarget)
Ben Tyner89c0a7a2020-08-07 12:07:35 -0500289 {
Ben Tyner98430b32020-08-19 19:14:02 -0500290 if (PDBG_TARGET_ENABLED == pdbg_target_probe(tiInfoTarget))
291 {
Ben Tyner98430b32020-08-19 19:14:02 -0500292 sbe_mpipl_get_ti_info(tiInfoTarget, &tiInfo, &tiInfoLen);
293 if (tiInfo == nullptr)
294 {
295 trace<level::INFO>("TI info data ptr is null after call");
296 }
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 Tyner792f32f2020-06-02 08:50:47 -0500308 // trace a few known TI data area values
Ben Tyner8c5e4f42020-10-28 11:11:55 -0500309 std::stringstream ss;
310 ss << std::hex << std::showbase;
Ben Tyner40717722020-09-23 09:43:20 -0500311
312 ss << "TI data command = " << (int)tiDataArea->command;
Ben Tyner792f32f2020-06-02 08:50:47 -0500313 trace<level::INFO>(ss.str().c_str());
Ben Tyner40717722020-09-23 09:43:20 -0500314 ss.str(std::string());
315
Ben Tyner0fe5df42020-12-03 08:57:17 -0600316 // Another check for valid TI Info since it has been seen that
317 // tiInfo[0] != 0 but TI info is not valid
318 if (0xa1 == tiDataArea->command)
Ben Tyner792f32f2020-06-02 08:50:47 -0500319 {
Ben Tyner0fe5df42020-12-03 08:57:17 -0600320 tiInfoValid = true;
321
322 // trace some more data since TI info appears valid
323 ss << "TI data hb_terminate_type = "
324 << (int)tiDataArea->hbTerminateType;
325 trace<level::INFO>(ss.str().c_str());
326 ss.str(std::string());
327
328 ss << "TI data SRC format = " << (int)tiDataArea->srcFormat;
329 trace<level::INFO>(ss.str().c_str());
330 ss.str(std::string());
331
332 ss << "TI data source = " << (int)tiDataArea->source;
333 trace<level::INFO>(ss.str().c_str());
334 ss.str(std::string());
335
336 if (true == (i_attention->getConfig()->getFlag(enTerminate)))
337 {
338 // Call TI special attention handler
339 rc = tiHandler(tiDataArea);
340 }
Ben Tyner792f32f2020-06-02 08:50:47 -0500341 }
Ben Tyner3fb52e52020-03-31 10:10:07 -0500342 }
Ben Tyner0fe5df42020-12-03 08:57:17 -0600343
344 // If TI area not valid or not available
345 if (false == tiInfoValid)
Ben Tyner3fb52e52020-03-31 10:10:07 -0500346 {
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500347 trace<level::INFO>("TI info NOT available");
Ben Tyner98430b32020-08-19 19:14:02 -0500348
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500349 // if configured to handle breakpoint as default special attention
350 if (i_attention->getConfig()->getFlag(dfltBreakpoint))
Ben Tyner3fb52e52020-03-31 10:10:07 -0500351 {
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500352 if (true == (i_attention->getConfig()->getFlag(enBreakpoints)))
353 {
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500354 // Call the breakpoint special attention handler
355 bpHandler();
356 }
357 }
358 // if configured to handle TI as default special attention
359 else
360 {
361 trace<level::INFO>("assuming TI");
362
363 if (true == (i_attention->getConfig()->getFlag(enTerminate)))
364 {
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500365 // Call TI special attention handler
366 rc = tiHandler(nullptr);
367 }
Ben Tyner3fb52e52020-03-31 10:10:07 -0500368 }
Ben Tyner970fd4f2020-02-19 13:46:42 -0600369 }
Ben Tyneref320152020-01-09 10:31:23 -0600370
Ben Tyner792f32f2020-06-02 08:50:47 -0500371 // release TI data buffer
372 if (nullptr != tiInfo)
373 {
374 free(tiInfo);
375 }
376
Ben Tyner3fb52e52020-03-31 10:10:07 -0500377 if (RC_SUCCESS != rc)
378 {
Ben Tyner792f32f2020-06-02 08:50:47 -0500379 trace<level::INFO>("Special attn not handled");
Ben Tyner3fb52e52020-03-31 10:10:07 -0500380 }
Ben Tyneref320152020-01-09 10:31:23 -0600381
382 return rc;
383}
384
Ben Tynerfb190542020-11-06 09:27:56 -0600385/**
386 * @brief Determine if attention is active and not masked
387 *
388 * Determine whether an attention needs to be handled and trace details of
389 * attention type and whether it is masked or not.
390 *
391 * @param i_val attention status register
392 * @param i_mask attention true mask register
393 * @param i_attn attention type
394 * @param i_proc processor associated with registers
395 *
396 * @return true if attention is active and not masked, otherwise false
397 */
Ben Tyner1965e502020-11-20 10:32:24 -0600398bool activeAttn(uint32_t i_val, uint32_t i_mask, uint32_t i_attn)
Ben Tynerfb190542020-11-06 09:27:56 -0600399{
400 bool rc = false; // assume attn masked and/or inactive
401 bool validAttn = true; // known attention type
402
403 // if attention active
404 if (0 != (i_val & i_attn))
405 {
Ben Tynerfb190542020-11-06 09:27:56 -0600406 std::stringstream ss;
Ben Tynerfb190542020-11-06 09:27:56 -0600407
408 switch (i_attn)
409 {
410 case SBE_ATTN:
411 ss << "SBE attn";
412 break;
413 case CHECKSTOP_ATTN:
414 ss << "Checkstop attn";
415 break;
416 case SPECIAL_ATTN:
417 ss << "Special attn";
418 break;
419 default:
420 ss << "Unknown attn";
421 validAttn = false;
422 }
423
424 // see if attention is masked
425 if (true == validAttn)
426 {
427 if (0 != (i_mask & i_attn))
428 {
429 rc = true; // attention active and not masked
430 }
431 else
432 {
433 ss << " masked";
434 }
435 }
436
437 trace<level::INFO>(ss.str().c_str()); // commit trace stream
438 }
439
440 return rc;
441}
442
Ben Tyneref320152020-01-09 10:31:23 -0600443} // namespace attn