1d84ed6e9SZane Shelley #include <assert.h> 287eabc65SBen Tyner #include <libpdbg.h> 39fb7393eSZane Shelley #include <unistd.h> 487eabc65SBen Tyner 54ed4be56SZane Shelley #include <analyzer/service_data.hpp> 60205f3b3SBen Tyner #include <hei_main.hpp> 79fb7393eSZane Shelley #include <phosphor-logging/log.hpp> 8f4bd5ff6SZane Shelley #include <util/pdbg.hpp> 9d84ed6e9SZane Shelley #include <util/trace.hpp> 100205f3b3SBen Tyner 11d84ed6e9SZane Shelley #include <algorithm> 1287eabc65SBen Tyner #include <fstream> 1387eabc65SBen Tyner #include <iostream> 14b1ebfcb1SBen Tyner #include <map> 15b1ebfcb1SBen Tyner #include <string> 16b1ebfcb1SBen Tyner 170205f3b3SBen Tyner namespace analyzer 180205f3b3SBen Tyner { 190205f3b3SBen Tyner 20f4bd5ff6SZane Shelley //------------------------------------------------------------------------------ 21b1ebfcb1SBen Tyner 22f4bd5ff6SZane Shelley // Forward references for externally defined functions. 2387eabc65SBen Tyner 24d3b9bac9SZane Shelley /** 25d3b9bac9SZane Shelley * @brief Will get the list of active chip and initialize the isolator. 26d3b9bac9SZane Shelley * @param o_chips The returned list of active chips. 27d3b9bac9SZane Shelley */ 28171a2e04SZane Shelley void initializeIsolator(std::vector<libhei::Chip>& o_chips); 2987eabc65SBen Tyner 30d3b9bac9SZane Shelley /** 31*e5411f0fSZane Shelley * @brief Apply any RAS actions required by the given data. 32*e5411f0fSZane Shelley * @param i_servData Data regarding service actions gathered during analysis. 33*e5411f0fSZane Shelley */ 34*e5411f0fSZane Shelley void applyRasActions(ServiceData& io_servData); 35*e5411f0fSZane Shelley 36*e5411f0fSZane Shelley /** 37d3b9bac9SZane Shelley * @brief Will create and submit a PEL using the given data. 38d3b9bac9SZane Shelley * @param i_isoData The data gathered during isolation (for FFDC). 394ed4be56SZane Shelley * @param i_servData Data regarding service actions gathered during analysis. 40d3b9bac9SZane Shelley */ 418af9e46fSZane Shelley void createPel(const libhei::IsolationData& i_isoData, 424ed4be56SZane Shelley const ServiceData& i_servData); 43d3b9bac9SZane Shelley 44d84ed6e9SZane Shelley //------------------------------------------------------------------------------ 45d84ed6e9SZane Shelley 462f263181SZane Shelley const char* __attn(libhei::AttentionType_t i_attnType) 472f263181SZane Shelley { 482f263181SZane Shelley const char* str = ""; 492f263181SZane Shelley switch (i_attnType) 502f263181SZane Shelley { 512f263181SZane Shelley case libhei::ATTN_TYPE_CHECKSTOP: 522f263181SZane Shelley str = "CHECKSTOP"; 532f263181SZane Shelley break; 542f263181SZane Shelley case libhei::ATTN_TYPE_UNIT_CS: 552f263181SZane Shelley str = "UNIT_CS"; 562f263181SZane Shelley break; 572f263181SZane Shelley case libhei::ATTN_TYPE_RECOVERABLE: 582f263181SZane Shelley str = "RECOVERABLE"; 592f263181SZane Shelley break; 602f263181SZane Shelley case libhei::ATTN_TYPE_SP_ATTN: 612f263181SZane Shelley str = "SP_ATTN"; 622f263181SZane Shelley break; 632f263181SZane Shelley case libhei::ATTN_TYPE_HOST_ATTN: 642f263181SZane Shelley str = "HOST_ATTN"; 652f263181SZane Shelley break; 662f263181SZane Shelley default: 672f263181SZane Shelley trace::err("Unsupported attention type: %u", i_attnType); 682f263181SZane Shelley assert(0); 692f263181SZane Shelley } 702f263181SZane Shelley return str; 712f263181SZane Shelley } 722f263181SZane Shelley 732f263181SZane Shelley //------------------------------------------------------------------------------ 742f263181SZane Shelley 75cb457383SZane Shelley bool __filterRootCause(const libhei::IsolationData& i_isoData, 76cb457383SZane Shelley libhei::Signature& o_signature) 77097a71adSZane Shelley { 78cb457383SZane Shelley // We'll need to make a copy of the list so that the original list is 79cb457383SZane Shelley // maintained for the log. 80cb457383SZane Shelley std::vector<libhei::Signature> sigList{i_isoData.getSignatureList()}; 81cb457383SZane Shelley 822f263181SZane Shelley // For debug, trace out the original list of signatures before filtering. 83cb457383SZane Shelley for (const auto& sig : sigList) 842f263181SZane Shelley { 85f4bd5ff6SZane Shelley trace::inf("Signature: %s 0x%0" PRIx32 " %s", 86cb457383SZane Shelley util::pdbg::getPath(sig.getChip()), sig.toUint32(), 87f4bd5ff6SZane Shelley __attn(sig.getAttnType())); 882f263181SZane Shelley } 892f263181SZane Shelley 90097a71adSZane Shelley // Special and host attentions are not supported by this user application. 91097a71adSZane Shelley auto newEndItr = 92cb457383SZane Shelley std::remove_if(sigList.begin(), sigList.end(), [&](const auto& t) { 93097a71adSZane Shelley return (libhei::ATTN_TYPE_SP_ATTN == t.getAttnType() || 94097a71adSZane Shelley libhei::ATTN_TYPE_HOST_ATTN == t.getAttnType()); 95097a71adSZane Shelley }); 96097a71adSZane Shelley 97097a71adSZane Shelley // Shrink the vector, if needed. 98cb457383SZane Shelley sigList.resize(std::distance(sigList.begin(), newEndItr)); 99097a71adSZane Shelley 100097a71adSZane Shelley // START WORKAROUND 101097a71adSZane Shelley // TODO: Filtering should be determined by the RAS Data Files provided by 102097a71adSZane Shelley // the host firmware via the PNOR (similar to the Chip Data Files). 103097a71adSZane Shelley // Until that support is available, use a rudimentary filter that 104097a71adSZane Shelley // first looks for any recoverable attention, then any unit checkstop, 105097a71adSZane Shelley // and then any system checkstop. This is built on the premise that 106097a71adSZane Shelley // recoverable errors could be the root cause of an system checkstop 107097a71adSZane Shelley // attentions. Fortunately, we just need to sort the list by the 108097a71adSZane Shelley // greater attention type value. 109cb457383SZane Shelley std::sort(sigList.begin(), sigList.end(), 110097a71adSZane Shelley [&](const auto& a, const auto& b) { 111097a71adSZane Shelley return a.getAttnType() > b.getAttnType(); 112097a71adSZane Shelley }); 113097a71adSZane Shelley // END WORKAROUND 114cb457383SZane Shelley 115cb457383SZane Shelley // Check if a root cause attention was found. 116cb457383SZane Shelley if (!sigList.empty()) 117cb457383SZane Shelley { 118cb457383SZane Shelley // The entry at the front of the list will be the root cause. 119cb457383SZane Shelley o_signature = sigList.front(); 120cb457383SZane Shelley return true; 121cb457383SZane Shelley } 122cb457383SZane Shelley 123cb457383SZane Shelley return false; // default, no active attentions found. 124097a71adSZane Shelley } 125097a71adSZane Shelley 126097a71adSZane Shelley //------------------------------------------------------------------------------ 127097a71adSZane Shelley 1289fb7393eSZane Shelley bool analyzeHardware() 12987eabc65SBen Tyner { 130097a71adSZane Shelley bool attnFound = false; 13187eabc65SBen Tyner 132*e5411f0fSZane Shelley if (!util::pdbg::queryHardwareAnalysisSupported()) 133*e5411f0fSZane Shelley { 134*e5411f0fSZane Shelley trace::err("Hardware error analysis is not supported on this system"); 135*e5411f0fSZane Shelley return attnFound; 136*e5411f0fSZane Shelley } 137*e5411f0fSZane Shelley 1382f263181SZane Shelley trace::inf(">>> enter analyzeHardware()"); 1392f263181SZane Shelley 140171a2e04SZane Shelley // Initialize the isolator and get all of the chips to be analyzed. 141f4bd5ff6SZane Shelley trace::inf("Initializing the isolator..."); 142171a2e04SZane Shelley std::vector<libhei::Chip> chips; 143f4bd5ff6SZane Shelley initializeIsolator(chips); 1442e994bcdSZane Shelley 145097a71adSZane Shelley // Isolate attentions. 146f4bd5ff6SZane Shelley trace::inf("Isolating errors: # of chips=%u", chips.size()); 147097a71adSZane Shelley libhei::IsolationData isoData{}; 148f4bd5ff6SZane Shelley libhei::isolate(chips, isoData); 14987eabc65SBen Tyner 150*e5411f0fSZane Shelley // Filter for root cause attention. 151*e5411f0fSZane Shelley libhei::Signature rootCause{}; 152*e5411f0fSZane Shelley attnFound = __filterRootCause(isoData, rootCause); 153*e5411f0fSZane Shelley 154*e5411f0fSZane Shelley if (!attnFound) 155*e5411f0fSZane Shelley { 156*e5411f0fSZane Shelley // It is possible for TI handling, or manually initiated analysis via 157*e5411f0fSZane Shelley // the command line, that there will not be an active attention. In 158*e5411f0fSZane Shelley // which case, we will do nothing and let the caller of this function 159*e5411f0fSZane Shelley // determine if this is the expected behavior. 160*e5411f0fSZane Shelley trace::inf("No active attentions found"); 161*e5411f0fSZane Shelley } 162*e5411f0fSZane Shelley else 163*e5411f0fSZane Shelley { 164*e5411f0fSZane Shelley trace::inf("Root cause attention: %s 0x%0" PRIx32 " %s", 165*e5411f0fSZane Shelley util::pdbg::getPath(rootCause.getChip()), 166*e5411f0fSZane Shelley rootCause.toUint32(), __attn(rootCause.getAttnType())); 167*e5411f0fSZane Shelley 168*e5411f0fSZane Shelley // Perform service actions based on the root cause. 169*e5411f0fSZane Shelley ServiceData servData{rootCause}; 170*e5411f0fSZane Shelley applyRasActions(servData); 171*e5411f0fSZane Shelley 172*e5411f0fSZane Shelley // Create and commit a PEL. 173*e5411f0fSZane Shelley createPel(isoData, servData); 174*e5411f0fSZane Shelley } 17587eabc65SBen Tyner 176097a71adSZane Shelley // All done, clean up the isolator. 177f4bd5ff6SZane Shelley trace::inf("Uninitializing isolator..."); 178097a71adSZane Shelley libhei::uninitialize(); 179b1ebfcb1SBen Tyner 1802f263181SZane Shelley trace::inf("<<< exit analyzeHardware()"); 1812f263181SZane Shelley 182097a71adSZane Shelley return attnFound; 1830205f3b3SBen Tyner } 1840205f3b3SBen Tyner 185eea45427SBen Tyner //------------------------------------------------------------------------------ 186eea45427SBen Tyner 187eea45427SBen Tyner /** 188eea45427SBen Tyner * @brief Get error isolator build information 189eea45427SBen Tyner * 190eea45427SBen Tyner * @return Pointer to build information 191eea45427SBen Tyner */ 192eea45427SBen Tyner const char* getBuildInfo() 193eea45427SBen Tyner { 194eea45427SBen Tyner return libhei::getBuildInfo(); 195eea45427SBen Tyner } 196eea45427SBen Tyner 1970205f3b3SBen Tyner } // namespace analyzer 198