blob: c95220713700fbf3e65221250cea1ae5317be51d [file] [log] [blame]
Zane Shelley7bf1f6d2019-10-18 16:03:51 -05001#include <isolator/hei_isolation_node.hpp>
Zane Shelley6722b5b2020-05-12 22:09:04 -05002#include <util/hei_bit_string.hpp>
Zane Shelley7bf1f6d2019-10-18 16:03:51 -05003
4namespace libhei
5{
6
7//------------------------------------------------------------------------------
8
Zane Shelleyfe27b652019-10-28 11:33:07 -05009bool IsolationNode::analyze(const Chip& i_chip, AttentionType_t i_attnType,
10 IsolationData& io_isoData) const
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050011{
12 bool o_activeAttn = false; // Initially, assume no active attentions.
13
14 // Keep track of nodes that have been analyzed to avoid cyclic isolation.
15 pushIsolationStack();
16
17 // A rule for i_attnType must exist.
Zane Shelley83da2452019-10-25 15:45:34 -050018 auto rule_itr = iv_rules.find(i_attnType);
19 HEI_ASSERT(iv_rules.end() != rule_itr);
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050020
21 // Get the returned BitString for this rule.
Zane Shelleyfe27b652019-10-28 11:33:07 -050022 const BitString* bs = rule_itr->second->getBitString(i_chip);
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050023
24 // Ensure this BitString is not longer than the maximum bit field.
Zane Shelley13b182b2020-05-07 20:23:45 -050025 HEI_ASSERT(bs->getBitLen() <= (1 << (sizeof(BitPosition_t) * 8)));
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050026
27 // Find all active bits for this rule.
Zane Shelley13b182b2020-05-07 20:23:45 -050028 for (BitPosition_t bit = 0; bit < bs->getBitLen(); bit++)
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050029 {
30 // Continue to the next bit if not active.
Zane Shelley7f7a42d2019-10-28 13:28:31 -050031 if (!bs->isBitSet(bit))
32 continue;
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050033
34 // At least one active bit was found.
35 o_activeAttn = true;
36
37 // Determine if this attention originated from another register or if it
38 // is a leaf in the isolation tree.
Zane Shelley83da2452019-10-25 15:45:34 -050039 auto child_itr = iv_children.find(bit);
40 if (iv_children.end() != child_itr)
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050041 {
42 // This bit was driven from an attention from another register.
43 // Continue down the isolation tree to look for more attentions.
Zane Shelley7f7a42d2019-10-28 13:28:31 -050044 bool attnFound =
45 child_itr->second->analyze(i_chip, i_attnType, io_isoData);
Zane Shelley83da2452019-10-25 15:45:34 -050046 if (!attnFound)
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050047 {
48 // Something went wrong. There should have been an active
49 // attention. It's possible there is a bug in the Chip Data
50 // File. Or, it is also possible some other piece of code is
51 // clearing the attention before this code is able to analyze
52 // it. Another possibility is that the hardware it not behaving
53 // as expected. Since we really don't know what happened, we
54 // should not assert. Instead, add this bit's signature to
55 // io_isoData. If there are no other active attentions, the user
56 // application could use this signature to help determine, and
57 // circumvent, the isolation problem.
Zane Shelley6722b5b2020-05-12 22:09:04 -050058 io_isoData.addSignature(
59 Signature{i_chip, iv_id, iv_instance, 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 Shelley6722b5b2020-05-12 22:09:04 -050066 io_isoData.addSignature(
67 Signature{i_chip, iv_id, iv_instance, 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 Shelley4de8ff82020-05-14 15:39:01 -050079void IsolationNode::addRule(AttentionType_t i_attnType,
80 Register::ConstPtr i_rule)
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050081{
Zane Shelley6722b5b2020-05-12 22:09:04 -050082 HEI_ASSERT(i_rule); // should not be null
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050083
Zane Shelley6722b5b2020-05-12 22:09:04 -050084 auto ret = iv_rules.emplace(i_attnType, i_rule);
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050085
Zane Shelley6722b5b2020-05-12 22:09:04 -050086 // If an entry already existed, it must point to the same object.
87 HEI_ASSERT(ret.second || (ret.first->second == i_rule));
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050088}
89
90//------------------------------------------------------------------------------
91
Zane Shelley4de8ff82020-05-14 15:39:01 -050092void IsolationNode::addChild(uint8_t i_bit, ConstPtr i_child)
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050093{
Zane Shelley6722b5b2020-05-12 22:09:04 -050094 HEI_ASSERT(i_child); // should not be null
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050095
Zane Shelley6722b5b2020-05-12 22:09:04 -050096 auto ret = iv_children.emplace(i_bit, i_child);
Zane Shelley7bf1f6d2019-10-18 16:03:51 -050097
Zane Shelley6722b5b2020-05-12 22:09:04 -050098 // If an entry already existed, it must point to the same object.
99 HEI_ASSERT(ret.second || (ret.first->second == i_child));
Zane Shelley7bf1f6d2019-10-18 16:03:51 -0500100}
101
102//------------------------------------------------------------------------------
103
Zane Shelley4de8ff82020-05-14 15:39:01 -0500104std::vector<IsolationNode::ConstPtr> IsolationNode::cv_isolationStack{};
Zane Shelley7bf1f6d2019-10-18 16:03:51 -0500105
106//------------------------------------------------------------------------------
107
108void IsolationNode::pushIsolationStack() const
109{
110 // Ensure this node does not already exist in cv_isolationStack.
Zane Shelley6722b5b2020-05-12 22:09:04 -0500111 auto itr = std::find(cv_isolationStack.begin(), cv_isolationStack.end(),
Zane Shelley4de8ff82020-05-14 15:39:01 -0500112 ConstPtr(this));
Zane Shelley83da2452019-10-25 15:45:34 -0500113 HEI_ASSERT(cv_isolationStack.end() == itr);
Zane Shelley7bf1f6d2019-10-18 16:03:51 -0500114
115 // Push to node to the stack.
Zane Shelley4de8ff82020-05-14 15:39:01 -0500116 cv_isolationStack.push_back(ConstPtr(this));
Zane Shelley7bf1f6d2019-10-18 16:03:51 -0500117}
118
119//------------------------------------------------------------------------------
120
121} // end namespace libhei