1d84ed6e9SZane Shelley #include <assert.h> 287eabc65SBen Tyner #include <libpdbg.h> 39fb7393eSZane Shelley #include <unistd.h> 487eabc65SBen Tyner 5a9b44344SZane Shelley #include <analyzer/ras-data/ras-data-parser.hpp> 64ed4be56SZane Shelley #include <analyzer/service_data.hpp> 7*7029e525SBen Tyner #include <attn/attn_dump.hpp> 80205f3b3SBen Tyner #include <hei_main.hpp> 99fb7393eSZane Shelley #include <phosphor-logging/log.hpp> 10f4bd5ff6SZane Shelley #include <util/pdbg.hpp> 11d84ed6e9SZane Shelley #include <util/trace.hpp> 120205f3b3SBen Tyner 13d84ed6e9SZane Shelley #include <algorithm> 1487eabc65SBen Tyner #include <fstream> 1587eabc65SBen Tyner #include <iostream> 16b1ebfcb1SBen Tyner #include <map> 17b1ebfcb1SBen Tyner #include <string> 18b1ebfcb1SBen Tyner 190205f3b3SBen Tyner namespace analyzer 200205f3b3SBen Tyner { 210205f3b3SBen Tyner 22f4bd5ff6SZane Shelley //------------------------------------------------------------------------------ 23b1ebfcb1SBen Tyner 24f4bd5ff6SZane Shelley // Forward references for externally defined functions. 2587eabc65SBen Tyner 26d3b9bac9SZane Shelley /** 27d3b9bac9SZane Shelley * @brief Will get the list of active chip and initialize the isolator. 28d3b9bac9SZane Shelley * @param o_chips The returned list of active chips. 29d3b9bac9SZane Shelley */ 30171a2e04SZane Shelley void initializeIsolator(std::vector<libhei::Chip>& o_chips); 3187eabc65SBen Tyner 32d3b9bac9SZane Shelley /** 33d3b9bac9SZane Shelley * @brief Will create and submit a PEL using the given data. 34d3b9bac9SZane Shelley * @param i_isoData The data gathered during isolation (for FFDC). 354ed4be56SZane Shelley * @param i_servData Data regarding service actions gathered during analysis. 36*7029e525SBen Tyner * @return Tuple of BMC log id, platform log id 37d3b9bac9SZane Shelley */ 38*7029e525SBen Tyner std::tuple<uint32_t, uint32_t> createPel(const libhei::IsolationData& i_isoData, 394ed4be56SZane Shelley const ServiceData& i_servData); 40d3b9bac9SZane Shelley 41d84ed6e9SZane Shelley //------------------------------------------------------------------------------ 42d84ed6e9SZane Shelley 432f263181SZane Shelley const char* __attn(libhei::AttentionType_t i_attnType) 442f263181SZane Shelley { 452f263181SZane Shelley const char* str = ""; 462f263181SZane Shelley switch (i_attnType) 472f263181SZane Shelley { 482f263181SZane Shelley case libhei::ATTN_TYPE_CHECKSTOP: 492f263181SZane Shelley str = "CHECKSTOP"; 502f263181SZane Shelley break; 512f263181SZane Shelley case libhei::ATTN_TYPE_UNIT_CS: 522f263181SZane Shelley str = "UNIT_CS"; 532f263181SZane Shelley break; 542f263181SZane Shelley case libhei::ATTN_TYPE_RECOVERABLE: 552f263181SZane Shelley str = "RECOVERABLE"; 562f263181SZane Shelley break; 572f263181SZane Shelley case libhei::ATTN_TYPE_SP_ATTN: 582f263181SZane Shelley str = "SP_ATTN"; 592f263181SZane Shelley break; 602f263181SZane Shelley case libhei::ATTN_TYPE_HOST_ATTN: 612f263181SZane Shelley str = "HOST_ATTN"; 622f263181SZane Shelley break; 632f263181SZane Shelley default: 642f263181SZane Shelley trace::err("Unsupported attention type: %u", i_attnType); 652f263181SZane Shelley assert(0); 662f263181SZane Shelley } 672f263181SZane Shelley return str; 682f263181SZane Shelley } 692f263181SZane Shelley 702f263181SZane Shelley //------------------------------------------------------------------------------ 712f263181SZane Shelley 72cb457383SZane Shelley bool __filterRootCause(const libhei::IsolationData& i_isoData, 73cb457383SZane Shelley libhei::Signature& o_signature) 74097a71adSZane Shelley { 75cb457383SZane Shelley // We'll need to make a copy of the list so that the original list is 76cb457383SZane Shelley // maintained for the log. 77cb457383SZane Shelley std::vector<libhei::Signature> sigList{i_isoData.getSignatureList()}; 78cb457383SZane Shelley 792f263181SZane Shelley // For debug, trace out the original list of signatures before filtering. 80cb457383SZane Shelley for (const auto& sig : sigList) 812f263181SZane Shelley { 82f4bd5ff6SZane Shelley trace::inf("Signature: %s 0x%0" PRIx32 " %s", 83cb457383SZane Shelley util::pdbg::getPath(sig.getChip()), sig.toUint32(), 84f4bd5ff6SZane Shelley __attn(sig.getAttnType())); 852f263181SZane Shelley } 862f263181SZane Shelley 87097a71adSZane Shelley // Special and host attentions are not supported by this user application. 88097a71adSZane Shelley auto newEndItr = 89cb457383SZane Shelley std::remove_if(sigList.begin(), sigList.end(), [&](const auto& t) { 90097a71adSZane Shelley return (libhei::ATTN_TYPE_SP_ATTN == t.getAttnType() || 91097a71adSZane Shelley libhei::ATTN_TYPE_HOST_ATTN == t.getAttnType()); 92097a71adSZane Shelley }); 93097a71adSZane Shelley 94097a71adSZane Shelley // Shrink the vector, if needed. 95cb457383SZane Shelley sigList.resize(std::distance(sigList.begin(), newEndItr)); 96097a71adSZane Shelley 97097a71adSZane Shelley // START WORKAROUND 98097a71adSZane Shelley // TODO: Filtering should be determined by the RAS Data Files provided by 99097a71adSZane Shelley // the host firmware via the PNOR (similar to the Chip Data Files). 100097a71adSZane Shelley // Until that support is available, use a rudimentary filter that 101097a71adSZane Shelley // first looks for any recoverable attention, then any unit checkstop, 102097a71adSZane Shelley // and then any system checkstop. This is built on the premise that 103097a71adSZane Shelley // recoverable errors could be the root cause of an system checkstop 104097a71adSZane Shelley // attentions. Fortunately, we just need to sort the list by the 105097a71adSZane Shelley // greater attention type value. 106cb457383SZane Shelley std::sort(sigList.begin(), sigList.end(), 107097a71adSZane Shelley [&](const auto& a, const auto& b) { 108097a71adSZane Shelley return a.getAttnType() > b.getAttnType(); 109097a71adSZane Shelley }); 110097a71adSZane Shelley // END WORKAROUND 111cb457383SZane Shelley 112cb457383SZane Shelley // Check if a root cause attention was found. 113cb457383SZane Shelley if (!sigList.empty()) 114cb457383SZane Shelley { 115cb457383SZane Shelley // The entry at the front of the list will be the root cause. 116cb457383SZane Shelley o_signature = sigList.front(); 117cb457383SZane Shelley return true; 118cb457383SZane Shelley } 119cb457383SZane Shelley 120cb457383SZane Shelley return false; // default, no active attentions found. 121097a71adSZane Shelley } 122097a71adSZane Shelley 123097a71adSZane Shelley //------------------------------------------------------------------------------ 124097a71adSZane Shelley 125*7029e525SBen Tyner bool analyzeHardware(attn::DumpParameters& o_dumpParameters) 12687eabc65SBen Tyner { 127097a71adSZane Shelley bool attnFound = false; 12887eabc65SBen Tyner 129e5411f0fSZane Shelley if (!util::pdbg::queryHardwareAnalysisSupported()) 130e5411f0fSZane Shelley { 131e5411f0fSZane Shelley trace::err("Hardware error analysis is not supported on this system"); 132e5411f0fSZane Shelley return attnFound; 133e5411f0fSZane Shelley } 134e5411f0fSZane Shelley 1352f263181SZane Shelley trace::inf(">>> enter analyzeHardware()"); 1362f263181SZane Shelley 137171a2e04SZane Shelley // Initialize the isolator and get all of the chips to be analyzed. 138f4bd5ff6SZane Shelley trace::inf("Initializing the isolator..."); 139171a2e04SZane Shelley std::vector<libhei::Chip> chips; 140f4bd5ff6SZane Shelley initializeIsolator(chips); 1412e994bcdSZane Shelley 142097a71adSZane Shelley // Isolate attentions. 143f4bd5ff6SZane Shelley trace::inf("Isolating errors: # of chips=%u", chips.size()); 144097a71adSZane Shelley libhei::IsolationData isoData{}; 145f4bd5ff6SZane Shelley libhei::isolate(chips, isoData); 14687eabc65SBen Tyner 147e5411f0fSZane Shelley // Filter for root cause attention. 148e5411f0fSZane Shelley libhei::Signature rootCause{}; 149e5411f0fSZane Shelley attnFound = __filterRootCause(isoData, rootCause); 150e5411f0fSZane Shelley 151e5411f0fSZane Shelley if (!attnFound) 152e5411f0fSZane Shelley { 153e5411f0fSZane Shelley // It is possible for TI handling, or manually initiated analysis via 154e5411f0fSZane Shelley // the command line, that there will not be an active attention. In 155e5411f0fSZane Shelley // which case, we will do nothing and let the caller of this function 156e5411f0fSZane Shelley // determine if this is the expected behavior. 157e5411f0fSZane Shelley trace::inf("No active attentions found"); 158e5411f0fSZane Shelley } 159e5411f0fSZane Shelley else 160e5411f0fSZane Shelley { 161e5411f0fSZane Shelley trace::inf("Root cause attention: %s 0x%0" PRIx32 " %s", 162e5411f0fSZane Shelley util::pdbg::getPath(rootCause.getChip()), 163e5411f0fSZane Shelley rootCause.toUint32(), __attn(rootCause.getAttnType())); 164e5411f0fSZane Shelley 165e5411f0fSZane Shelley // Perform service actions based on the root cause. 166a9b44344SZane Shelley RasDataParser rasData{}; 167ca496198SZane Shelley ServiceData servData{rootCause, isoData.queryCheckstop()}; 168a9b44344SZane Shelley rasData.getResolution(rootCause)->resolve(servData); 169e5411f0fSZane Shelley 170e5411f0fSZane Shelley // Create and commit a PEL. 171*7029e525SBen Tyner uint32_t logId = std::get<1>(createPel(isoData, servData)); 172*7029e525SBen Tyner 173*7029e525SBen Tyner // Populate dump parameters 174*7029e525SBen Tyner o_dumpParameters.logId = logId; 175*7029e525SBen Tyner o_dumpParameters.unitId = 0; 176*7029e525SBen Tyner o_dumpParameters.dumpType = attn::DumpType::Hardware; 177e5411f0fSZane Shelley } 17887eabc65SBen Tyner 179097a71adSZane Shelley // All done, clean up the isolator. 180f4bd5ff6SZane Shelley trace::inf("Uninitializing isolator..."); 181097a71adSZane Shelley libhei::uninitialize(); 182b1ebfcb1SBen Tyner 1832f263181SZane Shelley trace::inf("<<< exit analyzeHardware()"); 1842f263181SZane Shelley 185097a71adSZane Shelley return attnFound; 1860205f3b3SBen Tyner } 1870205f3b3SBen Tyner 188eea45427SBen Tyner //------------------------------------------------------------------------------ 189eea45427SBen Tyner 190eea45427SBen Tyner /** 191eea45427SBen Tyner * @brief Get error isolator build information 192eea45427SBen Tyner * 193eea45427SBen Tyner * @return Pointer to build information 194eea45427SBen Tyner */ 195eea45427SBen Tyner const char* getBuildInfo() 196eea45427SBen Tyner { 197eea45427SBen Tyner return libhei::getBuildInfo(); 198eea45427SBen Tyner } 199eea45427SBen Tyner 2000205f3b3SBen Tyner } // namespace analyzer 201