blob: 196f74869f2ec13d15cc98f450d2b33ed86cffa5 [file] [log] [blame]
Ben Tynerbcf65a82020-12-01 08:46:36 -06001#include <attn/attention.hpp>
2#include <attn/attn_common.hpp>
Ben Tyner7f6ce6a2021-08-17 19:40:00 -05003#include <attn/attn_dump.hpp>
Ben Tyner90516852022-12-14 21:04:18 -06004#include <attn/attn_handler.hpp>
Ben Tynerbcf65a82020-12-01 08:46:36 -06005#include <attn/attn_logging.hpp>
6#include <sdbusplus/bus.hpp>
Ben Tyner93067162021-07-23 10:39:30 -05007#include <util/dbus.hpp>
Ben Tyner90516852022-12-14 21:04:18 -06008#include <util/pdbg.hpp>
9#include <util/pldm.hpp>
austinfcuibfa831a2022-01-26 15:37:07 -060010#include <util/trace.hpp>
Ben Tynerbcf65a82020-12-01 08:46:36 -060011
12namespace attn
13{
Ben Tyner90516852022-12-14 21:04:18 -060014/*
15 * @brief Request SBE hreset and try to clear sbe attentions
16 *
17 * @param[in] sbeInstance - sbe instance to hreset (0 based)
18 *
19 * @return true if hreset is successful and attentions cleared
20 */
21bool attemptSbeRecovery(int sbeInstance)
22{
23 // attempt sbe hreset and attention interrupt clear
24 if (!util::pldm::hresetSbe(sbeInstance))
25 {
26 return false;
27 }
28
29 trace::inf("hreset completed");
30
31 // try to clear attention interrupts
32 clearAttnInterrupts();
33
34 // loop through processors checking attention interrupts
35 bool recovered = true;
36 pdbg_target* procTarget;
37 pdbg_for_each_class_target("proc", procTarget)
38 {
39 // active processors only
40 if (PDBG_TARGET_ENABLED !=
41 pdbg_target_probe(util::pdbg::getPibTrgt(procTarget)))
42 {
43 continue;
44 }
45
46 // get cfam is an fsi read
47 pdbg_target* fsiTarget = util::pdbg::getFsiTrgt(procTarget);
48 uint32_t int_val;
49
50 // get attention interrupts on processor
51 if (RC_SUCCESS == fsi_read(fsiTarget, 0x100b, &int_val))
52 {
53 if (int_val & SBE_ATTN)
54 {
55 trace::err("sbe attention did not clear");
56 recovered = false;
57 break;
58 }
59 }
60 else
61 {
62 // log cfam read error
63 trace::err("cfam read error");
64 recovered = false;
65 break;
66 }
67 }
68
69 if (recovered)
70 {
71 trace::inf("sbe attention cleared");
72 }
73
74 return recovered;
75}
76
77/**
78 * @brief Check for active checkstop attention
79 *
80 * @param procInstance - proc to check for attentions
81 *
82 * @pre pdbg target associated with proc instance is enabled for fsi access
83 *
84 * @return true if checkstop acive false otherwise
85 * */
86bool checkstopActive(int procInstance)
87{
88 // get fsi target
89 char path[16];
90 sprintf(path, "/proc%d/fsi", procInstance);
91 pdbg_target* fsiTarget = pdbg_target_from_path(nullptr, path);
92 if (nullptr == fsiTarget)
93 {
94 trace::inf("fsi path or target not found");
95 return false;
96 }
97
98 // check for active checkstop attention
99 int r;
100 uint32_t isr_val, isr_mask;
101
102 isr_val = 0xffffffff;
Patrick Williams27dd6362023-05-10 07:51:20 -0500103 r = fsi_read(fsiTarget, 0x1007, &isr_val);
Ben Tyner90516852022-12-14 21:04:18 -0600104 if ((RC_SUCCESS != r) || (0xffffffff == isr_val))
105 {
106 trace::err("cfam 1007 read error");
107 return false;
108 }
109
110 isr_mask = 0xffffffff;
Patrick Williams27dd6362023-05-10 07:51:20 -0500111 r = fsi_read(fsiTarget, 0x100d, &isr_mask);
Ben Tyner90516852022-12-14 21:04:18 -0600112 if ((RC_SUCCESS != r) || (0xffffffff == isr_mask))
113 {
114 trace::err("cfam 100d read error");
115 return false;
116 }
117
118 return activeAttn(isr_val, isr_mask, CHECKSTOP_ATTN);
119}
Ben Tynerbcf65a82020-12-01 08:46:36 -0600120
121/**
122 * @brief Handle SBE vital attention
123 *
Ben Tyner90516852022-12-14 21:04:18 -0600124 * @param i_attention - attention object
125 *
126 * @return non-zero if attention was not successfully handled
Ben Tynerbcf65a82020-12-01 08:46:36 -0600127 */
128int handleVital(Attention* i_attention)
129{
austinfcuibfa831a2022-01-26 15:37:07 -0600130 trace::inf("vital handler started");
Ben Tynerbcf65a82020-12-01 08:46:36 -0600131
Ben Tyner90516852022-12-14 21:04:18 -0600132 // if vital handling disabled
Ben Tynerbcf65a82020-12-01 08:46:36 -0600133 if (false == (i_attention->getConfig()->getFlag(enVital)))
134 {
austinfcuibfa831a2022-01-26 15:37:07 -0600135 trace::inf("vital handling disabled");
Ben Tyner90516852022-12-14 21:04:18 -0600136 return RC_NOT_HANDLED;
Ben Tynerbcf65a82020-12-01 08:46:36 -0600137 }
Ben Tyner90516852022-12-14 21:04:18 -0600138
139 // if power fault then we don't do anything
140 sleepSeconds(POWER_FAULT_WAIT);
141 if (util::dbus::powerFault())
Ben Tynerbcf65a82020-12-01 08:46:36 -0600142 {
Ben Tyner90516852022-12-14 21:04:18 -0600143 trace::inf("power fault was reported");
144 return RC_SUCCESS;
Ben Tynerbcf65a82020-12-01 08:46:36 -0600145 }
146
Ben Tyner90516852022-12-14 21:04:18 -0600147 // if no checkstop and host is running
148 int instance =
149 pdbg_target_index(i_attention->getTarget()); // get processor number
150
151 if (!checkstopActive(instance) &&
152 util::dbus::HostRunningState::Started == util::dbus::hostRunningState())
153 {
154 // attempt to recover the sbe
155 if (attemptSbeRecovery(instance))
156 {
157 eventVital(levelPelInfo);
158 return RC_SUCCESS;
159 }
160 }
161
162 // host not running, checkstop active or recovery failed
163 auto pelId = eventVital(levelPelError);
164 requestDump(pelId, DumpParameters{0, DumpType::SBE});
165 util::dbus::transitionHost(util::dbus::HostState::Quiesce);
166
167 return RC_SUCCESS;
Ben Tynerbcf65a82020-12-01 08:46:36 -0600168}
169
170} // namespace attn