blob: 59dfab3f55ac09a58457867f2b41e467ca76f727 [file] [log] [blame]
Jayanth Othayothb1eda6a2021-06-28 00:26:30 -05001extern "C"
2{
Ben Tyner792f32f2020-06-02 08:50:47 -05003#include <libpdbg.h>
Jayanth Othayothb1eda6a2021-06-28 00:26:30 -05004#include <libpdbg_sbe.h>
5}
Ben Tyner792f32f2020-06-02 08:50:47 -05006
Zane Shelleya06dcf82021-11-03 10:23:21 -05007#include <config.h>
8
Ben Tynerb9715172021-09-29 08:46:19 -05009#ifdef CONFIG_PHAL_API
10#include <libphal.H>
11#endif
12
Ben Tyner0205f3b2020-02-24 10:24:47 -060013#include <analyzer/analyzer_main.hpp>
Ben Tynerb797b3e2020-06-29 10:12:05 -050014#include <attn/attention.hpp>
Ben Tynerbcf65a82020-12-01 08:46:36 -060015#include <attn/attn_common.hpp>
Ben Tynerb797b3e2020-06-29 10:12:05 -050016#include <attn/attn_config.hpp>
Ben Tyner4bbcb382021-02-22 09:29:00 -060017#include <attn/attn_dbus.hpp>
Ben Tynerb797b3e2020-06-29 10:12:05 -050018#include <attn/attn_handler.hpp>
19#include <attn/attn_logging.hpp>
20#include <attn/bp_handler.hpp>
21#include <attn/ti_handler.hpp>
Ben Tynerbcf65a82020-12-01 08:46:36 -060022#include <attn/vital_handler.hpp>
Ben Tynerfe2c50d2021-07-23 13:38:53 -050023#include <util/dbus.hpp>
Ben Tyner76e52f62022-02-01 10:46:44 -060024#include <util/ffdc_file.hpp>
Ben Tyner6a69e6e2022-04-05 23:18:29 -050025#include <util/pdbg.hpp>
Ben Tyner76e52f62022-02-01 10:46:44 -060026#include <util/trace.hpp>
Ben Tyneref320152020-01-09 10:31:23 -060027
Ben Tynerb481d902020-03-05 10:24:23 -060028#include <algorithm>
Ben Tyneref320152020-01-09 10:31:23 -060029#include <iomanip>
Ben Tynerb1ebfcb2020-05-08 18:52:48 -050030#include <map>
Ben Tyner9ae5ca42020-02-28 13:13:50 -060031#include <sstream>
Ben Tynerb481d902020-03-05 10:24:23 -060032#include <vector>
Ben Tyneref320152020-01-09 10:31:23 -060033
34namespace attn
35{
36
37/**
Ben Tyneref320152020-01-09 10:31:23 -060038 * @brief Handle checkstop attention
39 *
Ben Tynerb481d902020-03-05 10:24:23 -060040 * @param i_attention Attention object
Ben Tyner3fb52e52020-03-31 10:10:07 -050041 * @return 0 indicates that the checkstop attention was successfully handled
42 * 1 indicates that the checkstop attention was NOT successfully
43 * handled.
Ben Tyneref320152020-01-09 10:31:23 -060044 */
Ben Tynerb481d902020-03-05 10:24:23 -060045int handleCheckstop(Attention* i_attention);
Ben Tyneref320152020-01-09 10:31:23 -060046
47/**
48 * @brief Handle special attention
49 *
Ben Tynerb481d902020-03-05 10:24:23 -060050 * @param i_attention Attention object
Ben Tyner3fb52e52020-03-31 10:10:07 -050051 * @return 0 indicates that the special attention was successfully handled
52 * 1 indicates that the special attention was NOT successfully handled
Ben Tyneref320152020-01-09 10:31:23 -060053 */
Ben Tynerb481d902020-03-05 10:24:23 -060054int handleSpecial(Attention* i_attention);
Ben Tyneref320152020-01-09 10:31:23 -060055
Ben Tynerfb190542020-11-06 09:27:56 -060056/** @brief Determine if attention is active and not masked */
Ben Tyner1965e502020-11-20 10:32:24 -060057bool activeAttn(uint32_t i_val, uint32_t i_mask, uint32_t i_attn);
Ben Tynerfb190542020-11-06 09:27:56 -060058
Ben Tynerb9715172021-09-29 08:46:19 -050059#ifdef CONFIG_PHAL_API
60/** @brief Handle phal sbe exception */
61void phalSbeExceptionHandler(openpower::phal::exception::SbeError& e,
Ben Tyner76e52f62022-02-01 10:46:44 -060062 uint32_t chipPosition, uint32_t command);
Ben Tynerb9715172021-09-29 08:46:19 -050063#endif
64
65/** @brief Get static TI info data based on host state */
66void getStaticTiInfo(uint8_t*& tiInfoPtr);
67
68/** @brief Check if TI info data is valid */
69bool tiInfoValid(uint8_t* tiInfo);
70
Ben Tyner6a69e6e2022-04-05 23:18:29 -050071/** @brief Clear attention interrupts */
72void clearAttnInterrupts();
73
Ben Tyneref320152020-01-09 10:31:23 -060074/**
Ben Tyneref320152020-01-09 10:31:23 -060075 * @brief The main attention handler logic
Ben Tyner970fd4f2020-02-19 13:46:42 -060076 *
77 * @param i_breakpoints true = breakpoint special attn handling enabled
Ben Tyneref320152020-01-09 10:31:23 -060078 */
Ben Tyner3fb52e52020-03-31 10:10:07 -050079void attnHandler(Config* i_config)
Ben Tyneref320152020-01-09 10:31:23 -060080{
Ben Tyner6a69e6e2022-04-05 23:18:29 -050081 // Clear attention interrupts that may still be active (MPIPL)
82 clearAttnInterrupts();
83
Ben Tynerb481d902020-03-05 10:24:23 -060084 // Vector of active attentions to be handled
85 std::vector<Attention> active_attentions;
86
Ben Tyneref320152020-01-09 10:31:23 -060087 uint32_t isr_val, isr_mask;
Ben Tyneref320152020-01-09 10:31:23 -060088
89 // loop through processors looking for active attentions
austinfcuibfa831a2022-01-26 15:37:07 -060090 trace::inf("Attention handler started");
Ben Tyner117af992020-05-22 13:32:11 -050091
Ben Tyneref320152020-01-09 10:31:23 -060092 pdbg_target* target;
Ben Tyner5e622d82020-09-11 10:10:24 -050093 pdbg_for_each_class_target("proc", target)
Ben Tyneref320152020-01-09 10:31:23 -060094 {
95 if (PDBG_TARGET_ENABLED == pdbg_target_probe(target))
96 {
Zane Shelleya79f6c82021-01-12 16:38:49 -060097 auto proc = pdbg_target_index(target); // get processor number
Ben Tyneref320152020-01-09 10:31:23 -060098
Ben Tynerb83c8522020-11-20 10:45:26 -060099 // Use PIB target to determine if a processor is enabled
Ben Tyner5e622d82020-09-11 10:10:24 -0500100 char path[16];
Ben Tynerb83c8522020-11-20 10:45:26 -0600101 sprintf(path, "/proc%d/pib", proc);
Ben Tyner8882c322021-02-05 12:13:21 -0600102 pdbg_target* pibTarget = pdbg_target_from_path(nullptr, path);
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500103
Ben Tynerb83c8522020-11-20 10:45:26 -0600104 // sanity check
Ben Tyner8882c322021-02-05 12:13:21 -0600105 if (nullptr == pibTarget)
Ben Tynerb83c8522020-11-20 10:45:26 -0600106 {
austinfcuibfa831a2022-01-26 15:37:07 -0600107 trace::inf("pib path or target not found");
Ben Tynerb83c8522020-11-20 10:45:26 -0600108 continue;
109 }
110
Ben Tyner8882c322021-02-05 12:13:21 -0600111 // check if pib target is enabled
112 if (PDBG_TARGET_ENABLED == pdbg_target_probe(pibTarget))
Ben Tyneref320152020-01-09 10:31:23 -0600113 {
Ben Tynerb83c8522020-11-20 10:45:26 -0600114 // The processor FSI target is required for CFAM read
115 sprintf(path, "/proc%d/fsi", proc);
Ben Tyner8882c322021-02-05 12:13:21 -0600116 pdbg_target* fsiTarget = pdbg_target_from_path(nullptr, path);
Ben Tynerb83c8522020-11-20 10:45:26 -0600117
118 // sanity check
Ben Tyner8882c322021-02-05 12:13:21 -0600119 if (nullptr == fsiTarget)
Ben Tynerb83c8522020-11-20 10:45:26 -0600120 {
austinfcuibfa831a2022-01-26 15:37:07 -0600121 trace::inf("fsi path or target not found");
Ben Tynerb83c8522020-11-20 10:45:26 -0600122 continue;
123 }
124
Ben Tyner8882c322021-02-05 12:13:21 -0600125 // trace the proc number
austinfcuibfa831a2022-01-26 15:37:07 -0600126 trace::inf("proc: %u", proc);
Ben Tyner1965e502020-11-20 10:32:24 -0600127
Ben Tyner5adc96e2020-11-20 10:54:12 -0600128 isr_val = 0xffffffff; // invalid isr value
129
Ben Tyner5e622d82020-09-11 10:10:24 -0500130 // get active attentions on processor
Ben Tyner8882c322021-02-05 12:13:21 -0600131 if (RC_SUCCESS != fsi_read(fsiTarget, 0x1007, &isr_val))
Ben Tyneref320152020-01-09 10:31:23 -0600132 {
Ben Tynerfb190542020-11-06 09:27:56 -0600133 // log cfam read error
austinfcuibfa831a2022-01-26 15:37:07 -0600134 trace::err("cfam read 0x1007 FAILED");
Ben Tyner7a0dd542021-02-12 09:33:44 -0600135 eventAttentionFail((int)AttnSection::attnHandler |
136 ATTN_PDBG_CFAM);
Ben Tyneref320152020-01-09 10:31:23 -0600137 }
Ben Tyner5adc96e2020-11-20 10:54:12 -0600138 else if (0xffffffff == isr_val)
139 {
austinfcuibfa831a2022-01-26 15:37:07 -0600140 trace::err("cfam read 0x1007 INVALID");
Ben Tyner5adc96e2020-11-20 10:54:12 -0600141 continue;
142 }
Ben Tyneref320152020-01-09 10:31:23 -0600143 else
144 {
Ben Tyner8882c322021-02-05 12:13:21 -0600145 // trace isr value
austinfcuibfa831a2022-01-26 15:37:07 -0600146 trace::inf("cfam 0x1007 = 0x%08x", isr_val);
Ben Tyner1965e502020-11-20 10:32:24 -0600147
Ben Tyner5adc96e2020-11-20 10:54:12 -0600148 isr_mask = 0xffffffff; // invalid isr mask
149
Ben Tyner5e622d82020-09-11 10:10:24 -0500150 // get interrupt enabled special attentions mask
Ben Tyner8882c322021-02-05 12:13:21 -0600151 if (RC_SUCCESS != fsi_read(fsiTarget, 0x100d, &isr_mask))
Ben Tyneref320152020-01-09 10:31:23 -0600152 {
Ben Tynerfb190542020-11-06 09:27:56 -0600153 // log cfam read error
austinfcuibfa831a2022-01-26 15:37:07 -0600154 trace::err("cfam read 0x100d FAILED");
Ben Tyner7a0dd542021-02-12 09:33:44 -0600155 eventAttentionFail((int)AttnSection::attnHandler |
156 ATTN_PDBG_CFAM);
Ben Tyneref320152020-01-09 10:31:23 -0600157 }
Ben Tyner5adc96e2020-11-20 10:54:12 -0600158 else if (0xffffffff == isr_mask)
159 {
austinfcuibfa831a2022-01-26 15:37:07 -0600160 trace::err("cfam read 0x100d INVALID");
Ben Tyner5adc96e2020-11-20 10:54:12 -0600161 continue;
162 }
Ben Tyner5e622d82020-09-11 10:10:24 -0500163 else
164 {
Ben Tyner8882c322021-02-05 12:13:21 -0600165 // trace true mask
austinfcuibfa831a2022-01-26 15:37:07 -0600166 trace::inf("cfam 0x100d = 0x%08x", isr_mask);
Ben Tyner1965e502020-11-20 10:32:24 -0600167
Ben Tynerfb190542020-11-06 09:27:56 -0600168 // SBE vital attention active and not masked?
Ben Tyner1965e502020-11-20 10:32:24 -0600169 if (true == activeAttn(isr_val, isr_mask, SBE_ATTN))
Ben Tyner5e622d82020-09-11 10:10:24 -0500170 {
171 active_attentions.emplace_back(Attention::Vital,
172 handleVital, target,
173 i_config);
174 }
175
Ben Tynerfb190542020-11-06 09:27:56 -0600176 // Checkstop attention active and not masked?
177 if (true ==
Ben Tyner1965e502020-11-20 10:32:24 -0600178 activeAttn(isr_val, isr_mask, CHECKSTOP_ATTN))
Ben Tyner5e622d82020-09-11 10:10:24 -0500179 {
180 active_attentions.emplace_back(Attention::Checkstop,
181 handleCheckstop,
182 target, i_config);
183 }
184
Ben Tynerfb190542020-11-06 09:27:56 -0600185 // Special attention active and not masked?
Ben Tyner1965e502020-11-20 10:32:24 -0600186 if (true == activeAttn(isr_val, isr_mask, SPECIAL_ATTN))
Ben Tyner5e622d82020-09-11 10:10:24 -0500187 {
188 active_attentions.emplace_back(Attention::Special,
189 handleSpecial,
190 target, i_config);
191 }
192 } // cfam 0x100d valid
193 } // cfam 0x1007 valid
Ben Tyner8882c322021-02-05 12:13:21 -0600194 } // fsi target enabled
195 } // pib target enabled
Ben Tyner5e622d82020-09-11 10:10:24 -0500196 } // next processor
Ben Tyneref320152020-01-09 10:31:23 -0600197
Ben Tynerb481d902020-03-05 10:24:23 -0600198 // convert to heap, highest priority is at front
199 if (!std::is_heap(active_attentions.begin(), active_attentions.end()))
200 {
201 std::make_heap(active_attentions.begin(), active_attentions.end());
202 }
203
204 // call the attention handler until one is handled or all were attempted
205 while (false == active_attentions.empty())
206 {
207 // handle highest priority attention, done if successful
208 if (RC_SUCCESS == active_attentions.front().handle())
209 {
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500210 // an attention was handled so we are done
Ben Tynerb481d902020-03-05 10:24:23 -0600211 break;
212 }
213
214 // move attention to back of vector
215 std::pop_heap(active_attentions.begin(), active_attentions.end());
216
217 // remove attention from vector
218 active_attentions.pop_back();
219 }
Ben Tyneref320152020-01-09 10:31:23 -0600220}
221
222/**
Ben Tyneref320152020-01-09 10:31:23 -0600223 * @brief Handle checkstop attention
Ben Tyner3fb52e52020-03-31 10:10:07 -0500224 *
225 * @param i_attention Attention object
226 * @return 0 indicates that the checkstop attention was successfully handled
227 * 1 indicates that the checkstop attention was NOT successfully
228 * handled.
Ben Tyneref320152020-01-09 10:31:23 -0600229 */
Ben Tynerb481d902020-03-05 10:24:23 -0600230int handleCheckstop(Attention* i_attention)
Ben Tyneref320152020-01-09 10:31:23 -0600231{
Ben Tyner3fb52e52020-03-31 10:10:07 -0500232 int rc = RC_SUCCESS; // assume checkstop handled
Ben Tyneref320152020-01-09 10:31:23 -0600233
austinfcuibfa831a2022-01-26 15:37:07 -0600234 trace::inf("checkstop handler started");
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500235
Ben Tynerb8335562021-07-16 12:43:52 -0500236 // capture some additional data for logs/traces
237 addHbStatusRegs();
238
Ben Tyner3fb52e52020-03-31 10:10:07 -0500239 // if checkstop handling enabled, handle checkstop attention
240 if (false == (i_attention->getConfig()->getFlag(enCheckstop)))
241 {
austinfcuibfa831a2022-01-26 15:37:07 -0600242 trace::inf("Checkstop handling disabled");
Ben Tyner3fb52e52020-03-31 10:10:07 -0500243 }
244 else
245 {
Ben Tyner07ebb9b2021-12-01 12:16:24 -0600246 // wait for power fault handling before starting analyses
247 sleepSeconds(POWER_FAULT_WAIT);
248
Zane Shelley9fb73932020-09-15 13:34:57 -0500249 // Look for any attentions found in hardware. This will generate and
Zane Shelley7ae9c8c2020-12-02 20:10:31 -0600250 // commit a PEL if any errors are found.
Ben Tyner7029e522021-08-09 19:18:24 -0500251 DumpParameters dumpParameters;
Zane Shelleyebff0d32021-11-21 10:52:07 -0600252 auto logid = analyzer::analyzeHardware(
253 analyzer::AnalysisType::SYSTEM_CHECKSTOP, dumpParameters);
Zane Shelley611b3442021-11-19 16:02:01 -0600254 if (0 == logid)
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500255 {
Zane Shelley611b3442021-11-19 16:02:01 -0600256 // A PEL should exist for a checkstop attention.
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500257 rc = RC_ANALYZER_ERROR;
258 }
Ben Tyner7029e522021-08-09 19:18:24 -0500259 else
260 {
Zane Shelley611b3442021-11-19 16:02:01 -0600261 requestDump(logid, dumpParameters);
Ben Tyner7029e522021-08-09 19:18:24 -0500262 util::dbus::transitionHost(util::dbus::HostState::Quiesce);
263 }
Ben Tyner3fb52e52020-03-31 10:10:07 -0500264 }
Ben Tyneref320152020-01-09 10:31:23 -0600265
Ben Tyneref320152020-01-09 10:31:23 -0600266 return rc;
267}
268
269/**
270 * @brief Handle special attention
Ben Tyner3fb52e52020-03-31 10:10:07 -0500271 *
272 * @param i_attention Attention object
273 * @return 0 indicates that the special attention was successfully handled
274 * 1 indicates that the special attention was NOT successfully handled
Ben Tyneref320152020-01-09 10:31:23 -0600275 */
Ben Tynerb481d902020-03-05 10:24:23 -0600276int handleSpecial(Attention* i_attention)
Ben Tyneref320152020-01-09 10:31:23 -0600277{
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500278 int rc = RC_SUCCESS; // assume special attention handled
Ben Tyneref320152020-01-09 10:31:23 -0600279
Ben Tynerfb190542020-11-06 09:27:56 -0600280 // The TI info chipop will give us a pointer to the TI info data
Ben Tyner98430b32020-08-19 19:14:02 -0500281 uint8_t* tiInfo = nullptr; // ptr to TI info data
282 uint32_t tiInfoLen = 0; // length of TI info data
283 pdbg_target* attnProc = i_attention->getTarget(); // proc with attention
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500284
Ben Tyner29651ef2021-02-08 10:51:03 -0600285 bool tiInfoStatic = false; // assume TI info was provided (not created)
286
Ben Tynerb9715172021-09-29 08:46:19 -0500287 // need proc target to get dynamic TI info
288 if (nullptr != attnProc)
Ben Tyner89c0a7a2020-08-07 12:07:35 -0500289 {
Ben Tynerb9715172021-09-29 08:46:19 -0500290#ifdef CONFIG_PHAL_API
austinfcuibfa831a2022-01-26 15:37:07 -0600291 trace::inf("using libphal to get TI info");
Ben Tynerb9715172021-09-29 08:46:19 -0500292
293 // phal library uses proc target for get ti info
294 if (PDBG_TARGET_ENABLED == pdbg_target_probe(attnProc))
295 {
296 try
297 {
298 // get dynamic TI info
299 openpower::phal::sbe::getTiInfo(attnProc, &tiInfo, &tiInfoLen);
300 }
Ben Tyner76e52f62022-02-01 10:46:44 -0600301 catch (openpower::phal::exception::SbeError& sbeError)
Ben Tynerb9715172021-09-29 08:46:19 -0500302 {
303 // library threw an exception
Ben Tyner76e52f62022-02-01 10:46:44 -0600304 // note: phal::sbe::getTiInfo = command class | command ==
305 // 0xa900 | 0x04 = 0xa904. The sbe fifo command class and
Ben Tyner6a69e6e2022-04-05 23:18:29 -0500306 // commands are defined in the sbefifo library source code
307 // but do not seem to be exported/installed for consumption
Ben Tyner76e52f62022-02-01 10:46:44 -0600308 // externally.
Ben Tynerb9715172021-09-29 08:46:19 -0500309 uint32_t procNum = pdbg_target_index(attnProc);
Ben Tyner76e52f62022-02-01 10:46:44 -0600310 phalSbeExceptionHandler(sbeError, procNum, 0xa904);
Ben Tynerb9715172021-09-29 08:46:19 -0500311 }
312 }
313#else
austinfcuibfa831a2022-01-26 15:37:07 -0600314 trace::inf("using libpdbg to get TI info");
Ben Tynerb9715172021-09-29 08:46:19 -0500315
316 // pdbg library uses pib target for get ti info
Ben Tyner98430b32020-08-19 19:14:02 -0500317 char path[16];
318 sprintf(path, "/proc%d/pib", pdbg_target_index(attnProc));
319 pdbg_target* tiInfoTarget = pdbg_target_from_path(nullptr, path);
320
321 if (nullptr != tiInfoTarget)
Ben Tyner89c0a7a2020-08-07 12:07:35 -0500322 {
Ben Tyner98430b32020-08-19 19:14:02 -0500323 if (PDBG_TARGET_ENABLED == pdbg_target_probe(tiInfoTarget))
324 {
Ben Tyner98430b32020-08-19 19:14:02 -0500325 sbe_mpipl_get_ti_info(tiInfoTarget, &tiInfo, &tiInfoLen);
Ben Tyner98430b32020-08-19 19:14:02 -0500326 }
Ben Tyner89c0a7a2020-08-07 12:07:35 -0500327 }
Ben Tynerb9715172021-09-29 08:46:19 -0500328#endif
Ben Tyner89c0a7a2020-08-07 12:07:35 -0500329 }
Ben Tyneref320152020-01-09 10:31:23 -0600330
Ben Tynerb9715172021-09-29 08:46:19 -0500331 // dynamic TI info is not available
332 if (nullptr == tiInfo)
Ben Tyner970fd4f2020-02-19 13:46:42 -0600333 {
austinfcuibfa831a2022-01-26 15:37:07 -0600334 trace::inf("TI info data ptr is invalid");
Ben Tynerb9715172021-09-29 08:46:19 -0500335 getStaticTiInfo(tiInfo);
336 tiInfoStatic = true;
Ben Tyner3fb52e52020-03-31 10:10:07 -0500337 }
Ben Tyner0fe5df42020-12-03 08:57:17 -0600338
Ben Tynerb9715172021-09-29 08:46:19 -0500339 // check TI info for validity and handle
340 if (true == tiInfoValid(tiInfo))
341 {
342 // TI info is valid handle TI if support enabled
343 if (true == (i_attention->getConfig()->getFlag(enTerminate)))
344 {
345 // Call TI special attention handler
346 rc = tiHandler((TiDataArea*)tiInfo);
347 }
348 }
349 else
Ben Tyner3fb52e52020-03-31 10:10:07 -0500350 {
austinfcuibfa831a2022-01-26 15:37:07 -0600351 trace::inf("TI info NOT valid");
Ben Tyner98430b32020-08-19 19:14:02 -0500352
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500353 // if configured to handle TI as default special attention
Ben Tynerfe156492021-04-08 07:28:13 -0500354 if (i_attention->getConfig()->getFlag(dfltTi))
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500355 {
Ben Tynerfe156492021-04-08 07:28:13 -0500356 // TI handling may be disabled
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500357 if (true == (i_attention->getConfig()->getFlag(enTerminate)))
358 {
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500359 // Call TI special attention handler
Ben Tynerb9715172021-09-29 08:46:19 -0500360 rc = tiHandler((TiDataArea*)tiInfo);
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500361 }
Ben Tyner3fb52e52020-03-31 10:10:07 -0500362 }
Ben Tynerb9715172021-09-29 08:46:19 -0500363 // configured to handle breakpoint as default special attention
Ben Tynerfe156492021-04-08 07:28:13 -0500364 else
365 {
366 // breakpoint handling may be disabled
367 if (true == (i_attention->getConfig()->getFlag(enBreakpoints)))
368 {
369 // Call the breakpoint special attention handler
370 rc = bpHandler();
371 }
372 }
Ben Tyner970fd4f2020-02-19 13:46:42 -0600373 }
Ben Tyneref320152020-01-09 10:31:23 -0600374
Ben Tynerb9715172021-09-29 08:46:19 -0500375 // release TI data buffer if not ours
376 if (false == tiInfoStatic)
Ben Tyner792f32f2020-06-02 08:50:47 -0500377 {
Ben Tynerb9715172021-09-29 08:46:19 -0500378 // sanity check
379 if (nullptr != tiInfo)
380 {
381 free(tiInfo);
382 }
Ben Tyner792f32f2020-06-02 08:50:47 -0500383 }
384
Ben Tynerb9715172021-09-29 08:46:19 -0500385 // trace non-successful exit condition
Ben Tyner3fb52e52020-03-31 10:10:07 -0500386 if (RC_SUCCESS != rc)
387 {
austinfcuibfa831a2022-01-26 15:37:07 -0600388 trace::inf("Special attn not handled");
Ben Tyner3fb52e52020-03-31 10:10:07 -0500389 }
Ben Tyneref320152020-01-09 10:31:23 -0600390
391 return rc;
392}
393
Ben Tynerfb190542020-11-06 09:27:56 -0600394/**
395 * @brief Determine if attention is active and not masked
396 *
397 * Determine whether an attention needs to be handled and trace details of
398 * attention type and whether it is masked or not.
399 *
400 * @param i_val attention status register
401 * @param i_mask attention true mask register
402 * @param i_attn attention type
403 * @param i_proc processor associated with registers
404 *
405 * @return true if attention is active and not masked, otherwise false
406 */
Ben Tyner1965e502020-11-20 10:32:24 -0600407bool activeAttn(uint32_t i_val, uint32_t i_mask, uint32_t i_attn)
Ben Tynerfb190542020-11-06 09:27:56 -0600408{
Zane Shelley9fb657f2021-01-12 15:30:58 -0600409 bool rc = false; // assume attn masked and/or inactive
Ben Tynerfb190542020-11-06 09:27:56 -0600410
411 // if attention active
412 if (0 != (i_val & i_attn))
413 {
austinfcuibfa831a2022-01-26 15:37:07 -0600414 std::string msg;
Ben Tynerfb190542020-11-06 09:27:56 -0600415
Zane Shelley9fb657f2021-01-12 15:30:58 -0600416 bool validAttn = true; // known attention type
417
Ben Tynerfb190542020-11-06 09:27:56 -0600418 switch (i_attn)
419 {
420 case SBE_ATTN:
austinfcuibfa831a2022-01-26 15:37:07 -0600421 msg = "SBE attn";
Ben Tynerfb190542020-11-06 09:27:56 -0600422 break;
423 case CHECKSTOP_ATTN:
austinfcuibfa831a2022-01-26 15:37:07 -0600424 msg = "Checkstop attn";
Ben Tynerfb190542020-11-06 09:27:56 -0600425 break;
426 case SPECIAL_ATTN:
austinfcuibfa831a2022-01-26 15:37:07 -0600427 msg = "Special attn";
Ben Tynerfb190542020-11-06 09:27:56 -0600428 break;
429 default:
austinfcuibfa831a2022-01-26 15:37:07 -0600430 msg = "Unknown attn";
Ben Tynerfb190542020-11-06 09:27:56 -0600431 validAttn = false;
432 }
433
434 // see if attention is masked
435 if (true == validAttn)
436 {
437 if (0 != (i_mask & i_attn))
438 {
439 rc = true; // attention active and not masked
440 }
441 else
442 {
austinfcuibfa831a2022-01-26 15:37:07 -0600443 msg += " masked";
Ben Tynerfb190542020-11-06 09:27:56 -0600444 }
445 }
446
austinfcuibfa831a2022-01-26 15:37:07 -0600447 trace::inf(msg.c_str()); // commit trace stream
Ben Tynerfb190542020-11-06 09:27:56 -0600448 }
449
450 return rc;
451}
Ben Tynerb9715172021-09-29 08:46:19 -0500452
453#ifdef CONFIG_PHAL_API
Ben Tyner76e52f62022-02-01 10:46:44 -0600454
Ben Tynerb9715172021-09-29 08:46:19 -0500455/**
456 * @brief Handle phal sbe exception
457 *
458 * @param[in] e - exception object
459 * @param[in] procNum - processor number associated with sbe exception
460 */
Ben Tyner76e52f62022-02-01 10:46:44 -0600461void phalSbeExceptionHandler(openpower::phal::exception::SbeError& sbeError,
462 uint32_t chipPosition, uint32_t command)
Ben Tynerb9715172021-09-29 08:46:19 -0500463{
Ben Tyner76e52f62022-02-01 10:46:44 -0600464 trace::err("Attention handler phal exception handler");
Ben Tynerb9715172021-09-29 08:46:19 -0500465
Ben Tyner76e52f62022-02-01 10:46:44 -0600466 // Trace exception details
467 trace::err(sbeError.what());
468
469 // Create event log entry with SBE FFDC data if provided
470 auto fd = sbeError.getFd();
471 if (fd > 0)
Ben Tynerb9715172021-09-29 08:46:19 -0500472 {
Ben Tyner76e52f62022-02-01 10:46:44 -0600473 trace::err("SBE FFDC data is available");
474
475 // FFDC parser expects chip position and command (command class |
476 // command) to be in the additional data.
477 std::map<std::string, std::string> additionalData = {
478 {"SRC6", std::to_string((chipPosition << 16) | command)}};
479
Ben Tyner6a69e6e2022-04-05 23:18:29 -0500480 // See phosphor-logging/extensions/openpower-pels/README.md, "Self
481 // Boot Engine(SBE) First Failure Data Capture(FFDC)" - SBE FFDC
482 // file type is 0xCB, version is 0x01.
Ben Tyner76e52f62022-02-01 10:46:44 -0600483 std::vector<util::FFDCTuple> ffdc{util::FFDCTuple{
484 util::FFDCFormat::Custom, static_cast<uint8_t>(0xCB),
485 static_cast<uint8_t>(0x01), fd}};
486
487 // Create event log entry with FFDC data
Ben Tyner13159682022-02-16 14:55:38 -0600488 util::dbus::createPel("org.open_power.Processor.Error.SbeChipOpFailure",
489 levelPelError, additionalData, ffdc);
Ben Tynerb9715172021-09-29 08:46:19 -0500490 }
491}
492#endif
493
494/**
495 * @brief Get static TI info data based on host state
496 *
497 * @param[out] tiInfo - pointer to static TI info data
498 */
499void getStaticTiInfo(uint8_t*& tiInfo)
500{
501 util::dbus::HostRunningState runningState = util::dbus::hostRunningState();
502
503 // assume host state is unknown
504 std::string stateString = "host state unknown";
505
506 if ((util::dbus::HostRunningState::Started == runningState) ||
507 (util::dbus::HostRunningState::Unknown == runningState))
508 {
509 if (util::dbus::HostRunningState::Started == runningState)
510 {
511 stateString = "host started";
512 }
513 tiInfo = (uint8_t*)defaultPhypTiInfo;
514 }
515 else
516 {
517 stateString = "host not started";
518 tiInfo = (uint8_t*)defaultHbTiInfo;
519 }
520
521 // trace host state
austinfcuibfa831a2022-01-26 15:37:07 -0600522 trace::inf(stateString.c_str());
Ben Tynerb9715172021-09-29 08:46:19 -0500523}
524
525/**
526 * @brief Check if TI info data is valid
527 *
528 * @param[in] tiInfo - pointer to TI info data
529 * @return true if TI info data is valid, else false
530 */
531bool tiInfoValid(uint8_t* tiInfo)
532{
533 bool tiInfoValid = false; // assume TI info invalid
534
535 // TI info data[0] non-zero indicates TI info valid (usually)
536 if ((nullptr != tiInfo) && (0 != tiInfo[0]))
537 {
538 TiDataArea* tiDataArea = (TiDataArea*)tiInfo;
539
Ben Tynerb9715172021-09-29 08:46:19 -0500540 // trace a few known TI data area values
Ben Tyner535a8d42022-03-08 18:07:14 -0600541 trace::inf("TI data command = 0x%02x", tiDataArea->command);
Ben Tynerb9715172021-09-29 08:46:19 -0500542
543 // Another check for valid TI Info since it has been seen that
544 // tiInfo[0] != 0 but TI info is not valid
545 if (0xa1 == tiDataArea->command)
546 {
547 tiInfoValid = true;
548
549 // trace some more data since TI info appears valid
Ben Tyner535a8d42022-03-08 18:07:14 -0600550 trace::inf("TI data term-type = 0x%02x",
austinfcuibfa831a2022-01-26 15:37:07 -0600551 tiDataArea->hbTerminateType);
Ben Tynerb9715172021-09-29 08:46:19 -0500552
Ben Tyner535a8d42022-03-08 18:07:14 -0600553 trace::inf("TI data SRC format = 0x%02x", tiDataArea->srcFormat);
Ben Tynerb9715172021-09-29 08:46:19 -0500554
Ben Tyner535a8d42022-03-08 18:07:14 -0600555 trace::inf("TI data source = 0x%02x", tiDataArea->source);
Ben Tynerb9715172021-09-29 08:46:19 -0500556 }
557 }
558
559 return tiInfoValid;
560}
561
Ben Tyner6a69e6e2022-04-05 23:18:29 -0500562/**
563 * @brief Clear attention interrupts
564 *
565 * The attention interrupts are sticky and may still be set (MPIPL) even if
566 * there are no active attentions. If there is an active attention then
567 * clearing the associated interrupt will have no effect.
568 */
569void clearAttnInterrupts()
570{
571 trace::inf("Clearing attention interrupts");
572
573 // loop through processors clearing attention interrupts
574 pdbg_target* procTarget;
575 pdbg_for_each_class_target("proc", procTarget)
576 {
577 // active processors only
578 if (PDBG_TARGET_ENABLED !=
579 pdbg_target_probe(util::pdbg::getPibTrgt(procTarget)))
580 {
581 continue;
582 }
583
584 // get cfam is an fsi read
585 pdbg_target* fsiTarget = util::pdbg::getFsiTrgt(procTarget);
586 uint32_t int_val;
587
588 // get attention interrupts on processor
589 if (RC_SUCCESS == fsi_read(fsiTarget, 0x100b, &int_val))
590 {
591 // trace int value
592 trace::inf("cfam 0x100b = 0x%08x", int_val);
593
594 int_val &= ~(ANY_ATTN | CHECKSTOP_ATTN | SPECIAL_ATTN |
595 RECOVERABLE_ATTN | SBE_ATTN);
596
597 // clear attention interrupts on processor
598 if (RC_SUCCESS != fsi_write(fsiTarget, 0x100b, int_val))
599 {
600 // log cfam write error
601 trace::err("cfam write 0x100b FAILED");
602 }
603 }
604 else
605 {
606 // log cfam read error
607 trace::err("cfam read 0x100b FAILED");
608 }
609 }
610}
611
Ben Tyneref320152020-01-09 10:31:23 -0600612} // namespace attn