blob: b30a67861bea8cd66ce5ad17f29cc0aa16ec12e5 [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 Shelley83da2452019-10-25 15:45:34 -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 Shelley83da2452019-10-25 15:45:34 -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 Shelley83da2452019-10-25 15:45:34 -050030 if (!bs->isBitSet(bit)) continue;
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050031
32 // At least one active bit was found.
33 o_activeAttn = true;
34
35 // Determine if this attention originated from another register or if it
36 // is a leaf in the isolation tree.
Zane Shelley83da2452019-10-25 15:45:34 -050037 auto child_itr = iv_children.find(bit);
38 if (iv_children.end() != child_itr)
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050039 {
40 // This bit was driven from an attention from another register.
41 // Continue down the isolation tree to look for more attentions.
Zane Shelley83da2452019-10-25 15:45:34 -050042 bool attnFound = child_itr->second->analyze(i_chip, i_attnType,
43 io_isoData);
44 if (!attnFound)
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050045 {
46 // Something went wrong. There should have been an active
47 // attention. It's possible there is a bug in the Chip Data
48 // File. Or, it is also possible some other piece of code is
49 // clearing the attention before this code is able to analyze
50 // it. Another possibility is that the hardware it not behaving
51 // as expected. Since we really don't know what happened, we
52 // should not assert. Instead, add this bit's signature to
53 // io_isoData. If there are no other active attentions, the user
54 // application could use this signature to help determine, and
55 // circumvent, the isolation problem.
Zane Shelley83da2452019-10-25 15:45:34 -050056 io_isoData.addSignature(Signature { i_chip, iv_hwReg.getId(),
57 iv_hwReg.getInstance(),
58 bit, i_attnType });
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050059 }
60 }
61 else
62 {
63 // We have reached a leaf in the isolation tree. Add this bit's
64 // signature to io_isoData.
Zane Shelley83da2452019-10-25 15:45:34 -050065 io_isoData.addSignature(Signature { i_chip, iv_hwReg.getId(),
66 iv_hwReg.getInstance(),
67 bit, i_attnType });
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050068 }
69 }
70
71 // Analysis is complete on this node. So remove it from cv_isolationStack.
72 popIsolationStack();
73
74 return o_activeAttn;
75}
76
77//------------------------------------------------------------------------------
78
Zane Shelley83da2452019-10-25 15:45:34 -050079void IsolationNode::addRule(AttentionType_t i_attnType, const Register * i_rule)
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050080{
81 // A rule for this attention type should not already exist.
Zane Shelley83da2452019-10-25 15:45:34 -050082 HEI_ASSERT(iv_rules.end() == iv_rules.find(i_attnType));
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050083
84 // The rule should not be null.
Zane Shelley83da2452019-10-25 15:45:34 -050085 HEI_ASSERT(nullptr != i_rule);
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050086
87 // Add the new rule.
88 iv_rules[i_attnType] = i_rule;
89}
90
91//------------------------------------------------------------------------------
92
Zane Shelley83da2452019-10-25 15:45:34 -050093void IsolationNode::addChild(uint8_t i_bit, const IsolationNode * i_child)
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050094{
95 // An entry for this bit should not already exist.
Zane Shelley83da2452019-10-25 15:45:34 -050096 HEI_ASSERT(iv_children.end() == iv_children.find(i_bit));
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050097
98 // The child register should not be null.
Zane Shelley83da2452019-10-25 15:45:34 -050099 HEI_ASSERT(nullptr != i_child);
Zane Shelley7bf1f6d2019-10-18 16:03:51 -0500100
101 // Add the new rule.
102 iv_children[i_bit] = i_child;
103}
104
105//------------------------------------------------------------------------------
106
107std::vector<const IsolationNode *> IsolationNode::cv_isolationStack {};
108
109//------------------------------------------------------------------------------
110
111void IsolationNode::pushIsolationStack() const
112{
113 // Ensure this node does not already exist in cv_isolationStack.
Zane Shelley83da2452019-10-25 15:45:34 -0500114 auto itr = std::find(cv_isolationStack.begin(),
115 cv_isolationStack.end(), this);
116 HEI_ASSERT(cv_isolationStack.end() == itr);
Zane Shelley7bf1f6d2019-10-18 16:03:51 -0500117
118 // Push to node to the stack.
Zane Shelley83da2452019-10-25 15:45:34 -0500119 cv_isolationStack.push_back(this);
Zane Shelley7bf1f6d2019-10-18 16:03:51 -0500120}
121
122//------------------------------------------------------------------------------
123
124} // end namespace libhei