Capture data support for an isolation bit

User applications can not specify registers to capture if there is an
active attention on a specific bit in an isolation node. This helps
reduce the number of registers captured by default when analyzing an
isolation node.

Change-Id: I50c88cb8a2fa3d89d2c7446dbc04d0f33bbb0cd2
Signed-off-by: Zane Shelley <zshelle@us.ibm.com>
diff --git a/src/chip_data/CHIP_DATA.md b/src/chip_data/CHIP_DATA.md
index 24fe1a8..a3cb561 100644
--- a/src/chip_data/CHIP_DATA.md
+++ b/src/chip_data/CHIP_DATA.md
@@ -117,9 +117,8 @@
 ##### 3.1.1) Capture Registers
 
 This list specifies which registers to capture and store for debugging purposes.
-It is suggested to at least capture all registers referenced in a node's rules,
-but it is not required and it is left up to the user application to decide which
-registers to capture, if any.
+Note that any register referenced in the isolation rules will be automatically
+captured and do not need to be duplicated in this list.
 
 Each capture register will have the following metadata, if any exist, and will
 immediately following the metadata for each node instance.
@@ -129,6 +128,26 @@
 |     3 | register ID       | See section 2 for details |
 |     1 | register instance | See section 2 for details |
 
+**Version 2 and newer:**
+
+The user application can now specify registers to be captured when isolating to
+a specific bit in an isolation node as opposed to any bit in the isolation
+node. This can reduce the amount of default data captured if a particular bit
+requires capturing registers that are uninteresting to the other bits.
+
+Beginning with **version 2**, the following will be appended to the above
+capture register metadata:
+
+| Bytes | Desc                                   | Value/Example   |
+|:-----:|:---------------------------------------|:----------------|
+|     1 | bit position within the isolation node | see notes below |
+
+Notes:
+* The bit position will not exceed number of bits defined by the register type.
+* The order of the bit position is dependent on the register type.
+* A value of **255** indicates the register will be captured for all bit
+  positions within the isolation node.
+
 ##### 3.1.2) Isolation Rules
 
 Each node instance will represent a register, or set of registers. The
diff --git a/src/chip_data/hei_chip_data.cpp b/src/chip_data/hei_chip_data.cpp
index f5c588d..3224f3f 100644
--- a/src/chip_data/hei_chip_data.cpp
+++ b/src/chip_data/hei_chip_data.cpp
@@ -17,6 +17,7 @@
 using Version_t = uint8_t;
 
 constexpr Version_t VERSION_1 = 0x01;
+constexpr Version_t VERSION_2 = 0x02;
 
 //------------------------------------------------------------------------------
 
@@ -242,7 +243,7 @@
 using TmpNodeMap      = std::map<IsolationNode::Key, TmpNodeData>;
 
 void __readNode(ChipDataStream& io_stream, const IsolationChip::Ptr& i_isoChip,
-                TmpNodeMap& io_tmpNodeMap)
+                TmpNodeMap& io_tmpNodeMap, Version_t i_version)
 {
     // Read the node metadata.
     NodeId_t nodeId;
@@ -274,13 +275,19 @@
             Instance_t regInst;
             io_stream >> regId >> regInst;
 
+            BitPosition_t bit = MAX_BIT_POSITION; // default all bits
+            if (VERSION_2 <= i_version)
+            {
+                io_stream >> bit;
+            }
+
             // Find the hardware register that is stored in this isolation chip
             // and add it to the list of capture registers. Note that this will
             // assert that the target register must exist in the isolation chip.
             auto hwReg = i_isoChip->getHardwareRegister({regId, regInst});
 
             // Add the register to the isolation node.
-            isoNode->addCaptureRegister(hwReg);
+            isoNode->addCaptureRegister(hwReg, bit);
         }
 
         // Add isolation rules.
@@ -389,8 +396,8 @@
     // This chip type should not already exist.
     HEI_ASSERT(io_isoChips.end() == io_isoChips.find(chipType));
 
-    // So far there is only one supported version type so check it here.
-    HEI_ASSERT(VERSION_1 == version);
+    // Check supported versions.
+    HEI_ASSERT(VERSION_1 <= version && version <= VERSION_2);
 
     // Allocate memory for the new isolation chip.
     auto isoChip = std::make_unique<IsolationChip>(chipType);
@@ -425,7 +432,7 @@
     TmpNodeMap tmpNodeMap; // Stores all nodes with child node map.
     for (unsigned int i = 0; i < numNodes; i++)
     {
-        __readNode(stream, isoChip, tmpNodeMap);
+        __readNode(stream, isoChip, tmpNodeMap, version);
     }
     // Link all nodes with their child nodes. Then add them to isoChip.
     __insertNodes(isoChip, tmpNodeMap);