1 #include <analyzer/analyzer_main.hpp> 2 #include <attention.hpp> 3 #include <attn_config.hpp> 4 #include <bp_handler.hpp> 5 #include <logging.hpp> 6 #include <ti_handler.hpp> 7 8 #include <algorithm> 9 #include <iomanip> 10 #include <sstream> 11 #include <vector> 12 13 namespace attn 14 { 15 16 /** @brief Return codes */ 17 static constexpr int RC_SUCCESS = 0; 18 static constexpr int RC_NOT_SUCCESS = 1; 19 20 /** 21 * @brief Handle SBE vital attention 22 * 23 * @param i_attention Attention object 24 * @return 0 indicates that the vital attention was successfully handled 25 * 1 indicates that the vital attention was NOT successfully handled 26 */ 27 int handleVital(Attention* i_attention); 28 29 /** 30 * @brief Handle checkstop attention 31 * 32 * @param i_attention Attention object 33 * @return 0 indicates that the checkstop attention was successfully handled 34 * 1 indicates that the checkstop attention was NOT successfully 35 * handled. 36 */ 37 int handleCheckstop(Attention* i_attention); 38 39 /** 40 * @brief Handle special attention 41 * 42 * @param i_attention Attention object 43 * @return 0 indicates that the special attention was successfully handled 44 * 1 indicates that the special attention was NOT successfully handled 45 */ 46 int handleSpecial(Attention* i_attention); 47 48 /** 49 * @brief The main attention handler logic 50 * 51 * @param i_breakpoints true = breakpoint special attn handling enabled 52 */ 53 void attnHandler(Config* i_config) 54 { 55 // Vector of active attentions to be handled 56 std::vector<Attention> active_attentions; 57 58 uint32_t isr_val, isr_mask; 59 uint32_t proc; 60 61 // loop through processors looking for active attentions 62 pdbg_target* target; 63 pdbg_for_each_class_target("fsi", target) 64 { 65 if (PDBG_TARGET_ENABLED == pdbg_target_probe(target)) 66 { 67 proc = pdbg_target_index(target); // get processor number 68 69 std::stringstream ss; // log message stream 70 ss << "checking processor " << proc; 71 log<level::INFO>(ss.str().c_str()); 72 73 // get active attentions on processor 74 if (RC_SUCCESS != fsi_read(target, 0x1007, &isr_val)) 75 { 76 log<level::INFO>("Error! cfam read 0x1007 FAILED"); 77 } 78 else 79 { 80 std::stringstream ss; // log message stream 81 ss << "cfam 0x1007 = 0x"; 82 ss << std::hex << std::setw(8) << std::setfill('0'); 83 ss << isr_val; 84 log<level::INFO>(ss.str().c_str()); 85 86 // get interrupt enabled special attentions mask 87 if (RC_SUCCESS != fsi_read(target, 0x100d, &isr_mask)) 88 { 89 log<level::INFO>("Error! cfam read 0x100d FAILED"); 90 } 91 else 92 { 93 std::stringstream ss; // log message stream 94 ss << "cfam 0x100d = 0x"; 95 ss << std::hex << std::setw(8) << std::setfill('0'); 96 ss << isr_mask; 97 log<level::INFO>(ss.str().c_str()); 98 99 // bit 0 on "left": bit 30 = SBE vital attention 100 if (isr_val & isr_mask & 0x00000002) 101 { 102 active_attentions.emplace_back( 103 Attention::Vital, handleVital, target, i_config); 104 } 105 106 // bit 0 on "left": bit 1 = checkstop 107 if (isr_val & isr_mask & 0x40000000) 108 { 109 active_attentions.emplace_back(Attention::Checkstop, 110 handleCheckstop, target, 111 i_config); 112 } 113 114 // bit 0 on "left": bit 2 = special attention 115 if (isr_val & isr_mask & 0x20000000) 116 { 117 active_attentions.emplace_back(Attention::Special, 118 handleSpecial, target, 119 i_config); 120 } 121 } // cfam 0x100d valid 122 } // cfam 0x1007 valid 123 } // fsi target enabled 124 } // next processor 125 126 // convert to heap, highest priority is at front 127 if (!std::is_heap(active_attentions.begin(), active_attentions.end())) 128 { 129 std::make_heap(active_attentions.begin(), active_attentions.end()); 130 } 131 132 // call the attention handler until one is handled or all were attempted 133 while (false == active_attentions.empty()) 134 { 135 // handle highest priority attention, done if successful 136 if (RC_SUCCESS == active_attentions.front().handle()) 137 { 138 break; 139 } 140 141 // move attention to back of vector 142 std::pop_heap(active_attentions.begin(), active_attentions.end()); 143 144 // remove attention from vector 145 active_attentions.pop_back(); 146 } 147 } 148 149 /** 150 * @brief Handle SBE vital attention 151 * 152 * @param i_attention Attention object 153 * @return 0 indicates that the vital attention was successfully handled 154 * 1 indicates that the vital attention was NOT successfully handled 155 */ 156 int handleVital(Attention* i_attention) 157 { 158 int rc = RC_SUCCESS; // assume vital handled 159 160 // if vital handling enabled, handle vital attention 161 if (false == (i_attention->getConfig()->getFlag(enVital))) 162 { 163 log<level::INFO>("vital handling disabled"); 164 rc = RC_NOT_SUCCESS; 165 } 166 else 167 { 168 log<level::INFO>("vital NOT handled"); 169 rc = RC_NOT_SUCCESS; 170 } 171 172 return rc; 173 } 174 175 /** 176 * @brief Handle checkstop attention 177 * 178 * @param i_attention Attention object 179 * @return 0 indicates that the checkstop attention was successfully handled 180 * 1 indicates that the checkstop attention was NOT successfully 181 * handled. 182 */ 183 int handleCheckstop(Attention* i_attention) 184 { 185 int rc = RC_SUCCESS; // assume checkstop handled 186 187 // if checkstop handling enabled, handle checkstop attention 188 if (false == (i_attention->getConfig()->getFlag(enCheckstop))) 189 { 190 log<level::INFO>("Checkstop handling disabled"); 191 rc = RC_NOT_SUCCESS; 192 } 193 else 194 { 195 analyzer::analyzeHardware(); 196 rc = RC_SUCCESS; 197 } 198 199 return rc; 200 } 201 202 /** 203 * @brief Handle special attention 204 * 205 * @param i_attention Attention object 206 * @return 0 indicates that the special attention was successfully handled 207 * 1 indicates that the special attention was NOT successfully handled 208 */ 209 int handleSpecial(Attention* i_attention) 210 { 211 int rc = RC_NOT_SUCCESS; // assume special attention handling disabled 212 213 // Until the special attention chipop is availabe we will treat the special 214 // attention as a TI. If TI handling is disabled we will treat the special 215 // attention as a breakpopint. 216 217 // TI attention gets priority over breakpoints, if enabled then handle 218 if (true == (i_attention->getConfig()->getFlag(enTerminate))) 219 { 220 log<level::INFO>("TI (terminate immediately)"); 221 222 // Call TI special attention handler 223 tiHandler(); 224 rc = RC_SUCCESS; 225 } 226 else 227 { 228 if (true == (i_attention->getConfig()->getFlag(enBreakpoints))) 229 { 230 log<level::INFO>("breakpoint"); 231 232 // Call the breakpoint special attention handler 233 bpHandler(); 234 rc = RC_SUCCESS; 235 } 236 } 237 238 if (RC_SUCCESS != rc) 239 { 240 log<level::INFO>("Special attn handling disabled"); 241 } 242 243 return rc; 244 } 245 246 } // namespace attn 247