1b1eda6a3SJayanth Othayoth extern "C"
2b1eda6a3SJayanth Othayoth {
3792f32f7SBen Tyner #include <libpdbg.h>
4b1eda6a3SJayanth Othayoth #include <libpdbg_sbe.h>
5b1eda6a3SJayanth Othayoth }
6792f32f7SBen Tyner 
7*b9715179SBen Tyner #ifdef CONFIG_PHAL_API
8*b9715179SBen Tyner #include <libphal.H>
9*b9715179SBen Tyner #endif
10*b9715179SBen Tyner 
110205f3b3SBen Tyner #include <analyzer/analyzer_main.hpp>
12b797b3e1SBen Tyner #include <attn/attention.hpp>
13bcf65a8bSBen Tyner #include <attn/attn_common.hpp>
14b797b3e1SBen Tyner #include <attn/attn_config.hpp>
154bbcb38fSBen Tyner #include <attn/attn_dbus.hpp>
16b797b3e1SBen Tyner #include <attn/attn_handler.hpp>
17b797b3e1SBen Tyner #include <attn/attn_logging.hpp>
18b797b3e1SBen Tyner #include <attn/bp_handler.hpp>
19b797b3e1SBen Tyner #include <attn/ti_handler.hpp>
20bcf65a8bSBen Tyner #include <attn/vital_handler.hpp>
21fe2c50d7SBen Tyner #include <util/dbus.hpp>
22ef320154SBen Tyner 
23b481d905SBen Tyner #include <algorithm>
24ef320154SBen Tyner #include <iomanip>
25b1ebfcb1SBen Tyner #include <map>
269ae5ca41SBen Tyner #include <sstream>
27b481d905SBen Tyner #include <vector>
28ef320154SBen Tyner 
29ef320154SBen Tyner namespace attn
30ef320154SBen Tyner {
31ef320154SBen Tyner 
32ef320154SBen Tyner /**
33ef320154SBen Tyner  * @brief Handle checkstop attention
34ef320154SBen Tyner  *
35b481d905SBen Tyner  * @param i_attention Attention object
363fb52e53SBen Tyner  * @return 0 indicates that the checkstop attention was successfully handled
373fb52e53SBen Tyner  *         1 indicates that the checkstop attention was NOT successfully
383fb52e53SBen Tyner  *           handled.
39ef320154SBen Tyner  */
40b481d905SBen Tyner int handleCheckstop(Attention* i_attention);
41ef320154SBen Tyner 
42ef320154SBen Tyner /**
43ef320154SBen Tyner  * @brief Handle special attention
44ef320154SBen Tyner  *
45b481d905SBen Tyner  * @param i_attention Attention object
463fb52e53SBen Tyner  * @return 0 indicates that the special attention was successfully handled
473fb52e53SBen Tyner  *         1 indicates that the special attention was NOT successfully handled
48ef320154SBen Tyner  */
49b481d905SBen Tyner int handleSpecial(Attention* i_attention);
50ef320154SBen Tyner 
51fb190545SBen Tyner /** @brief Determine if attention is active and not masked */
521965e504SBen Tyner bool activeAttn(uint32_t i_val, uint32_t i_mask, uint32_t i_attn);
53fb190545SBen Tyner 
54*b9715179SBen Tyner #ifdef CONFIG_PHAL_API
55*b9715179SBen Tyner /** @brief Handle phal sbe exception */
56*b9715179SBen Tyner void phalSbeExceptionHandler(openpower::phal::exception::SbeError& e,
57*b9715179SBen Tyner                              uint32_t procNum);
58*b9715179SBen Tyner #endif
59*b9715179SBen Tyner 
60*b9715179SBen Tyner /** @brief Get static TI info data based on host state */
61*b9715179SBen Tyner void getStaticTiInfo(uint8_t*& tiInfoPtr);
62*b9715179SBen Tyner 
63*b9715179SBen Tyner /** @brief Check if TI info data is valid */
64*b9715179SBen Tyner bool tiInfoValid(uint8_t* tiInfo);
65*b9715179SBen Tyner 
66ef320154SBen Tyner /**
67ef320154SBen Tyner  * @brief The main attention handler logic
68970fd4fbSBen Tyner  *
69970fd4fbSBen Tyner  * @param i_breakpoints true = breakpoint special attn handling enabled
70ef320154SBen Tyner  */
713fb52e53SBen Tyner void attnHandler(Config* i_config)
72ef320154SBen Tyner {
73b481d905SBen Tyner     // Vector of active attentions to be handled
74b481d905SBen Tyner     std::vector<Attention> active_attentions;
75b481d905SBen Tyner 
76ef320154SBen Tyner     uint32_t isr_val, isr_mask;
77ef320154SBen Tyner 
78ef320154SBen Tyner     // loop through processors looking for active attentions
79b1ebfcb1SBen Tyner     trace<level::INFO>("Attention handler started");
80117af99bSBen Tyner 
81ef320154SBen Tyner     pdbg_target* target;
825e622d87SBen Tyner     pdbg_for_each_class_target("proc", target)
83ef320154SBen Tyner     {
84ef320154SBen Tyner         if (PDBG_TARGET_ENABLED == pdbg_target_probe(target))
85ef320154SBen Tyner         {
86a79f6c8fSZane Shelley             auto proc = pdbg_target_index(target); // get processor number
87ef320154SBen Tyner 
88b83c852aSBen Tyner             // Use PIB target to determine if a processor is enabled
895e622d87SBen Tyner             char path[16];
90b83c852aSBen Tyner             sprintf(path, "/proc%d/pib", proc);
918882c32aSBen Tyner             pdbg_target* pibTarget = pdbg_target_from_path(nullptr, path);
925e622d87SBen Tyner 
93b83c852aSBen Tyner             // sanity check
948882c32aSBen Tyner             if (nullptr == pibTarget)
95b83c852aSBen Tyner             {
96b83c852aSBen Tyner                 trace<level::INFO>("pib path or target not found");
97b83c852aSBen Tyner                 continue;
98b83c852aSBen Tyner             }
99b83c852aSBen Tyner 
1008882c32aSBen Tyner             // check if pib target is enabled
1018882c32aSBen Tyner             if (PDBG_TARGET_ENABLED == pdbg_target_probe(pibTarget))
1025e622d87SBen Tyner             {
103b83c852aSBen Tyner                 // The processor FSI target is required for CFAM read
104b83c852aSBen Tyner                 sprintf(path, "/proc%d/fsi", proc);
1058882c32aSBen Tyner                 pdbg_target* fsiTarget = pdbg_target_from_path(nullptr, path);
106b83c852aSBen Tyner 
107b83c852aSBen Tyner                 // sanity check
1088882c32aSBen Tyner                 if (nullptr == fsiTarget)
109b83c852aSBen Tyner                 {
110b83c852aSBen Tyner                     trace<level::INFO>("fsi path or target not found");
111b83c852aSBen Tyner                     continue;
112b83c852aSBen Tyner                 }
113b83c852aSBen Tyner 
1148882c32aSBen Tyner                 // trace the proc number
1158882c32aSBen Tyner                 std::string traceMsg = "proc: " + std::to_string(proc);
1168882c32aSBen Tyner                 trace<level::INFO>(traceMsg.c_str());
1171965e504SBen Tyner 
1185adc96eeSBen Tyner                 isr_val = 0xffffffff; // invalid isr value
1195adc96eeSBen Tyner 
120ef320154SBen Tyner                 // get active attentions on processor
1218882c32aSBen Tyner                 if (RC_SUCCESS != fsi_read(fsiTarget, 0x1007, &isr_val))
122ef320154SBen Tyner                 {
123fb190545SBen Tyner                     // log cfam read error
124b1ebfcb1SBen Tyner                     trace<level::INFO>("Error! cfam read 0x1007 FAILED");
1257a0dd543SBen Tyner                     eventAttentionFail((int)AttnSection::attnHandler |
1267a0dd543SBen Tyner                                        ATTN_PDBG_CFAM);
127ef320154SBen Tyner                 }
1285adc96eeSBen Tyner                 else if (0xffffffff == isr_val)
1295adc96eeSBen Tyner                 {
1305adc96eeSBen Tyner                     trace<level::INFO>("Error! cfam read 0x1007 INVALID");
1315adc96eeSBen Tyner                     continue;
1325adc96eeSBen Tyner                 }
133ef320154SBen Tyner                 else
134ef320154SBen Tyner                 {
1358882c32aSBen Tyner                     // trace isr value
1368882c32aSBen Tyner                     std::stringstream ssIsr;
1378882c32aSBen Tyner                     ssIsr << "cfam 0x1007 = 0x" << std::setw(8)
1388882c32aSBen Tyner                           << std::setfill('0') << std::hex << isr_val;
1398882c32aSBen Tyner                     std::string strobjIsr = ssIsr.str();
1408882c32aSBen Tyner                     trace<level::INFO>(strobjIsr.c_str());
1411965e504SBen Tyner 
1425adc96eeSBen Tyner                     isr_mask = 0xffffffff; // invalid isr mask
1435adc96eeSBen Tyner 
144ef320154SBen Tyner                     // get interrupt enabled special attentions mask
1458882c32aSBen Tyner                     if (RC_SUCCESS != fsi_read(fsiTarget, 0x100d, &isr_mask))
146ef320154SBen Tyner                     {
147fb190545SBen Tyner                         // log cfam read error
148b1ebfcb1SBen Tyner                         trace<level::INFO>("Error! cfam read 0x100d FAILED");
1497a0dd543SBen Tyner                         eventAttentionFail((int)AttnSection::attnHandler |
1507a0dd543SBen Tyner                                            ATTN_PDBG_CFAM);
151ef320154SBen Tyner                     }
1525adc96eeSBen Tyner                     else if (0xffffffff == isr_mask)
1535adc96eeSBen Tyner                     {
1545adc96eeSBen Tyner                         trace<level::INFO>("Error! cfam read 0x100d INVALID");
1555adc96eeSBen Tyner                         continue;
1565adc96eeSBen Tyner                     }
157ef320154SBen Tyner                     else
158ef320154SBen Tyner                     {
1598882c32aSBen Tyner                         // trace true mask
1608882c32aSBen Tyner                         std::stringstream ssMask;
1618882c32aSBen Tyner                         ssMask << "cfam 0x100d = 0x" << std::setw(8)
1628882c32aSBen Tyner                                << std::setfill('0') << std::hex << isr_mask;
1638882c32aSBen Tyner                         std::string strobjMask = ssMask.str();
1648882c32aSBen Tyner                         trace<level::INFO>(strobjMask.c_str());
1651965e504SBen Tyner 
166fb190545SBen Tyner                         // SBE vital attention active and not masked?
1671965e504SBen Tyner                         if (true == activeAttn(isr_val, isr_mask, SBE_ATTN))
168ef320154SBen Tyner                         {
1695e622d87SBen Tyner                             active_attentions.emplace_back(Attention::Vital,
1705e622d87SBen Tyner                                                            handleVital, target,
1715e622d87SBen Tyner                                                            i_config);
172ef320154SBen Tyner                         }
173ef320154SBen Tyner 
174fb190545SBen Tyner                         // Checkstop attention active and not masked?
175fb190545SBen Tyner                         if (true ==
1761965e504SBen Tyner                             activeAttn(isr_val, isr_mask, CHECKSTOP_ATTN))
177ef320154SBen Tyner                         {
178b481d905SBen Tyner                             active_attentions.emplace_back(Attention::Checkstop,
1795e622d87SBen Tyner                                                            handleCheckstop,
1805e622d87SBen Tyner                                                            target, i_config);
181ef320154SBen Tyner                         }
182ef320154SBen Tyner 
183fb190545SBen Tyner                         // Special attention active and not masked?
1841965e504SBen Tyner                         if (true == activeAttn(isr_val, isr_mask, SPECIAL_ATTN))
185ef320154SBen Tyner                         {
186b481d905SBen Tyner                             active_attentions.emplace_back(Attention::Special,
1875e622d87SBen Tyner                                                            handleSpecial,
1885e622d87SBen Tyner                                                            target, i_config);
189ef320154SBen Tyner                         }
190ef320154SBen Tyner                     } // cfam 0x100d valid
191ef320154SBen Tyner                 }     // cfam 0x1007 valid
192ef320154SBen Tyner             }         // fsi target enabled
1938882c32aSBen Tyner         }             // pib target enabled
194ef320154SBen Tyner     }                 // next processor
195ef320154SBen Tyner 
196b481d905SBen Tyner     // convert to heap, highest priority is at front
197b481d905SBen Tyner     if (!std::is_heap(active_attentions.begin(), active_attentions.end()))
198b481d905SBen Tyner     {
199b481d905SBen Tyner         std::make_heap(active_attentions.begin(), active_attentions.end());
200b481d905SBen Tyner     }
201b481d905SBen Tyner 
202b481d905SBen Tyner     // call the attention handler until one is handled or all were attempted
203b481d905SBen Tyner     while (false == active_attentions.empty())
204b481d905SBen Tyner     {
205b481d905SBen Tyner         // handle highest priority attention, done if successful
206b481d905SBen Tyner         if (RC_SUCCESS == active_attentions.front().handle())
207b481d905SBen Tyner         {
208b1ebfcb1SBen Tyner             // an attention was handled so we are done
209b481d905SBen Tyner             break;
210b481d905SBen Tyner         }
211b481d905SBen Tyner 
212b481d905SBen Tyner         // move attention to back of vector
213b481d905SBen Tyner         std::pop_heap(active_attentions.begin(), active_attentions.end());
214b481d905SBen Tyner 
215b481d905SBen Tyner         // remove attention from vector
216b481d905SBen Tyner         active_attentions.pop_back();
217b481d905SBen Tyner     }
218ef320154SBen Tyner }
219ef320154SBen Tyner 
220ef320154SBen Tyner /**
221ef320154SBen Tyner  * @brief Handle checkstop attention
2223fb52e53SBen Tyner  *
2233fb52e53SBen Tyner  * @param i_attention Attention object
2243fb52e53SBen Tyner  * @return 0 indicates that the checkstop attention was successfully handled
2253fb52e53SBen Tyner  *         1 indicates that the checkstop attention was NOT successfully
2263fb52e53SBen Tyner  *           handled.
227ef320154SBen Tyner  */
228b481d905SBen Tyner int handleCheckstop(Attention* i_attention)
229ef320154SBen Tyner {
2303fb52e53SBen Tyner     int rc = RC_SUCCESS; // assume checkstop handled
231ef320154SBen Tyner 
232b1ebfcb1SBen Tyner     trace<level::INFO>("checkstop handler started");
233b1ebfcb1SBen Tyner 
234b8335568SBen Tyner     // capture some additional data for logs/traces
235b8335568SBen Tyner     addHbStatusRegs();
236b8335568SBen Tyner 
2373fb52e53SBen Tyner     // if checkstop handling enabled, handle checkstop attention
2383fb52e53SBen Tyner     if (false == (i_attention->getConfig()->getFlag(enCheckstop)))
2393fb52e53SBen Tyner     {
240b1ebfcb1SBen Tyner         trace<level::INFO>("Checkstop handling disabled");
2413fb52e53SBen Tyner     }
2423fb52e53SBen Tyner     else
2433fb52e53SBen Tyner     {
2449fb7393eSZane Shelley         // Look for any attentions found in hardware. This will generate and
2457ae9c8c7SZane Shelley         // commit a PEL if any errors are found.
2467029e525SBen Tyner         DumpParameters dumpParameters;
2477029e525SBen Tyner         if (true != analyzer::analyzeHardware(dumpParameters))
248b1ebfcb1SBen Tyner         {
249b1ebfcb1SBen Tyner             rc = RC_ANALYZER_ERROR;
250b1ebfcb1SBen Tyner         }
2517029e525SBen Tyner         else
2527029e525SBen Tyner         {
2537029e525SBen Tyner             requestDump(dumpParameters);
2547029e525SBen Tyner             util::dbus::transitionHost(util::dbus::HostState::Quiesce);
2557029e525SBen Tyner         }
2563fb52e53SBen Tyner     }
257ef320154SBen Tyner 
258ef320154SBen Tyner     return rc;
259ef320154SBen Tyner }
260ef320154SBen Tyner 
261ef320154SBen Tyner /**
262ef320154SBen Tyner  * @brief Handle special attention
2633fb52e53SBen Tyner  *
2643fb52e53SBen Tyner  * @param i_attention Attention object
2653fb52e53SBen Tyner  * @return 0 indicates that the special attention was successfully handled
2663fb52e53SBen Tyner  *         1 indicates that the special attention was NOT successfully handled
267ef320154SBen Tyner  */
268b481d905SBen Tyner int handleSpecial(Attention* i_attention)
269ef320154SBen Tyner {
270b1ebfcb1SBen Tyner     int rc = RC_SUCCESS; // assume special attention handled
271ef320154SBen Tyner 
272fb190545SBen Tyner     // The TI info chipop will give us a pointer to the TI info data
273792f32f7SBen Tyner     uint8_t* tiInfo       = nullptr;                  // ptr to TI info data
274792f32f7SBen Tyner     uint32_t tiInfoLen    = 0;                        // length of TI info data
27598430b30SBen Tyner     pdbg_target* attnProc = i_attention->getTarget(); // proc with attention
276b1ebfcb1SBen Tyner 
27729651ef8SBen Tyner     bool tiInfoStatic = false; // assume TI info was provided (not created)
27829651ef8SBen Tyner 
279*b9715179SBen Tyner     // need proc target to get dynamic TI info
280*b9715179SBen Tyner     if (nullptr != attnProc)
28198430b30SBen Tyner     {
282*b9715179SBen Tyner #ifdef CONFIG_PHAL_API
283*b9715179SBen Tyner         trace<level::INFO>("using libphal to get TI info");
284*b9715179SBen Tyner 
285*b9715179SBen Tyner         // phal library uses proc target for get ti info
286*b9715179SBen Tyner         if (PDBG_TARGET_ENABLED == pdbg_target_probe(attnProc))
287*b9715179SBen Tyner         {
288*b9715179SBen Tyner             try
289*b9715179SBen Tyner             {
290*b9715179SBen Tyner                 // get dynamic TI info
291*b9715179SBen Tyner                 openpower::phal::sbe::getTiInfo(attnProc, &tiInfo, &tiInfoLen);
292*b9715179SBen Tyner             }
293*b9715179SBen Tyner             catch (openpower::phal::exception::SbeError& e)
294*b9715179SBen Tyner             {
295*b9715179SBen Tyner                 // library threw an exception
296*b9715179SBen Tyner                 uint32_t procNum = pdbg_target_index(attnProc);
297*b9715179SBen Tyner                 phalSbeExceptionHandler(e, procNum);
298*b9715179SBen Tyner             }
299*b9715179SBen Tyner         }
300*b9715179SBen Tyner #else
301*b9715179SBen Tyner         trace<level::INFO>("using libpdbg to get TI info");
302*b9715179SBen Tyner 
303*b9715179SBen Tyner         // pdbg library uses pib target for get ti info
30498430b30SBen Tyner         char path[16];
30598430b30SBen Tyner         sprintf(path, "/proc%d/pib", pdbg_target_index(attnProc));
30698430b30SBen Tyner         pdbg_target* tiInfoTarget = pdbg_target_from_path(nullptr, path);
30789c0a7afSBen Tyner 
30898430b30SBen Tyner         if (nullptr != tiInfoTarget)
30989c0a7afSBen Tyner         {
31089c0a7afSBen Tyner             if (PDBG_TARGET_ENABLED == pdbg_target_probe(tiInfoTarget))
31189c0a7afSBen Tyner             {
312792f32f7SBen Tyner                 sbe_mpipl_get_ti_info(tiInfoTarget, &tiInfo, &tiInfoLen);
313*b9715179SBen Tyner             }
314*b9715179SBen Tyner         }
315*b9715179SBen Tyner #endif
316*b9715179SBen Tyner     }
3174bbcb38fSBen Tyner 
318*b9715179SBen Tyner     // dynamic TI info is not available
3194bbcb38fSBen Tyner     if (nullptr == tiInfo)
32098430b30SBen Tyner     {
3214bbcb38fSBen Tyner         trace<level::INFO>("TI info data ptr is invalid");
322*b9715179SBen Tyner         getStaticTiInfo(tiInfo);
323*b9715179SBen Tyner         tiInfoStatic = true;
324*b9715179SBen Tyner     }
3254bbcb38fSBen Tyner 
326*b9715179SBen Tyner     // check TI info for validity and handle
327*b9715179SBen Tyner     if (true == tiInfoValid(tiInfo))
3284bbcb38fSBen Tyner     {
329*b9715179SBen Tyner         // TI info is valid handle TI if support enabled
3303fb52e53SBen Tyner         if (true == (i_attention->getConfig()->getFlag(enTerminate)))
331970fd4fbSBen Tyner         {
3329ae5ca41SBen Tyner             // Call TI special attention handler
333*b9715179SBen Tyner             rc = tiHandler((TiDataArea*)tiInfo);
3343fb52e53SBen Tyner         }
335792f32f7SBen Tyner     }
336*b9715179SBen Tyner     else
3373fb52e53SBen Tyner     {
338fe15649eSBen Tyner         trace<level::INFO>("TI info NOT valid");
339e4f5dbefSBen Tyner 
340e4f5dbefSBen Tyner         // if configured to handle TI as default special attention
341fe15649eSBen Tyner         if (i_attention->getConfig()->getFlag(dfltTi))
342e4f5dbefSBen Tyner         {
343fe15649eSBen Tyner             // TI handling may be disabled
344e4f5dbefSBen Tyner             if (true == (i_attention->getConfig()->getFlag(enTerminate)))
345e4f5dbefSBen Tyner             {
346e4f5dbefSBen Tyner                 // Call TI special attention handler
347*b9715179SBen Tyner                 rc = tiHandler((TiDataArea*)tiInfo);
348e4f5dbefSBen Tyner             }
349e4f5dbefSBen Tyner         }
350*b9715179SBen Tyner         // configured to handle breakpoint as default special attention
351fe15649eSBen Tyner         else
352fe15649eSBen Tyner         {
353fe15649eSBen Tyner             // breakpoint handling may be disabled
354fe15649eSBen Tyner             if (true == (i_attention->getConfig()->getFlag(enBreakpoints)))
355fe15649eSBen Tyner             {
356fe15649eSBen Tyner                 // Call the breakpoint special attention handler
357fe15649eSBen Tyner                 rc = bpHandler();
358fe15649eSBen Tyner             }
359fe15649eSBen Tyner         }
360e4f5dbefSBen Tyner     }
361ef320154SBen Tyner 
362*b9715179SBen Tyner     // release TI data buffer if not ours
363*b9715179SBen Tyner     if (false == tiInfoStatic)
364*b9715179SBen Tyner     {
365*b9715179SBen Tyner         // sanity check
366*b9715179SBen Tyner         if (nullptr != tiInfo)
367792f32f7SBen Tyner         {
368792f32f7SBen Tyner             free(tiInfo);
369792f32f7SBen Tyner         }
370*b9715179SBen Tyner     }
371792f32f7SBen Tyner 
372*b9715179SBen Tyner     // trace non-successful exit condition
3733fb52e53SBen Tyner     if (RC_SUCCESS != rc)
3743fb52e53SBen Tyner     {
375792f32f7SBen Tyner         trace<level::INFO>("Special attn not handled");
3763fb52e53SBen Tyner     }
377ef320154SBen Tyner 
378ef320154SBen Tyner     return rc;
379ef320154SBen Tyner }
380ef320154SBen Tyner 
381fb190545SBen Tyner /**
382fb190545SBen Tyner  * @brief Determine if attention is active and not masked
383fb190545SBen Tyner  *
384fb190545SBen Tyner  * Determine whether an attention needs to be handled and trace details of
385fb190545SBen Tyner  * attention type and whether it is masked or not.
386fb190545SBen Tyner  *
387fb190545SBen Tyner  * @param i_val attention status register
388fb190545SBen Tyner  * @param i_mask attention true mask register
389fb190545SBen Tyner  * @param i_attn attention type
390fb190545SBen Tyner  * @param i_proc processor associated with registers
391fb190545SBen Tyner  *
392fb190545SBen Tyner  * @return true if attention is active and not masked, otherwise false
393fb190545SBen Tyner  */
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     {
401fb190545SBen Tyner         std::stringstream ss;
402fb190545SBen Tyner 
4039fb657f9SZane Shelley         bool validAttn = true; // known attention type
4049fb657f9SZane Shelley 
405fb190545SBen Tyner         switch (i_attn)
406fb190545SBen Tyner         {
407fb190545SBen Tyner             case SBE_ATTN:
408fb190545SBen Tyner                 ss << "SBE attn";
409fb190545SBen Tyner                 break;
410fb190545SBen Tyner             case CHECKSTOP_ATTN:
411fb190545SBen Tyner                 ss << "Checkstop attn";
412fb190545SBen Tyner                 break;
413fb190545SBen Tyner             case SPECIAL_ATTN:
414fb190545SBen Tyner                 ss << "Special attn";
415fb190545SBen Tyner                 break;
416fb190545SBen Tyner             default:
417fb190545SBen Tyner                 ss << "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             {
430fb190545SBen Tyner                 ss << " masked";
431fb190545SBen Tyner             }
432fb190545SBen Tyner         }
433fb190545SBen Tyner 
4348882c32aSBen Tyner         std::string strobj = ss.str();      // ss.str() is temporary
4358882c32aSBen Tyner         trace<level::INFO>(strobj.c_str()); // commit trace stream
436fb190545SBen Tyner     }
437fb190545SBen Tyner 
438fb190545SBen Tyner     return rc;
439fb190545SBen Tyner }
440*b9715179SBen Tyner 
441*b9715179SBen Tyner #ifdef CONFIG_PHAL_API
442*b9715179SBen Tyner /**
443*b9715179SBen Tyner  * @brief Handle phal sbe exception
444*b9715179SBen Tyner  *
445*b9715179SBen Tyner  * @param[in] e - exception object
446*b9715179SBen Tyner  * @param[in] procNum - processor number associated with sbe exception
447*b9715179SBen Tyner  */
448*b9715179SBen Tyner void phalSbeExceptionHandler(openpower::phal::exception::SbeError& e,
449*b9715179SBen Tyner                              uint32_t procNum)
450*b9715179SBen Tyner {
451*b9715179SBen Tyner     // trace exception details
452*b9715179SBen Tyner     std::string traceMsg = std::string(e.what());
453*b9715179SBen Tyner     trace<level::ERROR>(traceMsg.c_str());
454*b9715179SBen Tyner 
455*b9715179SBen Tyner     // Handle SBE chipop timeout error
456*b9715179SBen Tyner     if (e.errType() == openpower::phal::exception::SBE_CHIPOP_NOT_ALLOWED)
457*b9715179SBen Tyner     {
458*b9715179SBen Tyner         eventPhalSbeChipop(procNum);
459*b9715179SBen Tyner     }
460*b9715179SBen Tyner }
461*b9715179SBen Tyner #endif
462*b9715179SBen Tyner 
463*b9715179SBen Tyner /**
464*b9715179SBen Tyner  * @brief Get static TI info data based on host state
465*b9715179SBen Tyner  *
466*b9715179SBen Tyner  * @param[out] tiInfo - pointer to static TI info data
467*b9715179SBen Tyner  */
468*b9715179SBen Tyner void getStaticTiInfo(uint8_t*& tiInfo)
469*b9715179SBen Tyner {
470*b9715179SBen Tyner     util::dbus::HostRunningState runningState = util::dbus::hostRunningState();
471*b9715179SBen Tyner 
472*b9715179SBen Tyner     // assume host state is unknown
473*b9715179SBen Tyner     std::string stateString = "host state unknown";
474*b9715179SBen Tyner 
475*b9715179SBen Tyner     if ((util::dbus::HostRunningState::Started == runningState) ||
476*b9715179SBen Tyner         (util::dbus::HostRunningState::Unknown == runningState))
477*b9715179SBen Tyner     {
478*b9715179SBen Tyner         if (util::dbus::HostRunningState::Started == runningState)
479*b9715179SBen Tyner         {
480*b9715179SBen Tyner             stateString = "host started";
481*b9715179SBen Tyner         }
482*b9715179SBen Tyner         tiInfo = (uint8_t*)defaultPhypTiInfo;
483*b9715179SBen Tyner     }
484*b9715179SBen Tyner     else
485*b9715179SBen Tyner     {
486*b9715179SBen Tyner         stateString = "host not started";
487*b9715179SBen Tyner         tiInfo      = (uint8_t*)defaultHbTiInfo;
488*b9715179SBen Tyner     }
489*b9715179SBen Tyner 
490*b9715179SBen Tyner     // trace host state
491*b9715179SBen Tyner     trace<level::INFO>(stateString.c_str());
492*b9715179SBen Tyner }
493*b9715179SBen Tyner 
494*b9715179SBen Tyner /**
495*b9715179SBen Tyner  * @brief Check if TI info data is valid
496*b9715179SBen Tyner  *
497*b9715179SBen Tyner  * @param[in] tiInfo - pointer to TI info data
498*b9715179SBen Tyner  * @return true if TI info data is valid, else false
499*b9715179SBen Tyner  */
500*b9715179SBen Tyner bool tiInfoValid(uint8_t* tiInfo)
501*b9715179SBen Tyner {
502*b9715179SBen Tyner     bool tiInfoValid = false; // assume TI info invalid
503*b9715179SBen Tyner 
504*b9715179SBen Tyner     // TI info data[0] non-zero indicates TI info valid (usually)
505*b9715179SBen Tyner     if ((nullptr != tiInfo) && (0 != tiInfo[0]))
506*b9715179SBen Tyner     {
507*b9715179SBen Tyner         TiDataArea* tiDataArea = (TiDataArea*)tiInfo;
508*b9715179SBen Tyner 
509*b9715179SBen Tyner         std::stringstream ss; // string stream object for tracing
510*b9715179SBen Tyner         std::string strobj;   // string object for tracing
511*b9715179SBen Tyner 
512*b9715179SBen Tyner         // trace a few known TI data area values
513*b9715179SBen Tyner         ss.str(std::string()); // empty the stream
514*b9715179SBen Tyner         ss.clear();            // clear the stream
515*b9715179SBen Tyner         ss << "TI data command = 0x" << std::setw(2) << std::setfill('0')
516*b9715179SBen Tyner            << std::hex << (int)tiDataArea->command;
517*b9715179SBen Tyner         strobj = ss.str();
518*b9715179SBen Tyner         trace<level::INFO>(strobj.c_str());
519*b9715179SBen Tyner 
520*b9715179SBen Tyner         // Another check for valid TI Info since it has been seen that
521*b9715179SBen Tyner         // tiInfo[0] != 0 but TI info is not valid
522*b9715179SBen Tyner         if (0xa1 == tiDataArea->command)
523*b9715179SBen Tyner         {
524*b9715179SBen Tyner             tiInfoValid = true;
525*b9715179SBen Tyner 
526*b9715179SBen Tyner             // trace some more data since TI info appears valid
527*b9715179SBen Tyner             ss.str(std::string()); // empty the stream
528*b9715179SBen Tyner             ss.clear();            // clear the stream
529*b9715179SBen Tyner             ss << "TI data term-type = 0x" << std::setw(2) << std::setfill('0')
530*b9715179SBen Tyner                << std::hex << (int)tiDataArea->hbTerminateType;
531*b9715179SBen Tyner             strobj = ss.str();
532*b9715179SBen Tyner             trace<level::INFO>(strobj.c_str());
533*b9715179SBen Tyner 
534*b9715179SBen Tyner             ss.str(std::string()); // empty the stream
535*b9715179SBen Tyner             ss.clear();            // clear the stream
536*b9715179SBen Tyner             ss << "TI data SRC format = 0x" << std::setw(2) << std::setfill('0')
537*b9715179SBen Tyner                << std::hex << (int)tiDataArea->srcFormat;
538*b9715179SBen Tyner             strobj = ss.str();
539*b9715179SBen Tyner             trace<level::INFO>(strobj.c_str());
540*b9715179SBen Tyner 
541*b9715179SBen Tyner             ss.str(std::string()); // empty the stream
542*b9715179SBen Tyner             ss.clear();            // clear the stream
543*b9715179SBen Tyner             ss << "TI data source = 0x" << std::setw(2) << std::setfill('0')
544*b9715179SBen Tyner                << std::hex << (int)tiDataArea->source;
545*b9715179SBen Tyner             strobj = ss.str();
546*b9715179SBen Tyner             trace<level::INFO>(strobj.c_str());
547*b9715179SBen Tyner         }
548*b9715179SBen Tyner     }
549*b9715179SBen Tyner 
550*b9715179SBen Tyner     return tiInfoValid;
551*b9715179SBen Tyner }
552*b9715179SBen Tyner 
553ef320154SBen Tyner } // namespace attn
554