1792f32f7SBen Tyner #include <libpdbg.h> 2792f32f7SBen Tyner 30205f3b3SBen Tyner #include <analyzer/analyzer_main.hpp> 4b797b3e1SBen Tyner #include <attn/attention.hpp> 5bcf65a8bSBen Tyner #include <attn/attn_common.hpp> 6b797b3e1SBen Tyner #include <attn/attn_config.hpp> 7b797b3e1SBen Tyner #include <attn/attn_handler.hpp> 8b797b3e1SBen Tyner #include <attn/attn_logging.hpp> 9b797b3e1SBen Tyner #include <attn/bp_handler.hpp> 10b797b3e1SBen Tyner #include <attn/ti_handler.hpp> 11bcf65a8bSBen Tyner #include <attn/vital_handler.hpp> 12ef320154SBen Tyner 13b481d905SBen Tyner #include <algorithm> 14ef320154SBen Tyner #include <iomanip> 15b1ebfcb1SBen Tyner #include <map> 169ae5ca41SBen Tyner #include <sstream> 17b481d905SBen Tyner #include <vector> 18ef320154SBen Tyner 19ef320154SBen Tyner namespace attn 20ef320154SBen Tyner { 21ef320154SBen Tyner 22ef320154SBen Tyner /** 23ef320154SBen Tyner * @brief Handle checkstop attention 24ef320154SBen Tyner * 25b481d905SBen Tyner * @param i_attention Attention object 263fb52e53SBen Tyner * @return 0 indicates that the checkstop attention was successfully handled 273fb52e53SBen Tyner * 1 indicates that the checkstop attention was NOT successfully 283fb52e53SBen Tyner * handled. 29ef320154SBen Tyner */ 30b481d905SBen Tyner int handleCheckstop(Attention* i_attention); 31ef320154SBen Tyner 32ef320154SBen Tyner /** 33ef320154SBen Tyner * @brief Handle special attention 34ef320154SBen Tyner * 35b481d905SBen Tyner * @param i_attention Attention object 363fb52e53SBen Tyner * @return 0 indicates that the special attention was successfully handled 373fb52e53SBen Tyner * 1 indicates that the special attention was NOT successfully handled 38ef320154SBen Tyner */ 39b481d905SBen Tyner int handleSpecial(Attention* i_attention); 40ef320154SBen Tyner 41fb190545SBen Tyner /** @brief Determine if attention is active and not masked */ 421965e504SBen Tyner bool activeAttn(uint32_t i_val, uint32_t i_mask, uint32_t i_attn); 43fb190545SBen Tyner 44ef320154SBen Tyner /** 45ef320154SBen Tyner * @brief The main attention handler logic 46970fd4fbSBen Tyner * 47970fd4fbSBen Tyner * @param i_breakpoints true = breakpoint special attn handling enabled 48ef320154SBen Tyner */ 493fb52e53SBen Tyner void attnHandler(Config* i_config) 50ef320154SBen Tyner { 51b481d905SBen Tyner // Vector of active attentions to be handled 52b481d905SBen Tyner std::vector<Attention> active_attentions; 53b481d905SBen Tyner 54ef320154SBen Tyner uint32_t isr_val, isr_mask; 55ef320154SBen Tyner uint32_t proc; 56ef320154SBen Tyner 571965e504SBen Tyner std::stringstream ss; // for trace messages 581965e504SBen Tyner 59ef320154SBen Tyner // loop through processors looking for active attentions 60b1ebfcb1SBen Tyner trace<level::INFO>("Attention handler started"); 61117af99bSBen Tyner 62ef320154SBen Tyner pdbg_target* target; 635e622d87SBen Tyner pdbg_for_each_class_target("proc", target) 64ef320154SBen Tyner { 65ef320154SBen Tyner if (PDBG_TARGET_ENABLED == pdbg_target_probe(target)) 66ef320154SBen Tyner { 67ef320154SBen Tyner proc = pdbg_target_index(target); // get processor number 68ef320154SBen Tyner 69b83c852aSBen Tyner // Use PIB target to determine if a processor is enabled 705e622d87SBen Tyner char path[16]; 71b83c852aSBen Tyner sprintf(path, "/proc%d/pib", proc); 725e622d87SBen Tyner pdbg_target* attnTarget = pdbg_target_from_path(nullptr, path); 735e622d87SBen Tyner 74b83c852aSBen Tyner // sanity check 75b83c852aSBen Tyner if (nullptr == attnTarget) 76b83c852aSBen Tyner { 77b83c852aSBen Tyner trace<level::INFO>("pib path or target not found"); 78b83c852aSBen Tyner continue; 79b83c852aSBen Tyner } 80b83c852aSBen Tyner 815e622d87SBen Tyner if (PDBG_TARGET_ENABLED == pdbg_target_probe(attnTarget)) 825e622d87SBen Tyner { 83b83c852aSBen Tyner // The processor FSI target is required for CFAM read 84b83c852aSBen Tyner sprintf(path, "/proc%d/fsi", proc); 85b83c852aSBen Tyner attnTarget = pdbg_target_from_path(nullptr, path); 86b83c852aSBen Tyner 87b83c852aSBen Tyner // sanity check 88b83c852aSBen Tyner if (nullptr == attnTarget) 89b83c852aSBen Tyner { 90b83c852aSBen Tyner trace<level::INFO>("fsi path or target not found"); 91b83c852aSBen Tyner continue; 92b83c852aSBen Tyner } 93b83c852aSBen Tyner 941965e504SBen Tyner // trace fsi path 951965e504SBen Tyner ss.str(std::string()); // clear stream 961965e504SBen Tyner ss << "target - " << path; 971965e504SBen Tyner trace<level::INFO>(ss.str().c_str()); 981965e504SBen Tyner 995adc96eeSBen Tyner isr_val = 0xffffffff; // invalid isr value 1005adc96eeSBen Tyner 101ef320154SBen Tyner // get active attentions on processor 1025e622d87SBen Tyner if (RC_SUCCESS != fsi_read(attnTarget, 0x1007, &isr_val)) 103ef320154SBen Tyner { 104fb190545SBen Tyner // log cfam read error 105b1ebfcb1SBen Tyner trace<level::INFO>("Error! cfam read 0x1007 FAILED"); 106fb190545SBen Tyner eventAttentionFail(RC_CFAM_ERROR); 107ef320154SBen Tyner } 1085adc96eeSBen Tyner else if (0xffffffff == isr_val) 1095adc96eeSBen Tyner { 1105adc96eeSBen Tyner trace<level::INFO>("Error! cfam read 0x1007 INVALID"); 1115adc96eeSBen Tyner continue; 1125adc96eeSBen Tyner } 113ef320154SBen Tyner else 114ef320154SBen Tyner { 1151965e504SBen Tyner // trace isr 1161965e504SBen Tyner ss.str(std::string()); // clear stream 1171965e504SBen Tyner ss << std::hex << std::showbase; // trace as hex vals 1181965e504SBen Tyner ss << "cfam 0x1007 = " << std::setw(8) << std::setfill('0') 1191965e504SBen Tyner << isr_val; 1201965e504SBen Tyner trace<level::INFO>(ss.str().c_str()); 1211965e504SBen Tyner 1225adc96eeSBen Tyner isr_mask = 0xffffffff; // invalid isr mask 1235adc96eeSBen Tyner 124ef320154SBen Tyner // get interrupt enabled special attentions mask 1255e622d87SBen Tyner if (RC_SUCCESS != fsi_read(attnTarget, 0x100d, &isr_mask)) 126ef320154SBen Tyner { 127fb190545SBen Tyner // log cfam read error 128b1ebfcb1SBen Tyner trace<level::INFO>("Error! cfam read 0x100d FAILED"); 129fb190545SBen Tyner eventAttentionFail(RC_CFAM_ERROR); 130ef320154SBen Tyner } 1315adc96eeSBen Tyner else if (0xffffffff == isr_mask) 1325adc96eeSBen Tyner { 1335adc96eeSBen Tyner trace<level::INFO>("Error! cfam read 0x100d INVALID"); 1345adc96eeSBen Tyner continue; 1355adc96eeSBen Tyner } 136ef320154SBen Tyner else 137ef320154SBen Tyner { 1381965e504SBen Tyner // trace true-mask 1391965e504SBen Tyner ss.str(std::string()); // clear stream 1401965e504SBen Tyner ss << std::hex << std::showbase; // trace as hex vals 1411965e504SBen Tyner ss << "cfam 0x100d = " << std::setw(8) 1421965e504SBen Tyner << std::setfill('0') << isr_mask; 1431965e504SBen Tyner trace<level::INFO>(ss.str().c_str()); 1441965e504SBen Tyner 145fb190545SBen Tyner // SBE vital attention active and not masked? 1461965e504SBen Tyner if (true == activeAttn(isr_val, isr_mask, SBE_ATTN)) 147ef320154SBen Tyner { 1485e622d87SBen Tyner active_attentions.emplace_back(Attention::Vital, 1495e622d87SBen Tyner handleVital, target, 1505e622d87SBen Tyner i_config); 151ef320154SBen Tyner } 152ef320154SBen Tyner 153fb190545SBen Tyner // Checkstop attention active and not masked? 154fb190545SBen Tyner if (true == 1551965e504SBen Tyner activeAttn(isr_val, isr_mask, CHECKSTOP_ATTN)) 156ef320154SBen Tyner { 157b481d905SBen Tyner active_attentions.emplace_back(Attention::Checkstop, 1585e622d87SBen Tyner handleCheckstop, 1595e622d87SBen Tyner target, i_config); 160ef320154SBen Tyner } 161ef320154SBen Tyner 162fb190545SBen Tyner // Special attention active and not masked? 1631965e504SBen Tyner if (true == activeAttn(isr_val, isr_mask, SPECIAL_ATTN)) 164ef320154SBen Tyner { 165b481d905SBen Tyner active_attentions.emplace_back(Attention::Special, 1665e622d87SBen Tyner handleSpecial, 1675e622d87SBen Tyner target, i_config); 168ef320154SBen Tyner } 169ef320154SBen Tyner } // cfam 0x100d valid 170ef320154SBen Tyner } // cfam 0x1007 valid 1715e622d87SBen Tyner } // proc target enabled 172ef320154SBen Tyner } // fsi target enabled 173ef320154SBen Tyner } // next processor 174ef320154SBen Tyner 175b481d905SBen Tyner // convert to heap, highest priority is at front 176b481d905SBen Tyner if (!std::is_heap(active_attentions.begin(), active_attentions.end())) 177b481d905SBen Tyner { 178b481d905SBen Tyner std::make_heap(active_attentions.begin(), active_attentions.end()); 179b481d905SBen Tyner } 180b481d905SBen Tyner 181b481d905SBen Tyner // call the attention handler until one is handled or all were attempted 182b481d905SBen Tyner while (false == active_attentions.empty()) 183b481d905SBen Tyner { 184b481d905SBen Tyner // handle highest priority attention, done if successful 185b481d905SBen Tyner if (RC_SUCCESS == active_attentions.front().handle()) 186b481d905SBen Tyner { 187b1ebfcb1SBen Tyner // an attention was handled so we are done 188b481d905SBen Tyner break; 189b481d905SBen Tyner } 190b481d905SBen Tyner 191b481d905SBen Tyner // move attention to back of vector 192b481d905SBen Tyner std::pop_heap(active_attentions.begin(), active_attentions.end()); 193b481d905SBen Tyner 194b481d905SBen Tyner // remove attention from vector 195b481d905SBen Tyner active_attentions.pop_back(); 196b481d905SBen Tyner } 197ef320154SBen Tyner } 198ef320154SBen Tyner 199ef320154SBen Tyner /** 200ef320154SBen Tyner * @brief Handle checkstop attention 2013fb52e53SBen Tyner * 2023fb52e53SBen Tyner * @param i_attention Attention object 2033fb52e53SBen Tyner * @return 0 indicates that the checkstop attention was successfully handled 2043fb52e53SBen Tyner * 1 indicates that the checkstop attention was NOT successfully 2053fb52e53SBen Tyner * handled. 206ef320154SBen Tyner */ 207b481d905SBen Tyner int handleCheckstop(Attention* i_attention) 208ef320154SBen Tyner { 2093fb52e53SBen Tyner int rc = RC_SUCCESS; // assume checkstop handled 210ef320154SBen Tyner 211b1ebfcb1SBen Tyner trace<level::INFO>("checkstop handler started"); 212b1ebfcb1SBen Tyner 2133fb52e53SBen Tyner // if checkstop handling enabled, handle checkstop attention 2143fb52e53SBen Tyner if (false == (i_attention->getConfig()->getFlag(enCheckstop))) 2153fb52e53SBen Tyner { 216b1ebfcb1SBen Tyner trace<level::INFO>("Checkstop handling disabled"); 2173fb52e53SBen Tyner } 2183fb52e53SBen Tyner else 2193fb52e53SBen Tyner { 2209fb7393eSZane Shelley // Look for any attentions found in hardware. This will generate and 2217ae9c8c7SZane Shelley // commit a PEL if any errors are found. 2229fb7393eSZane Shelley if (true != analyzer::analyzeHardware()) 223b1ebfcb1SBen Tyner { 224b1ebfcb1SBen Tyner rc = RC_ANALYZER_ERROR; 225b1ebfcb1SBen Tyner } 2263fb52e53SBen Tyner } 227ef320154SBen Tyner 228ef320154SBen Tyner return rc; 229ef320154SBen Tyner } 230ef320154SBen Tyner 231ef320154SBen Tyner /** 232ef320154SBen Tyner * @brief Handle special attention 2333fb52e53SBen Tyner * 2343fb52e53SBen Tyner * @param i_attention Attention object 2353fb52e53SBen Tyner * @return 0 indicates that the special attention was successfully handled 2363fb52e53SBen Tyner * 1 indicates that the special attention was NOT successfully handled 237ef320154SBen Tyner */ 238b481d905SBen Tyner int handleSpecial(Attention* i_attention) 239ef320154SBen Tyner { 240b1ebfcb1SBen Tyner int rc = RC_SUCCESS; // assume special attention handled 241ef320154SBen Tyner 242fb190545SBen Tyner // The TI info chipop will give us a pointer to the TI info data 243792f32f7SBen Tyner uint8_t* tiInfo = nullptr; // ptr to TI info data 244792f32f7SBen Tyner uint32_t tiInfoLen = 0; // length of TI info data 24598430b30SBen Tyner pdbg_target* attnProc = i_attention->getTarget(); // proc with attention 246b1ebfcb1SBen Tyner 24798430b30SBen Tyner if (attnProc != nullptr) 24898430b30SBen Tyner { 24998430b30SBen Tyner // The processor PIB target is required for get TI info chipop 25098430b30SBen Tyner char path[16]; 25198430b30SBen Tyner sprintf(path, "/proc%d/pib", pdbg_target_index(attnProc)); 25298430b30SBen Tyner pdbg_target* tiInfoTarget = pdbg_target_from_path(nullptr, path); 25389c0a7afSBen Tyner 25498430b30SBen Tyner if (nullptr != tiInfoTarget) 25589c0a7afSBen Tyner { 25689c0a7afSBen Tyner if (PDBG_TARGET_ENABLED == pdbg_target_probe(tiInfoTarget)) 25789c0a7afSBen Tyner { 258792f32f7SBen Tyner sbe_mpipl_get_ti_info(tiInfoTarget, &tiInfo, &tiInfoLen); 25998430b30SBen Tyner if (tiInfo == nullptr) 26098430b30SBen Tyner { 26198430b30SBen Tyner trace<level::INFO>("TI info data ptr is null after call"); 26298430b30SBen Tyner } 26398430b30SBen Tyner } 26489c0a7afSBen Tyner } 26589c0a7afSBen Tyner } 266ef320154SBen Tyner 2670fe5df40SBen Tyner bool tiInfoValid = false; // TI area data not valid or not available 2680fe5df40SBen Tyner 269792f32f7SBen Tyner // If TI area exists and is marked valid we can assume TI occurred 270792f32f7SBen Tyner if ((nullptr != tiInfo) && (0 != tiInfo[0])) 271792f32f7SBen Tyner { 272792f32f7SBen Tyner TiDataArea* tiDataArea = (TiDataArea*)tiInfo; 273792f32f7SBen Tyner 274792f32f7SBen Tyner // trace a few known TI data area values 2758c5e4f4eSBen Tyner std::stringstream ss; 2768c5e4f4eSBen Tyner ss << std::hex << std::showbase; 27740717725SBen Tyner 27840717725SBen Tyner ss << "TI data command = " << (int)tiDataArea->command; 279792f32f7SBen Tyner trace<level::INFO>(ss.str().c_str()); 28040717725SBen Tyner ss.str(std::string()); 28140717725SBen Tyner 2820fe5df40SBen Tyner // Another check for valid TI Info since it has been seen that 2830fe5df40SBen Tyner // tiInfo[0] != 0 but TI info is not valid 2840fe5df40SBen Tyner if (0xa1 == tiDataArea->command) 2850fe5df40SBen Tyner { 2860fe5df40SBen Tyner tiInfoValid = true; 2870fe5df40SBen Tyner 2880fe5df40SBen Tyner // trace some more data since TI info appears valid 2898c5e4f4eSBen Tyner ss << "TI data hb_terminate_type = " 2908c5e4f4eSBen Tyner << (int)tiDataArea->hbTerminateType; 2918c5e4f4eSBen Tyner trace<level::INFO>(ss.str().c_str()); 2928c5e4f4eSBen Tyner ss.str(std::string()); 2938c5e4f4eSBen Tyner 29440717725SBen Tyner ss << "TI data SRC format = " << (int)tiDataArea->srcFormat; 295792f32f7SBen Tyner trace<level::INFO>(ss.str().c_str()); 29640717725SBen Tyner ss.str(std::string()); 29740717725SBen Tyner 2988c5e4f4eSBen Tyner ss << "TI data source = " << (int)tiDataArea->source; 299792f32f7SBen Tyner trace<level::INFO>(ss.str().c_str()); 30040717725SBen Tyner ss.str(std::string()); 301792f32f7SBen Tyner 3023fb52e53SBen Tyner if (true == (i_attention->getConfig()->getFlag(enTerminate))) 303970fd4fbSBen Tyner { 3049ae5ca41SBen Tyner // Call TI special attention handler 305792f32f7SBen Tyner rc = tiHandler(tiDataArea); 3063fb52e53SBen Tyner } 307792f32f7SBen Tyner } 3080fe5df40SBen Tyner } 3090fe5df40SBen Tyner 3100fe5df40SBen Tyner // If TI area not valid or not available 3110fe5df40SBen Tyner if (false == tiInfoValid) 3123fb52e53SBen Tyner { 313e4f5dbefSBen Tyner trace<level::INFO>("TI info NOT available"); 314e4f5dbefSBen Tyner 315e4f5dbefSBen Tyner // if configured to handle breakpoint as default special attention 316e4f5dbefSBen Tyner if (i_attention->getConfig()->getFlag(dfltBreakpoint)) 317e4f5dbefSBen Tyner { 3183fb52e53SBen Tyner if (true == (i_attention->getConfig()->getFlag(enBreakpoints))) 3193fb52e53SBen Tyner { 3203fb52e53SBen Tyner // Call the breakpoint special attention handler 3213fb52e53SBen Tyner bpHandler(); 3223fb52e53SBen Tyner } 323970fd4fbSBen Tyner } 324e4f5dbefSBen Tyner // if configured to handle TI as default special attention 325e4f5dbefSBen Tyner else 326e4f5dbefSBen Tyner { 327e4f5dbefSBen Tyner trace<level::INFO>("assuming TI"); 328e4f5dbefSBen Tyner 329e4f5dbefSBen Tyner if (true == (i_attention->getConfig()->getFlag(enTerminate))) 330e4f5dbefSBen Tyner { 331e4f5dbefSBen Tyner // Call TI special attention handler 332e4f5dbefSBen Tyner rc = tiHandler(nullptr); 333e4f5dbefSBen Tyner } 334e4f5dbefSBen Tyner } 335e4f5dbefSBen Tyner } 336ef320154SBen Tyner 337792f32f7SBen Tyner // release TI data buffer 338792f32f7SBen Tyner if (nullptr != tiInfo) 339792f32f7SBen Tyner { 340792f32f7SBen Tyner free(tiInfo); 341792f32f7SBen Tyner } 342792f32f7SBen Tyner 3433fb52e53SBen Tyner if (RC_SUCCESS != rc) 3443fb52e53SBen Tyner { 345792f32f7SBen Tyner trace<level::INFO>("Special attn not handled"); 3463fb52e53SBen Tyner } 347ef320154SBen Tyner 348ef320154SBen Tyner return rc; 349ef320154SBen Tyner } 350ef320154SBen Tyner 351fb190545SBen Tyner /** 352fb190545SBen Tyner * @brief Determine if attention is active and not masked 353fb190545SBen Tyner * 354fb190545SBen Tyner * Determine whether an attention needs to be handled and trace details of 355fb190545SBen Tyner * attention type and whether it is masked or not. 356fb190545SBen Tyner * 357fb190545SBen Tyner * @param i_val attention status register 358fb190545SBen Tyner * @param i_mask attention true mask register 359fb190545SBen Tyner * @param i_attn attention type 360fb190545SBen Tyner * @param i_proc processor associated with registers 361fb190545SBen Tyner * 362fb190545SBen Tyner * @return true if attention is active and not masked, otherwise false 363fb190545SBen Tyner */ 3641965e504SBen Tyner bool activeAttn(uint32_t i_val, uint32_t i_mask, uint32_t i_attn) 365fb190545SBen Tyner { 366fb190545SBen Tyner bool rc = false; // assume attn masked and/or inactive 367fb190545SBen Tyner 368fb190545SBen Tyner // if attention active 369fb190545SBen Tyner if (0 != (i_val & i_attn)) 370fb190545SBen Tyner { 371fb190545SBen Tyner std::stringstream ss; 372fb190545SBen Tyner 373*9fb657f9SZane Shelley bool validAttn = true; // known attention type 374*9fb657f9SZane Shelley 375fb190545SBen Tyner switch (i_attn) 376fb190545SBen Tyner { 377fb190545SBen Tyner case SBE_ATTN: 378fb190545SBen Tyner ss << "SBE attn"; 379fb190545SBen Tyner break; 380fb190545SBen Tyner case CHECKSTOP_ATTN: 381fb190545SBen Tyner ss << "Checkstop attn"; 382fb190545SBen Tyner break; 383fb190545SBen Tyner case SPECIAL_ATTN: 384fb190545SBen Tyner ss << "Special attn"; 385fb190545SBen Tyner break; 386fb190545SBen Tyner default: 387fb190545SBen Tyner ss << "Unknown attn"; 388fb190545SBen Tyner validAttn = false; 389fb190545SBen Tyner } 390fb190545SBen Tyner 391fb190545SBen Tyner // see if attention is masked 392fb190545SBen Tyner if (true == validAttn) 393fb190545SBen Tyner { 394fb190545SBen Tyner if (0 != (i_mask & i_attn)) 395fb190545SBen Tyner { 396fb190545SBen Tyner rc = true; // attention active and not masked 397fb190545SBen Tyner } 398fb190545SBen Tyner else 399fb190545SBen Tyner { 400fb190545SBen Tyner ss << " masked"; 401fb190545SBen Tyner } 402fb190545SBen Tyner } 403fb190545SBen Tyner 404fb190545SBen Tyner trace<level::INFO>(ss.str().c_str()); // commit trace stream 405fb190545SBen Tyner } 406fb190545SBen Tyner 407fb190545SBen Tyner return rc; 408fb190545SBen Tyner } 409fb190545SBen Tyner 410ef320154SBen Tyner } // namespace attn 411