Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 1 | #include <isolator/hei_isolation_node.hpp> |
Zane Shelley | 995be6c | 2021-02-24 15:48:55 -0600 | [diff] [blame] | 2 | #include <util/hei_bit_string.hpp> |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 3 | |
| 4 | namespace libhei |
| 5 | { |
| 6 | |
| 7 | //------------------------------------------------------------------------------ |
| 8 | |
Zane Shelley | fe27b65 | 2019-10-28 11:33:07 -0500 | [diff] [blame] | 9 | bool IsolationNode::analyze(const Chip& i_chip, AttentionType_t i_attnType, |
| 10 | IsolationData& io_isoData) const |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 11 | { |
| 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 | |
Zane Shelley | 6b1fe16 | 2022-11-18 13:37:42 -0600 | [diff] [blame] | 17 | // Capture default set of registers for this node. |
| 18 | captureRegisters(i_chip, io_isoData); |
Zane Shelley | e8dc72c | 2020-05-14 16:40:52 -0500 | [diff] [blame] | 19 | |
Zane Shelley | bcb4395 | 2021-07-08 22:13:57 -0500 | [diff] [blame] | 20 | // Get the rule for this attention type. |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 21 | auto rule_itr = iv_rules.find(i_attnType); |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 22 | |
Zane Shelley | bcb4395 | 2021-07-08 22:13:57 -0500 | [diff] [blame] | 23 | // It is possible that a rule does not exist. The likely scenario is that |
| 24 | // this node is intended to only gather FFDC for a specific bit in the |
| 25 | // parent node. |
| 26 | if (iv_rules.end() != rule_itr) |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 27 | { |
Zane Shelley | bcb4395 | 2021-07-08 22:13:57 -0500 | [diff] [blame] | 28 | // Get the returned BitString for this rule. |
| 29 | const BitString* bs = rule_itr->second->getBitString(i_chip); |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 30 | |
Zane Shelley | bcb4395 | 2021-07-08 22:13:57 -0500 | [diff] [blame] | 31 | // Ensure this BitString is not longer than the maximum bit field. |
| 32 | HEI_ASSERT(bs->getBitLen() <= (1 << (sizeof(BitPosition_t) * 8))); |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 33 | |
Zane Shelley | bcb4395 | 2021-07-08 22:13:57 -0500 | [diff] [blame] | 34 | // Find all active bits for this rule. |
| 35 | for (BitPosition_t bit = 0; bit < bs->getBitLen(); bit++) |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 36 | { |
Zane Shelley | bcb4395 | 2021-07-08 22:13:57 -0500 | [diff] [blame] | 37 | // Continue to the next bit if not active. |
| 38 | if (!bs->isBitSet(bit)) |
| 39 | continue; |
| 40 | |
| 41 | // At least one active bit was found. |
| 42 | o_activeAttn = true; |
| 43 | |
Zane Shelley | 6b1fe16 | 2022-11-18 13:37:42 -0600 | [diff] [blame] | 44 | // Capture registers specific to this isolation bit. |
| 45 | captureRegisters(i_chip, io_isoData, bit); |
| 46 | |
Zane Shelley | bcb4395 | 2021-07-08 22:13:57 -0500 | [diff] [blame] | 47 | // Determine if this attention originated from another register or |
| 48 | // if it is a leaf in the isolation tree. |
| 49 | auto child_itr = iv_children.find(bit); |
| 50 | if (iv_children.end() != child_itr) |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 51 | { |
Zane Shelley | bcb4395 | 2021-07-08 22:13:57 -0500 | [diff] [blame] | 52 | // This bit was driven from an attention from another register. |
| 53 | // Continue down the isolation tree to look for more attentions. |
Patrick Williams | 2f7537d | 2023-05-10 07:51:39 -0500 | [diff] [blame] | 54 | bool attnFound = child_itr->second->analyze(i_chip, i_attnType, |
| 55 | io_isoData); |
Zane Shelley | bcb4395 | 2021-07-08 22:13:57 -0500 | [diff] [blame] | 56 | if (!attnFound) |
| 57 | { |
| 58 | // It is possible the child node is only intended for FFDC. |
| 59 | // See comment near the check for a valid rule above. |
| 60 | // Otherwise, it is possible something went wrong. If there |
| 61 | // should have been an active attention, it's possible there |
| 62 | // is a bug in the Chip Data File. Or, it is also possible |
| 63 | // some other piece of code is clearing the attention before |
| 64 | // this code is able to analyze it. Another possibility is |
| 65 | // that the hardware it not behaving as expected. Since we |
| 66 | // really don't know what happened, we should not assert. |
| 67 | // Instead, add this bit's signature to io_isoData. If there |
| 68 | // are no other active attentions, the user application |
| 69 | // could use this signature to help determine, and |
| 70 | // circumvent, the isolation problem. |
| 71 | io_isoData.addSignature( |
| 72 | Signature{i_chip, iv_id, iv_instance, bit, i_attnType}); |
| 73 | } |
| 74 | } |
| 75 | else |
| 76 | { |
| 77 | // We have reached a leaf in the isolation tree. Add this bit's |
| 78 | // signature to io_isoData. |
Zane Shelley | 6722b5b | 2020-05-12 22:09:04 -0500 | [diff] [blame] | 79 | io_isoData.addSignature( |
| 80 | Signature{i_chip, iv_id, iv_instance, bit, i_attnType}); |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 81 | } |
| 82 | } |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 83 | } |
| 84 | |
| 85 | // Analysis is complete on this node. So remove it from cv_isolationStack. |
| 86 | popIsolationStack(); |
| 87 | |
| 88 | return o_activeAttn; |
| 89 | } |
| 90 | |
| 91 | //------------------------------------------------------------------------------ |
| 92 | |
Zane Shelley | 6b1fe16 | 2022-11-18 13:37:42 -0600 | [diff] [blame] | 93 | void IsolationNode::addCaptureRegister(HardwareRegister::ConstPtr i_hwReg, |
| 94 | BitPosition_t i_bit) |
Zane Shelley | e8dc72c | 2020-05-14 16:40:52 -0500 | [diff] [blame] | 95 | { |
| 96 | HEI_ASSERT(i_hwReg); // should not be null |
| 97 | |
Zane Shelley | 6b1fe16 | 2022-11-18 13:37:42 -0600 | [diff] [blame] | 98 | // Check the bit range. |
| 99 | if (MAX_BIT_POSITION != i_bit) |
Zane Shelley | e8dc72c | 2020-05-14 16:40:52 -0500 | [diff] [blame] | 100 | { |
Zane Shelley | 6b1fe16 | 2022-11-18 13:37:42 -0600 | [diff] [blame] | 101 | if (REG_TYPE_SCOM == iv_regType || REG_TYPE_ID_SCOM == iv_regType) |
| 102 | { |
| 103 | HEI_ASSERT(i_bit < 64); |
| 104 | } |
| 105 | else |
| 106 | { |
| 107 | HEI_ASSERT(false); // register type unsupported |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | // Add this capture register only if it does not already exist in the list. |
| 112 | auto itr = iv_capRegs.find(i_bit); |
| 113 | if (iv_capRegs.end() == itr || |
| 114 | itr->second.end() == |
| 115 | std::find(itr->second.begin(), itr->second.end(), i_hwReg)) |
| 116 | { |
| 117 | iv_capRegs[i_bit].push_back(i_hwReg); |
Zane Shelley | e8dc72c | 2020-05-14 16:40:52 -0500 | [diff] [blame] | 118 | } |
| 119 | } |
| 120 | |
| 121 | //------------------------------------------------------------------------------ |
| 122 | |
Zane Shelley | 4de8ff8 | 2020-05-14 15:39:01 -0500 | [diff] [blame] | 123 | void IsolationNode::addRule(AttentionType_t i_attnType, |
| 124 | Register::ConstPtr i_rule) |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 125 | { |
Zane Shelley | 6722b5b | 2020-05-12 22:09:04 -0500 | [diff] [blame] | 126 | HEI_ASSERT(i_rule); // should not be null |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 127 | |
Zane Shelley | 6722b5b | 2020-05-12 22:09:04 -0500 | [diff] [blame] | 128 | auto ret = iv_rules.emplace(i_attnType, i_rule); |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 129 | |
Zane Shelley | 6722b5b | 2020-05-12 22:09:04 -0500 | [diff] [blame] | 130 | // If an entry already existed, it must point to the same object. |
| 131 | HEI_ASSERT(ret.second || (ret.first->second == i_rule)); |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 132 | } |
| 133 | |
| 134 | //------------------------------------------------------------------------------ |
| 135 | |
Zane Shelley | 4de8ff8 | 2020-05-14 15:39:01 -0500 | [diff] [blame] | 136 | void IsolationNode::addChild(uint8_t i_bit, ConstPtr i_child) |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 137 | { |
Zane Shelley | 6722b5b | 2020-05-12 22:09:04 -0500 | [diff] [blame] | 138 | HEI_ASSERT(i_child); // should not be null |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 139 | |
Zane Shelley | 6722b5b | 2020-05-12 22:09:04 -0500 | [diff] [blame] | 140 | auto ret = iv_children.emplace(i_bit, i_child); |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 141 | |
Zane Shelley | 6722b5b | 2020-05-12 22:09:04 -0500 | [diff] [blame] | 142 | // If an entry already existed, it must point to the same object. |
| 143 | HEI_ASSERT(ret.second || (ret.first->second == i_child)); |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 144 | } |
| 145 | |
| 146 | //------------------------------------------------------------------------------ |
| 147 | |
Caleb Palmer | f2a2932 | 2024-07-25 13:14:26 -0500 | [diff] [blame^] | 148 | void IsolationNode::addOpRule(OpRuleName_t i_opName, OpRuleType_t i_opType, |
| 149 | RegisterId_t i_regId) |
| 150 | { |
| 151 | std::pair<OpRuleType_t, RegisterId_t> tmpPair = {i_opType, i_regId}; |
| 152 | auto ret = iv_op_rules.emplace(i_opName, tmpPair); |
| 153 | |
| 154 | HEI_ASSERT(ret.second || ret.first->second == tmpPair); |
| 155 | } |
| 156 | |
| 157 | //------------------------------------------------------------------------------ |
| 158 | |
Zane Shelley | 2467db8 | 2020-05-18 19:56:30 -0500 | [diff] [blame] | 159 | std::vector<const IsolationNode*> IsolationNode::cv_isolationStack{}; |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 160 | |
| 161 | //------------------------------------------------------------------------------ |
| 162 | |
| 163 | void IsolationNode::pushIsolationStack() const |
| 164 | { |
| 165 | // Ensure this node does not already exist in cv_isolationStack. |
Patrick Williams | 2f7537d | 2023-05-10 07:51:39 -0500 | [diff] [blame] | 166 | auto itr = std::find(cv_isolationStack.begin(), cv_isolationStack.end(), |
| 167 | this); |
Zane Shelley | 83da245 | 2019-10-25 15:45:34 -0500 | [diff] [blame] | 168 | HEI_ASSERT(cv_isolationStack.end() == itr); |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 169 | |
| 170 | // Push to node to the stack. |
Zane Shelley | 2467db8 | 2020-05-18 19:56:30 -0500 | [diff] [blame] | 171 | cv_isolationStack.push_back(this); |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 172 | } |
| 173 | |
| 174 | //------------------------------------------------------------------------------ |
| 175 | |
Zane Shelley | 6b1fe16 | 2022-11-18 13:37:42 -0600 | [diff] [blame] | 176 | void IsolationNode::captureRegisters(const Chip& i_chip, |
| 177 | IsolationData& io_isoData, |
| 178 | BitPosition_t i_bit) const |
| 179 | { |
| 180 | auto itr = iv_capRegs.find(i_bit); |
| 181 | if (iv_capRegs.end() != itr) |
| 182 | { |
| 183 | // Capture all registers for this node. |
| 184 | for (const auto& hwReg : itr->second) |
| 185 | { |
| 186 | // Read the register (adds BitString to register cache). |
| 187 | if (hwReg->read(i_chip)) |
| 188 | { |
| 189 | // The register read failed. |
| 190 | // TODO: Would be nice to add SCOM errors to the log just in |
| 191 | // case |
| 192 | // traces are not available. |
| 193 | // TODO: This trace could be redundant with the user |
| 194 | // application, |
| 195 | // which will have more information on the actual chip |
| 196 | // that failed anyway. Leaving it commented out for now |
| 197 | // until the SCOM errors are added to the log. |
| 198 | // HEI_ERR("register read failed on chip type=0x%0" PRIx32 |
| 199 | // "address=0x%0" PRIx64, |
| 200 | // i_chip.getType(), hwReg->getAddress()); |
| 201 | } |
| 202 | else |
| 203 | { |
| 204 | // Add to the FFDC. |
| 205 | io_isoData.addRegister(i_chip, hwReg->getId(), |
| 206 | hwReg->getInstance(), |
| 207 | hwReg->getBitString(i_chip)); |
| 208 | } |
| 209 | } |
| 210 | } |
| 211 | } |
| 212 | |
| 213 | //------------------------------------------------------------------------------ |
| 214 | |
Zane Shelley | 7bf1f6d | 2019-10-18 16:03:51 -0500 | [diff] [blame] | 215 | } // end namespace libhei |