Shantappa Teekappanavar | 41d507e | 2021-10-05 12:17:55 -0500 | [diff] [blame] | 1 | #include <fmt/format.h> |
| 2 | extern "C" |
| 3 | { |
| 4 | #include <libpdbg.h> |
| 5 | #include <libpdbg_sbe.h> |
| 6 | } |
| 7 | |
| 8 | #include <libphal.H> |
| 9 | |
| 10 | #include <phosphor-logging/log.hpp> |
Shantappa Teekappanavar | 1ac6162 | 2021-06-22 19:07:29 -0500 | [diff] [blame] | 11 | #include <watchdog_common.hpp> |
Shantappa Teekappanavar | 41d507e | 2021-10-05 12:17:55 -0500 | [diff] [blame] | 12 | #include <watchdog_dbus.hpp> |
| 13 | #include <watchdog_handler.hpp> |
Shantappa Teekappanavar | 1ac6162 | 2021-06-22 19:07:29 -0500 | [diff] [blame] | 14 | #include <watchdog_logging.hpp> |
| 15 | |
| 16 | namespace watchdog |
| 17 | { |
| 18 | namespace dump |
| 19 | { |
| 20 | |
Shantappa Teekappanavar | 41d507e | 2021-10-05 12:17:55 -0500 | [diff] [blame] | 21 | using namespace phosphor::logging; |
| 22 | |
Shantappa Teekappanavar | 1ac6162 | 2021-06-22 19:07:29 -0500 | [diff] [blame] | 23 | void triggerHostbootDump(const uint32_t timeout) |
| 24 | { |
| 25 | constexpr auto HOST_STATE_DIAGNOSTIC_MODE = |
| 26 | "obmc-host-diagnostic-mode@0.target"; |
| 27 | constexpr auto HOST_STATE_QUIESCE_TGT = "obmc-host-quiesce@0.target"; |
| 28 | |
| 29 | // Put system into diagnostic mode |
| 30 | transitionHost(HOST_STATE_DIAGNOSTIC_MODE); |
| 31 | |
Shantappa Teekappanavar | a1ea5e5 | 2021-08-24 16:30:30 -0500 | [diff] [blame] | 32 | eventWatchdogTimeout(timeout); |
Shantappa Teekappanavar | 1ac6162 | 2021-06-22 19:07:29 -0500 | [diff] [blame] | 33 | |
| 34 | // Put system into quiesce state |
| 35 | transitionHost(HOST_STATE_QUIESCE_TGT); |
| 36 | } |
| 37 | |
Shantappa Teekappanavar | 41d507e | 2021-10-05 12:17:55 -0500 | [diff] [blame] | 38 | void handleSbeBootError(struct pdbg_target* procTarget, const uint32_t timeout) |
| 39 | { |
| 40 | using namespace openpower::phal; |
| 41 | |
| 42 | sbeError_t sbeError; |
| 43 | bool dumpIsRequired = false; |
| 44 | |
| 45 | try |
| 46 | { |
| 47 | // Capture FFDC information on primary processor |
| 48 | sbeError = sbe::captureFFDC(procTarget); |
| 49 | } |
| 50 | catch (const std::exception& e) |
| 51 | { |
| 52 | // Failed to collect FFDC information |
| 53 | log<level::ERR>( |
| 54 | fmt::format("captureFFDC: Exception{}", e.what()).c_str()); |
| 55 | dumpIsRequired = true; |
| 56 | } |
| 57 | |
| 58 | // event type |
| 59 | std::string event; |
| 60 | if ((sbeError.errType() == exception::SBE_FFDC_NO_DATA) || |
| 61 | (sbeError.errType() == exception::SBE_CMD_TIMEOUT) || (dumpIsRequired)) |
| 62 | { |
| 63 | log<level::INFO>("No FFDC data"); |
| 64 | event = "org.open_power.Processor.Error.SbeBootTimeout"; |
| 65 | dumpIsRequired = true; |
| 66 | } |
| 67 | else |
| 68 | { |
| 69 | log<level::ERR>("SBE Boot failure"); |
| 70 | event = "org.open_power.Processor.Error.SbeBootFailure"; |
| 71 | } |
| 72 | |
| 73 | // Additional data |
| 74 | std::map<std::string, std::string> additionalData; |
| 75 | |
| 76 | // SRC6 : [0:15] chip position |
| 77 | uint32_t index = pdbg_target_index(procTarget); |
| 78 | additionalData.emplace("SRC6", std::to_string(index << 16)); |
| 79 | additionalData.emplace("SBE_ERR_MSG", sbeError.what()); |
| 80 | |
| 81 | // FFDC |
| 82 | auto ffdc = std::vector<FFDCTuple>{}; |
| 83 | // get SBE ffdc file descriptor |
| 84 | auto fd = sbeError.getFd(); |
| 85 | |
| 86 | // Log error with additional ffdc if fd is valid |
| 87 | if (fd > 0) |
| 88 | { |
| 89 | ffdc.push_back( |
| 90 | std::make_tuple(sdbusplus::xyz::openbmc_project::Logging::server:: |
| 91 | Create::FFDCFormat::Custom, |
| 92 | static_cast<uint8_t>(0xCB), |
| 93 | static_cast<uint8_t>(0x01), sbeError.getFd())); |
| 94 | } |
| 95 | |
| 96 | auto pelId = createPel(event, additionalData, ffdc); |
| 97 | |
| 98 | if (dumpIsRequired) |
| 99 | { |
| 100 | try |
| 101 | { |
| 102 | using namespace openpower::phal; |
| 103 | |
| 104 | // Check SBE dump collection allowed |
| 105 | bool dumpAllowed = sbe::isDumpAllowed(procTarget); |
| 106 | if (!dumpAllowed) |
| 107 | { |
| 108 | // Possibly another collection in progress, skip dump collection |
| 109 | log<level::INFO>("Another collection is in progress, skipping " |
| 110 | "dump collection"); |
| 111 | return; |
| 112 | } |
| 113 | } |
| 114 | catch (const std::exception& e) |
| 115 | { |
| 116 | log<level::ERR>( |
| 117 | fmt::format("Exception {} occurred", e.what()).c_str()); |
| 118 | return; |
| 119 | } |
| 120 | |
| 121 | DumpParameters dumpParameters; |
| 122 | dumpParameters.logId = pelId; |
| 123 | dumpParameters.unitId = index; |
| 124 | dumpParameters.timeout = timeout; |
| 125 | dumpParameters.dumpType = DumpType::SBE; |
| 126 | |
| 127 | // will not return until dump is complete or timeout |
| 128 | requestDump(dumpParameters); |
| 129 | } |
| 130 | } |
| 131 | |
Shantappa Teekappanavar | 1ac6162 | 2021-06-22 19:07:29 -0500 | [diff] [blame] | 132 | } // namespace dump |
| 133 | } // namespace watchdog |