140fccd52SPatrick Williams #include <format>
241d507e5SShantappa Teekappanavar extern "C"
341d507e5SShantappa Teekappanavar {
441d507e5SShantappa Teekappanavar #include <libpdbg.h>
541d507e5SShantappa Teekappanavar #include <libpdbg_sbe.h>
641d507e5SShantappa Teekappanavar }
741d507e5SShantappa Teekappanavar
841d507e5SShantappa Teekappanavar #include <libphal.H>
941d507e5SShantappa Teekappanavar
10*ca9236c3SDhruvaraj Subhashchandran #include <phosphor-logging/lg2.hpp>
111ac6162dSShantappa Teekappanavar #include <watchdog_common.hpp>
1241d507e5SShantappa Teekappanavar #include <watchdog_dbus.hpp>
1341d507e5SShantappa Teekappanavar #include <watchdog_handler.hpp>
141ac6162dSShantappa Teekappanavar #include <watchdog_logging.hpp>
151ac6162dSShantappa Teekappanavar
161ac6162dSShantappa Teekappanavar namespace watchdog
171ac6162dSShantappa Teekappanavar {
181ac6162dSShantappa Teekappanavar namespace dump
191ac6162dSShantappa Teekappanavar {
201ac6162dSShantappa Teekappanavar
triggerHostbootDump(const uint32_t timeout)211ac6162dSShantappa Teekappanavar void triggerHostbootDump(const uint32_t timeout)
221ac6162dSShantappa Teekappanavar {
231ac6162dSShantappa Teekappanavar constexpr auto HOST_STATE_DIAGNOSTIC_MODE =
241ac6162dSShantappa Teekappanavar "obmc-host-diagnostic-mode@0.target";
251ac6162dSShantappa Teekappanavar constexpr auto HOST_STATE_QUIESCE_TGT = "obmc-host-quiesce@0.target";
261ac6162dSShantappa Teekappanavar
271ac6162dSShantappa Teekappanavar // Put system into diagnostic mode
281ac6162dSShantappa Teekappanavar transitionHost(HOST_STATE_DIAGNOSTIC_MODE);
291ac6162dSShantappa Teekappanavar
301ac6162dSShantappa Teekappanavar eventWatchdogTimeout(timeout);
311ac6162dSShantappa Teekappanavar
321ac6162dSShantappa Teekappanavar // Put system into quiesce state
331ac6162dSShantappa Teekappanavar transitionHost(HOST_STATE_QUIESCE_TGT);
341ac6162dSShantappa Teekappanavar }
351ac6162dSShantappa Teekappanavar
36b64983f0SShantappa Teekappanavar /**
37b64983f0SShantappa Teekappanavar * @brief get SBE special callout information
38b64983f0SShantappa Teekappanavar *
39b64983f0SShantappa Teekappanavar * @details This function adds the special sbe callout in the user provided
40b64983f0SShantappa Teekappanavar * json callout list. includes BMC0002 procedure callout with high priority
41b64983f0SShantappa Teekappanavar * and processor callout with medium priority.
42b64983f0SShantappa Teekappanavar *
43b64983f0SShantappa Teekappanavar * @param[in] procTarget - pdbg processor target
44b64983f0SShantappa Teekappanavar * @param[out] jsonCalloutDataList - reference to json callout list
45b64983f0SShantappa Teekappanavar */
getSBECallout(struct pdbg_target * procTarget,json & jsonCalloutDataList)46b64983f0SShantappa Teekappanavar static void getSBECallout(struct pdbg_target* procTarget,
47b64983f0SShantappa Teekappanavar json& jsonCalloutDataList)
48b64983f0SShantappa Teekappanavar {
49b64983f0SShantappa Teekappanavar using namespace openpower::phal::pdbg;
50b64983f0SShantappa Teekappanavar json jsonProcedCallout;
51b64983f0SShantappa Teekappanavar
52b64983f0SShantappa Teekappanavar // Add procedure callout
53b64983f0SShantappa Teekappanavar jsonProcedCallout["Procedure"] = "BMC0002";
54b64983f0SShantappa Teekappanavar jsonProcedCallout["Priority"] = "H";
55b64983f0SShantappa Teekappanavar jsonCalloutDataList.emplace_back(jsonProcedCallout);
56b64983f0SShantappa Teekappanavar try
57b64983f0SShantappa Teekappanavar {
58b64983f0SShantappa Teekappanavar ATTR_LOCATION_CODE_Type locationCode;
59b64983f0SShantappa Teekappanavar // Initialize with default data.
60b64983f0SShantappa Teekappanavar memset(&locationCode, '\0', sizeof(locationCode));
61b64983f0SShantappa Teekappanavar // Get location code information
62b64983f0SShantappa Teekappanavar openpower::phal::pdbg::getLocationCode(procTarget, locationCode);
63b64983f0SShantappa Teekappanavar json jsonProcCallout;
64b64983f0SShantappa Teekappanavar jsonProcCallout["LocationCode"] = locationCode;
65b64983f0SShantappa Teekappanavar jsonProcCallout["Deconfigured"] = false;
66b64983f0SShantappa Teekappanavar jsonProcCallout["Guarded"] = false;
67b64983f0SShantappa Teekappanavar jsonProcCallout["Priority"] = "M";
68b64983f0SShantappa Teekappanavar jsonCalloutDataList.emplace_back(jsonProcCallout);
69b64983f0SShantappa Teekappanavar }
70b64983f0SShantappa Teekappanavar catch (const std::exception& e)
71b64983f0SShantappa Teekappanavar {
72*ca9236c3SDhruvaraj Subhashchandran lg2::error("getLocationCode({LOCATION}): Exception({ERROR})",
73*ca9236c3SDhruvaraj Subhashchandran "LOCATION", pdbg_target_path(procTarget), "ERROR", e);
74b64983f0SShantappa Teekappanavar }
75b64983f0SShantappa Teekappanavar }
76b64983f0SShantappa Teekappanavar
handleSbeBootError(struct pdbg_target * procTarget,const uint32_t timeout)7741d507e5SShantappa Teekappanavar void handleSbeBootError(struct pdbg_target* procTarget, const uint32_t timeout)
7841d507e5SShantappa Teekappanavar {
7941d507e5SShantappa Teekappanavar using namespace openpower::phal;
8041d507e5SShantappa Teekappanavar
8141d507e5SShantappa Teekappanavar sbeError_t sbeError;
8241d507e5SShantappa Teekappanavar bool dumpIsRequired = false;
8341d507e5SShantappa Teekappanavar
8441d507e5SShantappa Teekappanavar try
8541d507e5SShantappa Teekappanavar {
8641d507e5SShantappa Teekappanavar // Capture FFDC information on primary processor
8741d507e5SShantappa Teekappanavar sbeError = sbe::captureFFDC(procTarget);
8841d507e5SShantappa Teekappanavar }
8941d507e5SShantappa Teekappanavar catch (const std::exception& e)
9041d507e5SShantappa Teekappanavar {
9141d507e5SShantappa Teekappanavar // Failed to collect FFDC information
92*ca9236c3SDhruvaraj Subhashchandran lg2::error("captureFFDC: Exception{ERROR}", "ERROR", e);
9341d507e5SShantappa Teekappanavar dumpIsRequired = true;
9441d507e5SShantappa Teekappanavar }
9541d507e5SShantappa Teekappanavar
9641d507e5SShantappa Teekappanavar // event type
9741d507e5SShantappa Teekappanavar std::string event;
9841d507e5SShantappa Teekappanavar if ((sbeError.errType() == exception::SBE_FFDC_NO_DATA) ||
9941d507e5SShantappa Teekappanavar (sbeError.errType() == exception::SBE_CMD_TIMEOUT) || (dumpIsRequired))
10041d507e5SShantappa Teekappanavar {
101*ca9236c3SDhruvaraj Subhashchandran lg2::info("No FFDC data");
10241d507e5SShantappa Teekappanavar event = "org.open_power.Processor.Error.SbeBootTimeout";
10341d507e5SShantappa Teekappanavar dumpIsRequired = true;
10441d507e5SShantappa Teekappanavar }
10541d507e5SShantappa Teekappanavar else
10641d507e5SShantappa Teekappanavar {
107*ca9236c3SDhruvaraj Subhashchandran lg2::error("SBE Boot failure");
10841d507e5SShantappa Teekappanavar event = "org.open_power.Processor.Error.SbeBootFailure";
10941d507e5SShantappa Teekappanavar }
11041d507e5SShantappa Teekappanavar
11141d507e5SShantappa Teekappanavar // Additional data
11241d507e5SShantappa Teekappanavar std::map<std::string, std::string> additionalData;
11341d507e5SShantappa Teekappanavar
11441d507e5SShantappa Teekappanavar // SRC6 : [0:15] chip position
11541d507e5SShantappa Teekappanavar uint32_t index = pdbg_target_index(procTarget);
11641d507e5SShantappa Teekappanavar additionalData.emplace("SRC6", std::to_string(index << 16));
11741d507e5SShantappa Teekappanavar additionalData.emplace("SBE_ERR_MSG", sbeError.what());
11841d507e5SShantappa Teekappanavar
11941d507e5SShantappa Teekappanavar // FFDC
12041d507e5SShantappa Teekappanavar auto ffdc = std::vector<FFDCTuple>{};
12141d507e5SShantappa Teekappanavar // get SBE ffdc file descriptor
12241d507e5SShantappa Teekappanavar auto fd = sbeError.getFd();
12341d507e5SShantappa Teekappanavar
12441d507e5SShantappa Teekappanavar // Log error with additional ffdc if fd is valid
12541d507e5SShantappa Teekappanavar if (fd > 0)
12641d507e5SShantappa Teekappanavar {
12741d507e5SShantappa Teekappanavar ffdc.push_back(
12841d507e5SShantappa Teekappanavar std::make_tuple(sdbusplus::xyz::openbmc_project::Logging::server::
12941d507e5SShantappa Teekappanavar Create::FFDCFormat::Custom,
13041d507e5SShantappa Teekappanavar static_cast<uint8_t>(0xCB),
13141d507e5SShantappa Teekappanavar static_cast<uint8_t>(0x01), sbeError.getFd()));
13241d507e5SShantappa Teekappanavar }
13341d507e5SShantappa Teekappanavar
134b64983f0SShantappa Teekappanavar std::unique_ptr<FFDCFile> ffdcFilePtr;
135b64983f0SShantappa Teekappanavar try
136b64983f0SShantappa Teekappanavar {
137fc327da9SJayanth Othayoth if (dumpIsRequired)
138fc327da9SJayanth Othayoth {
139fc327da9SJayanth Othayoth // Additional callout is required for SBE timeout case
140fc327da9SJayanth Othayoth // In this case no SBE FFDC information available and
141fc327da9SJayanth Othayoth // required to add default callouts.
142b64983f0SShantappa Teekappanavar json jsonCalloutDataList;
143b64983f0SShantappa Teekappanavar jsonCalloutDataList = json::array();
144b64983f0SShantappa Teekappanavar getSBECallout(procTarget, jsonCalloutDataList);
145b64983f0SShantappa Teekappanavar ffdcFilePtr = std::make_unique<FFDCFile>(jsonCalloutDataList);
146b64983f0SShantappa Teekappanavar ffdc.push_back(std::make_tuple(
147b64983f0SShantappa Teekappanavar sdbusplus::xyz::openbmc_project::Logging::server::Create::
148b64983f0SShantappa Teekappanavar FFDCFormat::JSON,
149b64983f0SShantappa Teekappanavar static_cast<uint8_t>(0xCA), static_cast<uint8_t>(0x01),
150b64983f0SShantappa Teekappanavar ffdcFilePtr->getFileDescriptor()));
151b64983f0SShantappa Teekappanavar }
152fc327da9SJayanth Othayoth }
153b64983f0SShantappa Teekappanavar catch (const std::exception& e)
154b64983f0SShantappa Teekappanavar {
155*ca9236c3SDhruvaraj Subhashchandran lg2::error("Skipping SBE special callout due to Exception({ERROR})",
156*ca9236c3SDhruvaraj Subhashchandran "ERROR", e);
157b64983f0SShantappa Teekappanavar }
15841d507e5SShantappa Teekappanavar auto pelId = createPel(event, additionalData, ffdc);
15941d507e5SShantappa Teekappanavar
16041d507e5SShantappa Teekappanavar if (dumpIsRequired)
16141d507e5SShantappa Teekappanavar {
16241d507e5SShantappa Teekappanavar try
16341d507e5SShantappa Teekappanavar {
16441d507e5SShantappa Teekappanavar using namespace openpower::phal;
16541d507e5SShantappa Teekappanavar
16641d507e5SShantappa Teekappanavar // Check SBE dump collection allowed
16741d507e5SShantappa Teekappanavar bool dumpAllowed = sbe::isDumpAllowed(procTarget);
16841d507e5SShantappa Teekappanavar if (!dumpAllowed)
16941d507e5SShantappa Teekappanavar {
17041d507e5SShantappa Teekappanavar // Possibly another collection in progress, skip dump collection
171*ca9236c3SDhruvaraj Subhashchandran lg2::error("Another collection is in progress, skipping "
17241d507e5SShantappa Teekappanavar "dump collection");
17341d507e5SShantappa Teekappanavar return;
17441d507e5SShantappa Teekappanavar }
17541d507e5SShantappa Teekappanavar }
17641d507e5SShantappa Teekappanavar catch (const std::exception& e)
17741d507e5SShantappa Teekappanavar {
178*ca9236c3SDhruvaraj Subhashchandran lg2::error("Exception {ERROR} occurred", "ERROR", e);
17941d507e5SShantappa Teekappanavar return;
18041d507e5SShantappa Teekappanavar }
18141d507e5SShantappa Teekappanavar
18241d507e5SShantappa Teekappanavar DumpParameters dumpParameters;
18341d507e5SShantappa Teekappanavar dumpParameters.logId = pelId;
18441d507e5SShantappa Teekappanavar dumpParameters.unitId = index;
18541d507e5SShantappa Teekappanavar dumpParameters.timeout = timeout;
18641d507e5SShantappa Teekappanavar dumpParameters.dumpType = DumpType::SBE;
18741d507e5SShantappa Teekappanavar
18841d507e5SShantappa Teekappanavar // will not return until dump is complete or timeout
18941d507e5SShantappa Teekappanavar requestDump(dumpParameters);
19041d507e5SShantappa Teekappanavar }
19141d507e5SShantappa Teekappanavar }
19241d507e5SShantappa Teekappanavar
1931ac6162dSShantappa Teekappanavar } // namespace dump
1941ac6162dSShantappa Teekappanavar } // namespace watchdog
195