1 #include <attn/attention.hpp> 2 #include <attn/attn_common.hpp> 3 #include <attn/attn_dump.hpp> 4 #include <attn/attn_handler.hpp> 5 #include <attn/attn_logging.hpp> 6 #include <sdbusplus/bus.hpp> 7 #include <util/dbus.hpp> 8 #include <util/pdbg.hpp> 9 #include <util/pldm.hpp> 10 #include <util/trace.hpp> 11 12 namespace attn 13 { 14 /* 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 */ 21 bool 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 * */ 86 bool 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; 103 r = fsi_read(fsiTarget, 0x1007, &isr_val); 104 if ((RC_SUCCESS != r) || (0xffffffff == isr_val)) 105 { 106 trace::err("cfam 1007 read error"); 107 return false; 108 } 109 110 isr_mask = 0xffffffff; 111 r = fsi_read(fsiTarget, 0x100d, &isr_mask); 112 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 } 120 121 /** 122 * @brief Handle SBE vital attention 123 * 124 * @param i_attention - attention object 125 * 126 * @return non-zero if attention was not successfully handled 127 */ 128 int handleVital(Attention* i_attention) 129 { 130 trace::inf("vital handler started"); 131 132 // if vital handling disabled 133 if (false == (i_attention->getConfig()->getFlag(enVital))) 134 { 135 trace::inf("vital handling disabled"); 136 return RC_NOT_HANDLED; 137 } 138 139 // if power fault then we don't do anything 140 sleepSeconds(POWER_FAULT_WAIT); 141 if (util::dbus::powerFault()) 142 { 143 trace::inf("power fault was reported"); 144 return RC_SUCCESS; 145 } 146 147 // 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; 168 } 169 170 } // namespace attn 171