Support to add capture registers to isolation nodes

Change-Id: I325e6e0ce9846042e5f6e830c5e39702f11d6c2e
Signed-off-by: Zane Shelley <zshelle@us.ibm.com>
diff --git a/src/isolator/hei_isolation_node.cpp b/src/isolator/hei_isolation_node.cpp
index c952207..c49b277 100644
--- a/src/isolator/hei_isolation_node.cpp
+++ b/src/isolator/hei_isolation_node.cpp
@@ -14,6 +14,27 @@
     // Keep track of nodes that have been analyzed to avoid cyclic isolation.
     pushIsolationStack();
 
+    // Capture all registers for this node.
+    for (const auto& hwReg : iv_capRegs)
+    {
+        // Read the register (adds BitString to register cache).
+        if (hwReg->read(i_chip))
+        {
+            // TODO: Would be nice to add SCOM errors to the log just in case
+            //       traces are not available.
+            HEI_ERR("register read failed on chip type=0x%0" PRIx32
+                    "address=0x%0" PRIx64,
+                    i_chip.getType(), hwReg->getAddress());
+        }
+
+        // TODO: Add this register to io_isoData.
+        // TODO: getBitString() does read hardware if read() has not been called
+        //       and there is nothing in the register cache. However, it does
+        //       not does not indicate if the read was successful. Not sure if
+        //       this is intentional. Will need to investigate.
+        // auto bs = hwReg->getBitString();
+    }
+
     // A rule for i_attnType must exist.
     auto rule_itr = iv_rules.find(i_attnType);
     HEI_ASSERT(iv_rules.end() != rule_itr);
@@ -76,6 +97,20 @@
 
 //------------------------------------------------------------------------------
 
+void IsolationNode::addCaptureRegister(HardwareRegister::ConstPtr i_hwReg)
+{
+    HEI_ASSERT(i_hwReg); // should not be null
+
+    // If the register already exists, ignore it. Otherwise, add it to the list.
+    auto itr = std::find(iv_capRegs.begin(), iv_capRegs.end(), i_hwReg);
+    if (iv_capRegs.end() == itr)
+    {
+        iv_capRegs.push_back(i_hwReg);
+    }
+}
+
+//------------------------------------------------------------------------------
+
 void IsolationNode::addRule(AttentionType_t i_attnType,
                             Register::ConstPtr i_rule)
 {
diff --git a/src/isolator/hei_isolation_node.hpp b/src/isolator/hei_isolation_node.hpp
index 26424cc..2546a93 100644
--- a/src/isolator/hei_isolation_node.hpp
+++ b/src/isolator/hei_isolation_node.hpp
@@ -2,7 +2,7 @@
 
 #include <hei_includes.hpp>
 #include <hei_isolation_data.hpp>
-#include <register/hei_register.hpp>
+#include <register/hei_hardware_register.hpp>
 
 namespace libhei
 {
@@ -75,6 +75,12 @@
     const Instance_t iv_instance;
 
     /**
+     * The list of register to capture and add to the log for additional
+     * debugging.
+     */
+    std::vector<HardwareRegister::ConstPtr> iv_capRegs;
+
+    /**
      * This register could report multiple types of attentions. We can use a
      * register 'rule' (value) to find any active attentions for each attention
      * type (key). A 'rule', like "register & ~mask", is a combination of
@@ -108,6 +114,17 @@
                  IsolationData& io_isoData) const;
 
     /**
+     * @brief Adds a hardware register to the list of registers that will be
+     *        captured for additional debugging. See iv_capRegs for details.
+     *
+     * This is only intended to be used during initialization of the isolator.
+     * Duplicate registers will be ignored.
+     *
+     * @param The target hardware register.
+     */
+    void addCaptureRegister(HardwareRegister::ConstPtr i_hwReg);
+
+    /**
      * @brief Adds a register rule for the given attention type. See iv_rules
      *        for details.
      *