Add support for getting a connected peer from IOHS or SMPGROUP
This adds getConnectedTarget support to get a connected peer
target that is across a bus from a provided IOHS or
SMPGROUP/IOLINK target
Signed-off-by: Caleb Palmer <cnpalmer@us.ibm.com>
Change-Id: I00320cf604ea21023b702fc984efd83f137ab36d
diff --git a/util/pdbg.cpp b/util/pdbg.cpp
index 10f3b73..46bb37b 100644
--- a/util/pdbg.cpp
+++ b/util/pdbg.cpp
@@ -9,15 +9,23 @@
#include <config.h>
#include <hei_main.hpp>
+#include <nlohmann/json.hpp>
+#include <util/dbus.hpp>
#include <util/pdbg.hpp>
#include <util/trace.hpp>
+#include <filesystem>
+#include <fstream>
+#include <string>
+
#ifdef CONFIG_PHAL_API
#include <attributes_info.H>
#endif
using namespace analyzer;
+namespace fs = std::filesystem;
+
namespace util
{
@@ -195,6 +203,67 @@
//------------------------------------------------------------------------------
+pdbg_target* getTargetAcrossBus(pdbg_target* i_rxTarget)
+{
+ assert(nullptr != i_rxTarget);
+
+ // Validate target type
+ auto rxType = util::pdbg::getTrgtType(i_rxTarget);
+ assert(util::pdbg::TYPE_IOLINK == rxType ||
+ util::pdbg::TYPE_IOHS == rxType);
+
+ pdbg_target* o_peerTarget;
+ fs::path filePath;
+
+ // Open the appropriate data file depending on machine type
+ util::dbus::MachineType machineType = util::dbus::getMachineType();
+ switch (machineType)
+ {
+ // Rainier 4U
+ case util::dbus::MachineType::Rainier_2S4U:
+ case util::dbus::MachineType::Rainier_1S4U:
+ filePath =
+ fs::path{PACKAGE_DIR "util-data/peer-targets-rainier-4u.json"};
+ break;
+ // Rainier 2U
+ case util::dbus::MachineType::Rainier_2S2U:
+ case util::dbus::MachineType::Rainier_1S2U:
+ filePath =
+ fs::path{PACKAGE_DIR "util-data/peer-targets-rainier-2u.json"};
+ break;
+ // Everest
+ case util::dbus::MachineType::Everest:
+ filePath =
+ fs::path{PACKAGE_DIR "util-data/peer-targets-everest.json"};
+ break;
+ default:
+ trace::err("Invalid machine type found %d",
+ static_cast<uint8_t>(machineType));
+ break;
+ }
+
+ std::ifstream file{filePath};
+ assert(file.good());
+
+ try
+ {
+ auto trgtMap = nlohmann::json::parse(file);
+ std::string rxPath = util::pdbg::getPath(i_rxTarget);
+ std::string peerPath = trgtMap.at(rxPath).get<std::string>();
+
+ o_peerTarget = util::pdbg::getTrgt(peerPath);
+ }
+ catch (...)
+ {
+ trace::err("Failed to parse file: %s", filePath.string().c_str());
+ throw;
+ }
+
+ return o_peerTarget;
+}
+
+//------------------------------------------------------------------------------
+
pdbg_target* getConnectedTarget(pdbg_target* i_rxTarget,
const callout::BusType& i_busType)
{
@@ -208,27 +277,19 @@
if (callout::BusType::SMP_BUS == i_busType &&
util::pdbg::TYPE_IOLINK == rxType)
{
- // TODO: Will need to reference some sort of data that can tell us how
- // the processors are connected in the system. For now, return the
- // RX target to avoid returning a nullptr.
- trace::inf("No support to get peer target on SMP bus");
- txTarget = i_rxTarget;
+ txTarget = getTargetAcrossBus(i_rxTarget);
}
else if (callout::BusType::SMP_BUS == i_busType &&
util::pdbg::TYPE_IOHS == rxType)
{
- // TODO: Will need to reference some sort of data that can tell us how
- // the processors are connected in the system. For now, return the
- // RX target to avoid returning a nullptr.
- trace::inf("No support to get peer target on SMP bus");
- txTarget = i_rxTarget;
+ txTarget = getTargetAcrossBus(i_rxTarget);
}
else if (callout::BusType::OMI_BUS == i_busType &&
util::pdbg::TYPE_OMI == rxType)
{
// This is a bit clunky. The pdbg APIs only give us the ability to
- // iterate over the children instead of just returning a list. So we'll
- // push all the children to a list and go from there.
+ // iterate over the children instead of just returning a list. So
+ // we'll push all the children to a list and go from there.
std::vector<pdbg_target*> childList;
pdbg_target* childTarget = nullptr;
@@ -309,9 +370,9 @@
//------------------------------------------------------------------------------
// 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.
+// 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;
@@ -320,9 +381,9 @@
}
// 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.
+// 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;
@@ -338,11 +399,11 @@
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.
+ // 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))
@@ -358,16 +419,16 @@
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 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)
{
- // 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.
+ // 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
{
@@ -385,8 +446,8 @@
{
// 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.
+ // 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)))
@@ -434,7 +495,8 @@
pdbg_target* getPrimaryProcessor()
{
- // TODO: For at least P10, the primary processor (the one connected directly
+ // 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");
@@ -519,10 +581,10 @@
ATTR_PHYS_BIN_PATH_Type value;
if (DT_GET_PROP(ATTR_PHYS_BIN_PATH, target, value))
{
- // The attrirbute for this target does not exist. Get the immediate
- // parent in the devtree path and try again. Note that if there is
- // no parent target, nullptr will be returned and that will be
- // checked above.
+ // The attrirbute for this target does not exist. Get the
+ // immediate parent in the devtree path and try again. Note that
+ // if there is no parent target, nullptr will be returned and
+ // that will be checked above.
return getPhysBinPath(pdbg_target_parent(nullptr, target));
}