blob: 7d52344778576cd51aa96fd20fcf3241790cb325 [file] [log] [blame]
Zane Shelley7bf1f6d2019-10-18 16:03:51 -05001#include <isolator/hei_isolation_node.hpp>
2
3namespace libhei
4{
5
6//------------------------------------------------------------------------------
7
Zane Shelleyfe27b652019-10-28 11:33:07 -05008bool IsolationNode::analyze(const Chip& i_chip, AttentionType_t i_attnType,
9 IsolationData& io_isoData) const
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050010{
11 bool o_activeAttn = false; // Initially, assume no active attentions.
12
13 // Keep track of nodes that have been analyzed to avoid cyclic isolation.
14 pushIsolationStack();
15
16 // A rule for i_attnType must exist.
Zane Shelley83da2452019-10-25 15:45:34 -050017 auto rule_itr = iv_rules.find(i_attnType);
18 HEI_ASSERT(iv_rules.end() != rule_itr);
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050019
20 // Get the returned BitString for this rule.
Zane Shelleyfe27b652019-10-28 11:33:07 -050021 const BitString* bs = rule_itr->second->getBitString(i_chip);
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050022
23 // Ensure this BitString is not longer than the maximum bit field.
Zane Shelley83da2452019-10-25 15:45:34 -050024 HEI_ASSERT(bs->getBitLen() <= sizeof(RegisterBit_t) * 8);
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050025
26 // Find all active bits for this rule.
Zane Shelley83da2452019-10-25 15:45:34 -050027 for (RegisterBit_t bit = 0; bit < bs->getBitLen(); bit++)
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050028 {
29 // Continue to the next bit if not active.
Zane Shelley7f7a42d2019-10-28 13:28:31 -050030 if (!bs->isBitSet(bit))
31 continue;
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050032
33 // At least one active bit was found.
34 o_activeAttn = true;
35
36 // Determine if this attention originated from another register or if it
37 // is a leaf in the isolation tree.
Zane Shelley83da2452019-10-25 15:45:34 -050038 auto child_itr = iv_children.find(bit);
39 if (iv_children.end() != child_itr)
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050040 {
41 // This bit was driven from an attention from another register.
42 // Continue down the isolation tree to look for more attentions.
Zane Shelley7f7a42d2019-10-28 13:28:31 -050043 bool attnFound =
44 child_itr->second->analyze(i_chip, i_attnType, io_isoData);
Zane Shelley83da2452019-10-25 15:45:34 -050045 if (!attnFound)
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050046 {
47 // Something went wrong. There should have been an active
48 // attention. It's possible there is a bug in the Chip Data
49 // File. Or, it is also possible some other piece of code is
50 // clearing the attention before this code is able to analyze
51 // it. Another possibility is that the hardware it not behaving
52 // as expected. Since we really don't know what happened, we
53 // should not assert. Instead, add this bit's signature to
54 // io_isoData. If there are no other active attentions, the user
55 // application could use this signature to help determine, and
56 // circumvent, the isolation problem.
Zane Shelley83da2452019-10-25 15:45:34 -050057 io_isoData.addSignature(Signature { i_chip, iv_hwReg.getId(),
58 iv_hwReg.getInstance(),
59 bit, i_attnType });
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050060 }
61 }
62 else
63 {
64 // We have reached a leaf in the isolation tree. Add this bit's
65 // signature to io_isoData.
Zane Shelley83da2452019-10-25 15:45:34 -050066 io_isoData.addSignature(Signature { i_chip, iv_hwReg.getId(),
67 iv_hwReg.getInstance(),
68 bit, i_attnType });
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050069 }
70 }
71
72 // Analysis is complete on this node. So remove it from cv_isolationStack.
73 popIsolationStack();
74
75 return o_activeAttn;
76}
77
78//------------------------------------------------------------------------------
79
Zane Shelleyfe27b652019-10-28 11:33:07 -050080void IsolationNode::addRule(AttentionType_t i_attnType, const Register* i_rule)
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050081{
82 // A rule for this attention type should not already exist.
Zane Shelley83da2452019-10-25 15:45:34 -050083 HEI_ASSERT(iv_rules.end() == iv_rules.find(i_attnType));
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050084
85 // The rule should not be null.
Zane Shelley83da2452019-10-25 15:45:34 -050086 HEI_ASSERT(nullptr != i_rule);
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050087
88 // Add the new rule.
89 iv_rules[i_attnType] = i_rule;
90}
91
92//------------------------------------------------------------------------------
93
Zane Shelleyfe27b652019-10-28 11:33:07 -050094void IsolationNode::addChild(uint8_t i_bit, const IsolationNode* i_child)
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050095{
96 // An entry for this bit should not already exist.
Zane Shelley83da2452019-10-25 15:45:34 -050097 HEI_ASSERT(iv_children.end() == iv_children.find(i_bit));
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050098
99 // The child register should not be null.
Zane Shelley83da2452019-10-25 15:45:34 -0500100 HEI_ASSERT(nullptr != i_child);
Zane Shelley7bf1f6d2019-10-18 16:03:51 -0500101
102 // Add the new rule.
103 iv_children[i_bit] = i_child;
104}
105
106//------------------------------------------------------------------------------
107
Zane Shelleyfe27b652019-10-28 11:33:07 -0500108std::vector<const IsolationNode*> IsolationNode::cv_isolationStack {};
Zane Shelley7bf1f6d2019-10-18 16:03:51 -0500109
110//------------------------------------------------------------------------------
111
112void IsolationNode::pushIsolationStack() const
113{
114 // Ensure this node does not already exist in cv_isolationStack.
Zane Shelley7f7a42d2019-10-28 13:28:31 -0500115 auto itr =
116 std::find(cv_isolationStack.begin(), cv_isolationStack.end(), this);
Zane Shelley83da2452019-10-25 15:45:34 -0500117 HEI_ASSERT(cv_isolationStack.end() == itr);
Zane Shelley7bf1f6d2019-10-18 16:03:51 -0500118
119 // Push to node to the stack.
Zane Shelley83da2452019-10-25 15:45:34 -0500120 cv_isolationStack.push_back(this);
Zane Shelley7bf1f6d2019-10-18 16:03:51 -0500121}
122
123//------------------------------------------------------------------------------
124
125} // end namespace libhei