10205f3b3SBen Tyner #include <analyzer/analyzer_main.hpp>
2b481d905SBen Tyner #include <attention.hpp>
33fb52e53SBen Tyner #include <attn_config.hpp>
49ae5ca41SBen Tyner #include <bp_handler.hpp>
59ae5ca41SBen Tyner #include <logging.hpp>
69ae5ca41SBen Tyner #include <ti_handler.hpp>
7ef320154SBen Tyner 
8b481d905SBen Tyner #include <algorithm>
9ef320154SBen Tyner #include <iomanip>
109ae5ca41SBen Tyner #include <sstream>
11b481d905SBen Tyner #include <vector>
12ef320154SBen Tyner 
13ef320154SBen Tyner namespace attn
14ef320154SBen Tyner {
15ef320154SBen Tyner 
16b481d905SBen Tyner /** @brief Return codes */
17b481d905SBen Tyner static constexpr int RC_SUCCESS     = 0;
18b481d905SBen Tyner static constexpr int RC_NOT_SUCCESS = 1;
19b481d905SBen Tyner 
20ef320154SBen Tyner /**
21ef320154SBen Tyner  * @brief Handle SBE vital attention
22ef320154SBen Tyner  *
23b481d905SBen Tyner  * @param i_attention Attention object
243fb52e53SBen Tyner  * @return 0 indicates that the vital attention was successfully handled
253fb52e53SBen Tyner  *         1 indicates that the vital attention was NOT successfully handled
26ef320154SBen Tyner  */
27b481d905SBen Tyner int handleVital(Attention* i_attention);
28ef320154SBen Tyner 
29ef320154SBen Tyner /**
30ef320154SBen Tyner  * @brief Handle checkstop attention
31ef320154SBen Tyner  *
32b481d905SBen Tyner  * @param i_attention Attention object
333fb52e53SBen Tyner  * @return 0 indicates that the checkstop attention was successfully handled
343fb52e53SBen Tyner  *         1 indicates that the checkstop attention was NOT successfully
353fb52e53SBen Tyner  *           handled.
36ef320154SBen Tyner  */
37b481d905SBen Tyner int handleCheckstop(Attention* i_attention);
38ef320154SBen Tyner 
39ef320154SBen Tyner /**
40ef320154SBen Tyner  * @brief Handle special attention
41ef320154SBen Tyner  *
42b481d905SBen Tyner  * @param i_attention Attention object
433fb52e53SBen Tyner  * @return 0 indicates that the special attention was successfully handled
443fb52e53SBen Tyner  *         1 indicates that the special attention was NOT successfully handled
45ef320154SBen Tyner  */
46b481d905SBen Tyner int handleSpecial(Attention* i_attention);
47ef320154SBen Tyner 
48ef320154SBen Tyner /**
49ef320154SBen Tyner  * @brief The main attention handler logic
50970fd4fbSBen Tyner  *
51970fd4fbSBen Tyner  * @param i_breakpoints true = breakpoint special attn handling enabled
52ef320154SBen Tyner  */
533fb52e53SBen Tyner void attnHandler(Config* i_config)
54ef320154SBen Tyner {
55b481d905SBen Tyner     // Vector of active attentions to be handled
56b481d905SBen Tyner     std::vector<Attention> active_attentions;
57b481d905SBen Tyner 
58ef320154SBen Tyner     uint32_t isr_val, isr_mask;
59ef320154SBen Tyner     uint32_t proc;
60ef320154SBen Tyner 
61ef320154SBen Tyner     // loop through processors looking for active attentions
62*117af99bSBen Tyner     log<level::INFO>("Attention handler started");
63*117af99bSBen Tyner 
64ef320154SBen Tyner     pdbg_target* target;
65ef320154SBen Tyner     pdbg_for_each_class_target("fsi", target)
66ef320154SBen Tyner     {
67*117af99bSBen Tyner         log<level::INFO>("iterating targets");
68ef320154SBen Tyner         if (PDBG_TARGET_ENABLED == pdbg_target_probe(target))
69ef320154SBen Tyner         {
70ef320154SBen Tyner             proc = pdbg_target_index(target); // get processor number
71ef320154SBen Tyner 
72ef320154SBen Tyner             std::stringstream ss; // log message stream
739dbab8beSBen Tyner             ss << "checking processor " << proc;
74ef320154SBen Tyner             log<level::INFO>(ss.str().c_str());
75ef320154SBen Tyner 
76ef320154SBen Tyner             // get active attentions on processor
77b481d905SBen Tyner             if (RC_SUCCESS != fsi_read(target, 0x1007, &isr_val))
78ef320154SBen Tyner             {
799dbab8beSBen Tyner                 log<level::INFO>("Error! cfam read 0x1007 FAILED");
80ef320154SBen Tyner             }
81ef320154SBen Tyner             else
82ef320154SBen Tyner             {
83ef320154SBen Tyner                 std::stringstream ss; // log message stream
849ae5ca41SBen Tyner                 ss << "cfam 0x1007 = 0x";
85ef320154SBen Tyner                 ss << std::hex << std::setw(8) << std::setfill('0');
869dbab8beSBen Tyner                 ss << isr_val;
87ef320154SBen Tyner                 log<level::INFO>(ss.str().c_str());
88ef320154SBen Tyner 
89ef320154SBen Tyner                 // get interrupt enabled special attentions mask
90b481d905SBen Tyner                 if (RC_SUCCESS != fsi_read(target, 0x100d, &isr_mask))
91ef320154SBen Tyner                 {
929dbab8beSBen Tyner                     log<level::INFO>("Error! cfam read 0x100d FAILED");
93ef320154SBen Tyner                 }
94ef320154SBen Tyner                 else
95ef320154SBen Tyner                 {
96ef320154SBen Tyner                     std::stringstream ss; // log message stream
979ae5ca41SBen Tyner                     ss << "cfam 0x100d = 0x";
98ef320154SBen Tyner                     ss << std::hex << std::setw(8) << std::setfill('0');
999dbab8beSBen Tyner                     ss << isr_mask;
100ef320154SBen Tyner                     log<level::INFO>(ss.str().c_str());
101ef320154SBen Tyner 
102ef320154SBen Tyner                     // bit 0 on "left": bit 30 = SBE vital attention
103ef320154SBen Tyner                     if (isr_val & isr_mask & 0x00000002)
104ef320154SBen Tyner                     {
1053fb52e53SBen Tyner                         active_attentions.emplace_back(
1063fb52e53SBen Tyner                             Attention::Vital, handleVital, target, i_config);
107ef320154SBen Tyner                     }
108ef320154SBen Tyner 
109ef320154SBen Tyner                     // bit 0 on "left": bit 1 = checkstop
110ef320154SBen Tyner                     if (isr_val & isr_mask & 0x40000000)
111ef320154SBen Tyner                     {
112b481d905SBen Tyner                         active_attentions.emplace_back(Attention::Checkstop,
113b481d905SBen Tyner                                                        handleCheckstop, target,
1143fb52e53SBen Tyner                                                        i_config);
115ef320154SBen Tyner                     }
116ef320154SBen Tyner 
117ef320154SBen Tyner                     // bit 0 on "left": bit 2 = special attention
118ef320154SBen Tyner                     if (isr_val & isr_mask & 0x20000000)
119ef320154SBen Tyner                     {
120b481d905SBen Tyner                         active_attentions.emplace_back(Attention::Special,
121b481d905SBen Tyner                                                        handleSpecial, target,
1223fb52e53SBen Tyner                                                        i_config);
123ef320154SBen Tyner                     }
124ef320154SBen Tyner                 } // cfam 0x100d valid
125ef320154SBen Tyner             }     // cfam 0x1007 valid
126ef320154SBen Tyner         }         // fsi target enabled
127ef320154SBen Tyner     }             // next processor
128ef320154SBen Tyner 
129b481d905SBen Tyner     // convert to heap, highest priority is at front
130b481d905SBen Tyner     if (!std::is_heap(active_attentions.begin(), active_attentions.end()))
131b481d905SBen Tyner     {
132b481d905SBen Tyner         std::make_heap(active_attentions.begin(), active_attentions.end());
133b481d905SBen Tyner     }
134b481d905SBen Tyner 
135b481d905SBen Tyner     // call the attention handler until one is handled or all were attempted
136b481d905SBen Tyner     while (false == active_attentions.empty())
137b481d905SBen Tyner     {
138b481d905SBen Tyner         // handle highest priority attention, done if successful
139b481d905SBen Tyner         if (RC_SUCCESS == active_attentions.front().handle())
140b481d905SBen Tyner         {
141b481d905SBen Tyner             break;
142b481d905SBen Tyner         }
143b481d905SBen Tyner 
144b481d905SBen Tyner         // move attention to back of vector
145b481d905SBen Tyner         std::pop_heap(active_attentions.begin(), active_attentions.end());
146b481d905SBen Tyner 
147b481d905SBen Tyner         // remove attention from vector
148b481d905SBen Tyner         active_attentions.pop_back();
149b481d905SBen Tyner     }
150ef320154SBen Tyner }
151ef320154SBen Tyner 
152ef320154SBen Tyner /**
153ef320154SBen Tyner  * @brief Handle SBE vital attention
1543fb52e53SBen Tyner  *
1553fb52e53SBen Tyner  * @param i_attention Attention object
1563fb52e53SBen Tyner  * @return 0 indicates that the vital attention was successfully handled
1573fb52e53SBen Tyner  *         1 indicates that the vital attention was NOT successfully handled
158ef320154SBen Tyner  */
159b481d905SBen Tyner int handleVital(Attention* i_attention)
160ef320154SBen Tyner {
1613fb52e53SBen Tyner     int rc = RC_SUCCESS; // assume vital handled
162ef320154SBen Tyner 
1633fb52e53SBen Tyner     // if vital handling enabled, handle vital attention
1643fb52e53SBen Tyner     if (false == (i_attention->getConfig()->getFlag(enVital)))
1653fb52e53SBen Tyner     {
1663fb52e53SBen Tyner         log<level::INFO>("vital handling disabled");
1673fb52e53SBen Tyner         rc = RC_NOT_SUCCESS;
1683fb52e53SBen Tyner     }
1693fb52e53SBen Tyner     else
170ef320154SBen Tyner     {
1719dbab8beSBen Tyner         log<level::INFO>("vital NOT handled");
1723fb52e53SBen Tyner         rc = RC_NOT_SUCCESS;
173ef320154SBen Tyner     }
174ef320154SBen Tyner 
175ef320154SBen Tyner     return rc;
176ef320154SBen Tyner }
177ef320154SBen Tyner 
178ef320154SBen Tyner /**
179ef320154SBen Tyner  * @brief Handle checkstop attention
1803fb52e53SBen Tyner  *
1813fb52e53SBen Tyner  * @param i_attention Attention object
1823fb52e53SBen Tyner  * @return 0 indicates that the checkstop attention was successfully handled
1833fb52e53SBen Tyner  *         1 indicates that the checkstop attention was NOT successfully
1843fb52e53SBen Tyner  *           handled.
185ef320154SBen Tyner  */
186b481d905SBen Tyner int handleCheckstop(Attention* i_attention)
187ef320154SBen Tyner {
1883fb52e53SBen Tyner     int rc = RC_SUCCESS; // assume checkstop handled
189ef320154SBen Tyner 
1903fb52e53SBen Tyner     // if checkstop handling enabled, handle checkstop attention
1913fb52e53SBen Tyner     if (false == (i_attention->getConfig()->getFlag(enCheckstop)))
1923fb52e53SBen Tyner     {
1933fb52e53SBen Tyner         log<level::INFO>("Checkstop handling disabled");
1943fb52e53SBen Tyner         rc = RC_NOT_SUCCESS;
1953fb52e53SBen Tyner     }
1963fb52e53SBen Tyner     else
1973fb52e53SBen Tyner     {
1980205f3b3SBen Tyner         analyzer::analyzeHardware();
1993fb52e53SBen Tyner         rc = RC_SUCCESS;
2003fb52e53SBen Tyner     }
201ef320154SBen Tyner 
202ef320154SBen Tyner     return rc;
203ef320154SBen Tyner }
204ef320154SBen Tyner 
205ef320154SBen Tyner /**
206ef320154SBen Tyner  * @brief Handle special attention
2073fb52e53SBen Tyner  *
2083fb52e53SBen Tyner  * @param i_attention Attention object
2093fb52e53SBen Tyner  * @return 0 indicates that the special attention was successfully handled
2103fb52e53SBen Tyner  *         1 indicates that the special attention was NOT successfully handled
211ef320154SBen Tyner  */
212b481d905SBen Tyner int handleSpecial(Attention* i_attention)
213ef320154SBen Tyner {
2143fb52e53SBen Tyner     int rc = RC_NOT_SUCCESS; // assume special attention handling disabled
215ef320154SBen Tyner 
2163fb52e53SBen Tyner     // Until the special attention chipop is availabe we will treat the special
2173fb52e53SBen Tyner     // attention as a TI. If TI handling is disabled we will treat the special
2183fb52e53SBen Tyner     // attention as a breakpopint.
219ef320154SBen Tyner 
2203fb52e53SBen Tyner     // TI attention gets priority over breakpoints, if enabled then handle
2213fb52e53SBen Tyner     if (true == (i_attention->getConfig()->getFlag(enTerminate)))
222970fd4fbSBen Tyner     {
2239dbab8beSBen Tyner         log<level::INFO>("TI (terminate immediately)");
224970fd4fbSBen Tyner 
2259ae5ca41SBen Tyner         // Call TI special attention handler
2269ae5ca41SBen Tyner         tiHandler();
2273fb52e53SBen Tyner         rc = RC_SUCCESS;
2283fb52e53SBen Tyner     }
2293fb52e53SBen Tyner     else
2303fb52e53SBen Tyner     {
2313fb52e53SBen Tyner         if (true == (i_attention->getConfig()->getFlag(enBreakpoints)))
2323fb52e53SBen Tyner         {
2333fb52e53SBen Tyner             log<level::INFO>("breakpoint");
2343fb52e53SBen Tyner 
2353fb52e53SBen Tyner             // Call the breakpoint special attention handler
2363fb52e53SBen Tyner             bpHandler();
2373fb52e53SBen Tyner             rc = RC_SUCCESS;
2383fb52e53SBen Tyner         }
239970fd4fbSBen Tyner     }
240ef320154SBen Tyner 
2413fb52e53SBen Tyner     if (RC_SUCCESS != rc)
2423fb52e53SBen Tyner     {
2433fb52e53SBen Tyner         log<level::INFO>("Special attn handling disabled");
2443fb52e53SBen Tyner     }
245ef320154SBen Tyner 
246ef320154SBen Tyner     return rc;
247ef320154SBen Tyner }
248ef320154SBen Tyner 
249ef320154SBen Tyner } // namespace attn
250