Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 1 | #include <isolator/hei_isolation_node.hpp> |
| 2 | |
| 3 | namespace libhei |
| 4 | { |
| 5 | |
| 6 | //------------------------------------------------------------------------------ |
| 7 | |
Zane Shelley | fe27b65 | 2019-10-28 11:33:07 -0500 | [diff] [blame^] | 8 | bool IsolationNode::analyze(const Chip& i_chip, AttentionType_t i_attnType, |
| 9 | IsolationData& io_isoData) const |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 10 | { |
| 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 Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 17 | auto rule_itr = iv_rules.find(i_attnType); |
| 18 | HEI_ASSERT(iv_rules.end() != rule_itr); |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 19 | |
| 20 | // Get the returned BitString for this rule. |
Zane Shelley | fe27b65 | 2019-10-28 11:33:07 -0500 | [diff] [blame^] | 21 | const BitString* bs = rule_itr->second->getBitString(i_chip); |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 22 | |
| 23 | // Ensure this BitString is not longer than the maximum bit field. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 24 | HEI_ASSERT(bs->getBitLen() <= sizeof(RegisterBit_t) * 8); |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 25 | |
| 26 | // Find all active bits for this rule. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 27 | for (RegisterBit_t bit = 0; bit < bs->getBitLen(); bit++) |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 28 | { |
| 29 | // Continue to the next bit if not active. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 30 | if (!bs->isBitSet(bit)) continue; |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 31 | |
| 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 Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 37 | auto child_itr = iv_children.find(bit); |
| 38 | if (iv_children.end() != child_itr) |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 39 | { |
| 40 | // This bit was driven from an attention from another register. |
| 41 | // Continue down the isolation tree to look for more attentions. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 42 | bool attnFound = child_itr->second->analyze(i_chip, i_attnType, |
| 43 | io_isoData); |
| 44 | if (!attnFound) |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 45 | { |
| 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 Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 56 | io_isoData.addSignature(Signature { i_chip, iv_hwReg.getId(), |
| 57 | iv_hwReg.getInstance(), |
| 58 | bit, i_attnType }); |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 59 | } |
| 60 | } |
| 61 | else |
| 62 | { |
| 63 | // We have reached a leaf in the isolation tree. Add this bit's |
| 64 | // signature to io_isoData. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 65 | io_isoData.addSignature(Signature { i_chip, iv_hwReg.getId(), |
| 66 | iv_hwReg.getInstance(), |
| 67 | bit, i_attnType }); |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 68 | } |
| 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 Shelley | fe27b65 | 2019-10-28 11:33:07 -0500 | [diff] [blame^] | 79 | void IsolationNode::addRule(AttentionType_t i_attnType, const Register* i_rule) |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 80 | { |
| 81 | // A rule for this attention type should not already exist. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 82 | HEI_ASSERT(iv_rules.end() == iv_rules.find(i_attnType)); |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 83 | |
| 84 | // The rule should not be null. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 85 | HEI_ASSERT(nullptr != i_rule); |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 86 | |
| 87 | // Add the new rule. |
| 88 | iv_rules[i_attnType] = i_rule; |
| 89 | } |
| 90 | |
| 91 | //------------------------------------------------------------------------------ |
| 92 | |
Zane Shelley | fe27b65 | 2019-10-28 11:33:07 -0500 | [diff] [blame^] | 93 | void IsolationNode::addChild(uint8_t i_bit, const IsolationNode* i_child) |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 94 | { |
| 95 | // An entry for this bit should not already exist. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 96 | HEI_ASSERT(iv_children.end() == iv_children.find(i_bit)); |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 97 | |
| 98 | // The child register should not be null. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 99 | HEI_ASSERT(nullptr != i_child); |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 100 | |
| 101 | // Add the new rule. |
| 102 | iv_children[i_bit] = i_child; |
| 103 | } |
| 104 | |
| 105 | //------------------------------------------------------------------------------ |
| 106 | |
Zane Shelley | fe27b65 | 2019-10-28 11:33:07 -0500 | [diff] [blame^] | 107 | std::vector<const IsolationNode*> IsolationNode::cv_isolationStack {}; |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 108 | |
| 109 | //------------------------------------------------------------------------------ |
| 110 | |
| 111 | void IsolationNode::pushIsolationStack() const |
| 112 | { |
| 113 | // Ensure this node does not already exist in cv_isolationStack. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 114 | auto itr = std::find(cv_isolationStack.begin(), |
| 115 | cv_isolationStack.end(), this); |
| 116 | HEI_ASSERT(cv_isolationStack.end() == itr); |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 117 | |
| 118 | // Push to node to the stack. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 119 | cv_isolationStack.push_back(this); |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 120 | } |
| 121 | |
| 122 | //------------------------------------------------------------------------------ |
| 123 | |
| 124 | } // end namespace libhei |