10205f3b3SBen Tyner #include <analyzer/analyzer_main.hpp> 2b481d905SBen Tyner #include <attention.hpp> 39ae5ca41SBen Tyner #include <bp_handler.hpp> 49ae5ca41SBen Tyner #include <logging.hpp> 59ae5ca41SBen Tyner #include <ti_handler.hpp> 6ef320154SBen Tyner 7b481d905SBen Tyner #include <algorithm> 8ef320154SBen Tyner #include <iomanip> 99ae5ca41SBen Tyner #include <sstream> 10b481d905SBen Tyner #include <vector> 11ef320154SBen Tyner 12ef320154SBen Tyner namespace attn 13ef320154SBen Tyner { 14ef320154SBen Tyner 15b481d905SBen Tyner /** @brief Return codes */ 16b481d905SBen Tyner static constexpr int RC_SUCCESS = 0; 17b481d905SBen Tyner static constexpr int RC_NOT_SUCCESS = 1; 18b481d905SBen Tyner 19ef320154SBen Tyner /** 20ef320154SBen Tyner * @brief Handle SBE vital attention 21ef320154SBen Tyner * 22b481d905SBen Tyner * @param i_attention Attention object 23ef320154SBen Tyner * @return 0 = success 24ef320154SBen Tyner */ 25b481d905SBen Tyner int handleVital(Attention* i_attention); 26ef320154SBen Tyner 27ef320154SBen Tyner /** 28ef320154SBen Tyner * @brief Handle checkstop attention 29ef320154SBen Tyner * 30b481d905SBen Tyner * @param i_attention Attention object 31ef320154SBen Tyner * @return 0 = success 32ef320154SBen Tyner */ 33b481d905SBen Tyner int handleCheckstop(Attention* i_attention); 34ef320154SBen Tyner 35ef320154SBen Tyner /** 36ef320154SBen Tyner * @brief Handle special attention 37ef320154SBen Tyner * 38b481d905SBen Tyner * @param i_attention Attention object 39ef320154SBen Tyner * @return 0 = success 40ef320154SBen Tyner */ 41b481d905SBen Tyner int handleSpecial(Attention* i_attention); 42ef320154SBen Tyner 43ef320154SBen Tyner /** 44ef320154SBen Tyner * @brief The main attention handler logic 45970fd4fbSBen Tyner * 46970fd4fbSBen Tyner * @param i_breakpoints true = breakpoint special attn handling enabled 47ef320154SBen Tyner */ 48b481d905SBen Tyner void attnHandler(const bool i_breakpoints) 49ef320154SBen Tyner { 50b481d905SBen Tyner // Vector of active attentions to be handled 51b481d905SBen Tyner std::vector<Attention> active_attentions; 52b481d905SBen Tyner 53ef320154SBen Tyner uint32_t isr_val, isr_mask; 54ef320154SBen Tyner uint32_t proc; 55ef320154SBen Tyner 56ef320154SBen Tyner // loop through processors looking for active attentions 57ef320154SBen Tyner pdbg_target* target; 58ef320154SBen Tyner pdbg_for_each_class_target("fsi", target) 59ef320154SBen Tyner { 60ef320154SBen Tyner if (PDBG_TARGET_ENABLED == pdbg_target_probe(target)) 61ef320154SBen Tyner { 62ef320154SBen Tyner proc = pdbg_target_index(target); // get processor number 63ef320154SBen Tyner 64ef320154SBen Tyner std::stringstream ss; // log message stream 65*9dbab8beSBen Tyner ss << "checking processor " << proc; 66ef320154SBen Tyner log<level::INFO>(ss.str().c_str()); 67ef320154SBen Tyner 68ef320154SBen Tyner // get active attentions on processor 69b481d905SBen Tyner if (RC_SUCCESS != fsi_read(target, 0x1007, &isr_val)) 70ef320154SBen Tyner { 71*9dbab8beSBen Tyner log<level::INFO>("Error! cfam read 0x1007 FAILED"); 72ef320154SBen Tyner } 73ef320154SBen Tyner else 74ef320154SBen Tyner { 75ef320154SBen Tyner std::stringstream ss; // log message stream 769ae5ca41SBen Tyner ss << "cfam 0x1007 = 0x"; 77ef320154SBen Tyner ss << std::hex << std::setw(8) << std::setfill('0'); 78*9dbab8beSBen Tyner ss << isr_val; 79ef320154SBen Tyner log<level::INFO>(ss.str().c_str()); 80ef320154SBen Tyner 81ef320154SBen Tyner // get interrupt enabled special attentions mask 82b481d905SBen Tyner if (RC_SUCCESS != fsi_read(target, 0x100d, &isr_mask)) 83ef320154SBen Tyner { 84*9dbab8beSBen Tyner log<level::INFO>("Error! cfam read 0x100d FAILED"); 85ef320154SBen Tyner } 86ef320154SBen Tyner else 87ef320154SBen Tyner { 88ef320154SBen Tyner std::stringstream ss; // log message stream 899ae5ca41SBen Tyner ss << "cfam 0x100d = 0x"; 90ef320154SBen Tyner ss << std::hex << std::setw(8) << std::setfill('0'); 91*9dbab8beSBen Tyner ss << isr_mask; 92ef320154SBen Tyner log<level::INFO>(ss.str().c_str()); 93ef320154SBen Tyner 94ef320154SBen Tyner // bit 0 on "left": bit 30 = SBE vital attention 95ef320154SBen Tyner if (isr_val & isr_mask & 0x00000002) 96ef320154SBen Tyner { 97b481d905SBen Tyner active_attentions.emplace_back(Attention::Vital, 98b481d905SBen Tyner handleVital, target, 99b481d905SBen Tyner i_breakpoints); 100ef320154SBen Tyner } 101ef320154SBen Tyner 102ef320154SBen Tyner // bit 0 on "left": bit 1 = checkstop 103ef320154SBen Tyner if (isr_val & isr_mask & 0x40000000) 104ef320154SBen Tyner { 105b481d905SBen Tyner active_attentions.emplace_back(Attention::Checkstop, 106b481d905SBen Tyner handleCheckstop, target, 107b481d905SBen Tyner i_breakpoints); 108ef320154SBen Tyner } 109ef320154SBen Tyner 110ef320154SBen Tyner // bit 0 on "left": bit 2 = special attention 111ef320154SBen Tyner if (isr_val & isr_mask & 0x20000000) 112ef320154SBen Tyner { 113b481d905SBen Tyner active_attentions.emplace_back(Attention::Special, 114b481d905SBen Tyner handleSpecial, target, 115b481d905SBen Tyner i_breakpoints); 116ef320154SBen Tyner } 117ef320154SBen Tyner } // cfam 0x100d valid 118ef320154SBen Tyner } // cfam 0x1007 valid 119ef320154SBen Tyner } // fsi target enabled 120ef320154SBen Tyner } // next processor 121ef320154SBen Tyner 122b481d905SBen Tyner // convert to heap, highest priority is at front 123b481d905SBen Tyner if (!std::is_heap(active_attentions.begin(), active_attentions.end())) 124b481d905SBen Tyner { 125b481d905SBen Tyner std::make_heap(active_attentions.begin(), active_attentions.end()); 126b481d905SBen Tyner } 127b481d905SBen Tyner 128b481d905SBen Tyner // call the attention handler until one is handled or all were attempted 129b481d905SBen Tyner while (false == active_attentions.empty()) 130b481d905SBen Tyner { 131b481d905SBen Tyner // handle highest priority attention, done if successful 132b481d905SBen Tyner if (RC_SUCCESS == active_attentions.front().handle()) 133b481d905SBen Tyner { 134b481d905SBen Tyner break; 135b481d905SBen Tyner } 136b481d905SBen Tyner 137b481d905SBen Tyner // move attention to back of vector 138b481d905SBen Tyner std::pop_heap(active_attentions.begin(), active_attentions.end()); 139b481d905SBen Tyner 140b481d905SBen Tyner // remove attention from vector 141b481d905SBen Tyner active_attentions.pop_back(); 142b481d905SBen Tyner } 143ef320154SBen Tyner } 144ef320154SBen Tyner 145ef320154SBen Tyner /** 146ef320154SBen Tyner * @brief Handle SBE vital attention 147ef320154SBen Tyner */ 148b481d905SBen Tyner int handleVital(Attention* i_attention) 149ef320154SBen Tyner { 150b481d905SBen Tyner int rc = RC_NOT_SUCCESS; // vital attention handling not yet supported 151ef320154SBen Tyner 152*9dbab8beSBen Tyner log<level::INFO>("vital"); 153ef320154SBen Tyner 154b481d905SBen Tyner if (RC_SUCCESS != rc) 155ef320154SBen Tyner { 156*9dbab8beSBen Tyner log<level::INFO>("vital NOT handled"); 157ef320154SBen Tyner } 158ef320154SBen Tyner 159ef320154SBen Tyner return rc; 160ef320154SBen Tyner } 161ef320154SBen Tyner 162ef320154SBen Tyner /** 163ef320154SBen Tyner * @brief Handle checkstop attention 164ef320154SBen Tyner */ 165b481d905SBen Tyner int handleCheckstop(Attention* i_attention) 166ef320154SBen Tyner { 167b481d905SBen Tyner int rc = RC_SUCCESS; // checkstop handling supported 168ef320154SBen Tyner 169*9dbab8beSBen Tyner log<level::INFO>("checkstop"); 170ef320154SBen Tyner 1710205f3b3SBen Tyner analyzer::analyzeHardware(); 172ef320154SBen Tyner 173ef320154SBen Tyner return rc; 174ef320154SBen Tyner } 175ef320154SBen Tyner 176ef320154SBen Tyner /** 177ef320154SBen Tyner * @brief Handle special attention 178ef320154SBen Tyner */ 179b481d905SBen Tyner int handleSpecial(Attention* i_attention) 180ef320154SBen Tyner { 181b481d905SBen Tyner int rc = RC_SUCCESS; // special attention handling supported 182ef320154SBen Tyner 183*9dbab8beSBen Tyner log<level::INFO>("special"); 184ef320154SBen Tyner 185970fd4fbSBen Tyner // Right now we always handle breakpoint special attentions if breakpoint 186970fd4fbSBen Tyner // attn handling is enabled. This will eventually check if breakpoint attn 187970fd4fbSBen Tyner // handing is enabled AND there is a breakpoint pending. 188b481d905SBen Tyner if (0 != (i_attention->getFlags() & enableBreakpoints)) 189970fd4fbSBen Tyner { 190*9dbab8beSBen Tyner log<level::INFO>("breakpoint"); 191ef320154SBen Tyner 1929ae5ca41SBen Tyner // Call the breakpoint special attention handler 1939ae5ca41SBen Tyner bpHandler(); 194970fd4fbSBen Tyner } 195970fd4fbSBen Tyner // Right now if breakpoint attn handling is not enabled we will treat the 196970fd4fbSBen Tyner // special attention as a TI. This will eventually be changed to check 197970fd4fbSBen Tyner // whether a TI is active and handle it regardless of whether breakpoint 198970fd4fbSBen Tyner // handling is enbaled or not. 199970fd4fbSBen Tyner else 200970fd4fbSBen Tyner { 201*9dbab8beSBen Tyner log<level::INFO>("TI (terminate immediately)"); 202970fd4fbSBen Tyner 2039ae5ca41SBen Tyner // Call TI special attention handler 2049ae5ca41SBen Tyner tiHandler(); 205970fd4fbSBen Tyner } 206ef320154SBen Tyner 207ef320154SBen Tyner // TODO recoverable errors? 208ef320154SBen Tyner 209ef320154SBen Tyner return rc; 210ef320154SBen Tyner } 211ef320154SBen Tyner 212ef320154SBen Tyner } // namespace attn 213