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 | b64983f | 2022-02-01 09:28:10 -0600 | [diff] [blame] | 38 | /** |
| 39 | * @brief get SBE special callout information |
| 40 | * |
| 41 | * @details This function adds the special sbe callout in the user provided |
| 42 | * json callout list. includes BMC0002 procedure callout with high priority |
| 43 | * and processor callout with medium priority. |
| 44 | * |
| 45 | * @param[in] procTarget - pdbg processor target |
| 46 | * @param[out] jsonCalloutDataList - reference to json callout list |
| 47 | */ |
| 48 | static void getSBECallout(struct pdbg_target* procTarget, |
| 49 | json& jsonCalloutDataList) |
| 50 | { |
| 51 | using namespace openpower::phal::pdbg; |
| 52 | json jsonProcedCallout; |
| 53 | |
| 54 | // Add procedure callout |
| 55 | jsonProcedCallout["Procedure"] = "BMC0002"; |
| 56 | jsonProcedCallout["Priority"] = "H"; |
| 57 | jsonCalloutDataList.emplace_back(jsonProcedCallout); |
| 58 | try |
| 59 | { |
| 60 | ATTR_LOCATION_CODE_Type locationCode; |
| 61 | // Initialize with default data. |
| 62 | memset(&locationCode, '\0', sizeof(locationCode)); |
| 63 | // Get location code information |
| 64 | openpower::phal::pdbg::getLocationCode(procTarget, locationCode); |
| 65 | json jsonProcCallout; |
| 66 | jsonProcCallout["LocationCode"] = locationCode; |
| 67 | jsonProcCallout["Deconfigured"] = false; |
| 68 | jsonProcCallout["Guarded"] = false; |
| 69 | jsonProcCallout["Priority"] = "M"; |
| 70 | jsonCalloutDataList.emplace_back(jsonProcCallout); |
| 71 | } |
| 72 | catch (const std::exception& e) |
| 73 | { |
| 74 | log<level::ERR>(fmt::format("getLocationCode({}): Exception({})", |
| 75 | pdbg_target_path(procTarget), e.what()) |
| 76 | .c_str()); |
| 77 | } |
| 78 | } |
| 79 | |
Shantappa Teekappanavar | 41d507e | 2021-10-05 12:17:55 -0500 | [diff] [blame] | 80 | void handleSbeBootError(struct pdbg_target* procTarget, const uint32_t timeout) |
| 81 | { |
| 82 | using namespace openpower::phal; |
| 83 | |
| 84 | sbeError_t sbeError; |
| 85 | bool dumpIsRequired = false; |
| 86 | |
| 87 | try |
| 88 | { |
| 89 | // Capture FFDC information on primary processor |
| 90 | sbeError = sbe::captureFFDC(procTarget); |
| 91 | } |
| 92 | catch (const std::exception& e) |
| 93 | { |
| 94 | // Failed to collect FFDC information |
| 95 | log<level::ERR>( |
| 96 | fmt::format("captureFFDC: Exception{}", e.what()).c_str()); |
| 97 | dumpIsRequired = true; |
| 98 | } |
| 99 | |
| 100 | // event type |
| 101 | std::string event; |
| 102 | if ((sbeError.errType() == exception::SBE_FFDC_NO_DATA) || |
| 103 | (sbeError.errType() == exception::SBE_CMD_TIMEOUT) || (dumpIsRequired)) |
| 104 | { |
| 105 | log<level::INFO>("No FFDC data"); |
| 106 | event = "org.open_power.Processor.Error.SbeBootTimeout"; |
| 107 | dumpIsRequired = true; |
| 108 | } |
| 109 | else |
| 110 | { |
| 111 | log<level::ERR>("SBE Boot failure"); |
| 112 | event = "org.open_power.Processor.Error.SbeBootFailure"; |
| 113 | } |
| 114 | |
| 115 | // Additional data |
| 116 | std::map<std::string, std::string> additionalData; |
| 117 | |
| 118 | // SRC6 : [0:15] chip position |
| 119 | uint32_t index = pdbg_target_index(procTarget); |
| 120 | additionalData.emplace("SRC6", std::to_string(index << 16)); |
| 121 | additionalData.emplace("SBE_ERR_MSG", sbeError.what()); |
| 122 | |
| 123 | // FFDC |
| 124 | auto ffdc = std::vector<FFDCTuple>{}; |
| 125 | // get SBE ffdc file descriptor |
| 126 | auto fd = sbeError.getFd(); |
| 127 | |
| 128 | // Log error with additional ffdc if fd is valid |
| 129 | if (fd > 0) |
| 130 | { |
| 131 | ffdc.push_back( |
| 132 | std::make_tuple(sdbusplus::xyz::openbmc_project::Logging::server:: |
| 133 | Create::FFDCFormat::Custom, |
| 134 | static_cast<uint8_t>(0xCB), |
| 135 | static_cast<uint8_t>(0x01), sbeError.getFd())); |
| 136 | } |
| 137 | |
Shantappa Teekappanavar | b64983f | 2022-02-01 09:28:10 -0600 | [diff] [blame] | 138 | std::unique_ptr<FFDCFile> ffdcFilePtr; |
| 139 | try |
| 140 | { |
Jayanth Othayoth | fc327da | 2022-04-18 06:24:20 -0500 | [diff] [blame] | 141 | if (dumpIsRequired) |
| 142 | { |
| 143 | // Additional callout is required for SBE timeout case |
| 144 | // In this case no SBE FFDC information available and |
| 145 | // required to add default callouts. |
| 146 | json jsonCalloutDataList; |
| 147 | jsonCalloutDataList = json::array(); |
| 148 | getSBECallout(procTarget, jsonCalloutDataList); |
| 149 | ffdcFilePtr = std::make_unique<FFDCFile>(jsonCalloutDataList); |
| 150 | ffdc.push_back(std::make_tuple( |
| 151 | sdbusplus::xyz::openbmc_project::Logging::server::Create:: |
| 152 | FFDCFormat::JSON, |
| 153 | static_cast<uint8_t>(0xCA), static_cast<uint8_t>(0x01), |
| 154 | ffdcFilePtr->getFileDescriptor())); |
| 155 | } |
Shantappa Teekappanavar | b64983f | 2022-02-01 09:28:10 -0600 | [diff] [blame] | 156 | } |
| 157 | catch (const std::exception& e) |
| 158 | { |
| 159 | log<level::ERR>( |
| 160 | fmt::format("Skipping SBE special callout due to Exception({})", |
| 161 | e.what()) |
| 162 | .c_str()); |
| 163 | } |
Shantappa Teekappanavar | 41d507e | 2021-10-05 12:17:55 -0500 | [diff] [blame] | 164 | auto pelId = createPel(event, additionalData, ffdc); |
| 165 | |
| 166 | if (dumpIsRequired) |
| 167 | { |
| 168 | try |
| 169 | { |
| 170 | using namespace openpower::phal; |
| 171 | |
| 172 | // Check SBE dump collection allowed |
| 173 | bool dumpAllowed = sbe::isDumpAllowed(procTarget); |
| 174 | if (!dumpAllowed) |
| 175 | { |
| 176 | // Possibly another collection in progress, skip dump collection |
| 177 | log<level::INFO>("Another collection is in progress, skipping " |
| 178 | "dump collection"); |
| 179 | return; |
| 180 | } |
| 181 | } |
| 182 | catch (const std::exception& e) |
| 183 | { |
| 184 | log<level::ERR>( |
| 185 | fmt::format("Exception {} occurred", e.what()).c_str()); |
| 186 | return; |
| 187 | } |
| 188 | |
| 189 | DumpParameters dumpParameters; |
| 190 | dumpParameters.logId = pelId; |
| 191 | dumpParameters.unitId = index; |
| 192 | dumpParameters.timeout = timeout; |
| 193 | dumpParameters.dumpType = DumpType::SBE; |
| 194 | |
| 195 | // will not return until dump is complete or timeout |
| 196 | requestDump(dumpParameters); |
| 197 | } |
| 198 | } |
| 199 | |
Shantappa Teekappanavar | 1ac6162 | 2021-06-22 19:07:29 -0500 | [diff] [blame] | 200 | } // namespace dump |
| 201 | } // namespace watchdog |