Add Hostboot scratch registers to PEL
Signed-off-by: Zane Shelley <zshelle@us.ibm.com>
Change-Id: I8f095b49ec204e6e33afc0ab300beeab5d3759a9
diff --git a/analyzer/create_pel.cpp b/analyzer/create_pel.cpp
index f1c245f..adc2264 100644
--- a/analyzer/create_pel.cpp
+++ b/analyzer/create_pel.cpp
@@ -25,9 +25,10 @@
enum FfdcSubType_t : uint8_t
{
- FFDC_SIGNATURES = 0x01,
- FFDC_REGISTER_DUMP = 0x02,
- FFDC_CALLOUT_FFDC = 0x03,
+ FFDC_SIGNATURES = 0x01,
+ FFDC_REGISTER_DUMP = 0x02,
+ FFDC_CALLOUT_FFDC = 0x03,
+ FFDC_HB_SCRATCH_REGS = 0x04,
// For the callout section, the value of '0xCA' is required per the
// phosphor-logging openpower-pel extention spec.
@@ -224,6 +225,57 @@
//------------------------------------------------------------------------------
+void __captureHostbootScratchRegisters(
+ std::vector<util::FFDCFile>& io_userDataFiles)
+{
+ // Get the Hostboot scratch registers from the primary processor.
+
+ uint32_t cfamAddr = 0x283C;
+ uint32_t cfamValue = 0;
+
+ uint64_t scomAddr = 0x4602F489;
+ uint64_t scomValue = 0;
+
+ auto priProc = util::pdbg::getPrimaryProcessor();
+ if (nullptr == priProc)
+ {
+ trace::err("Unable to get primary processor");
+ }
+ else
+ {
+ if (0 != util::pdbg::getCfam(priProc, cfamAddr, cfamValue))
+ {
+ cfamValue = 0; // just in case
+ }
+
+ if (0 != util::pdbg::getScom(priProc, scomAddr, scomValue))
+ {
+ scomValue = 0; // just in case
+ }
+ }
+
+ // Create a new entry for this user data section.
+ io_userDataFiles.emplace_back(util::FFDCFormat::Custom,
+ FFDC_HB_SCRATCH_REGS, FFDC_VERSION1);
+
+ // Create a streamer for easy writing to the FFDC file.
+ auto path = io_userDataFiles.back().getPath();
+ util::BinFileWriter stream{path};
+
+ // Add the data (CFAM addr/val, then SCOM addr/val).
+ stream << cfamAddr << cfamValue << scomAddr << scomValue;
+
+ // If the stream failed for any reason, remove the FFDC file.
+ if (!stream.good())
+ {
+ trace::err("Unable to write register dump FFDC file: %s",
+ path.string().c_str());
+ io_userDataFiles.pop_back();
+ }
+}
+
+//------------------------------------------------------------------------------
+
std::string __getMessageRegistry(bool i_isCheckstop)
{
// For now, there are only two choices:
@@ -279,6 +331,9 @@
// Add the list of callouts to the PEL.
__addCalloutList(i_servData, userDataFiles);
+ // Add the Hostboot scratch register to the PEL.
+ __captureHostbootScratchRegisters(userDataFiles);
+
// Add the callout FFDC to the PEL.
__addCalloutFFDC(i_servData, userDataFiles);
diff --git a/util/pdbg.cpp b/util/pdbg.cpp
index fb36a8e..d4170a7 100644
--- a/util/pdbg.cpp
+++ b/util/pdbg.cpp
@@ -107,6 +107,27 @@
//------------------------------------------------------------------------------
+int getScom(pdbg_target* i_trgt, uint64_t i_addr, uint64_t& o_val)
+{
+ // Only processor targets are supported.
+ // TODO: Will need to add OCMB support later.
+ assert(TYPE_PROC == getTrgtType(i_trgt));
+
+ auto pibTrgt = util::pdbg::getPibTrgt(i_trgt);
+
+ int rc = pib_read(pibTrgt, i_addr, &o_val);
+
+ if (0 != rc)
+ {
+ trace::err("pib_read failure: target=%s addr=0x%0" PRIx64,
+ util::pdbg::getPath(pibTrgt), i_addr);
+ }
+
+ return rc;
+}
+
+//------------------------------------------------------------------------------
+
int getCfam(pdbg_target* i_trgt, uint32_t i_addr, uint32_t& o_val)
{
// Only processor targets are supported.
@@ -118,7 +139,7 @@
if (0 != rc)
{
- trace::err("fsi_read failure: trgt=%s addr=0x%08x",
+ trace::err("fsi_read failure: target=%s addr=0x%08x",
util::pdbg::getPath(fsiTrgt), i_addr);
}
@@ -230,6 +251,16 @@
//------------------------------------------------------------------------------
+pdbg_target* getPrimaryProcessor()
+{
+ // TODO: For at least P10, the primary processor (the one connected directly
+ // to the BMC), will always be PROC 0. We will need to update this
+ // later if we ever support an alternate primary processor.
+ return getTrgt("/proc0");
+}
+
+//------------------------------------------------------------------------------
+
bool queryHardwareAnalysisSupported()
{
// Hardware analysis is only supported on P10 systems and up.
diff --git a/util/pdbg.hpp b/util/pdbg.hpp
index 2fabcf3..6c604ac 100644
--- a/util/pdbg.hpp
+++ b/util/pdbg.hpp
@@ -67,6 +67,16 @@
pdbg_target* getFsiTrgt(pdbg_target* i_procTrgt);
/**
+ * @brief Reads a SCOM register.
+ * @param i_trgt Given target.
+ * @param i_addr Given address.
+ * @param o_val The returned value of the register.
+ * @return 0 if successful, non-0 otherwise.
+ * @note Will assert the given target is a proc target.
+ */
+int getScom(pdbg_target* i_trgt, uint64_t i_addr, uint64_t& o_val);
+
+/**
* @brief Reads a CFAM FSI register.
* @param i_trgt Given target.
* @param i_addr Given address.
@@ -83,6 +93,11 @@
void getActiveChips(std::vector<libhei::Chip>& o_chips);
/**
+ * @return The primary processor (i.e. the processor connected to the BMC).
+ */
+pdbg_target* getPrimaryProcessor();
+
+/**
* @return True, if hardware analysis is supported on this system. False,
* otherwise.
* @note Support for hardware analysis from the BMC started with P10 systems