Get chip ID/EC from hardware if not synced in attributes
Signed-off-by: Zane Shelley <zshelle@us.ibm.com>
Change-Id: I988fd16c1514d9fe2058f8becdfcf3a39abf8b85
diff --git a/util/pdbg.cpp b/util/pdbg.cpp
index f0142b5..605df77 100644
--- a/util/pdbg.cpp
+++ b/util/pdbg.cpp
@@ -62,7 +62,7 @@
pdbg_target* getPibTrgt(pdbg_target* i_procTrgt)
{
// The input target must be a processor.
- assert(0x05 == getTrgtType(i_procTrgt));
+ assert(TYPE_PROC == getTrgtType(i_procTrgt));
// Get the pib path.
char path[16];
@@ -80,7 +80,7 @@
pdbg_target* getFsiTrgt(pdbg_target* i_procTrgt)
{
// The input target must be a processor.
- assert(0x05 == getTrgtType(i_procTrgt));
+ assert(TYPE_PROC == getTrgtType(i_procTrgt));
// Get the fsi path.
char path[16];
@@ -95,6 +95,30 @@
//------------------------------------------------------------------------------
+int getCfam(pdbg_target* i_trgt, uint32_t i_addr, uint32_t& o_val)
+{
+ // Only processor targets are supported.
+ assert(TYPE_PROC == getTrgtType(i_trgt));
+
+ auto fsiTrgt = util::pdbg::getFsiTrgt(i_trgt);
+
+ int rc = fsi_read(fsiTrgt, i_addr, &o_val);
+
+ if (0 != rc)
+ {
+ trace::err("fsi_read failure: trgt=%s addr=0x%08x",
+ util::pdbg::getPath(fsiTrgt), i_addr);
+ }
+
+ return rc;
+}
+
+//------------------------------------------------------------------------------
+
+// IMPORTANT:
+// The ATTR_CHIP_ID attribute will be synced from Hostboot to the BMC at some
+// point during the IPL. It is possible that this information is needed before
+// the sync occurs, in which case the value will return 0.
uint32_t __getChipId(pdbg_target* i_trgt)
{
uint32_t attr = 0;
@@ -102,6 +126,10 @@
return attr;
}
+// IMPORTANT:
+// The ATTR_EC attribute will be synced from Hostboot to the BMC at some point
+// during the IPL. It is possible that this information is needed before the
+// sync occurs, in which case the value will return 0.
uint8_t __getChipEc(pdbg_target* i_trgt)
{
uint8_t attr = 0;
@@ -111,7 +139,27 @@
uint32_t __getChipIdEc(pdbg_target* i_trgt)
{
- return ((__getChipId(i_trgt) & 0xffff) << 16) | __getChipEc(i_trgt);
+ auto chipId = __getChipId(i_trgt);
+ auto chipEc = __getChipEc(i_trgt);
+
+ if (((0 == chipId) || (0 == chipEc)) && (TYPE_PROC == getTrgtType(i_trgt)))
+ {
+ // There is a special case where the model/level attributes have not
+ // been initialized in the devtree. This is possible on the epoch IPL
+ // where an attention occurs before Hostboot is able to update the
+ // devtree information on the BMC. It may is still possible to get this
+ // information from chips with CFAM access (i.e. a processor) via the
+ // CFAM chip ID register.
+
+ uint32_t val = 0;
+ if (0 == getCfam(i_trgt, 0x100a, val))
+ {
+ chipId = ((val & 0x0F0FF000) >> 12);
+ chipEc = ((val & 0xF0000000) >> 24) | ((val & 0x00F00000) >> 20);
+ }
+ }
+
+ return ((chipId & 0xffff) << 16) | (chipEc & 0xff);
}
void __addChip(std::vector<libhei::Chip>& o_chips, pdbg_target* i_trgt,
@@ -124,10 +172,9 @@
if (0 == i_type)
{
- // There is a special case where the model/level attributes have not
- // been initialized in the devtree. This is possible on the epoch IPL
- // where an attention occurs before Hostboot is able to update the
- // devtree information on the BMC. For now, just ignore the chip.
+ // This is a special case. See the details in __getChipIdEC(). There is
+ // nothing more we can do with this chip since we don't know what it is.
+ // So ignore the chip for now.
}
else
{
diff --git a/util/pdbg.hpp b/util/pdbg.hpp
index 3b293e0..5d6314d 100644
--- a/util/pdbg.hpp
+++ b/util/pdbg.hpp
@@ -17,6 +17,13 @@
namespace pdbg
{
+/** Chip target types. */
+enum TargetType_t : uint8_t
+{
+ TYPE_PROC = 0x05,
+ TYPE_OCMB = 0x4b,
+};
+
/** @return The target associated with the given chip. */
pdbg_target* getTrgt(const libhei::Chip& i_chip);
@@ -53,6 +60,16 @@
pdbg_target* getFsiTrgt(pdbg_target* i_procTrgt);
/**
+ * @brief Reads a CFAM FSI 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 getCfam(pdbg_target* i_trgt, uint32_t i_addr, uint32_t& o_val);
+
+/**
* @brief Returns the list of all active chips in the system.
* @param o_chips The returned list of chips.
*/