Add capture regs from Chip Data File to IsolationNode
Change-Id: Ia91821f2b14e12ed917c97b622789710ffb8bdb4
Signed-off-by: Zane Shelley <zshelle@us.ibm.com>
diff --git a/src/chip_data/hei_chip_data.cpp b/src/chip_data/hei_chip_data.cpp
index 87044db..752014b 100644
--- a/src/chip_data/hei_chip_data.cpp
+++ b/src/chip_data/hei_chip_data.cpp
@@ -75,7 +75,8 @@
//------------------------------------------------------------------------------
-void __readExpr(ChipDataStream& io_stream, RegisterType_t i_regType)
+void __readExpr(ChipDataStream& io_stream, const IsolationChip::Ptr& i_isoChip,
+ IsolationNode::Ptr& io_isoNode)
{
uint8_t exprType;
io_stream >> exprType;
@@ -86,11 +87,23 @@
RegisterId_t regId;
Instance_t regInst;
io_stream >> regId >> regInst;
+
+ // Find the hardware register that is stored in this isolation chip
+ // and add it to the list of capture registers. This ensures all
+ // registers referenced in the rules are are captured by default.
+ // 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.
+ io_isoNode->addCaptureRegister(hwReg);
+
break;
}
case 0x02: // integer constant
{
- if (REG_TYPE_SCOM == i_regType || REG_TYPE_ID_SCOM == i_regType)
+ if (REG_TYPE_SCOM == io_isoNode->getRegisterType() ||
+ REG_TYPE_ID_SCOM == io_isoNode->getRegisterType())
{
uint64_t constant; // 8-byte value
io_stream >> constant;
@@ -107,7 +120,7 @@
io_stream >> numSubExpr;
for (uint8_t i = 0; i < numSubExpr; i++)
{
- __readExpr(io_stream, i_regType);
+ __readExpr(io_stream, i_isoChip, io_isoNode);
}
break;
}
@@ -117,27 +130,27 @@
io_stream >> numSubExpr;
for (uint8_t i = 0; i < numSubExpr; i++)
{
- __readExpr(io_stream, i_regType);
+ __readExpr(io_stream, i_isoChip, io_isoNode);
}
break;
}
case 0x12: // NOT operation
{
- __readExpr(io_stream, i_regType);
+ __readExpr(io_stream, i_isoChip, io_isoNode);
break;
}
case 0x13: // left shift operation
{
uint8_t shiftValue;
io_stream >> shiftValue;
- __readExpr(io_stream, i_regType);
+ __readExpr(io_stream, i_isoChip, io_isoNode);
break;
}
case 0x14: // right shift operation
{
uint8_t shiftValue;
io_stream >> shiftValue;
- __readExpr(io_stream, i_regType);
+ __readExpr(io_stream, i_isoChip, io_isoNode);
break;
}
default:
@@ -162,30 +175,51 @@
uint8_t numCapRegs, numIsoRules, numChildNodes;
io_stream >> nodeInst >> numCapRegs >> numIsoRules >> numChildNodes;
+ // There must be at least one isolation rule defined.
+ HEI_ASSERT(0 != numIsoRules);
+
+ // Allocate memory for this isolation node.
+ auto isoNode =
+ std::make_shared<IsolationNode>(nodeId, nodeInst, regType);
+
// Add capture registers.
for (unsigned int j = 0; j < numCapRegs; j++)
{
+ // Read the capture register metadata.
RegisterId_t regId;
Instance_t regInst;
io_stream >> regId >> regInst;
+
+ // 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 = io_isoChip->getHardwareRegister({regId, regInst});
+
+ // Add the register to the isolation node.
+ isoNode->addCaptureRegister(hwReg);
}
// Add isolation rules.
for (unsigned int j = 0; j < numIsoRules; j++)
{
+ // Read the rule metadata.
AttentionType_t attnType;
io_stream >> attnType;
- __readExpr(io_stream, regType);
+ __readExpr(io_stream, io_isoChip, isoNode);
}
// Add child nodes.
for (unsigned int j = 0; j < numChildNodes; j++)
{
+ // Read the child node metadata.
BitPosition_t bit;
NodeId_t childId;
Instance_t childInst;
io_stream >> bit >> childId >> childInst;
}
+
+ // Add this node to the isolation chip.
+ io_isoChip->addIsolationNode(isoNode);
}
}
diff --git a/src/isolator/hei_isolation_node.hpp b/src/isolator/hei_isolation_node.hpp
index 2546a93..33df441 100644
--- a/src/isolator/hei_isolation_node.hpp
+++ b/src/isolator/hei_isolation_node.hpp
@@ -51,8 +51,10 @@
* @param i_id Unique ID for all instances of this node.
* @param i_instance Instance of this node.
*/
- IsolationNode(NodeId_t i_id, Instance_t i_instance) :
- iv_id(i_id), iv_instance(i_instance)
+ IsolationNode(NodeId_t i_id, Instance_t i_instance,
+ RegisterType_t i_regType) :
+ iv_id(i_id),
+ iv_instance(i_instance), iv_regType(i_regType)
{}
/** @brief Destructor. */
@@ -75,6 +77,14 @@
const Instance_t iv_instance;
/**
+ * A registers referenced by this node's rules must be of this type. No
+ * mixing of register types is allowed because comparing different sized
+ * registers is undefined behavior. Note that it is possible to have capture
+ * registers of mixed types.
+ */
+ const RegisterType_t iv_regType;
+
+ /**
* The list of register to capture and add to the log for additional
* debugging.
*/
@@ -85,7 +95,8 @@
* register 'rule' (value) to find any active attentions for each attention
* type (key). A 'rule', like "register & ~mask", is a combination of
* HardwareRegister objects and virtual operator registers (all children
- * of the Register class).
+ * of the Register class). Note that all registers referenced by these rules
+ * must be the same type as iv_regType.
*/
std::map<AttentionType_t, const Register::ConstPtr> iv_rules;
@@ -166,6 +177,12 @@
return {iv_id, iv_instance};
}
+ /** @return This node's register type.. */
+ RegisterType_t getRegisterType() const
+ {
+ return iv_regType;
+ }
+
private: // Isolation stack and supporting functions.
/** When analyze() is called at the tree root, all recursive calls to
* analyze() will target the same chip and attention type. So we only need
diff --git a/src/register/hei_operator_register.hpp b/src/register/hei_operator_register.hpp
index 6bfaca9..5c225b1 100644
--- a/src/register/hei_operator_register.hpp
+++ b/src/register/hei_operator_register.hpp
@@ -72,18 +72,18 @@
* @brief Constructor from components.
* @param i_arg Target register for operation.
*/
- explicit NotRegister(Register& i_arg) :
- OperatorRegister(i_arg.getSize()), iv_child(&i_arg)
+ explicit NotRegister(Register::ConstPtr i_arg) :
+ OperatorRegister(i_arg->getSize()), iv_child(i_arg)
{}
- /** @brief Default destructor. */
+ /** @brief Destructor. */
~NotRegister() = default;
- /** @brief Default copy constructor. */
- NotRegister(const NotRegister&) = default;
+ /** @brief Copy constructor. */
+ NotRegister(const NotRegister&) = delete;
- /** @brief Default assignment operator. */
- NotRegister& operator=(const NotRegister& r) = default;
+ /** @brief Assignment operator. */
+ NotRegister& operator=(const NotRegister& r) = delete;
/** @brief Overloaded from parent class. */
const BitString* getBitString(const Chip& i_chip) const override
@@ -108,7 +108,7 @@
}
private:
- Register* iv_child;
+ const Register::ConstPtr iv_child;
};
/**
@@ -126,18 +126,18 @@
* @param i_arg Target register for operation.
* @param i_amount The shift value.
*/
- LeftShiftRegister(Register& i_arg, uint16_t i_amount) :
- OperatorRegister(i_arg.getSize()), iv_child(&i_arg), iv_amount(i_amount)
+ LeftShiftRegister(Register::ConstPtr i_arg, size_t i_amount) :
+ OperatorRegister(i_arg->getSize()), iv_child(i_arg), iv_amount(i_amount)
{}
- /** @brief Default destructor. */
+ /** @brief Destructor. */
~LeftShiftRegister() = default;
- /** @brief Default copy constructor. */
- LeftShiftRegister(const LeftShiftRegister&) = default;
+ /** @brief Copy constructor. */
+ LeftShiftRegister(const LeftShiftRegister&) = delete;
- /** @brief Default assignment operator. */
- LeftShiftRegister& operator=(const LeftShiftRegister& r) = default;
+ /** @brief Assignment operator. */
+ LeftShiftRegister& operator=(const LeftShiftRegister& r) = delete;
/** @brief Overloaded from parent class. */
const BitString* getBitString(const Chip& i_chip) const override
@@ -164,8 +164,8 @@
}
private:
- Register* iv_child;
- uint16_t iv_amount;
+ const Register::ConstPtr iv_child;
+ const size_t iv_amount;
};
/**
@@ -183,18 +183,18 @@
* @param i_arg Target register for operation.
* @param i_amount The shift value.
*/
- RightShiftRegister(Register& i_arg, uint16_t i_amount) :
- OperatorRegister(i_arg.getSize()), iv_child(&i_arg), iv_amount(i_amount)
+ RightShiftRegister(Register::ConstPtr i_arg, size_t i_amount) :
+ OperatorRegister(i_arg->getSize()), iv_child(i_arg), iv_amount(i_amount)
{}
- /** @brief Default destructor. */
+ /** @brief Destructor. */
~RightShiftRegister() = default;
- /** @brief Default copy constructor. */
- RightShiftRegister(const RightShiftRegister&) = default;
+ /** @brief Copy constructor. */
+ RightShiftRegister(const RightShiftRegister&) = delete;
- /** @brief Default assignment operator. */
- RightShiftRegister& operator=(const RightShiftRegister& r) = default;
+ /** @brief Assignment operator. */
+ RightShiftRegister& operator=(const RightShiftRegister& r) = delete;
/** @brief Overloaded from parent class. */
const BitString* getBitString(const Chip& i_chip) const override
@@ -221,8 +221,8 @@
}
private:
- Register* iv_child;
- uint16_t iv_amount;
+ const Register::ConstPtr iv_child;
+ const size_t iv_amount;
};
/**
@@ -241,19 +241,22 @@
* @param i_left Target register for operation.
* @param i_right Target register for operation.
*/
- AndRegister(Register& i_left, Register& i_right) :
- OperatorRegister(std::min(i_left.getSize(), i_right.getSize())),
- iv_left(&i_left), iv_right(&i_right)
- {}
+ AndRegister(Register::ConstPtr i_left, Register::ConstPtr i_right) :
+ OperatorRegister(i_left->getSize()), iv_left(i_left), iv_right(i_right)
+ {
+ // The two registers must be the same sizes or it makes for some weird
+ // results.
+ HEI_ASSERT(iv_left->getSize() == iv_right->getSize());
+ }
- /** @brief Default destructor. */
+ /** @brief Destructor. */
~AndRegister() = default;
- /** @brief Default copy constructor. */
- AndRegister(const AndRegister&) = default;
+ /** @brief Copy constructor. */
+ AndRegister(const AndRegister&) = delete;
- /** @brief Default assignment operator. */
- AndRegister& operator=(const AndRegister& r) = default;
+ /** @brief Assignment operator. */
+ AndRegister& operator=(const AndRegister& r) = delete;
/** @brief Overloaded from parent class. */
const BitString* getBitString(const Chip& i_chip) const override
@@ -281,8 +284,8 @@
}
private:
- Register* iv_left;
- Register* iv_right;
+ const Register::ConstPtr iv_left;
+ const Register::ConstPtr iv_right;
};
/**
@@ -301,19 +304,22 @@
* @param i_left Target register for operation.
* @param i_right Target register for operation.
*/
- OrRegister(Register& i_left, Register& i_right) :
- OperatorRegister(std::min(i_left.getSize(), i_right.getSize())),
- iv_left(&i_left), iv_right(&i_right)
- {}
+ OrRegister(Register::ConstPtr i_left, Register::ConstPtr i_right) :
+ OperatorRegister(i_left->getSize()), iv_left(i_left), iv_right(i_right)
+ {
+ // The two registers must be the same sizes or it makes for some weird
+ // results.
+ HEI_ASSERT(iv_left->getSize() == iv_right->getSize());
+ }
- /** @brief Default destructor. */
+ /** @brief Destructor. */
~OrRegister() = default;
- /** @brief Default copy constructor. */
- OrRegister(const OrRegister&) = default;
+ /** @brief Copy constructor. */
+ OrRegister(const OrRegister&) = delete;
- /** @brief Default assignment operator. */
- OrRegister& operator=(const OrRegister& r) = default;
+ /** @brief Assignment operator. */
+ OrRegister& operator=(const OrRegister& r) = delete;
/** @brief Overloaded from parent class. */
const BitString* getBitString(const Chip& i_chip) const override
@@ -341,36 +347,38 @@
}
private:
- Register* iv_left;
- Register* iv_right;
+ const Register::ConstPtr iv_left;
+ const Register::ConstPtr iv_right;
};
/**
* @brief Contains a constant value that can be used within any of the other
* register operators. The value can be retrieved using the
* getBitString() function.
- **/
+ */
class ConstantRegister : public OperatorRegister
{
public:
/**
* @brief Constructor from components.
- * @param i_arg A BitStringBuffer containing the constant value.
+ * @param i_val An unsigned integer value. iv_result will be initialized to
+ * the size of type T and this value will be copied into that
+ * buffer.
*/
- explicit ConstantRegister(const BitStringBuffer& i_arg) :
- OperatorRegister(BitString::getMinBytes(i_arg.getBitLen()))
+ template <class T>
+ explicit ConstantRegister(T i_val) : OperatorRegister(sizeof(i_val))
{
- iv_result = i_arg;
+ iv_result.setFieldRight(0, iv_result.getBitLen(), i_val);
}
- /** @brief Default destructor. */
+ /** @brief Destructor. */
~ConstantRegister() = default;
- /** @brief Default copy constructor. */
- ConstantRegister(const ConstantRegister&) = default;
+ /** @brief Copy constructor. */
+ ConstantRegister(const ConstantRegister&) = delete;
- /** @brief Default assignment operator. */
- ConstantRegister& operator=(const ConstantRegister& r) = default;
+ /** @brief Assignment operator. */
+ ConstantRegister& operator=(const ConstantRegister& r) = delete;
/** @brief Overloaded from parent class. */
const BitString* getBitString(const Chip& i_chip) const override
diff --git a/src/util/hei_bit_string.cpp b/src/util/hei_bit_string.cpp
index 9cc2613..a04fb43 100644
--- a/src/util/hei_bit_string.cpp
+++ b/src/util/hei_bit_string.cpp
@@ -286,25 +286,29 @@
bool BitString::operator<(const BitString& i_str) const
{
- // The two bit strings must be the same length. Otherwise, the comparison
- // undefined (i.e. compare from the left vs. right).
- HEI_ASSERT(getBitLen() == i_str.getBitLen());
-
- for (uint64_t pos = 0; pos < getBitLen(); pos += UINT64_BIT_LEN)
+ if (getBitLen() < i_str.getBitLen())
{
- uint64_t len = std::min(getBitLen() - pos, UINT64_BIT_LEN);
-
- auto l_str = getFieldRight(pos, len);
- auto r_str = i_str.getFieldRight(pos, len);
-
- if (l_str < r_str)
+ return true;
+ }
+ else if (getBitLen() == i_str.getBitLen())
+ {
+ // Can only compare the bit strings if the length is the same.
+ for (uint64_t pos = 0; pos < getBitLen(); pos += UINT64_BIT_LEN)
{
- return true;
- }
- // The loop can only continue if the values are equal.
- else if (l_str > r_str)
- {
- return false;
+ uint64_t len = std::min(getBitLen() - pos, UINT64_BIT_LEN);
+
+ auto l_str = getFieldRight(pos, len);
+ auto r_str = i_str.getFieldRight(pos, len);
+
+ if (l_str < r_str)
+ {
+ return true;
+ }
+ // The loop can only continue if the values are equal.
+ else if (l_str > r_str)
+ {
+ return false;
+ }
}
}
diff --git a/src/util/hei_bit_string.hpp b/src/util/hei_bit_string.hpp
index 669e755..59369b7 100644
--- a/src/util/hei_bit_string.hpp
+++ b/src/util/hei_bit_string.hpp
@@ -333,7 +333,15 @@
return isEqual(i_str);
}
- /** @brief Less-than operator */
+ /**
+ * @brief Less-than operator.
+ *
+ * IMPORTANT:
+ * The purpose of this function is primarily for sorting these objects in
+ * data structures like map and vector. It does not guarantee a less than
+ * comparison of the bit strings because bit strings can vary in length and
+ * it is difficult to define that kind of comparison.
+ */
bool operator<(const BitString& i_str) const;
/** @brief Bitwise NOT operator. */