1b1eda6a3SJayanth Othayoth extern "C"
2b1eda6a3SJayanth Othayoth {
3792f32f7SBen Tyner #include <libpdbg.h>
4b1eda6a3SJayanth Othayoth #include <libpdbg_sbe.h>
5b1eda6a3SJayanth Othayoth }
6792f32f7SBen Tyner
7a06dcf82SZane Shelley #include <config.h>
8a06dcf82SZane Shelley
9b9715179SBen Tyner #ifdef CONFIG_PHAL_API
10b9715179SBen Tyner #include <libphal.H>
11b9715179SBen Tyner #endif
12b9715179SBen Tyner
130205f3b3SBen Tyner #include <analyzer/analyzer_main.hpp>
14b797b3e1SBen Tyner #include <attn/attention.hpp>
15bcf65a8bSBen Tyner #include <attn/attn_common.hpp>
16b797b3e1SBen Tyner #include <attn/attn_config.hpp>
174bbcb38fSBen Tyner #include <attn/attn_dbus.hpp>
18b797b3e1SBen Tyner #include <attn/attn_handler.hpp>
19b797b3e1SBen Tyner #include <attn/attn_logging.hpp>
20b797b3e1SBen Tyner #include <attn/bp_handler.hpp>
21b797b3e1SBen Tyner #include <attn/ti_handler.hpp>
22bcf65a8bSBen Tyner #include <attn/vital_handler.hpp>
23fe2c50d7SBen Tyner #include <util/dbus.hpp>
2476e52f6dSBen Tyner #include <util/ffdc_file.hpp>
256a69e6e5SBen Tyner #include <util/pdbg.hpp>
2676e52f6dSBen Tyner #include <util/trace.hpp>
27ef320154SBen Tyner
28b481d905SBen Tyner #include <algorithm>
29ef320154SBen Tyner #include <iomanip>
30b1ebfcb1SBen Tyner #include <map>
319ae5ca41SBen Tyner #include <sstream>
32b481d905SBen Tyner #include <vector>
33ef320154SBen Tyner
34ef320154SBen Tyner namespace attn
35ef320154SBen Tyner {
36ef320154SBen Tyner /**
37ef320154SBen Tyner * @brief Handle checkstop attention
38ef320154SBen Tyner *
39b481d905SBen Tyner * @param i_attention Attention object
403fb52e53SBen Tyner * @return 0 indicates that the checkstop attention was successfully handled
413fb52e53SBen Tyner * 1 indicates that the checkstop attention was NOT successfully
423fb52e53SBen Tyner * handled.
43ef320154SBen Tyner */
44b481d905SBen Tyner int handleCheckstop(Attention* i_attention);
45ef320154SBen Tyner
46ef320154SBen Tyner /**
47ef320154SBen Tyner * @brief Handle special attention
48ef320154SBen Tyner *
49b481d905SBen Tyner * @param i_attention Attention object
503fb52e53SBen Tyner * @return 0 indicates that the special attention was successfully handled
513fb52e53SBen Tyner * 1 indicates that the special attention was NOT successfully handled
52ef320154SBen Tyner */
53b481d905SBen Tyner int handleSpecial(Attention* i_attention);
54ef320154SBen Tyner
55b9715179SBen Tyner #ifdef CONFIG_PHAL_API
56b9715179SBen Tyner /** @brief Handle phal sbe exception */
57b9715179SBen Tyner void phalSbeExceptionHandler(openpower::phal::exception::SbeError& e,
5876e52f6dSBen Tyner uint32_t chipPosition, uint32_t command);
59b9715179SBen Tyner #endif
60b9715179SBen Tyner
61b9715179SBen Tyner /** @brief Get static TI info data based on host state */
62b9715179SBen Tyner void getStaticTiInfo(uint8_t*& tiInfoPtr);
63b9715179SBen Tyner
64b9715179SBen Tyner /** @brief Check if TI info data is valid */
65b9715179SBen Tyner bool tiInfoValid(uint8_t* tiInfo);
66b9715179SBen Tyner
67ef320154SBen Tyner /**
68ef320154SBen Tyner * @brief The main attention handler logic
69970fd4fbSBen Tyner *
70970fd4fbSBen Tyner * @param i_breakpoints true = breakpoint special attn handling enabled
71ef320154SBen Tyner */
attnHandler(Config * i_config)723fb52e53SBen Tyner void attnHandler(Config* i_config)
73ef320154SBen Tyner {
74d28d5f8bSaustinfcui // Check if enClrAttnIntr is enabled
75d28d5f8bSaustinfcui if (true == i_config->getFlag(enClrAttnIntr))
76d28d5f8bSaustinfcui {
776a69e6e5SBen Tyner // Clear attention interrupts that may still be active (MPIPL)
786a69e6e5SBen Tyner clearAttnInterrupts();
79d28d5f8bSaustinfcui }
806a69e6e5SBen Tyner
81b481d905SBen Tyner // Vector of active attentions to be handled
82b481d905SBen Tyner std::vector<Attention> active_attentions;
83b481d905SBen Tyner
84ef320154SBen Tyner uint32_t isr_val, isr_mask;
85ef320154SBen Tyner
86ef320154SBen Tyner // loop through processors looking for active attentions
87bfa831a8Saustinfcui trace::inf("Attention handler started");
88117af99bSBen Tyner
89ef320154SBen Tyner pdbg_target* target;
905e622d87SBen Tyner pdbg_for_each_class_target("proc", target)
91ef320154SBen Tyner {
92ef320154SBen Tyner if (PDBG_TARGET_ENABLED == pdbg_target_probe(target))
93ef320154SBen Tyner {
94a79f6c8fSZane Shelley auto proc = pdbg_target_index(target); // get processor number
95ef320154SBen Tyner
96b83c852aSBen Tyner // Use PIB target to determine if a processor is enabled
975e622d87SBen Tyner char path[16];
98b83c852aSBen Tyner sprintf(path, "/proc%d/pib", proc);
998882c32aSBen Tyner pdbg_target* pibTarget = pdbg_target_from_path(nullptr, path);
1005e622d87SBen Tyner
101b83c852aSBen Tyner // sanity check
1028882c32aSBen Tyner if (nullptr == pibTarget)
103b83c852aSBen Tyner {
104bfa831a8Saustinfcui trace::inf("pib path or target not found");
105b83c852aSBen Tyner continue;
106b83c852aSBen Tyner }
107b83c852aSBen Tyner
1088882c32aSBen Tyner // check if pib target is enabled
1098882c32aSBen Tyner if (PDBG_TARGET_ENABLED == pdbg_target_probe(pibTarget))
1105e622d87SBen Tyner {
111b83c852aSBen Tyner // The processor FSI target is required for CFAM read
112b83c852aSBen Tyner sprintf(path, "/proc%d/fsi", proc);
1138882c32aSBen Tyner pdbg_target* fsiTarget = pdbg_target_from_path(nullptr, path);
114b83c852aSBen Tyner
115b83c852aSBen Tyner // sanity check
1168882c32aSBen Tyner if (nullptr == fsiTarget)
117b83c852aSBen Tyner {
118bfa831a8Saustinfcui trace::inf("fsi path or target not found");
119b83c852aSBen Tyner continue;
120b83c852aSBen Tyner }
121b83c852aSBen Tyner
1228882c32aSBen Tyner // trace the proc number
123bfa831a8Saustinfcui trace::inf("proc: %u", proc);
1241965e504SBen Tyner
1255adc96eeSBen Tyner isr_val = 0xffffffff; // invalid isr value
1265adc96eeSBen Tyner
127ef320154SBen Tyner // get active attentions on processor
1288882c32aSBen Tyner if (RC_SUCCESS != fsi_read(fsiTarget, 0x1007, &isr_val))
129ef320154SBen Tyner {
130fb190545SBen Tyner // log cfam read error
131bfa831a8Saustinfcui trace::err("cfam read 0x1007 FAILED");
132*a0c724d3SPatrick Williams eventAttentionFail(
133*a0c724d3SPatrick Williams (int)AttnSection::attnHandler | ATTN_PDBG_CFAM);
134ef320154SBen Tyner }
1355adc96eeSBen Tyner else if (0xffffffff == isr_val)
1365adc96eeSBen Tyner {
137bfa831a8Saustinfcui trace::err("cfam read 0x1007 INVALID");
1385adc96eeSBen Tyner continue;
1395adc96eeSBen Tyner }
140ef320154SBen Tyner else
141ef320154SBen Tyner {
1428882c32aSBen Tyner // trace isr value
143bfa831a8Saustinfcui trace::inf("cfam 0x1007 = 0x%08x", isr_val);
1441965e504SBen Tyner
1455adc96eeSBen Tyner isr_mask = 0xffffffff; // invalid isr mask
1465adc96eeSBen Tyner
147ef320154SBen Tyner // get interrupt enabled special attentions mask
1488882c32aSBen Tyner if (RC_SUCCESS != fsi_read(fsiTarget, 0x100d, &isr_mask))
149ef320154SBen Tyner {
150fb190545SBen Tyner // log cfam read error
151bfa831a8Saustinfcui trace::err("cfam read 0x100d FAILED");
152*a0c724d3SPatrick Williams eventAttentionFail(
153*a0c724d3SPatrick Williams (int)AttnSection::attnHandler | ATTN_PDBG_CFAM);
154ef320154SBen Tyner }
1555adc96eeSBen Tyner else if (0xffffffff == isr_mask)
1565adc96eeSBen Tyner {
157bfa831a8Saustinfcui trace::err("cfam read 0x100d INVALID");
1585adc96eeSBen Tyner continue;
1595adc96eeSBen Tyner }
160ef320154SBen Tyner else
161ef320154SBen Tyner {
1628882c32aSBen Tyner // trace true mask
163bfa831a8Saustinfcui trace::inf("cfam 0x100d = 0x%08x", isr_mask);
1641965e504SBen Tyner
165fb190545SBen Tyner // SBE vital attention active and not masked?
1661965e504SBen Tyner if (true == activeAttn(isr_val, isr_mask, SBE_ATTN))
167ef320154SBen Tyner {
1685e622d87SBen Tyner active_attentions.emplace_back(Attention::Vital,
1695e622d87SBen Tyner handleVital, target,
1705e622d87SBen Tyner i_config);
171ef320154SBen Tyner }
172ef320154SBen Tyner
173fb190545SBen Tyner // Checkstop attention active and not masked?
174fb190545SBen Tyner if (true ==
1751965e504SBen Tyner activeAttn(isr_val, isr_mask, CHECKSTOP_ATTN))
176ef320154SBen Tyner {
177b481d905SBen Tyner active_attentions.emplace_back(Attention::Checkstop,
1785e622d87SBen Tyner handleCheckstop,
1795e622d87SBen Tyner target, i_config);
180ef320154SBen Tyner }
181ef320154SBen Tyner
182fb190545SBen Tyner // Special attention active and not masked?
1831965e504SBen Tyner if (true == activeAttn(isr_val, isr_mask, SPECIAL_ATTN))
184ef320154SBen Tyner {
185b481d905SBen Tyner active_attentions.emplace_back(Attention::Special,
1865e622d87SBen Tyner handleSpecial,
1875e622d87SBen Tyner target, i_config);
188ef320154SBen Tyner }
189ef320154SBen Tyner } // cfam 0x100d valid
190ef320154SBen Tyner } // cfam 0x1007 valid
191ef320154SBen Tyner } // fsi target enabled
1928882c32aSBen Tyner } // pib target enabled
193ef320154SBen Tyner } // next processor
194ef320154SBen Tyner
195b481d905SBen Tyner // convert to heap, highest priority is at front
196b481d905SBen Tyner if (!std::is_heap(active_attentions.begin(), active_attentions.end()))
197b481d905SBen Tyner {
198b481d905SBen Tyner std::make_heap(active_attentions.begin(), active_attentions.end());
199b481d905SBen Tyner }
200b481d905SBen Tyner
201b481d905SBen Tyner // call the attention handler until one is handled or all were attempted
202b481d905SBen Tyner while (false == active_attentions.empty())
203b481d905SBen Tyner {
204b481d905SBen Tyner // handle highest priority attention, done if successful
205b481d905SBen Tyner if (RC_SUCCESS == active_attentions.front().handle())
206b481d905SBen Tyner {
207b1ebfcb1SBen Tyner // an attention was handled so we are done
208b481d905SBen Tyner break;
209b481d905SBen Tyner }
210b481d905SBen Tyner
211b481d905SBen Tyner // move attention to back of vector
212b481d905SBen Tyner std::pop_heap(active_attentions.begin(), active_attentions.end());
213b481d905SBen Tyner
214b481d905SBen Tyner // remove attention from vector
215b481d905SBen Tyner active_attentions.pop_back();
216b481d905SBen Tyner }
217ef320154SBen Tyner }
218ef320154SBen Tyner
219ef320154SBen Tyner /**
220ef320154SBen Tyner * @brief Handle checkstop attention
2213fb52e53SBen Tyner *
2223fb52e53SBen Tyner * @param i_attention Attention object
2233fb52e53SBen Tyner * @return 0 indicates that the checkstop attention was successfully handled
2243fb52e53SBen Tyner * 1 indicates that the checkstop attention was NOT successfully
2253fb52e53SBen Tyner * handled.
226ef320154SBen Tyner */
handleCheckstop(Attention * i_attention)227b481d905SBen Tyner int handleCheckstop(Attention* i_attention)
228ef320154SBen Tyner {
2293fb52e53SBen Tyner int rc = RC_SUCCESS; // assume checkstop handled
230ef320154SBen Tyner
231bfa831a8Saustinfcui trace::inf("checkstop handler started");
232b1ebfcb1SBen Tyner
233b8335568SBen Tyner // capture some additional data for logs/traces
234b8335568SBen Tyner addHbStatusRegs();
235b8335568SBen Tyner
2363fb52e53SBen Tyner // if checkstop handling enabled, handle checkstop attention
2373fb52e53SBen Tyner if (false == (i_attention->getConfig()->getFlag(enCheckstop)))
2383fb52e53SBen Tyner {
239bfa831a8Saustinfcui trace::inf("Checkstop handling disabled");
2403fb52e53SBen Tyner }
2413fb52e53SBen Tyner else
2423fb52e53SBen Tyner {
2432b26b2bbSBen Tyner // check for power fault before starting analyses
24407ebb9beSBen Tyner sleepSeconds(POWER_FAULT_WAIT);
2452b26b2bbSBen Tyner if (!util::dbus::powerFault())
2462b26b2bbSBen Tyner {
2479fb7393eSZane Shelley // Look for any attentions found in hardware. This will generate and
2487ae9c8c7SZane Shelley // commit a PEL if any errors are found.
2497029e525SBen Tyner DumpParameters dumpParameters;
250ebff0d37SZane Shelley auto logid = analyzer::analyzeHardware(
251ebff0d37SZane Shelley analyzer::AnalysisType::SYSTEM_CHECKSTOP, dumpParameters);
252611b3442SZane Shelley if (0 == logid)
253b1ebfcb1SBen Tyner {
254611b3442SZane Shelley // A PEL should exist for a checkstop attention.
255b1ebfcb1SBen Tyner rc = RC_ANALYZER_ERROR;
256b1ebfcb1SBen Tyner }
2577029e525SBen Tyner else
2587029e525SBen Tyner {
259611b3442SZane Shelley requestDump(logid, dumpParameters);
2607029e525SBen Tyner util::dbus::transitionHost(util::dbus::HostState::Quiesce);
2617029e525SBen Tyner }
2623fb52e53SBen Tyner }
2632b26b2bbSBen Tyner }
264ef320154SBen Tyner
265ef320154SBen Tyner return rc;
266ef320154SBen Tyner }
267ef320154SBen Tyner
268ef320154SBen Tyner /**
269ef320154SBen Tyner * @brief Handle special attention
2703fb52e53SBen Tyner *
2713fb52e53SBen Tyner * @param i_attention Attention object
2723fb52e53SBen Tyner * @return 0 indicates that the special attention was successfully handled
2733fb52e53SBen Tyner * 1 indicates that the special attention was NOT successfully handled
274ef320154SBen Tyner */
handleSpecial(Attention * i_attention)275b481d905SBen Tyner int handleSpecial(Attention* i_attention)
276ef320154SBen Tyner {
277b1ebfcb1SBen Tyner int rc = RC_SUCCESS; // assume special attention handled
278ef320154SBen Tyner
279fb190545SBen Tyner // The TI info chipop will give us a pointer to the TI info data
280792f32f7SBen Tyner uint8_t* tiInfo = nullptr; // ptr to TI info data
281792f32f7SBen Tyner uint32_t tiInfoLen = 0; // length of TI info data
28298430b30SBen Tyner pdbg_target* attnProc = i_attention->getTarget(); // proc with attention
283b1ebfcb1SBen Tyner
28429651ef8SBen Tyner bool tiInfoStatic = false; // assume TI info was provided (not created)
28529651ef8SBen Tyner
286b9715179SBen Tyner // need proc target to get dynamic TI info
287b9715179SBen Tyner if (nullptr != attnProc)
28898430b30SBen Tyner {
289b9715179SBen Tyner #ifdef CONFIG_PHAL_API
290bfa831a8Saustinfcui trace::inf("using libphal to get TI info");
291b9715179SBen Tyner
292b9715179SBen Tyner // phal library uses proc target for get ti info
293b9715179SBen Tyner if (PDBG_TARGET_ENABLED == pdbg_target_probe(attnProc))
294b9715179SBen Tyner {
295b9715179SBen Tyner try
296b9715179SBen Tyner {
297b9715179SBen Tyner // get dynamic TI info
298b9715179SBen Tyner openpower::phal::sbe::getTiInfo(attnProc, &tiInfo, &tiInfoLen);
299b9715179SBen Tyner }
30076e52f6dSBen Tyner catch (openpower::phal::exception::SbeError& sbeError)
301b9715179SBen Tyner {
302b9715179SBen Tyner // library threw an exception
30376e52f6dSBen Tyner // note: phal::sbe::getTiInfo = command class | command ==
30476e52f6dSBen Tyner // 0xa900 | 0x04 = 0xa904. The sbe fifo command class and
3056a69e6e5SBen Tyner // commands are defined in the sbefifo library source code
3066a69e6e5SBen Tyner // but do not seem to be exported/installed for consumption
30776e52f6dSBen Tyner // externally.
308b9715179SBen Tyner uint32_t procNum = pdbg_target_index(attnProc);
30976e52f6dSBen Tyner phalSbeExceptionHandler(sbeError, procNum, 0xa904);
310b9715179SBen Tyner }
311b9715179SBen Tyner }
312b9715179SBen Tyner #else
313bfa831a8Saustinfcui trace::inf("using libpdbg to get TI info");
314b9715179SBen Tyner
315b9715179SBen Tyner // pdbg library uses pib target for get ti info
31698430b30SBen Tyner char path[16];
31798430b30SBen Tyner sprintf(path, "/proc%d/pib", pdbg_target_index(attnProc));
31898430b30SBen Tyner pdbg_target* tiInfoTarget = pdbg_target_from_path(nullptr, path);
31989c0a7afSBen Tyner
32098430b30SBen Tyner if (nullptr != tiInfoTarget)
32189c0a7afSBen Tyner {
32289c0a7afSBen Tyner if (PDBG_TARGET_ENABLED == pdbg_target_probe(tiInfoTarget))
32389c0a7afSBen Tyner {
324792f32f7SBen Tyner sbe_mpipl_get_ti_info(tiInfoTarget, &tiInfo, &tiInfoLen);
325b9715179SBen Tyner }
326b9715179SBen Tyner }
327b9715179SBen Tyner #endif
328b9715179SBen Tyner }
3294bbcb38fSBen Tyner
330b9715179SBen Tyner // dynamic TI info is not available
3314bbcb38fSBen Tyner if (nullptr == tiInfo)
33298430b30SBen Tyner {
333bfa831a8Saustinfcui trace::inf("TI info data ptr is invalid");
334b9715179SBen Tyner getStaticTiInfo(tiInfo);
335b9715179SBen Tyner tiInfoStatic = true;
336b9715179SBen Tyner }
3374bbcb38fSBen Tyner
338b9715179SBen Tyner // check TI info for validity and handle
339b9715179SBen Tyner if (true == tiInfoValid(tiInfo))
3404bbcb38fSBen Tyner {
341b9715179SBen Tyner // TI info is valid handle TI if support enabled
3423fb52e53SBen Tyner if (true == (i_attention->getConfig()->getFlag(enTerminate)))
343970fd4fbSBen Tyner {
3449ae5ca41SBen Tyner // Call TI special attention handler
345b9715179SBen Tyner rc = tiHandler((TiDataArea*)tiInfo);
3463fb52e53SBen Tyner }
347792f32f7SBen Tyner }
348b9715179SBen Tyner else
3493fb52e53SBen Tyner {
350bfa831a8Saustinfcui trace::inf("TI info NOT valid");
351e4f5dbefSBen Tyner
352e4f5dbefSBen Tyner // if configured to handle TI as default special attention
353fe15649eSBen Tyner if (i_attention->getConfig()->getFlag(dfltTi))
354e4f5dbefSBen Tyner {
355fe15649eSBen Tyner // TI handling may be disabled
356e4f5dbefSBen Tyner if (true == (i_attention->getConfig()->getFlag(enTerminate)))
357e4f5dbefSBen Tyner {
358e4f5dbefSBen Tyner // Call TI special attention handler
359b9715179SBen Tyner rc = tiHandler((TiDataArea*)tiInfo);
360e4f5dbefSBen Tyner }
361e4f5dbefSBen Tyner }
362b9715179SBen Tyner // configured to handle breakpoint as default special attention
363fe15649eSBen Tyner else
364fe15649eSBen Tyner {
365fe15649eSBen Tyner // breakpoint handling may be disabled
366fe15649eSBen Tyner if (true == (i_attention->getConfig()->getFlag(enBreakpoints)))
367fe15649eSBen Tyner {
368fe15649eSBen Tyner // Call the breakpoint special attention handler
369fe15649eSBen Tyner rc = bpHandler();
370fe15649eSBen Tyner }
371fe15649eSBen Tyner }
372e4f5dbefSBen Tyner }
373ef320154SBen Tyner
374b9715179SBen Tyner // release TI data buffer if not ours
375b9715179SBen Tyner if (false == tiInfoStatic)
376b9715179SBen Tyner {
377b9715179SBen Tyner // sanity check
378b9715179SBen Tyner if (nullptr != tiInfo)
379792f32f7SBen Tyner {
380792f32f7SBen Tyner free(tiInfo);
381792f32f7SBen Tyner }
382b9715179SBen Tyner }
383792f32f7SBen Tyner
384b9715179SBen Tyner // trace non-successful exit condition
3853fb52e53SBen Tyner if (RC_SUCCESS != rc)
3863fb52e53SBen Tyner {
387bfa831a8Saustinfcui trace::inf("Special attn not handled");
3883fb52e53SBen Tyner }
389ef320154SBen Tyner
390ef320154SBen Tyner return rc;
391ef320154SBen Tyner }
392ef320154SBen Tyner
39390516851SBen Tyner /** @brief Determine if attention is active and not masked */
activeAttn(uint32_t i_val,uint32_t i_mask,uint32_t i_attn)3941965e504SBen Tyner bool activeAttn(uint32_t i_val, uint32_t i_mask, uint32_t i_attn)
395fb190545SBen Tyner {
396fb190545SBen Tyner bool rc = false; // assume attn masked and/or inactive
397fb190545SBen Tyner
398fb190545SBen Tyner // if attention active
399fb190545SBen Tyner if (0 != (i_val & i_attn))
400fb190545SBen Tyner {
401bfa831a8Saustinfcui std::string msg;
402fb190545SBen Tyner
4039fb657f9SZane Shelley bool validAttn = true; // known attention type
4049fb657f9SZane Shelley
405fb190545SBen Tyner switch (i_attn)
406fb190545SBen Tyner {
407fb190545SBen Tyner case SBE_ATTN:
408bfa831a8Saustinfcui msg = "SBE attn";
409fb190545SBen Tyner break;
410fb190545SBen Tyner case CHECKSTOP_ATTN:
411bfa831a8Saustinfcui msg = "Checkstop attn";
412fb190545SBen Tyner break;
413fb190545SBen Tyner case SPECIAL_ATTN:
414bfa831a8Saustinfcui msg = "Special attn";
415fb190545SBen Tyner break;
416fb190545SBen Tyner default:
417bfa831a8Saustinfcui msg = "Unknown attn";
418fb190545SBen Tyner validAttn = false;
419fb190545SBen Tyner }
420fb190545SBen Tyner
421fb190545SBen Tyner // see if attention is masked
422fb190545SBen Tyner if (true == validAttn)
423fb190545SBen Tyner {
424fb190545SBen Tyner if (0 != (i_mask & i_attn))
425fb190545SBen Tyner {
426fb190545SBen Tyner rc = true; // attention active and not masked
427fb190545SBen Tyner }
428fb190545SBen Tyner else
429fb190545SBen Tyner {
430bfa831a8Saustinfcui msg += " masked";
431fb190545SBen Tyner }
432fb190545SBen Tyner }
433fb190545SBen Tyner
434bfa831a8Saustinfcui trace::inf(msg.c_str()); // commit trace stream
435fb190545SBen Tyner }
436fb190545SBen Tyner
437fb190545SBen Tyner return rc;
438fb190545SBen Tyner }
439b9715179SBen Tyner
440b9715179SBen Tyner #ifdef CONFIG_PHAL_API
44176e52f6dSBen Tyner
442b9715179SBen Tyner /**
443b9715179SBen Tyner * @brief Handle phal sbe exception
444b9715179SBen Tyner *
445b9715179SBen Tyner * @param[in] e - exception object
446b9715179SBen Tyner * @param[in] procNum - processor number associated with sbe exception
447b9715179SBen Tyner */
phalSbeExceptionHandler(openpower::phal::exception::SbeError & sbeError,uint32_t chipPosition,uint32_t command)44876e52f6dSBen Tyner void phalSbeExceptionHandler(openpower::phal::exception::SbeError& sbeError,
44976e52f6dSBen Tyner uint32_t chipPosition, uint32_t command)
450b9715179SBen Tyner {
45176e52f6dSBen Tyner trace::err("Attention handler phal exception handler");
452b9715179SBen Tyner
45376e52f6dSBen Tyner // Trace exception details
45476e52f6dSBen Tyner trace::err(sbeError.what());
45576e52f6dSBen Tyner
45676e52f6dSBen Tyner // Create event log entry with SBE FFDC data if provided
45776e52f6dSBen Tyner auto fd = sbeError.getFd();
45876e52f6dSBen Tyner if (fd > 0)
459b9715179SBen Tyner {
46076e52f6dSBen Tyner trace::err("SBE FFDC data is available");
46176e52f6dSBen Tyner
46276e52f6dSBen Tyner // FFDC parser expects chip position and command (command class |
46376e52f6dSBen Tyner // command) to be in the additional data.
46476e52f6dSBen Tyner std::map<std::string, std::string> additionalData = {
46576e52f6dSBen Tyner {"SRC6", std::to_string((chipPosition << 16) | command)}};
46676e52f6dSBen Tyner
4676a69e6e5SBen Tyner // See phosphor-logging/extensions/openpower-pels/README.md, "Self
4686a69e6e5SBen Tyner // Boot Engine(SBE) First Failure Data Capture(FFDC)" - SBE FFDC
4696a69e6e5SBen Tyner // file type is 0xCB, version is 0x01.
47076e52f6dSBen Tyner std::vector<util::FFDCTuple> ffdc{util::FFDCTuple{
47176e52f6dSBen Tyner util::FFDCFormat::Custom, static_cast<uint8_t>(0xCB),
47276e52f6dSBen Tyner static_cast<uint8_t>(0x01), fd}};
47376e52f6dSBen Tyner
47476e52f6dSBen Tyner // Create event log entry with FFDC data
4751315968cSBen Tyner util::dbus::createPel("org.open_power.Processor.Error.SbeChipOpFailure",
4761315968cSBen Tyner levelPelError, additionalData, ffdc);
477b9715179SBen Tyner }
478b9715179SBen Tyner }
479b9715179SBen Tyner #endif
480b9715179SBen Tyner
481b9715179SBen Tyner /**
482b9715179SBen Tyner * @brief Get static TI info data based on host state
483b9715179SBen Tyner *
484b9715179SBen Tyner * @param[out] tiInfo - pointer to static TI info data
485b9715179SBen Tyner */
getStaticTiInfo(uint8_t * & tiInfo)486b9715179SBen Tyner void getStaticTiInfo(uint8_t*& tiInfo)
487b9715179SBen Tyner {
488b9715179SBen Tyner util::dbus::HostRunningState runningState = util::dbus::hostRunningState();
489b9715179SBen Tyner
490b9715179SBen Tyner // assume host state is unknown
491b9715179SBen Tyner std::string stateString = "host state unknown";
492b9715179SBen Tyner
493b9715179SBen Tyner if ((util::dbus::HostRunningState::Started == runningState) ||
494b9715179SBen Tyner (util::dbus::HostRunningState::Unknown == runningState))
495b9715179SBen Tyner {
496b9715179SBen Tyner if (util::dbus::HostRunningState::Started == runningState)
497b9715179SBen Tyner {
498b9715179SBen Tyner stateString = "host started";
499b9715179SBen Tyner }
500b9715179SBen Tyner tiInfo = (uint8_t*)defaultPhypTiInfo;
501b9715179SBen Tyner }
502b9715179SBen Tyner else
503b9715179SBen Tyner {
504b9715179SBen Tyner stateString = "host not started";
505b9715179SBen Tyner tiInfo = (uint8_t*)defaultHbTiInfo;
506b9715179SBen Tyner }
507b9715179SBen Tyner
508b9715179SBen Tyner // trace host state
509bfa831a8Saustinfcui trace::inf(stateString.c_str());
510b9715179SBen Tyner }
511b9715179SBen Tyner
512b9715179SBen Tyner /**
513b9715179SBen Tyner * @brief Check if TI info data is valid
514b9715179SBen Tyner *
515b9715179SBen Tyner * @param[in] tiInfo - pointer to TI info data
516b9715179SBen Tyner * @return true if TI info data is valid, else false
517b9715179SBen Tyner */
tiInfoValid(uint8_t * tiInfo)518b9715179SBen Tyner bool tiInfoValid(uint8_t* tiInfo)
519b9715179SBen Tyner {
520b9715179SBen Tyner bool tiInfoValid = false; // assume TI info invalid
521b9715179SBen Tyner
522b9715179SBen Tyner // TI info data[0] non-zero indicates TI info valid (usually)
523b9715179SBen Tyner if ((nullptr != tiInfo) && (0 != tiInfo[0]))
524b9715179SBen Tyner {
525b9715179SBen Tyner TiDataArea* tiDataArea = (TiDataArea*)tiInfo;
526b9715179SBen Tyner
527b9715179SBen Tyner // trace a few known TI data area values
528535a8d4aSBen Tyner trace::inf("TI data command = 0x%02x", tiDataArea->command);
529b9715179SBen Tyner
530b9715179SBen Tyner // Another check for valid TI Info since it has been seen that
531b9715179SBen Tyner // tiInfo[0] != 0 but TI info is not valid
532b9715179SBen Tyner if (0xa1 == tiDataArea->command)
533b9715179SBen Tyner {
534b9715179SBen Tyner tiInfoValid = true;
535b9715179SBen Tyner
536b9715179SBen Tyner // trace some more data since TI info appears valid
537535a8d4aSBen Tyner trace::inf("TI data term-type = 0x%02x",
538bfa831a8Saustinfcui tiDataArea->hbTerminateType);
539b9715179SBen Tyner
540535a8d4aSBen Tyner trace::inf("TI data SRC format = 0x%02x", tiDataArea->srcFormat);
541b9715179SBen Tyner
542535a8d4aSBen Tyner trace::inf("TI data source = 0x%02x", tiDataArea->source);
543b9715179SBen Tyner }
544b9715179SBen Tyner }
545b9715179SBen Tyner
546b9715179SBen Tyner return tiInfoValid;
547b9715179SBen Tyner }
548b9715179SBen Tyner
54990516851SBen Tyner /** @brief Clear attention interrupts */
clearAttnInterrupts()5506a69e6e5SBen Tyner void clearAttnInterrupts()
5516a69e6e5SBen Tyner {
5526a69e6e5SBen Tyner trace::inf("Clearing attention interrupts");
5536a69e6e5SBen Tyner
5546a69e6e5SBen Tyner // loop through processors clearing attention interrupts
5556a69e6e5SBen Tyner pdbg_target* procTarget;
5566a69e6e5SBen Tyner pdbg_for_each_class_target("proc", procTarget)
5576a69e6e5SBen Tyner {
5586a69e6e5SBen Tyner // active processors only
5596a69e6e5SBen Tyner if (PDBG_TARGET_ENABLED !=
5606a69e6e5SBen Tyner pdbg_target_probe(util::pdbg::getPibTrgt(procTarget)))
5616a69e6e5SBen Tyner {
5626a69e6e5SBen Tyner continue;
5636a69e6e5SBen Tyner }
5646a69e6e5SBen Tyner
5656a69e6e5SBen Tyner // get cfam is an fsi read
5666a69e6e5SBen Tyner pdbg_target* fsiTarget = util::pdbg::getFsiTrgt(procTarget);
5676a69e6e5SBen Tyner uint32_t int_val;
5686a69e6e5SBen Tyner
5696a69e6e5SBen Tyner // get attention interrupts on processor
5706a69e6e5SBen Tyner if (RC_SUCCESS == fsi_read(fsiTarget, 0x100b, &int_val))
5716a69e6e5SBen Tyner {
5726a69e6e5SBen Tyner // trace int value
5736a69e6e5SBen Tyner trace::inf("cfam 0x100b = 0x%08x", int_val);
5746a69e6e5SBen Tyner
5756a69e6e5SBen Tyner int_val &= ~(ANY_ATTN | CHECKSTOP_ATTN | SPECIAL_ATTN |
5766a69e6e5SBen Tyner RECOVERABLE_ATTN | SBE_ATTN);
5776a69e6e5SBen Tyner
5786a69e6e5SBen Tyner // clear attention interrupts on processor
5796a69e6e5SBen Tyner if (RC_SUCCESS != fsi_write(fsiTarget, 0x100b, int_val))
5806a69e6e5SBen Tyner {
5816a69e6e5SBen Tyner // log cfam write error
5826a69e6e5SBen Tyner trace::err("cfam write 0x100b FAILED");
5836a69e6e5SBen Tyner }
5846a69e6e5SBen Tyner }
5856a69e6e5SBen Tyner else
5866a69e6e5SBen Tyner {
5876a69e6e5SBen Tyner // log cfam read error
5886a69e6e5SBen Tyner trace::err("cfam read 0x100b FAILED");
5896a69e6e5SBen Tyner }
5906a69e6e5SBen Tyner }
5916a69e6e5SBen Tyner }
5926a69e6e5SBen Tyner
593ef320154SBen Tyner } // namespace attn
594