blob: 274867aec5fa343b27cdf3d4bbe4aabf71cb7d58 [file] [log] [blame]
#include <fmt/format.h>
extern "C"
{
#include <libpdbg.h>
#include <libpdbg_sbe.h>
}
#include <libphal.H>
#include <phosphor-logging/log.hpp>
#include <watchdog_common.hpp>
#include <watchdog_dbus.hpp>
#include <watchdog_handler.hpp>
#include <watchdog_logging.hpp>
namespace watchdog
{
namespace dump
{
using namespace phosphor::logging;
void triggerHostbootDump(const uint32_t timeout)
{
constexpr auto HOST_STATE_DIAGNOSTIC_MODE =
"obmc-host-diagnostic-mode@0.target";
constexpr auto HOST_STATE_QUIESCE_TGT = "obmc-host-quiesce@0.target";
// Put system into diagnostic mode
transitionHost(HOST_STATE_DIAGNOSTIC_MODE);
eventWatchdogTimeout(timeout);
// Put system into quiesce state
transitionHost(HOST_STATE_QUIESCE_TGT);
}
void handleSbeBootError(struct pdbg_target* procTarget, const uint32_t timeout)
{
using namespace openpower::phal;
sbeError_t sbeError;
bool dumpIsRequired = false;
try
{
// Capture FFDC information on primary processor
sbeError = sbe::captureFFDC(procTarget);
}
catch (const std::exception& e)
{
// Failed to collect FFDC information
log<level::ERR>(
fmt::format("captureFFDC: Exception{}", e.what()).c_str());
dumpIsRequired = true;
}
// event type
std::string event;
if ((sbeError.errType() == exception::SBE_FFDC_NO_DATA) ||
(sbeError.errType() == exception::SBE_CMD_TIMEOUT) || (dumpIsRequired))
{
log<level::INFO>("No FFDC data");
event = "org.open_power.Processor.Error.SbeBootTimeout";
dumpIsRequired = true;
}
else
{
log<level::ERR>("SBE Boot failure");
event = "org.open_power.Processor.Error.SbeBootFailure";
}
// Additional data
std::map<std::string, std::string> additionalData;
// SRC6 : [0:15] chip position
uint32_t index = pdbg_target_index(procTarget);
additionalData.emplace("SRC6", std::to_string(index << 16));
additionalData.emplace("SBE_ERR_MSG", sbeError.what());
// FFDC
auto ffdc = std::vector<FFDCTuple>{};
// get SBE ffdc file descriptor
auto fd = sbeError.getFd();
// Log error with additional ffdc if fd is valid
if (fd > 0)
{
ffdc.push_back(
std::make_tuple(sdbusplus::xyz::openbmc_project::Logging::server::
Create::FFDCFormat::Custom,
static_cast<uint8_t>(0xCB),
static_cast<uint8_t>(0x01), sbeError.getFd()));
}
auto pelId = createPel(event, additionalData, ffdc);
if (dumpIsRequired)
{
try
{
using namespace openpower::phal;
// Check SBE dump collection allowed
bool dumpAllowed = sbe::isDumpAllowed(procTarget);
if (!dumpAllowed)
{
// Possibly another collection in progress, skip dump collection
log<level::INFO>("Another collection is in progress, skipping "
"dump collection");
return;
}
}
catch (const std::exception& e)
{
log<level::ERR>(
fmt::format("Exception {} occurred", e.what()).c_str());
return;
}
DumpParameters dumpParameters;
dumpParameters.logId = pelId;
dumpParameters.unitId = index;
dumpParameters.timeout = timeout;
dumpParameters.dumpType = DumpType::SBE;
// will not return until dump is complete or timeout
requestDump(dumpParameters);
}
}
} // namespace dump
} // namespace watchdog