Add support for decoding new write operations defined in chip data files
Change-Id: I83f2f72073fe05e1f0d9bde85e3aabe4c9df1a33
Signed-off-by: Caleb Palmer <cnpalmer@us.ibm.com>
diff --git a/README.md b/README.md
index 8b406dd..5ae5bc2 100644
--- a/README.md
+++ b/README.md
@@ -21,14 +21,14 @@
## User Application Requirements and APIs
- The process to access hardware register data will vary per user application.
- Therefore, this library will declare the hardware access [user APIs][], but
- each user application must implement the APIs for their own environment.
+ Therefore, this library will declare the hardware access [user APIs][], but each
+ user application must implement the APIs for their own environment.
- This library will not contain data regarding hardware specific information.
Instead, that information will be provided by the user application in the form
of the [Chip Data Files][].
- Tracing, or logging, methods will vary per user application. Therefore, this
- library will declare the tracing/logging [user APIs][], but each user
- application must implement the APIs for their own environment.
+ library will declare the tracing/logging [user APIs][], but each user application
+ must implement the APIs for their own environment.
## Environment configuration
diff --git a/src/chip_data/hei_chip_data.cpp b/src/chip_data/hei_chip_data.cpp
index c5506aa..b37eb58 100644
--- a/src/chip_data/hei_chip_data.cpp
+++ b/src/chip_data/hei_chip_data.cpp
@@ -18,6 +18,7 @@
constexpr Version_t VERSION_1 = 0x01;
constexpr Version_t VERSION_2 = 0x02;
+constexpr Version_t VERSION_3 = 0x03;
//------------------------------------------------------------------------------
@@ -251,6 +252,25 @@
Instance_t numInsts;
io_stream >> nodeId >> regType >> numInsts;
+ // Version 3 and above: Read any write operations that exist.
+ std::map<OpRuleName_t, std::pair<OpRuleType_t, RegisterId_t>> opRules;
+ if (VERSION_3 <= i_version)
+ {
+ uint8_t numOpRules;
+ io_stream >> numOpRules;
+ for (unsigned int i = 0; i < numOpRules; i++)
+ {
+ OpRuleName_t opName;
+ OpRuleType_t opType;
+ RegisterId_t regId;
+ io_stream >> opName >> opType >> regId;
+
+ std::pair<OpRuleType_t, RegisterId_t> tmpPair = {opType, regId};
+ auto ret = opRules.emplace(opName, tmpPair);
+ HEI_ASSERT(ret.second || ret.first->second == tmpPair);
+ }
+ }
+
for (unsigned int i = 0; i < numInsts; i++)
{
// Read the node instance metadata.
@@ -325,6 +345,16 @@
HEI_ASSERT(ret.second); // Should not have duplicate entries
}
+ // Version 3 and above: Add any write operations to the isoNode.
+ if (VERSION_3 <= i_version)
+ {
+ for (const auto& rule : opRules)
+ {
+ isoNode->addOpRule(rule.first, rule.second.first,
+ rule.second.second);
+ }
+ }
+
// Add this isolation node with the temporary child node map to the
// returned map of nodes.
auto ret = io_tmpNodeMap.emplace(IsolationNode::Key{nodeId, nodeInst},
@@ -397,7 +427,7 @@
HEI_ASSERT(io_isoChips.end() == io_isoChips.find(chipType));
// Check supported versions.
- HEI_ASSERT(VERSION_1 <= version && version <= VERSION_2);
+ HEI_ASSERT(VERSION_1 <= version && version <= VERSION_3);
// Allocate memory for the new isolation chip.
auto isoChip = std::make_shared<IsolationChip>(chipType);
diff --git a/src/hei_types.hpp b/src/hei_types.hpp
index 80f5ef8..dc88351 100644
--- a/src/hei_types.hpp
+++ b/src/hei_types.hpp
@@ -134,6 +134,32 @@
using RegisterAddress_t = uint64_t;
/**
+ * This is used to define the name of a write operation rule for a FIR,
+ * defined in the Chip Data Files.
+ *
+ * Values:
+ * This is a hashed value of one of the following string names:
+ * "FIR_SET", "FIR_CLEAR", "MASK_SET", "MASK_CLEAR".
+ *
+ * Range:
+ * This is defined as a 1-byte field in the Chip Data Files.
+ */
+using OpRuleName_t = uint8_t;
+
+/**
+ * This is used to define the type of a write operation rule for a FIR,
+ * defined in the Chip Data Files.
+ *
+ * Values:
+ * This is a hashed value of one of the following string names:
+ * "atomic_or", "atomic_and", "read_set_write", "read_clear_write".
+ *
+ * Range:
+ * This is defined as a 1-byte field in the Chip Data Files.
+ */
+using OpRuleType_t = uint8_t;
+
+/**
* The hardware register attribute flags.
*
* Values:
diff --git a/src/isolator/hei_isolation_node.cpp b/src/isolator/hei_isolation_node.cpp
index 78c5b65..d156015 100644
--- a/src/isolator/hei_isolation_node.cpp
+++ b/src/isolator/hei_isolation_node.cpp
@@ -145,6 +145,17 @@
//------------------------------------------------------------------------------
+void IsolationNode::addOpRule(OpRuleName_t i_opName, OpRuleType_t i_opType,
+ RegisterId_t i_regId)
+{
+ std::pair<OpRuleType_t, RegisterId_t> tmpPair = {i_opType, i_regId};
+ auto ret = iv_op_rules.emplace(i_opName, tmpPair);
+
+ HEI_ASSERT(ret.second || ret.first->second == tmpPair);
+}
+
+//------------------------------------------------------------------------------
+
std::vector<const IsolationNode*> IsolationNode::cv_isolationStack{};
//------------------------------------------------------------------------------
diff --git a/src/isolator/hei_isolation_node.hpp b/src/isolator/hei_isolation_node.hpp
index d88ad02..9043f1d 100644
--- a/src/isolator/hei_isolation_node.hpp
+++ b/src/isolator/hei_isolation_node.hpp
@@ -110,6 +110,12 @@
*/
std::map<BitPosition_t, const ConstPtr> iv_children;
+ /**
+ * This map is used to store the write operation rules for the isolation
+ * node as defined in the Chip Data Files.
+ */
+ std::map<OpRuleName_t, std::pair<OpRuleType_t, RegisterId_t>> iv_op_rules;
+
public: // Member functions
/**
* @brief Finds all active attentions on this node. If an active bit is a
@@ -151,8 +157,8 @@
* This is only intended to be used during initialization of the isolator.
* Will assert that a rule has not already been defined for this type.
*
- * @param The target attention type.
- * @param The rule for this attention type.
+ * @param i_attnType The target attention type.
+ * @param i_rule The rule for this attention type.
*/
void addRule(AttentionType_t i_attnType, Register::ConstPtr i_rule);
@@ -163,11 +169,24 @@
* This is only intended to be used during initialization of the isolator.
* Will assert that nothing has already been defined for this bit.
*
- * @param The target bit on this node.
- * @param The child node to analyze for the given bit.
+ * @param i_bit The target bit on this node.
+ * @param i_child The child node to analyze for the given bit.
*/
void addChild(BitPosition_t i_bit, ConstPtr i_child);
+ /**
+ * @brief Adds a new write operation for the isolation node.
+ *
+ * This is only intended to be used during initialization of the isolator.
+ * Will assert that nothing has already been defined for this type.
+ *
+ * @param i_opName The name of the operation.
+ * @param i_opType The type of the operation.
+ * @param i_regId The ID of the register to be written.
+ */
+ void addOpRule(OpRuleName_t i_opName, OpRuleType_t i_opType,
+ RegisterId_t i_regId);
+
/** @return The node ID. */
NodeId_t getId() const
{