blob: 5ca4c692ed1a30c272d451acac4a083507468d7e [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
48/**
Ben Tyneref320152020-01-09 10:31:23 -060049 * @brief The main attention handler logic
Ben Tyner970fd4f2020-02-19 13:46:42 -060050 *
51 * @param i_breakpoints true = breakpoint special attn handling enabled
Ben Tyneref320152020-01-09 10:31:23 -060052 */
Ben Tyner3fb52e52020-03-31 10:10:07 -050053void attnHandler(Config* i_config)
Ben Tyneref320152020-01-09 10:31:23 -060054{
Ben Tynerb481d902020-03-05 10:24:23 -060055 // Vector of active attentions to be handled
56 std::vector<Attention> active_attentions;
57
Ben Tyneref320152020-01-09 10:31:23 -060058 uint32_t isr_val, isr_mask;
59 uint32_t proc;
60
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 {
69 proc = pdbg_target_index(target); // get processor number
70
71 std::stringstream ss; // log message stream
Ben Tyner9dbab8b2020-03-31 08:55:23 -050072 ss << "checking processor " << proc;
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050073 trace<level::INFO>(ss.str().c_str());
Ben Tyneref320152020-01-09 10:31:23 -060074
Ben Tyner5e622d82020-09-11 10:10:24 -050075 // The processor FSI target is required for CFAM read
76 char path[16];
77 sprintf(path, "/proc%d/fsi", proc);
78 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 Tynerb1ebfcb2020-05-08 18:52:48 -050085 // event
86 eventAttentionFail(RC_CFAM_ERROR);
87
88 // trace
Ben Tyner5e622d82020-09-11 10:10:24 -050089 trace<level::INFO>("Error! cfam read 0x1007 FAILED");
Ben Tyneref320152020-01-09 10:31:23 -060090 }
91 else
92 {
93 std::stringstream ss; // log message stream
Ben Tyner5e622d82020-09-11 10:10:24 -050094 ss << "cfam 0x1007 = 0x";
Ben Tyneref320152020-01-09 10:31:23 -060095 ss << std::hex << std::setw(8) << std::setfill('0');
Ben Tyner5e622d82020-09-11 10:10:24 -050096 ss << isr_val;
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050097 trace<level::INFO>(ss.str().c_str());
Ben Tyneref320152020-01-09 10:31:23 -060098
Ben Tyner5e622d82020-09-11 10:10:24 -050099 // get interrupt enabled special attentions mask
100 if (RC_SUCCESS != fsi_read(attnTarget, 0x100d, &isr_mask))
Ben Tyneref320152020-01-09 10:31:23 -0600101 {
Ben Tyner5e622d82020-09-11 10:10:24 -0500102 // event
103 eventAttentionFail(RC_CFAM_ERROR);
Ben Tyneref320152020-01-09 10:31:23 -0600104
Ben Tyner5e622d82020-09-11 10:10:24 -0500105 // trace
106 trace<level::INFO>("Error! cfam read 0x100d FAILED");
Ben Tyneref320152020-01-09 10:31:23 -0600107 }
Ben Tyner5e622d82020-09-11 10:10:24 -0500108 else
109 {
110 // CFAM 0x100d is expected to have bits set
111 // corresponding to attentions that can generate an
Ben Tyner04cbbb32020-10-07 13:27:46 -0500112 // attention interrupt.
Ben Tyneref320152020-01-09 10:31:23 -0600113
Ben Tyner5e622d82020-09-11 10:10:24 -0500114 std::stringstream ss; // log message stream
115 ss << "cfam 0x100d = 0x";
116 ss << std::hex << std::setw(8) << std::setfill('0');
117 ss << isr_mask;
118 trace<level::INFO>(ss.str().c_str());
119
120 // bit 0 on "left": bit 30 = SBE vital attention
Ben Tyner04cbbb32020-10-07 13:27:46 -0500121 if (isr_val & isr_mask & 0x00000002)
Ben Tyner5e622d82020-09-11 10:10:24 -0500122 {
123 active_attentions.emplace_back(Attention::Vital,
124 handleVital, target,
125 i_config);
126 }
127
128 // bit 0 on "left": bit 1 = checkstop
Ben Tyner04cbbb32020-10-07 13:27:46 -0500129 if (isr_val & isr_mask & 0x40000000)
Ben Tyner5e622d82020-09-11 10:10:24 -0500130 {
131 active_attentions.emplace_back(Attention::Checkstop,
132 handleCheckstop,
133 target, i_config);
134 }
135
136 // bit 0 on "left": bit 2 = special attention
Ben Tyner04cbbb32020-10-07 13:27:46 -0500137 if (isr_val & isr_mask & 0x20000000)
Ben Tyner5e622d82020-09-11 10:10:24 -0500138 {
139 active_attentions.emplace_back(Attention::Special,
140 handleSpecial,
141 target, i_config);
142 }
143 } // cfam 0x100d valid
144 } // cfam 0x1007 valid
145 } // proc target enabled
146 } // fsi target enabled
147 } // next processor
Ben Tyneref320152020-01-09 10:31:23 -0600148
Ben Tynerb481d902020-03-05 10:24:23 -0600149 // convert to heap, highest priority is at front
150 if (!std::is_heap(active_attentions.begin(), active_attentions.end()))
151 {
152 std::make_heap(active_attentions.begin(), active_attentions.end());
153 }
154
155 // call the attention handler until one is handled or all were attempted
156 while (false == active_attentions.empty())
157 {
158 // handle highest priority attention, done if successful
159 if (RC_SUCCESS == active_attentions.front().handle())
160 {
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500161 // an attention was handled so we are done
Ben Tynerb481d902020-03-05 10:24:23 -0600162 break;
163 }
164
165 // move attention to back of vector
166 std::pop_heap(active_attentions.begin(), active_attentions.end());
167
168 // remove attention from vector
169 active_attentions.pop_back();
170 }
Ben Tyneref320152020-01-09 10:31:23 -0600171}
172
173/**
174 * @brief Handle SBE vital attention
Ben Tyner3fb52e52020-03-31 10:10:07 -0500175 *
176 * @param i_attention Attention object
177 * @return 0 indicates that the vital attention was successfully handled
178 * 1 indicates that the vital attention was NOT successfully handled
Ben Tyneref320152020-01-09 10:31:23 -0600179 */
Ben Tynerb481d902020-03-05 10:24:23 -0600180int handleVital(Attention* i_attention)
Ben Tyneref320152020-01-09 10:31:23 -0600181{
Ben Tyner3fb52e52020-03-31 10:10:07 -0500182 int rc = RC_SUCCESS; // assume vital handled
Ben Tyneref320152020-01-09 10:31:23 -0600183
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500184 trace<level::INFO>("vital handler started");
185
Ben Tyner3fb52e52020-03-31 10:10:07 -0500186 // if vital handling enabled, handle vital attention
187 if (false == (i_attention->getConfig()->getFlag(enVital)))
188 {
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500189 trace<level::INFO>("vital handling disabled");
Ben Tyner792f32f2020-06-02 08:50:47 -0500190 rc = RC_NOT_HANDLED;
Ben Tyner3fb52e52020-03-31 10:10:07 -0500191 }
192 else
Ben Tyneref320152020-01-09 10:31:23 -0600193 {
Ben Tyner792f32f2020-06-02 08:50:47 -0500194 eventVital();
Ben Tyneref320152020-01-09 10:31:23 -0600195 }
196
197 return rc;
198}
199
200/**
201 * @brief Handle checkstop attention
Ben Tyner3fb52e52020-03-31 10:10:07 -0500202 *
203 * @param i_attention Attention object
204 * @return 0 indicates that the checkstop attention was successfully handled
205 * 1 indicates that the checkstop attention was NOT successfully
206 * handled.
Ben Tyneref320152020-01-09 10:31:23 -0600207 */
Ben Tynerb481d902020-03-05 10:24:23 -0600208int handleCheckstop(Attention* i_attention)
Ben Tyneref320152020-01-09 10:31:23 -0600209{
Ben Tyner3fb52e52020-03-31 10:10:07 -0500210 int rc = RC_SUCCESS; // assume checkstop handled
Ben Tyneref320152020-01-09 10:31:23 -0600211
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500212 trace<level::INFO>("checkstop handler started");
213
Ben Tyner3fb52e52020-03-31 10:10:07 -0500214 // if checkstop handling enabled, handle checkstop attention
215 if (false == (i_attention->getConfig()->getFlag(enCheckstop)))
216 {
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500217 trace<level::INFO>("Checkstop handling disabled");
Ben Tyner3fb52e52020-03-31 10:10:07 -0500218 }
219 else
220 {
Zane Shelley9fb73932020-09-15 13:34:57 -0500221 // Look for any attentions found in hardware. This will generate and
222 // comment a PEL if any errors are found.
223 if (true != analyzer::analyzeHardware())
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500224 {
225 rc = RC_ANALYZER_ERROR;
226 }
Ben Tyner3fb52e52020-03-31 10:10:07 -0500227 }
Ben Tyneref320152020-01-09 10:31:23 -0600228
Ben Tyneref320152020-01-09 10:31:23 -0600229 return rc;
230}
231
232/**
233 * @brief Handle special attention
Ben Tyner3fb52e52020-03-31 10:10:07 -0500234 *
235 * @param i_attention Attention object
236 * @return 0 indicates that the special attention was successfully handled
237 * 1 indicates that the special attention was NOT successfully handled
Ben Tyneref320152020-01-09 10:31:23 -0600238 */
Ben Tynerb481d902020-03-05 10:24:23 -0600239int handleSpecial(Attention* i_attention)
Ben Tyneref320152020-01-09 10:31:23 -0600240{
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500241 int rc = RC_SUCCESS; // assume special attention handled
Ben Tyneref320152020-01-09 10:31:23 -0600242
Ben Tyner792f32f2020-06-02 08:50:47 -0500243 // The TI infor chipop will give us a pointer to the TI info data
Ben Tyner98430b32020-08-19 19:14:02 -0500244 uint8_t* tiInfo = nullptr; // ptr to TI info data
245 uint32_t tiInfoLen = 0; // length of TI info data
246 pdbg_target* attnProc = i_attention->getTarget(); // proc with attention
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500247
Ben Tyner98430b32020-08-19 19:14:02 -0500248 if (attnProc != nullptr)
Ben Tyner89c0a7a2020-08-07 12:07:35 -0500249 {
Ben Tyner98430b32020-08-19 19:14:02 -0500250 // The processor PIB target is required for get TI info chipop
251 char path[16];
252 sprintf(path, "/proc%d/pib", pdbg_target_index(attnProc));
253 pdbg_target* tiInfoTarget = pdbg_target_from_path(nullptr, path);
254
255 if (nullptr != tiInfoTarget)
Ben Tyner89c0a7a2020-08-07 12:07:35 -0500256 {
Ben Tyner98430b32020-08-19 19:14:02 -0500257 if (PDBG_TARGET_ENABLED == pdbg_target_probe(tiInfoTarget))
258 {
259 trace<level::INFO>("calling sbe_mpipl_get_ti_info");
260 sbe_mpipl_get_ti_info(tiInfoTarget, &tiInfo, &tiInfoLen);
261 if (tiInfo == nullptr)
262 {
263 trace<level::INFO>("TI info data ptr is null after call");
264 }
265 }
Ben Tyner89c0a7a2020-08-07 12:07:35 -0500266 }
267 }
Ben Tyneref320152020-01-09 10:31:23 -0600268
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 Tyner98430b32020-08-19 19:14:02 -0500272 trace<level::INFO>("TI info data present and valid");
273
Ben Tyner792f32f2020-06-02 08:50:47 -0500274 TiDataArea* tiDataArea = (TiDataArea*)tiInfo;
Ben Tyner7e6611f2020-02-13 16:42:56 -0600275
Ben Tyner792f32f2020-06-02 08:50:47 -0500276 // trace a few known TI data area values
277 std::stringstream ss; // log message stream
Ben Tyner40717722020-09-23 09:43:20 -0500278
279 ss << "TI data command = " << (int)tiDataArea->command;
Ben Tyner792f32f2020-06-02 08:50:47 -0500280 trace<level::INFO>(ss.str().c_str());
Ben Tyner40717722020-09-23 09:43:20 -0500281 ss.str(std::string());
282
283 ss << "TI data SRC format = " << (int)tiDataArea->srcFormat;
Ben Tyner792f32f2020-06-02 08:50:47 -0500284 trace<level::INFO>(ss.str().c_str());
Ben Tyner40717722020-09-23 09:43:20 -0500285 ss.str(std::string());
286
287 ss << "TI data hb_terminate_type = "
288 << (int)tiDataArea->hbTerminateType;
Ben Tyner792f32f2020-06-02 08:50:47 -0500289 trace<level::INFO>(ss.str().c_str());
Ben Tyner40717722020-09-23 09:43:20 -0500290 ss.str(std::string());
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500291
Ben Tyner792f32f2020-06-02 08:50:47 -0500292 if (true == (i_attention->getConfig()->getFlag(enTerminate)))
293 {
294 trace<level::INFO>("TI (terminate immediately)");
295
296 // Call TI special attention handler
297 rc = tiHandler(tiDataArea);
298 }
Ben Tyner3fb52e52020-03-31 10:10:07 -0500299 }
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500300 // TI area not valid or not available
Ben Tyner3fb52e52020-03-31 10:10:07 -0500301 else
302 {
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500303 trace<level::INFO>("TI info NOT available");
Ben Tyner98430b32020-08-19 19:14:02 -0500304
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500305 // if configured to handle breakpoint as default special attention
306 if (i_attention->getConfig()->getFlag(dfltBreakpoint))
Ben Tyner3fb52e52020-03-31 10:10:07 -0500307 {
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500308 trace<level::INFO>("assuming breakpoint");
Ben Tyner3fb52e52020-03-31 10:10:07 -0500309
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500310 if (true == (i_attention->getConfig()->getFlag(enBreakpoints)))
311 {
312 trace<level::INFO>("breakpoint");
313
314 // Call the breakpoint special attention handler
315 bpHandler();
316 }
317 }
318 // if configured to handle TI as default special attention
319 else
320 {
321 trace<level::INFO>("assuming TI");
322
323 if (true == (i_attention->getConfig()->getFlag(enTerminate)))
324 {
325 trace<level::INFO>("TI (terminate immediately)");
326
327 // Call TI special attention handler
328 rc = tiHandler(nullptr);
329 }
Ben Tyner3fb52e52020-03-31 10:10:07 -0500330 }
Ben Tyner970fd4f2020-02-19 13:46:42 -0600331 }
Ben Tyneref320152020-01-09 10:31:23 -0600332
Ben Tyner792f32f2020-06-02 08:50:47 -0500333 // release TI data buffer
334 if (nullptr != tiInfo)
335 {
336 free(tiInfo);
337 }
338
Ben Tyner3fb52e52020-03-31 10:10:07 -0500339 if (RC_SUCCESS != rc)
340 {
Ben Tyner792f32f2020-06-02 08:50:47 -0500341 trace<level::INFO>("Special attn not handled");
Ben Tyner3fb52e52020-03-31 10:10:07 -0500342 }
Ben Tyneref320152020-01-09 10:31:23 -0600343
344 return rc;
345}
346
Ben Tyneref320152020-01-09 10:31:23 -0600347} // namespace attn