PHAL: SBE boot failure support
Added support to handle SBE boot failure reported during
SBE start process. This features required support from
libphal library which is part of ipl repository.
This function invoked for any SBE related boot failure reason code.
libphal library provided api's is used for capturing FFDC information
from SBE. Creates SBE specific PEL for a valid FFDC data. In case the
error is related SBE timeout initiates SBE dump to capture additional
debug data.
Tested: verified PEL log
Signed-off-by: Jayanth Othayoth <ojayanth@in.ibm.com>
Change-Id: Iff9a23359de8f5ca273d195b29afe2fdc659283f
diff --git a/extensions/phal/phal_error.cpp b/extensions/phal/phal_error.cpp
index db03068..d769d11 100644
--- a/extensions/phal/phal_error.cpp
+++ b/extensions/phal/phal_error.cpp
@@ -4,11 +4,13 @@
}
#include "create_pel.hpp"
+#include "extensions/phal/common_utils.hpp"
#include "phal_error.hpp"
#include <attributes_info.H>
#include <fmt/format.h>
#include <libekb.H>
+#include <libphal.H>
#include <nlohmann/json.hpp>
#include <phosphor-logging/elog.hpp>
@@ -259,7 +261,7 @@
void processIplErrorCallback(const ipl_error_info& errInfo)
{
log<level::INFO>(
- fmt::format("processIplErrorCallback: Error type(%x) \n", errInfo.type)
+ fmt::format("processIplErrorCallback: Error type({})", errInfo.type)
.c_str());
if (errInfo.type == IPL_ERR_OK)
@@ -268,6 +270,13 @@
reset();
return;
}
+
+ if (errInfo.type == IPL_ERR_SBE_BOOT)
+ {
+ processSbeBootError();
+ return;
+ }
+
// TODO: Keeping the existing behaviour now
// Handle errors based on special reason codes once support is available
processBootError(false);
@@ -491,6 +500,78 @@
reset();
}
+void processSbeBootError()
+{
+ log<level::INFO>("processSbeBootError : Entered ");
+
+ using namespace openpower::phal::sbe;
+ using namespace openpower::phal::exception;
+
+ // To store phal trace and other additional data about ffdc.
+ FFDCData pelAdditionalData;
+
+ // Adding collected phal logs into PEL additional data
+ for_each(
+ traceLog.begin(), traceLog.end(),
+ [&pelAdditionalData](std::pair<std::string, std::string>& ele) -> void {
+ pelAdditionalData.emplace_back(ele.first, ele.second);
+ });
+
+ // reset the trace log and counter
+ reset();
+
+ // get primary processor to collect FFDC/Dump information.
+ struct pdbg_target* procTarget;
+ pdbg_for_each_class_target("proc", procTarget)
+ {
+ if (openpower::phal::isPrimaryProc(procTarget))
+ break;
+ procTarget = nullptr;
+ }
+ // check valid primary processor is available
+ if (procTarget == nullptr)
+ {
+ log<level::ERR>("processSbeBootError: fail to get primary processor");
+ // Initialise the SRC6 with default data, not used in this use case.
+ pelAdditionalData.emplace_back("SRC6", "00000000");
+ openpower::pel::createPEL(
+ "org.open_power.Processor.Error.SbeBootFailure", pelAdditionalData);
+ return;
+ }
+ // SBE error object.
+ sbeError_t sbeError;
+ bool dumpIsRequired = false;
+
+ try
+ {
+ // Capture FFDC information on primary processor
+ sbeError = captureFFDC(procTarget);
+ }
+ catch (const std::exception& e)
+ {
+ // Fail to collect FFDC information , trigger Dump
+ log<level::ERR>(
+ fmt::format("captureFFDC: Exception{}", e.what()).c_str());
+ dumpIsRequired = true;
+ }
+
+ if ((sbeError.errType() == SBE_FFDC_NO_DATA) ||
+ (sbeError.errType() == SBE_CMD_TIMEOUT) || (dumpIsRequired))
+ {
+ // Create SBE Dump type error log and trigger Dump
+ openpower::pel::createPEL(
+ "org.open_power.Processor.Error.SbeBootTimeout", pelAdditionalData);
+ // TODO Add dump request
+ return;
+ }
+ // SRC6 : [0:15] chip position
+ uint32_t word6 = pdbg_target_index(procTarget);
+ pelAdditionalData.emplace_back("SRC6", std::to_string(word6 << 16));
+ // Create SBE Error with FFDC data.
+ createSbeErrorPEL("org.open_power.Processor.Error.SbeBootFailure", sbeError,
+ pelAdditionalData);
+}
+
void reset()
{
// reset the trace log and counter
diff --git a/extensions/phal/phal_error.hpp b/extensions/phal/phal_error.hpp
index 746b733..734d6f2 100644
--- a/extensions/phal/phal_error.hpp
+++ b/extensions/phal/phal_error.hpp
@@ -46,6 +46,17 @@
void processBootError(bool status);
/**
+ * @brief Process SBE boot failure/success status
+ *
+ * This function is used for SBE related failure handling during
+ * boot path. For any SBE related boot failure reason code, collects
+ * the SBE FFDC using libphal api's. Based on the reason code provided
+ * as part of error object collects Dump or PEL.
+ * Also resets the trace buffer.
+ */
+void processSbeBootError();
+
+/**
* @brief Reset trace log list
*/
void reset();
diff --git a/meson.build b/meson.build
index 446912d..886f837 100644
--- a/meson.build
+++ b/meson.build
@@ -91,6 +91,7 @@
dependency('libdt-api'),
cxx.find_library('ekb'),
cxx.find_library('ipl'),
+ cxx.find_library('phal'),
]
extra_unit_files = [
'service_files/set-spi-mux.service',