pdbg utils for finding all active chips
Change-Id: I444c1062d28c10ecd47426c60ffe0604cc5eaac5
Signed-off-by: Zane Shelley <zshelle@us.ibm.com>
diff --git a/analyzer/analyzer_main.cpp b/analyzer/analyzer_main.cpp
index cf78149..30efd74 100644
--- a/analyzer/analyzer_main.cpp
+++ b/analyzer/analyzer_main.cpp
@@ -20,7 +20,7 @@
// Forward references for externally defined functions.
-void initializeIsolator(const std::vector<libhei::Chip>& i_chips);
+void initializeIsolator(std::vector<libhei::Chip>& o_chips);
//------------------------------------------------------------------------------
@@ -69,67 +69,6 @@
//------------------------------------------------------------------------------
-// Returns the chip model/level of the given target.
-libhei::ChipType_t __getChipType(pdbg_target* i_trgt)
-{
- libhei::ChipType_t type;
-
- // START WORKAROUND
- // TODO: Will need to grab the model/level from the target attributes when
- // they are available. For now, use ATTR_TYPE to determine which
- // currently supported value to use supported.
- uint8_t attrType = util::pdbg::getTrgtType(i_trgt);
- switch (attrType)
- {
- case 0x05: // PROC
- type = 0x120DA049;
- break;
-
- case 0x4b: // OCMB_CHIP
- type = 0x160D2000;
- break;
-
- default:
- trace::err("Unsupported ATTR_TYPE value: 0x%02x", attrType);
- assert(0);
- }
- // END WORKAROUND
-
- return type;
-}
-
-//------------------------------------------------------------------------------
-
-// Gathers list of active chips to analyze.
-void __getActiveChips(std::vector<libhei::Chip>& o_chips)
-{
- // Iterate each processor.
- pdbg_target* procTrgt;
- pdbg_for_each_class_target("proc", procTrgt)
- {
- // Active processors only.
- if (PDBG_TARGET_ENABLED != pdbg_target_probe(procTrgt))
- continue;
-
- // Add the processor to the list.
- o_chips.emplace_back(procTrgt, __getChipType(procTrgt));
-
- // Iterate the connected OCMBs, if they exist.
- pdbg_target* ocmbTrgt;
- pdbg_for_each_target("ocmb", procTrgt, ocmbTrgt)
- {
- // Active OCMBs only.
- if (PDBG_TARGET_ENABLED != pdbg_target_probe(ocmbTrgt))
- continue;
-
- // Add the OCMB to the list.
- o_chips.emplace_back(ocmbTrgt, __getChipType(ocmbTrgt));
- }
- }
-}
-
-//------------------------------------------------------------------------------
-
// Takes a signature list that will be filtered and sorted. The first entry in
// the returned list will be the root cause. If the returned list is empty,
// analysis failed.
@@ -237,12 +176,9 @@
trace::inf(">>> enter analyzeHardware()");
- // Get the active chips to be analyzed.
- std::vector<libhei::Chip> chips;
- __getActiveChips(chips);
-
- // Initialize the isolator for all chips.
+ // Initialize the isolator and get all of the chips to be analyzed.
trace::inf("Initializing the isolator...");
+ std::vector<libhei::Chip> chips;
initializeIsolator(chips);
// Isolate attentions.
diff --git a/analyzer/hei_user_interface.cpp b/analyzer/hei_user_interface.cpp
index 0f4a441..2422b38 100644
--- a/analyzer/hei_user_interface.cpp
+++ b/analyzer/hei_user_interface.cpp
@@ -43,10 +43,7 @@
bool accessFailure = false;
// The processor PIB target is required for SCOM access.
- char path[16];
- sprintf(path, "/proc%d/pib", pdbg_target_index(i_procTrgt));
- pdbg_target* scomTrgt = pdbg_target_from_path(nullptr, path);
- assert(nullptr != scomTrgt);
+ pdbg_target* scomTrgt = util::pdbg::getPibTrgt(i_procTrgt);
switch (i_regType)
{
diff --git a/analyzer/initialize_isolator.cpp b/analyzer/initialize_isolator.cpp
index 941b500..e75f5b3 100644
--- a/analyzer/initialize_isolator.cpp
+++ b/analyzer/initialize_isolator.cpp
@@ -105,8 +105,11 @@
//------------------------------------------------------------------------------
-void initializeIsolator(const std::vector<libhei::Chip>& i_chips)
+void initializeIsolator(std::vector<libhei::Chip>& o_chips)
{
+ // Get all of the active chips to be analyzed.
+ util::pdbg::getActiveChips(o_chips);
+
// Find all of the existing chip data files.
std::map<libhei::ChipType_t, fs::path> files;
__getChipDataFiles(files);
@@ -114,25 +117,10 @@
// Keep track of models/levels that have already been initialized.
std::map<libhei::ChipType_t, unsigned int> initTypes;
- for (const auto& chip : i_chips)
+ for (const auto& chip : o_chips)
{
auto chipType = chip.getType();
- // Trace each chip for debug.
- trace::inf("Chip found: type=0x%0" PRIx32 " chip=%s", chipType,
- util::pdbg::getPath(chip));
-
- if (0 == chipType)
- {
- // This is a special case. It means 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.
-
- // TODO: Consider logging a PEL. Just skip for now.
- continue;
- }
-
// Mark this chip type as initialized (or will be if it hasn't been).
auto ret = initTypes.emplace(chipType, 1);
if (!ret.second)
diff --git a/util/pdbg.cpp b/util/pdbg.cpp
index 53c8020..0ca6574 100644
--- a/util/pdbg.cpp
+++ b/util/pdbg.cpp
@@ -1,4 +1,7 @@
+#include <assert.h>
+
#include <util/pdbg.hpp>
+#include <util/trace.hpp>
namespace util
{
@@ -55,6 +58,100 @@
//------------------------------------------------------------------------------
+pdbg_target* getPibTrgt(pdbg_target* i_procTrgt)
+{
+ // The input target must be a processor.
+ assert(0x05 == getTrgtType(i_procTrgt));
+
+ // Get the pib path.
+ char path[16];
+ sprintf(path, "/proc%d/pib", pdbg_target_index(i_procTrgt));
+
+ // Return the pib target.
+ pdbg_target* pibTrgt = pdbg_target_from_path(nullptr, path);
+ assert(nullptr != pibTrgt);
+
+ return pibTrgt;
+}
+
+//------------------------------------------------------------------------------
+
+uint32_t __getChipId(pdbg_target* i_trgt)
+{
+ uint32_t attr = 0;
+ pdbg_target_get_attribute(i_trgt, "ATTR_CHIP_ID", 4, 1, &attr);
+ return attr;
+}
+
+uint8_t __getChipEc(pdbg_target* i_trgt)
+{
+ uint8_t attr = 0;
+ pdbg_target_get_attribute(i_trgt, "ATTR_EC", 1, 1, &attr);
+ return attr;
+}
+
+uint32_t __getChipIdEc(pdbg_target* i_trgt)
+{
+ return ((__getChipId(i_trgt) & 0xffff) << 16) | __getChipEc(i_trgt);
+}
+
+void __addChip(std::vector<libhei::Chip>& o_chips, pdbg_target* i_trgt,
+ libhei::ChipType_t i_type)
+{
+ // Trace each chip for debug. It is important to show the type just in case
+ // the model/EC does not exist. See note below.
+ trace::inf("Chip found: type=0x%08" PRIx32 " chip=%s", i_type,
+ getPath(i_trgt));
+
+ 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.
+ }
+ else
+ {
+ o_chips.emplace_back(i_trgt, i_type);
+ }
+}
+
+void getActiveChips(std::vector<libhei::Chip>& o_chips)
+{
+ o_chips.clear();
+
+ // Iterate each processor.
+ pdbg_target* procTrgt;
+ pdbg_for_each_class_target("proc", procTrgt)
+ {
+ // We cannot use the proc target to determine if the chip is active.
+ // There is some design limitation in pdbg that requires the proc
+ // targets to always be active. Instead, we must get the associated pib
+ // target and check if it is active.
+
+ // Active processors only.
+ if (PDBG_TARGET_ENABLED != pdbg_target_probe(getPibTrgt(procTrgt)))
+ continue;
+
+ // Add the processor to the list.
+ __addChip(o_chips, procTrgt, __getChipIdEc(procTrgt));
+
+ // Iterate the connected OCMBs, if they exist.
+ pdbg_target* ocmbTrgt;
+ pdbg_for_each_target("ocmb", procTrgt, ocmbTrgt)
+ {
+ // Active OCMBs only.
+ if (PDBG_TARGET_ENABLED != pdbg_target_probe(ocmbTrgt))
+ continue;
+
+ // Add the OCMB to the list.
+ __addChip(o_chips, ocmbTrgt, __getChipIdEc(ocmbTrgt));
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+
} // namespace pdbg
} // namespace util
diff --git a/util/pdbg.hpp b/util/pdbg.hpp
index 58af138..33e4320 100644
--- a/util/pdbg.hpp
+++ b/util/pdbg.hpp
@@ -31,6 +31,19 @@
/** @return The target type of the given chip. */
uint8_t getTrgtType(const libhei::Chip& i_chip);
+/**
+ * @return The pib target associated with the given proc target.
+ * @note Will assert the given target is a proc target.
+ * @note Will assert the returned pib target it not nullptr.
+ */
+pdbg_target* getPibTrgt(pdbg_target* i_procTrgt);
+
+/**
+ * @brief Returns the list of all active chips in the system.
+ * @param o_chips The returned list of chips.
+ */
+void getActiveChips(std::vector<libhei::Chip>& o_chips);
+
} // namespace pdbg
} // namespace util