blob: 04447abf151515a18f73d537cc8f0f1f96996554 [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;
65 pdbg_for_each_class_target("fsi", target)
66 {
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
75 // get active attentions on processor
Ben Tynerb481d902020-03-05 10:24:23 -060076 if (RC_SUCCESS != fsi_read(target, 0x1007, &isr_val))
Ben Tyneref320152020-01-09 10:31:23 -060077 {
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050078 // event
79 eventAttentionFail(RC_CFAM_ERROR);
80
81 // trace
82 trace<level::INFO>("Error! cfam read 0x1007 FAILED");
Ben Tyneref320152020-01-09 10:31:23 -060083 }
84 else
85 {
86 std::stringstream ss; // log message stream
Ben Tyner9ae5ca42020-02-28 13:13:50 -060087 ss << "cfam 0x1007 = 0x";
Ben Tyneref320152020-01-09 10:31:23 -060088 ss << std::hex << std::setw(8) << std::setfill('0');
Ben Tyner9dbab8b2020-03-31 08:55:23 -050089 ss << isr_val;
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050090 trace<level::INFO>(ss.str().c_str());
Ben Tyneref320152020-01-09 10:31:23 -060091
92 // get interrupt enabled special attentions mask
Ben Tynerb481d902020-03-05 10:24:23 -060093 if (RC_SUCCESS != fsi_read(target, 0x100d, &isr_mask))
Ben Tyneref320152020-01-09 10:31:23 -060094 {
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050095 // event
96 eventAttentionFail(RC_CFAM_ERROR);
97
98 // trace
99 trace<level::INFO>("Error! cfam read 0x100d FAILED");
Ben Tyneref320152020-01-09 10:31:23 -0600100 }
101 else
102 {
Ben Tyner46b456b2020-07-07 12:30:08 -0500103 // CFAM 0x100d is expected to have bits set corresponding
104 // to attentions that can generate an attention interrupt.
105 // We will trace this register value to help debug cases
106 // where the attention handler was invoked unexpectedly.
107
Ben Tyneref320152020-01-09 10:31:23 -0600108 std::stringstream ss; // log message stream
Ben Tyner9ae5ca42020-02-28 13:13:50 -0600109 ss << "cfam 0x100d = 0x";
Ben Tyneref320152020-01-09 10:31:23 -0600110 ss << std::hex << std::setw(8) << std::setfill('0');
Ben Tyner9dbab8b2020-03-31 08:55:23 -0500111 ss << isr_mask;
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500112 trace<level::INFO>(ss.str().c_str());
Ben Tyneref320152020-01-09 10:31:23 -0600113
114 // bit 0 on "left": bit 30 = SBE vital attention
Ben Tyner46b456b2020-07-07 12:30:08 -0500115 if (isr_val & 0x00000002)
Ben Tyneref320152020-01-09 10:31:23 -0600116 {
Ben Tyner3fb52e52020-03-31 10:10:07 -0500117 active_attentions.emplace_back(
118 Attention::Vital, handleVital, target, i_config);
Ben Tyneref320152020-01-09 10:31:23 -0600119 }
120
121 // bit 0 on "left": bit 1 = checkstop
Ben Tyner46b456b2020-07-07 12:30:08 -0500122 if (isr_val & 0x40000000)
Ben Tyneref320152020-01-09 10:31:23 -0600123 {
Ben Tynerb481d902020-03-05 10:24:23 -0600124 active_attentions.emplace_back(Attention::Checkstop,
125 handleCheckstop, target,
Ben Tyner3fb52e52020-03-31 10:10:07 -0500126 i_config);
Ben Tyneref320152020-01-09 10:31:23 -0600127 }
128
129 // bit 0 on "left": bit 2 = special attention
Ben Tyner46b456b2020-07-07 12:30:08 -0500130 if (isr_val & 0x20000000)
Ben Tyneref320152020-01-09 10:31:23 -0600131 {
Ben Tynerb481d902020-03-05 10:24:23 -0600132 active_attentions.emplace_back(Attention::Special,
133 handleSpecial, target,
Ben Tyner3fb52e52020-03-31 10:10:07 -0500134 i_config);
Ben Tyneref320152020-01-09 10:31:23 -0600135 }
136 } // cfam 0x100d valid
137 } // cfam 0x1007 valid
138 } // fsi target enabled
139 } // next processor
140
Ben Tynerb481d902020-03-05 10:24:23 -0600141 // convert to heap, highest priority is at front
142 if (!std::is_heap(active_attentions.begin(), active_attentions.end()))
143 {
144 std::make_heap(active_attentions.begin(), active_attentions.end());
145 }
146
147 // call the attention handler until one is handled or all were attempted
148 while (false == active_attentions.empty())
149 {
150 // handle highest priority attention, done if successful
151 if (RC_SUCCESS == active_attentions.front().handle())
152 {
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500153 // an attention was handled so we are done
Ben Tynerb481d902020-03-05 10:24:23 -0600154 break;
155 }
156
157 // move attention to back of vector
158 std::pop_heap(active_attentions.begin(), active_attentions.end());
159
160 // remove attention from vector
161 active_attentions.pop_back();
162 }
Ben Tyneref320152020-01-09 10:31:23 -0600163}
164
165/**
166 * @brief Handle SBE vital attention
Ben Tyner3fb52e52020-03-31 10:10:07 -0500167 *
168 * @param i_attention Attention object
169 * @return 0 indicates that the vital attention was successfully handled
170 * 1 indicates that the vital attention was NOT successfully handled
Ben Tyneref320152020-01-09 10:31:23 -0600171 */
Ben Tynerb481d902020-03-05 10:24:23 -0600172int handleVital(Attention* i_attention)
Ben Tyneref320152020-01-09 10:31:23 -0600173{
Ben Tyner3fb52e52020-03-31 10:10:07 -0500174 int rc = RC_SUCCESS; // assume vital handled
Ben Tyneref320152020-01-09 10:31:23 -0600175
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500176 trace<level::INFO>("vital handler started");
177
Ben Tyner3fb52e52020-03-31 10:10:07 -0500178 // if vital handling enabled, handle vital attention
179 if (false == (i_attention->getConfig()->getFlag(enVital)))
180 {
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500181 trace<level::INFO>("vital handling disabled");
Ben Tyner792f32f2020-06-02 08:50:47 -0500182 rc = RC_NOT_HANDLED;
Ben Tyner3fb52e52020-03-31 10:10:07 -0500183 }
184 else
Ben Tyneref320152020-01-09 10:31:23 -0600185 {
Ben Tyner792f32f2020-06-02 08:50:47 -0500186 eventVital();
Ben Tyneref320152020-01-09 10:31:23 -0600187 }
188
189 return rc;
190}
191
192/**
193 * @brief Handle checkstop attention
Ben Tyner3fb52e52020-03-31 10:10:07 -0500194 *
195 * @param i_attention Attention object
196 * @return 0 indicates that the checkstop attention was successfully handled
197 * 1 indicates that the checkstop attention was NOT successfully
198 * handled.
Ben Tyneref320152020-01-09 10:31:23 -0600199 */
Ben Tynerb481d902020-03-05 10:24:23 -0600200int handleCheckstop(Attention* i_attention)
Ben Tyneref320152020-01-09 10:31:23 -0600201{
Ben Tyner3fb52e52020-03-31 10:10:07 -0500202 int rc = RC_SUCCESS; // assume checkstop handled
Ben Tyneref320152020-01-09 10:31:23 -0600203
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500204 trace<level::INFO>("checkstop handler started");
205
Ben Tyner3fb52e52020-03-31 10:10:07 -0500206 // if checkstop handling enabled, handle checkstop attention
207 if (false == (i_attention->getConfig()->getFlag(enCheckstop)))
208 {
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500209 trace<level::INFO>("Checkstop handling disabled");
Ben Tyner3fb52e52020-03-31 10:10:07 -0500210 }
211 else
212 {
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500213 // errors that were isolated
214 std::map<std::string, std::string> errors;
215
Ben Tynerdbeaf792020-05-14 08:27:18 -0500216 // analyze errors
217 if (true != analyzer::analyzeHardware(errors))
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500218 {
219 rc = RC_ANALYZER_ERROR;
220 }
221 else
222 {
223 std::stringstream ss;
224 ss << "Analyzer isolated " << errors.size() << " error(s)";
225 trace<level::INFO>(ss.str().c_str());
226
227 // add checkstop event to log
228 eventCheckstop(errors);
229 }
Ben Tyner3fb52e52020-03-31 10:10:07 -0500230 }
Ben Tyneref320152020-01-09 10:31:23 -0600231
Ben Tyneref320152020-01-09 10:31:23 -0600232 return rc;
233}
234
235/**
236 * @brief Handle special attention
Ben Tyner3fb52e52020-03-31 10:10:07 -0500237 *
238 * @param i_attention Attention object
239 * @return 0 indicates that the special attention was successfully handled
240 * 1 indicates that the special attention was NOT successfully handled
Ben Tyneref320152020-01-09 10:31:23 -0600241 */
Ben Tynerb481d902020-03-05 10:24:23 -0600242int handleSpecial(Attention* i_attention)
Ben Tyneref320152020-01-09 10:31:23 -0600243{
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500244 int rc = RC_SUCCESS; // assume special attention handled
Ben Tyneref320152020-01-09 10:31:23 -0600245
Ben Tyner792f32f2020-06-02 08:50:47 -0500246 // The TI infor chipop will give us a pointer to the TI info data
Ben Tyner98430b32020-08-19 19:14:02 -0500247 uint8_t* tiInfo = nullptr; // ptr to TI info data
248 uint32_t tiInfoLen = 0; // length of TI info data
249 pdbg_target* attnProc = i_attention->getTarget(); // proc with attention
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500250
Ben Tyner98430b32020-08-19 19:14:02 -0500251 if (attnProc != nullptr)
Ben Tyner89c0a7a2020-08-07 12:07:35 -0500252 {
Ben Tyner98430b32020-08-19 19:14:02 -0500253 // The processor PIB target is required for get TI info chipop
254 char path[16];
255 sprintf(path, "/proc%d/pib", pdbg_target_index(attnProc));
256 pdbg_target* tiInfoTarget = pdbg_target_from_path(nullptr, path);
257
258 if (nullptr != tiInfoTarget)
Ben Tyner89c0a7a2020-08-07 12:07:35 -0500259 {
Ben Tyner98430b32020-08-19 19:14:02 -0500260 if (PDBG_TARGET_ENABLED == pdbg_target_probe(tiInfoTarget))
261 {
262 trace<level::INFO>("calling sbe_mpipl_get_ti_info");
263 sbe_mpipl_get_ti_info(tiInfoTarget, &tiInfo, &tiInfoLen);
264 if (tiInfo == nullptr)
265 {
266 trace<level::INFO>("TI info data ptr is null after call");
267 }
268 }
Ben Tyner89c0a7a2020-08-07 12:07:35 -0500269 }
270 }
Ben Tyneref320152020-01-09 10:31:23 -0600271
Ben Tyner792f32f2020-06-02 08:50:47 -0500272 // Note: If we want to support running this application on architectures
273 // of different endian-ness we need to handler that here. The TI data
274 // will always be written in big-endian order.
275
276 // If TI area exists and is marked valid we can assume TI occurred
277 if ((nullptr != tiInfo) && (0 != tiInfo[0]))
Ben Tyner970fd4f2020-02-19 13:46:42 -0600278 {
Ben Tyner98430b32020-08-19 19:14:02 -0500279 trace<level::INFO>("TI info data present and valid");
280
Ben Tyner792f32f2020-06-02 08:50:47 -0500281 TiDataArea* tiDataArea = (TiDataArea*)tiInfo;
Ben Tyner7e6611f2020-02-13 16:42:56 -0600282
Ben Tyner792f32f2020-06-02 08:50:47 -0500283 // trace a few known TI data area values
284 std::stringstream ss; // log message stream
285 ss << "TI data command = " << tiDataArea->command;
286 trace<level::INFO>(ss.str().c_str());
287 ss << "TI data SRC format = " << tiDataArea->srcFormat;
288 trace<level::INFO>(ss.str().c_str());
289 ss << "TI data hb_terminate_type = " << tiDataArea->hbTerminateType;
290 trace<level::INFO>(ss.str().c_str());
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 Tyner792f32f2020-06-02 08:50:47 -0500300 // TI area not valid, assume breakpoint
Ben Tyner3fb52e52020-03-31 10:10:07 -0500301 else
302 {
Ben Tyner98430b32020-08-19 19:14:02 -0500303 trace<level::INFO>("TI info NOT available, assume breakpoint");
304
Ben Tyner3fb52e52020-03-31 10:10:07 -0500305 if (true == (i_attention->getConfig()->getFlag(enBreakpoints)))
306 {
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500307 trace<level::INFO>("breakpoint");
Ben Tyner3fb52e52020-03-31 10:10:07 -0500308
309 // Call the breakpoint special attention handler
310 bpHandler();
Ben Tyner3fb52e52020-03-31 10:10:07 -0500311 }
Ben Tyner970fd4f2020-02-19 13:46:42 -0600312 }
Ben Tyneref320152020-01-09 10:31:23 -0600313
Ben Tyner792f32f2020-06-02 08:50:47 -0500314 // release TI data buffer
315 if (nullptr != tiInfo)
316 {
317 free(tiInfo);
318 }
319
Ben Tyner3fb52e52020-03-31 10:10:07 -0500320 if (RC_SUCCESS != rc)
321 {
Ben Tyner792f32f2020-06-02 08:50:47 -0500322 trace<level::INFO>("Special attn not handled");
Ben Tyner3fb52e52020-03-31 10:10:07 -0500323 }
Ben Tyneref320152020-01-09 10:31:23 -0600324
325 return rc;
326}
327
Ben Tyneref320152020-01-09 10:31:23 -0600328} // namespace attn