bmc-reset: add support to write a cfam
A future commit requires this support so refactor the getCFAM a bit to
move some shared code to a common function and add putCFAM
Tested:
- Verified the putCFAM worked as expected when called on p10bmc hardware
Signed-off-by: Andrew Geissler <geissonator@yahoo.com>
Change-Id: I349505aa19bf0164a2f01d133a47298fabbf3299
diff --git a/procedures/phal/common_utils.cpp b/procedures/phal/common_utils.cpp
index 708df40..6f2995e 100644
--- a/procedures/phal/common_utils.cpp
+++ b/procedures/phal/common_utils.cpp
@@ -82,42 +82,106 @@
}
}
-uint32_t getCFAM(struct pdbg_target* procTarget, const uint32_t reg,
- uint32_t& val)
+pdbg_target* getFsiTarget(struct pdbg_target* procTarget)
{
- auto procIdx = pdbg_target_index(procTarget);
- char path[16];
- sprintf(path, "/proc%d/pib", procIdx);
- pdbg_target* pibTarget = pdbg_target_from_path(nullptr, path);
- if (nullptr == pibTarget)
+ struct pdbg_target* fsiTarget = nullptr;
+ pdbg_for_each_target("fsi", procTarget, fsiTarget)
{
- log<level::ERR>("pib path of target not found",
- entry("TARGET_PATH=%s", path));
- return -1;
+ // grab first one we find
+ break;
+ }
+ if (!fsiTarget)
+ {
+ log<level::ERR>(
+ "fsi path of target not found",
+ entry("PROC_TARGET_PATH=%s", pdbg_target_path(procTarget)));
+ return nullptr;
}
+ return fsiTarget;
+}
+
+uint32_t probeTarget(struct pdbg_target* procTarget)
+{
+ struct pdbg_target* pibTarget = nullptr;
+ pdbg_for_each_target("pib", procTarget, pibTarget)
+ {
+ // grab first one we find
+ break;
+ }
+ if (!pibTarget)
+ {
+ log<level::ERR>(
+ "pib path of target not found",
+ entry("PROC_TARGET_PATH=%s", pdbg_target_path(procTarget)));
+ return -1;
+ }
// probe PIB and ensure it's enabled
if (PDBG_TARGET_ENABLED != pdbg_target_probe(pibTarget))
{
- log<level::ERR>("probe on pib target failed");
+ log<level::ERR>(
+ "probe on pib target failed",
+ entry("PIB_TARGET_PATH=%s", pdbg_target_path(pibTarget)));
return -1;
}
+ return 0;
+}
- // now build FSI path and read the input reg
- sprintf(path, "/proc%d/fsi", procIdx);
- pdbg_target* fsiTarget = pdbg_target_from_path(nullptr, path);
+uint32_t getCFAM(struct pdbg_target* procTarget, const uint32_t reg,
+ uint32_t& val)
+{
+
+ pdbg_target* fsiTarget = getFsiTarget(procTarget);
if (nullptr == fsiTarget)
{
- log<level::ERR>("fsi path or target not found");
+ log<level::ERR>("getCFAM: fsi path or target not found");
return -1;
}
- auto rc = fsi_read(fsiTarget, reg, &val);
+ auto rc = probeTarget(procTarget);
if (rc)
{
- log<level::ERR>("failed to read input cfam", entry("RC=%u", rc),
- entry("CFAM=0x%X", reg), entry("TARGET_PATH=%s", path));
+ // probe function logged details to journal
+ return rc;
+ }
+
+ rc = fsi_read(fsiTarget, reg, &val);
+ if (rc)
+ {
+ log<level::ERR>(
+ "failed to read input cfam", entry("RC=%u", rc),
+ entry("CFAM=0x%X", reg),
+ entry("FSI_TARGET_PATH=%s", pdbg_target_path(fsiTarget)));
+ return rc;
+ }
+ return 0;
+}
+
+uint32_t putCFAM(struct pdbg_target* procTarget, const uint32_t reg,
+ const uint32_t val)
+{
+ pdbg_target* fsiTarget = getFsiTarget(procTarget);
+ if (nullptr == fsiTarget)
+ {
+ log<level::ERR>("putCFAM: fsi path or target not found");
+ return -1;
+ }
+
+ auto rc = probeTarget(procTarget);
+ if (rc)
+ {
+ // probe function logged details to journal
+ return rc;
+ }
+
+ rc = fsi_write(fsiTarget, reg, val);
+ if (rc)
+ {
+ log<level::ERR>(
+ "failed to write input cfam", entry("RC=%u", rc),
+ entry("CFAM=0x%X", reg),
+ entry("FSI_TARGET_PATH=%s", pdbg_target_path(fsiTarget)));
return rc;
}
return 0;
diff --git a/procedures/phal/common_utils.hpp b/procedures/phal/common_utils.hpp
index 2d9d57b..277272c 100644
--- a/procedures/phal/common_utils.hpp
+++ b/procedures/phal/common_utils.hpp
@@ -25,7 +25,7 @@
/**
* @brief Check if primary processor or not
*
- * @param[in] procTarget - Target to check if primary or not
+ * @param[in] procTarget - Processor target to check if primary or not
*
* @return True/False
*/
@@ -34,7 +34,7 @@
/**
* @brief Read the input CFAM register
*
- * @param[in] procTarget - The Target to perform the operation on
+ * @param[in] procTarget - Processor target to perform the operation on
* @param[in] reg - The register address to read
* @param[out] val - The value read from the register
*
@@ -43,5 +43,38 @@
uint32_t getCFAM(struct pdbg_target* procTarget, const uint32_t reg,
uint32_t& val);
+/**
+ * @brief Write the input CFAM register
+ *
+ * @param[in] procTarget - Processor target to perform the operation on
+ * @param[in] reg - The register address to write
+ * @param[out] val - The value to write to the register
+ *
+ * @return 0 on success, non-0 on failure
+ */
+uint32_t putCFAM(struct pdbg_target* procTarget, const uint32_t reg,
+ const uint32_t val);
+
+/**
+ * @brief Helper function to find FSI target needed for FSI operations
+ *
+ * @param[in] procTarget - Processor target to find the FSI target on
+ *
+ * @return Valid pointer to FSI target on success, nullptr on failure
+ */
+pdbg_target* getFsiTarget(struct pdbg_target* procTarget);
+
+/**
+ * @brief Helper function to probe the processor target
+ *
+ * The probe call only has to happen once per application start so ensure
+ * this function only probes once no matter how many times it's called.
+ *
+ * @param[in] procTarget - Processor target to probe
+ *
+ * @return 0 on success, non-0 on failure
+ */
+uint32_t probeTarget(struct pdbg_target* procTarget);
+
} // namespace phal
} // namespace openpower