blob: bfe70d10686370c7c1604af55e86409f6683259b [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{
Ben Tyneref320152020-01-09 10:31:23 -060036/**
Ben Tyneref320152020-01-09 10:31:23 -060037 * @brief Handle checkstop attention
38 *
Ben Tynerb481d902020-03-05 10:24:23 -060039 * @param i_attention Attention object
Ben Tyner3fb52e52020-03-31 10:10:07 -050040 * @return 0 indicates that the checkstop attention was successfully handled
41 * 1 indicates that the checkstop attention was NOT successfully
42 * handled.
Ben Tyneref320152020-01-09 10:31:23 -060043 */
Ben Tynerb481d902020-03-05 10:24:23 -060044int handleCheckstop(Attention* i_attention);
Ben Tyneref320152020-01-09 10:31:23 -060045
46/**
47 * @brief Handle special attention
48 *
Ben Tynerb481d902020-03-05 10:24:23 -060049 * @param i_attention Attention object
Ben Tyner3fb52e52020-03-31 10:10:07 -050050 * @return 0 indicates that the special attention was successfully handled
51 * 1 indicates that the special attention was NOT successfully handled
Ben Tyneref320152020-01-09 10:31:23 -060052 */
Ben Tynerb481d902020-03-05 10:24:23 -060053int handleSpecial(Attention* i_attention);
Ben Tyneref320152020-01-09 10:31:23 -060054
Ben Tynerb9715172021-09-29 08:46:19 -050055#ifdef CONFIG_PHAL_API
56/** @brief Handle phal sbe exception */
57void phalSbeExceptionHandler(openpower::phal::exception::SbeError& e,
Ben Tyner76e52f62022-02-01 10:46:44 -060058 uint32_t chipPosition, uint32_t command);
Ben Tynerb9715172021-09-29 08:46:19 -050059#endif
60
61/** @brief Get static TI info data based on host state */
62void getStaticTiInfo(uint8_t*& tiInfoPtr);
63
64/** @brief Check if TI info data is valid */
65bool tiInfoValid(uint8_t* tiInfo);
66
Ben Tyneref320152020-01-09 10:31:23 -060067/**
Ben Tyneref320152020-01-09 10:31:23 -060068 * @brief The main attention handler logic
Ben Tyner970fd4f2020-02-19 13:46:42 -060069 *
70 * @param i_breakpoints true = breakpoint special attn handling enabled
Ben Tyneref320152020-01-09 10:31:23 -060071 */
Ben Tyner3fb52e52020-03-31 10:10:07 -050072void attnHandler(Config* i_config)
Ben Tyneref320152020-01-09 10:31:23 -060073{
austinfcuid28d5f82022-04-28 16:20:39 -050074 // Check if enClrAttnIntr is enabled
75 if (true == i_config->getFlag(enClrAttnIntr))
76 {
77 // Clear attention interrupts that may still be active (MPIPL)
78 clearAttnInterrupts();
79 }
Ben Tyner6a69e6e2022-04-05 23:18:29 -050080
Ben Tynerb481d902020-03-05 10:24:23 -060081 // Vector of active attentions to be handled
82 std::vector<Attention> active_attentions;
83
Ben Tyneref320152020-01-09 10:31:23 -060084 uint32_t isr_val, isr_mask;
Ben Tyneref320152020-01-09 10:31:23 -060085
86 // loop through processors looking for active attentions
austinfcuibfa831a2022-01-26 15:37:07 -060087 trace::inf("Attention handler started");
Ben Tyner117af992020-05-22 13:32:11 -050088
Ben Tyneref320152020-01-09 10:31:23 -060089 pdbg_target* target;
Ben Tyner5e622d82020-09-11 10:10:24 -050090 pdbg_for_each_class_target("proc", target)
Ben Tyneref320152020-01-09 10:31:23 -060091 {
92 if (PDBG_TARGET_ENABLED == pdbg_target_probe(target))
93 {
Zane Shelleya79f6c82021-01-12 16:38:49 -060094 auto proc = pdbg_target_index(target); // get processor number
Ben Tyneref320152020-01-09 10:31:23 -060095
Ben Tynerb83c8522020-11-20 10:45:26 -060096 // Use PIB target to determine if a processor is enabled
Ben Tyner5e622d82020-09-11 10:10:24 -050097 char path[16];
Ben Tynerb83c8522020-11-20 10:45:26 -060098 sprintf(path, "/proc%d/pib", proc);
Ben Tyner8882c322021-02-05 12:13:21 -060099 pdbg_target* pibTarget = pdbg_target_from_path(nullptr, path);
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500100
Ben Tynerb83c8522020-11-20 10:45:26 -0600101 // sanity check
Ben Tyner8882c322021-02-05 12:13:21 -0600102 if (nullptr == pibTarget)
Ben Tynerb83c8522020-11-20 10:45:26 -0600103 {
austinfcuibfa831a2022-01-26 15:37:07 -0600104 trace::inf("pib path or target not found");
Ben Tynerb83c8522020-11-20 10:45:26 -0600105 continue;
106 }
107
Ben Tyner8882c322021-02-05 12:13:21 -0600108 // check if pib target is enabled
109 if (PDBG_TARGET_ENABLED == pdbg_target_probe(pibTarget))
Ben Tyneref320152020-01-09 10:31:23 -0600110 {
Ben Tynerb83c8522020-11-20 10:45:26 -0600111 // The processor FSI target is required for CFAM read
112 sprintf(path, "/proc%d/fsi", proc);
Ben Tyner8882c322021-02-05 12:13:21 -0600113 pdbg_target* fsiTarget = pdbg_target_from_path(nullptr, path);
Ben Tynerb83c8522020-11-20 10:45:26 -0600114
115 // sanity check
Ben Tyner8882c322021-02-05 12:13:21 -0600116 if (nullptr == fsiTarget)
Ben Tynerb83c8522020-11-20 10:45:26 -0600117 {
austinfcuibfa831a2022-01-26 15:37:07 -0600118 trace::inf("fsi path or target not found");
Ben Tynerb83c8522020-11-20 10:45:26 -0600119 continue;
120 }
121
Ben Tyner8882c322021-02-05 12:13:21 -0600122 // trace the proc number
austinfcuibfa831a2022-01-26 15:37:07 -0600123 trace::inf("proc: %u", proc);
Ben Tyner1965e502020-11-20 10:32:24 -0600124
Ben Tyner5adc96e2020-11-20 10:54:12 -0600125 isr_val = 0xffffffff; // invalid isr value
126
Ben Tyner5e622d82020-09-11 10:10:24 -0500127 // get active attentions on processor
Ben Tyner8882c322021-02-05 12:13:21 -0600128 if (RC_SUCCESS != fsi_read(fsiTarget, 0x1007, &isr_val))
Ben Tyneref320152020-01-09 10:31:23 -0600129 {
Ben Tynerfb190542020-11-06 09:27:56 -0600130 // log cfam read error
austinfcuibfa831a2022-01-26 15:37:07 -0600131 trace::err("cfam read 0x1007 FAILED");
Ben Tyner7a0dd542021-02-12 09:33:44 -0600132 eventAttentionFail((int)AttnSection::attnHandler |
133 ATTN_PDBG_CFAM);
Ben Tyneref320152020-01-09 10:31:23 -0600134 }
Ben Tyner5adc96e2020-11-20 10:54:12 -0600135 else if (0xffffffff == isr_val)
136 {
austinfcuibfa831a2022-01-26 15:37:07 -0600137 trace::err("cfam read 0x1007 INVALID");
Ben Tyner5adc96e2020-11-20 10:54:12 -0600138 continue;
139 }
Ben Tyneref320152020-01-09 10:31:23 -0600140 else
141 {
Ben Tyner8882c322021-02-05 12:13:21 -0600142 // trace isr value
austinfcuibfa831a2022-01-26 15:37:07 -0600143 trace::inf("cfam 0x1007 = 0x%08x", isr_val);
Ben Tyner1965e502020-11-20 10:32:24 -0600144
Ben Tyner5adc96e2020-11-20 10:54:12 -0600145 isr_mask = 0xffffffff; // invalid isr mask
146
Ben Tyner5e622d82020-09-11 10:10:24 -0500147 // get interrupt enabled special attentions mask
Ben Tyner8882c322021-02-05 12:13:21 -0600148 if (RC_SUCCESS != fsi_read(fsiTarget, 0x100d, &isr_mask))
Ben Tyneref320152020-01-09 10:31:23 -0600149 {
Ben Tynerfb190542020-11-06 09:27:56 -0600150 // log cfam read error
austinfcuibfa831a2022-01-26 15:37:07 -0600151 trace::err("cfam read 0x100d FAILED");
Ben Tyner7a0dd542021-02-12 09:33:44 -0600152 eventAttentionFail((int)AttnSection::attnHandler |
153 ATTN_PDBG_CFAM);
Ben Tyneref320152020-01-09 10:31:23 -0600154 }
Ben Tyner5adc96e2020-11-20 10:54:12 -0600155 else if (0xffffffff == isr_mask)
156 {
austinfcuibfa831a2022-01-26 15:37:07 -0600157 trace::err("cfam read 0x100d INVALID");
Ben Tyner5adc96e2020-11-20 10:54:12 -0600158 continue;
159 }
Ben Tyner5e622d82020-09-11 10:10:24 -0500160 else
161 {
Ben Tyner8882c322021-02-05 12:13:21 -0600162 // trace true mask
austinfcuibfa831a2022-01-26 15:37:07 -0600163 trace::inf("cfam 0x100d = 0x%08x", isr_mask);
Ben Tyner1965e502020-11-20 10:32:24 -0600164
Ben Tynerfb190542020-11-06 09:27:56 -0600165 // SBE vital attention active and not masked?
Ben Tyner1965e502020-11-20 10:32:24 -0600166 if (true == activeAttn(isr_val, isr_mask, SBE_ATTN))
Ben Tyner5e622d82020-09-11 10:10:24 -0500167 {
168 active_attentions.emplace_back(Attention::Vital,
169 handleVital, target,
170 i_config);
171 }
172
Ben Tynerfb190542020-11-06 09:27:56 -0600173 // Checkstop attention active and not masked?
174 if (true ==
Ben Tyner1965e502020-11-20 10:32:24 -0600175 activeAttn(isr_val, isr_mask, CHECKSTOP_ATTN))
Ben Tyner5e622d82020-09-11 10:10:24 -0500176 {
177 active_attentions.emplace_back(Attention::Checkstop,
178 handleCheckstop,
179 target, i_config);
180 }
181
Ben Tynerfb190542020-11-06 09:27:56 -0600182 // Special attention active and not masked?
Ben Tyner1965e502020-11-20 10:32:24 -0600183 if (true == activeAttn(isr_val, isr_mask, SPECIAL_ATTN))
Ben Tyner5e622d82020-09-11 10:10:24 -0500184 {
185 active_attentions.emplace_back(Attention::Special,
186 handleSpecial,
187 target, i_config);
188 }
189 } // cfam 0x100d valid
190 } // cfam 0x1007 valid
Ben Tyner8882c322021-02-05 12:13:21 -0600191 } // fsi target enabled
192 } // pib target enabled
Ben Tyner5e622d82020-09-11 10:10:24 -0500193 } // next processor
Ben Tyneref320152020-01-09 10:31:23 -0600194
Ben Tynerb481d902020-03-05 10:24:23 -0600195 // convert to heap, highest priority is at front
196 if (!std::is_heap(active_attentions.begin(), active_attentions.end()))
197 {
198 std::make_heap(active_attentions.begin(), active_attentions.end());
199 }
200
201 // call the attention handler until one is handled or all were attempted
202 while (false == active_attentions.empty())
203 {
204 // handle highest priority attention, done if successful
205 if (RC_SUCCESS == active_attentions.front().handle())
206 {
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500207 // an attention was handled so we are done
Ben Tynerb481d902020-03-05 10:24:23 -0600208 break;
209 }
210
211 // move attention to back of vector
212 std::pop_heap(active_attentions.begin(), active_attentions.end());
213
214 // remove attention from vector
215 active_attentions.pop_back();
216 }
Ben Tyneref320152020-01-09 10:31:23 -0600217}
218
219/**
Ben Tyneref320152020-01-09 10:31:23 -0600220 * @brief Handle checkstop attention
Ben Tyner3fb52e52020-03-31 10:10:07 -0500221 *
222 * @param i_attention Attention object
223 * @return 0 indicates that the checkstop attention was successfully handled
224 * 1 indicates that the checkstop attention was NOT successfully
225 * handled.
Ben Tyneref320152020-01-09 10:31:23 -0600226 */
Ben Tynerb481d902020-03-05 10:24:23 -0600227int handleCheckstop(Attention* i_attention)
Ben Tyneref320152020-01-09 10:31:23 -0600228{
Ben Tyner3fb52e52020-03-31 10:10:07 -0500229 int rc = RC_SUCCESS; // assume checkstop handled
Ben Tyneref320152020-01-09 10:31:23 -0600230
austinfcuibfa831a2022-01-26 15:37:07 -0600231 trace::inf("checkstop handler started");
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500232
Ben Tynerb8335562021-07-16 12:43:52 -0500233 // capture some additional data for logs/traces
234 addHbStatusRegs();
235
Ben Tyner3fb52e52020-03-31 10:10:07 -0500236 // if checkstop handling enabled, handle checkstop attention
237 if (false == (i_attention->getConfig()->getFlag(enCheckstop)))
238 {
austinfcuibfa831a2022-01-26 15:37:07 -0600239 trace::inf("Checkstop handling disabled");
Ben Tyner3fb52e52020-03-31 10:10:07 -0500240 }
241 else
242 {
Ben Tyner2b26b2b2022-12-15 15:42:02 -0600243 // check for power fault before starting analyses
Ben Tyner07ebb9b2021-12-01 12:16:24 -0600244 sleepSeconds(POWER_FAULT_WAIT);
Ben Tyner2b26b2b2022-12-15 15:42:02 -0600245 if (!util::dbus::powerFault())
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500246 {
Ben Tyner2b26b2b2022-12-15 15:42:02 -0600247 // Look for any attentions found in hardware. This will generate and
248 // commit a PEL if any errors are found.
249 DumpParameters dumpParameters;
250 auto logid = analyzer::analyzeHardware(
251 analyzer::AnalysisType::SYSTEM_CHECKSTOP, dumpParameters);
252 if (0 == logid)
253 {
254 // A PEL should exist for a checkstop attention.
255 rc = RC_ANALYZER_ERROR;
256 }
257 else
258 {
259 requestDump(logid, dumpParameters);
260 util::dbus::transitionHost(util::dbus::HostState::Quiesce);
261 }
Ben Tyner7029e522021-08-09 19:18:24 -0500262 }
Ben Tyner3fb52e52020-03-31 10:10:07 -0500263 }
Ben Tyneref320152020-01-09 10:31:23 -0600264
Ben Tyneref320152020-01-09 10:31:23 -0600265 return rc;
266}
267
268/**
269 * @brief Handle special attention
Ben Tyner3fb52e52020-03-31 10:10:07 -0500270 *
271 * @param i_attention Attention object
272 * @return 0 indicates that the special attention was successfully handled
273 * 1 indicates that the special attention was NOT successfully handled
Ben Tyneref320152020-01-09 10:31:23 -0600274 */
Ben Tynerb481d902020-03-05 10:24:23 -0600275int handleSpecial(Attention* i_attention)
Ben Tyneref320152020-01-09 10:31:23 -0600276{
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500277 int rc = RC_SUCCESS; // assume special attention handled
Ben Tyneref320152020-01-09 10:31:23 -0600278
Ben Tynerfb190542020-11-06 09:27:56 -0600279 // The TI info chipop will give us a pointer to the TI info data
Ben Tyner98430b32020-08-19 19:14:02 -0500280 uint8_t* tiInfo = nullptr; // ptr to TI info data
281 uint32_t tiInfoLen = 0; // length of TI info data
282 pdbg_target* attnProc = i_attention->getTarget(); // proc with attention
Ben Tynerb1ebfcb2020-05-08 18:52:48 -0500283
Ben Tyner29651ef2021-02-08 10:51:03 -0600284 bool tiInfoStatic = false; // assume TI info was provided (not created)
285
Ben Tynerb9715172021-09-29 08:46:19 -0500286 // need proc target to get dynamic TI info
287 if (nullptr != attnProc)
Ben Tyner89c0a7a2020-08-07 12:07:35 -0500288 {
Ben Tynerb9715172021-09-29 08:46:19 -0500289#ifdef CONFIG_PHAL_API
austinfcuibfa831a2022-01-26 15:37:07 -0600290 trace::inf("using libphal to get TI info");
Ben Tynerb9715172021-09-29 08:46:19 -0500291
292 // phal library uses proc target for get ti info
293 if (PDBG_TARGET_ENABLED == pdbg_target_probe(attnProc))
294 {
295 try
296 {
297 // get dynamic TI info
298 openpower::phal::sbe::getTiInfo(attnProc, &tiInfo, &tiInfoLen);
299 }
Ben Tyner76e52f62022-02-01 10:46:44 -0600300 catch (openpower::phal::exception::SbeError& sbeError)
Ben Tynerb9715172021-09-29 08:46:19 -0500301 {
302 // library threw an exception
Ben Tyner76e52f62022-02-01 10:46:44 -0600303 // note: phal::sbe::getTiInfo = command class | command ==
304 // 0xa900 | 0x04 = 0xa904. The sbe fifo command class and
Ben Tyner6a69e6e2022-04-05 23:18:29 -0500305 // commands are defined in the sbefifo library source code
306 // but do not seem to be exported/installed for consumption
Ben Tyner76e52f62022-02-01 10:46:44 -0600307 // externally.
Ben Tynerb9715172021-09-29 08:46:19 -0500308 uint32_t procNum = pdbg_target_index(attnProc);
Ben Tyner76e52f62022-02-01 10:46:44 -0600309 phalSbeExceptionHandler(sbeError, procNum, 0xa904);
Ben Tynerb9715172021-09-29 08:46:19 -0500310 }
311 }
312#else
austinfcuibfa831a2022-01-26 15:37:07 -0600313 trace::inf("using libpdbg to get TI info");
Ben Tynerb9715172021-09-29 08:46:19 -0500314
315 // pdbg library uses pib target for get ti info
Ben Tyner98430b32020-08-19 19:14:02 -0500316 char path[16];
317 sprintf(path, "/proc%d/pib", pdbg_target_index(attnProc));
318 pdbg_target* tiInfoTarget = pdbg_target_from_path(nullptr, path);
319
320 if (nullptr != tiInfoTarget)
Ben Tyner89c0a7a2020-08-07 12:07:35 -0500321 {
Ben Tyner98430b32020-08-19 19:14:02 -0500322 if (PDBG_TARGET_ENABLED == pdbg_target_probe(tiInfoTarget))
323 {
Ben Tyner98430b32020-08-19 19:14:02 -0500324 sbe_mpipl_get_ti_info(tiInfoTarget, &tiInfo, &tiInfoLen);
Ben Tyner98430b32020-08-19 19:14:02 -0500325 }
Ben Tyner89c0a7a2020-08-07 12:07:35 -0500326 }
Ben Tynerb9715172021-09-29 08:46:19 -0500327#endif
Ben Tyner89c0a7a2020-08-07 12:07:35 -0500328 }
Ben Tyneref320152020-01-09 10:31:23 -0600329
Ben Tynerb9715172021-09-29 08:46:19 -0500330 // dynamic TI info is not available
331 if (nullptr == tiInfo)
Ben Tyner970fd4f2020-02-19 13:46:42 -0600332 {
austinfcuibfa831a2022-01-26 15:37:07 -0600333 trace::inf("TI info data ptr is invalid");
Ben Tynerb9715172021-09-29 08:46:19 -0500334 getStaticTiInfo(tiInfo);
335 tiInfoStatic = true;
Ben Tyner3fb52e52020-03-31 10:10:07 -0500336 }
Ben Tyner0fe5df42020-12-03 08:57:17 -0600337
Ben Tynerb9715172021-09-29 08:46:19 -0500338 // check TI info for validity and handle
339 if (true == tiInfoValid(tiInfo))
340 {
341 // TI info is valid handle TI if support enabled
342 if (true == (i_attention->getConfig()->getFlag(enTerminate)))
343 {
344 // Call TI special attention handler
345 rc = tiHandler((TiDataArea*)tiInfo);
346 }
347 }
348 else
Ben Tyner3fb52e52020-03-31 10:10:07 -0500349 {
austinfcuibfa831a2022-01-26 15:37:07 -0600350 trace::inf("TI info NOT valid");
Ben Tyner98430b32020-08-19 19:14:02 -0500351
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500352 // if configured to handle TI as default special attention
Ben Tynerfe156492021-04-08 07:28:13 -0500353 if (i_attention->getConfig()->getFlag(dfltTi))
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500354 {
Ben Tynerfe156492021-04-08 07:28:13 -0500355 // TI handling may be disabled
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500356 if (true == (i_attention->getConfig()->getFlag(enTerminate)))
357 {
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500358 // Call TI special attention handler
Ben Tynerb9715172021-09-29 08:46:19 -0500359 rc = tiHandler((TiDataArea*)tiInfo);
Ben Tynere4f5dbe2020-10-19 07:19:33 -0500360 }
Ben Tyner3fb52e52020-03-31 10:10:07 -0500361 }
Ben Tynerb9715172021-09-29 08:46:19 -0500362 // configured to handle breakpoint as default special attention
Ben Tynerfe156492021-04-08 07:28:13 -0500363 else
364 {
365 // breakpoint handling may be disabled
366 if (true == (i_attention->getConfig()->getFlag(enBreakpoints)))
367 {
368 // Call the breakpoint special attention handler
369 rc = bpHandler();
370 }
371 }
Ben Tyner970fd4f2020-02-19 13:46:42 -0600372 }
Ben Tyneref320152020-01-09 10:31:23 -0600373
Ben Tynerb9715172021-09-29 08:46:19 -0500374 // release TI data buffer if not ours
375 if (false == tiInfoStatic)
Ben Tyner792f32f2020-06-02 08:50:47 -0500376 {
Ben Tynerb9715172021-09-29 08:46:19 -0500377 // sanity check
378 if (nullptr != tiInfo)
379 {
380 free(tiInfo);
381 }
Ben Tyner792f32f2020-06-02 08:50:47 -0500382 }
383
Ben Tynerb9715172021-09-29 08:46:19 -0500384 // trace non-successful exit condition
Ben Tyner3fb52e52020-03-31 10:10:07 -0500385 if (RC_SUCCESS != rc)
386 {
austinfcuibfa831a2022-01-26 15:37:07 -0600387 trace::inf("Special attn not handled");
Ben Tyner3fb52e52020-03-31 10:10:07 -0500388 }
Ben Tyneref320152020-01-09 10:31:23 -0600389
390 return rc;
391}
392
Ben Tyner90516852022-12-14 21:04:18 -0600393/** @brief Determine if attention is active and not masked */
Ben Tyner1965e502020-11-20 10:32:24 -0600394bool activeAttn(uint32_t i_val, uint32_t i_mask, uint32_t i_attn)
Ben Tynerfb190542020-11-06 09:27:56 -0600395{
Zane Shelley9fb657f2021-01-12 15:30:58 -0600396 bool rc = false; // assume attn masked and/or inactive
Ben Tynerfb190542020-11-06 09:27:56 -0600397
398 // if attention active
399 if (0 != (i_val & i_attn))
400 {
austinfcuibfa831a2022-01-26 15:37:07 -0600401 std::string msg;
Ben Tynerfb190542020-11-06 09:27:56 -0600402
Zane Shelley9fb657f2021-01-12 15:30:58 -0600403 bool validAttn = true; // known attention type
404
Ben Tynerfb190542020-11-06 09:27:56 -0600405 switch (i_attn)
406 {
407 case SBE_ATTN:
austinfcuibfa831a2022-01-26 15:37:07 -0600408 msg = "SBE attn";
Ben Tynerfb190542020-11-06 09:27:56 -0600409 break;
410 case CHECKSTOP_ATTN:
austinfcuibfa831a2022-01-26 15:37:07 -0600411 msg = "Checkstop attn";
Ben Tynerfb190542020-11-06 09:27:56 -0600412 break;
413 case SPECIAL_ATTN:
austinfcuibfa831a2022-01-26 15:37:07 -0600414 msg = "Special attn";
Ben Tynerfb190542020-11-06 09:27:56 -0600415 break;
416 default:
austinfcuibfa831a2022-01-26 15:37:07 -0600417 msg = "Unknown attn";
Ben Tynerfb190542020-11-06 09:27:56 -0600418 validAttn = false;
419 }
420
421 // see if attention is masked
422 if (true == validAttn)
423 {
424 if (0 != (i_mask & i_attn))
425 {
426 rc = true; // attention active and not masked
427 }
428 else
429 {
austinfcuibfa831a2022-01-26 15:37:07 -0600430 msg += " masked";
Ben Tynerfb190542020-11-06 09:27:56 -0600431 }
432 }
433
austinfcuibfa831a2022-01-26 15:37:07 -0600434 trace::inf(msg.c_str()); // commit trace stream
Ben Tynerfb190542020-11-06 09:27:56 -0600435 }
436
437 return rc;
438}
Ben Tynerb9715172021-09-29 08:46:19 -0500439
440#ifdef CONFIG_PHAL_API
Ben Tyner76e52f62022-02-01 10:46:44 -0600441
Ben Tynerb9715172021-09-29 08:46:19 -0500442/**
443 * @brief Handle phal sbe exception
444 *
445 * @param[in] e - exception object
446 * @param[in] procNum - processor number associated with sbe exception
447 */
Ben Tyner76e52f62022-02-01 10:46:44 -0600448void phalSbeExceptionHandler(openpower::phal::exception::SbeError& sbeError,
449 uint32_t chipPosition, uint32_t command)
Ben Tynerb9715172021-09-29 08:46:19 -0500450{
Ben Tyner76e52f62022-02-01 10:46:44 -0600451 trace::err("Attention handler phal exception handler");
Ben Tynerb9715172021-09-29 08:46:19 -0500452
Ben Tyner76e52f62022-02-01 10:46:44 -0600453 // Trace exception details
454 trace::err(sbeError.what());
455
456 // Create event log entry with SBE FFDC data if provided
457 auto fd = sbeError.getFd();
458 if (fd > 0)
Ben Tynerb9715172021-09-29 08:46:19 -0500459 {
Ben Tyner76e52f62022-02-01 10:46:44 -0600460 trace::err("SBE FFDC data is available");
461
462 // FFDC parser expects chip position and command (command class |
463 // command) to be in the additional data.
464 std::map<std::string, std::string> additionalData = {
465 {"SRC6", std::to_string((chipPosition << 16) | command)}};
466
Ben Tyner6a69e6e2022-04-05 23:18:29 -0500467 // See phosphor-logging/extensions/openpower-pels/README.md, "Self
468 // Boot Engine(SBE) First Failure Data Capture(FFDC)" - SBE FFDC
469 // file type is 0xCB, version is 0x01.
Ben Tyner76e52f62022-02-01 10:46:44 -0600470 std::vector<util::FFDCTuple> ffdc{util::FFDCTuple{
471 util::FFDCFormat::Custom, static_cast<uint8_t>(0xCB),
472 static_cast<uint8_t>(0x01), fd}};
473
474 // Create event log entry with FFDC data
Ben Tyner13159682022-02-16 14:55:38 -0600475 util::dbus::createPel("org.open_power.Processor.Error.SbeChipOpFailure",
476 levelPelError, additionalData, ffdc);
Ben Tynerb9715172021-09-29 08:46:19 -0500477 }
478}
479#endif
480
481/**
482 * @brief Get static TI info data based on host state
483 *
484 * @param[out] tiInfo - pointer to static TI info data
485 */
486void getStaticTiInfo(uint8_t*& tiInfo)
487{
488 util::dbus::HostRunningState runningState = util::dbus::hostRunningState();
489
490 // assume host state is unknown
491 std::string stateString = "host state unknown";
492
493 if ((util::dbus::HostRunningState::Started == runningState) ||
494 (util::dbus::HostRunningState::Unknown == runningState))
495 {
496 if (util::dbus::HostRunningState::Started == runningState)
497 {
498 stateString = "host started";
499 }
500 tiInfo = (uint8_t*)defaultPhypTiInfo;
501 }
502 else
503 {
504 stateString = "host not started";
505 tiInfo = (uint8_t*)defaultHbTiInfo;
506 }
507
508 // trace host state
austinfcuibfa831a2022-01-26 15:37:07 -0600509 trace::inf(stateString.c_str());
Ben Tynerb9715172021-09-29 08:46:19 -0500510}
511
512/**
513 * @brief Check if TI info data is valid
514 *
515 * @param[in] tiInfo - pointer to TI info data
516 * @return true if TI info data is valid, else false
517 */
518bool tiInfoValid(uint8_t* tiInfo)
519{
520 bool tiInfoValid = false; // assume TI info invalid
521
522 // TI info data[0] non-zero indicates TI info valid (usually)
523 if ((nullptr != tiInfo) && (0 != tiInfo[0]))
524 {
525 TiDataArea* tiDataArea = (TiDataArea*)tiInfo;
526
Ben Tynerb9715172021-09-29 08:46:19 -0500527 // trace a few known TI data area values
Ben Tyner535a8d42022-03-08 18:07:14 -0600528 trace::inf("TI data command = 0x%02x", tiDataArea->command);
Ben Tynerb9715172021-09-29 08:46:19 -0500529
530 // Another check for valid TI Info since it has been seen that
531 // tiInfo[0] != 0 but TI info is not valid
532 if (0xa1 == tiDataArea->command)
533 {
534 tiInfoValid = true;
535
536 // trace some more data since TI info appears valid
Ben Tyner535a8d42022-03-08 18:07:14 -0600537 trace::inf("TI data term-type = 0x%02x",
austinfcuibfa831a2022-01-26 15:37:07 -0600538 tiDataArea->hbTerminateType);
Ben Tynerb9715172021-09-29 08:46:19 -0500539
Ben Tyner535a8d42022-03-08 18:07:14 -0600540 trace::inf("TI data SRC format = 0x%02x", tiDataArea->srcFormat);
Ben Tynerb9715172021-09-29 08:46:19 -0500541
Ben Tyner535a8d42022-03-08 18:07:14 -0600542 trace::inf("TI data source = 0x%02x", tiDataArea->source);
Ben Tynerb9715172021-09-29 08:46:19 -0500543 }
544 }
545
546 return tiInfoValid;
547}
548
Ben Tyner90516852022-12-14 21:04:18 -0600549/** @brief Clear attention interrupts */
Ben Tyner6a69e6e2022-04-05 23:18:29 -0500550void clearAttnInterrupts()
551{
552 trace::inf("Clearing attention interrupts");
553
554 // loop through processors clearing attention interrupts
555 pdbg_target* procTarget;
556 pdbg_for_each_class_target("proc", procTarget)
557 {
558 // active processors only
559 if (PDBG_TARGET_ENABLED !=
560 pdbg_target_probe(util::pdbg::getPibTrgt(procTarget)))
561 {
562 continue;
563 }
564
565 // get cfam is an fsi read
566 pdbg_target* fsiTarget = util::pdbg::getFsiTrgt(procTarget);
567 uint32_t int_val;
568
569 // get attention interrupts on processor
570 if (RC_SUCCESS == fsi_read(fsiTarget, 0x100b, &int_val))
571 {
572 // trace int value
573 trace::inf("cfam 0x100b = 0x%08x", int_val);
574
575 int_val &= ~(ANY_ATTN | CHECKSTOP_ATTN | SPECIAL_ATTN |
576 RECOVERABLE_ATTN | SBE_ATTN);
577
578 // clear attention interrupts on processor
579 if (RC_SUCCESS != fsi_write(fsiTarget, 0x100b, int_val))
580 {
581 // log cfam write error
582 trace::err("cfam write 0x100b FAILED");
583 }
584 }
585 else
586 {
587 // log cfam read error
588 trace::err("cfam read 0x100b FAILED");
589 }
590 }
591}
592
Ben Tyneref320152020-01-09 10:31:23 -0600593} // namespace attn