1 #include <libpdbg.h>
2 
3 #include <analyzer/analyzer_main.hpp>
4 #include <bp_handler.hpp>
5 #include <logging.hpp>
6 #include <ti_handler.hpp>
7 
8 #include <iomanip>
9 #include <sstream>
10 
11 namespace attn
12 {
13 
14 /**
15  * @brief Handle SBE vital attention
16  *
17  * @return 0 = success
18  */
19 int handleVital();
20 
21 /**
22  * @brief Handle checkstop attention
23  *
24  * @return 0 = success
25  */
26 int handleCheckstop();
27 
28 /**
29  * @brief Handle special attention
30  *
31  * @param i_breakpoints true = breakpoint special attn handling enabled
32  * @return 0 = success
33  */
34 int handleSpecial(bool i_breakpoints);
35 
36 /**
37  * @brief The main attention handler logic
38  *
39  * @param i_breakpoints true = breakpoint special attn handling enabled
40  */
41 void attnHandler(bool i_breakpoints)
42 {
43     uint32_t isr_val, isr_mask;
44     uint32_t proc;
45 
46     // loop through processors looking for active attentions
47     pdbg_target* target;
48     pdbg_for_each_class_target("fsi", target)
49     {
50         if (PDBG_TARGET_ENABLED == pdbg_target_probe(target))
51         {
52             proc = pdbg_target_index(target); // get processor number
53 
54             std::stringstream ss; // log message stream
55             ss << "checking processor " << proc << std::endl;
56             log<level::INFO>(ss.str().c_str());
57 
58             // get active attentions on processor
59             if (0 != fsi_read(target, 0x1007, &isr_val))
60             {
61                 std::stringstream ss; // log message stream
62                 ss << "Error! cfam read 0x1007 FAILED" << std::endl;
63                 log<level::INFO>(ss.str().c_str());
64             }
65             else
66             {
67                 std::stringstream ss; // log message stream
68                 ss << "cfam 0x1007 = 0x";
69                 ss << std::hex << std::setw(8) << std::setfill('0');
70                 ss << isr_val << std::endl;
71                 log<level::INFO>(ss.str().c_str());
72 
73                 // get interrupt enabled special attentions mask
74                 if (0 != fsi_read(target, 0x100d, &isr_mask))
75                 {
76                     std::stringstream ss; // log message stream
77                     ss << "Error! cfam read 0x100d FAILED" << std::endl;
78                     log<level::INFO>(ss.str().c_str());
79                 }
80                 else
81                 {
82                     std::stringstream ss; // log message stream
83                     ss << "cfam 0x100d = 0x";
84                     ss << std::hex << std::setw(8) << std::setfill('0');
85                     ss << isr_mask << std::endl;
86                     log<level::INFO>(ss.str().c_str());
87 
88                     // bit 0 on "left": bit 30 = SBE vital attention
89                     if (isr_val & isr_mask & 0x00000002)
90                     {
91                         handleVital();
92                     }
93 
94                     // bit 0 on "left": bit 1 = checkstop
95                     if (isr_val & isr_mask & 0x40000000)
96                     {
97                         if (0 == handleCheckstop())
98                         {
99                             break;
100                         }
101                     }
102 
103                     // bit 0 on "left": bit 2 = special attention
104                     if (isr_val & isr_mask & 0x20000000)
105                     {
106                         handleSpecial(i_breakpoints);
107                     }
108                 } // cfam 0x100d valid
109             }     // cfam 0x1007 valid
110         }         // fsi target enabled
111     }             // next processor
112 
113     return; // checked all processors
114 }
115 
116 /**
117  * @brief Handle SBE vital attention
118  */
119 int handleVital()
120 {
121     int rc = 1; // vital attention handling not yet supported
122 
123     std::stringstream ss; // log message stream
124     ss << "vital" << std::endl;
125     log<level::INFO>(ss.str().c_str());
126 
127     if (0 != rc)
128     {
129         std::stringstream ss; // log message stream
130         ss << "vital NOT handled" << std::endl;
131         log<level::INFO>(ss.str().c_str());
132     }
133 
134     return rc;
135 }
136 
137 /**
138  * @brief Handle checkstop attention
139  */
140 int handleCheckstop()
141 {
142     int rc = 0; // checkstop handling supported
143 
144     std::stringstream ss; // log message stream
145     ss << "checkstop" << std::endl;
146     log<level::INFO>(ss.str().c_str());
147 
148     analyzer::analyzeHardware();
149 
150     // TODO recoverable errors?
151 
152     return rc;
153 }
154 
155 /**
156  * @brief Handle special attention
157  *
158  * @param i_breakpoints true = breakpoint special attn handling enabled
159  */
160 int handleSpecial(bool i_breakpoints)
161 {
162     int rc = 0; // special attention handling supported
163 
164     std::stringstream ss; // log message stream
165 
166     ss << "special" << std::endl;
167 
168     // Right now we always handle breakpoint special attentions if breakpoint
169     // attn handling is enabled. This will eventually check if breakpoint attn
170     // handing is enabled AND there is a breakpoint pending.
171     if (true == i_breakpoints)
172     {
173         ss << "breakpoint" << std::endl;
174         log<level::INFO>(ss.str().c_str());
175 
176         // Call the breakpoint special attention handler
177         bpHandler();
178     }
179     // Right now if breakpoint attn handling is not enabled we will treat the
180     // special attention as a TI. This will eventually be changed to check
181     // whether a TI is active and handle it regardless of whether breakpoint
182     // handling is enbaled or not.
183     else
184     {
185         ss << "TI (terminate immediately)" << std::endl;
186         log<level::INFO>(ss.str().c_str());
187 
188         // Call TI special attention handler
189         tiHandler();
190     }
191 
192     // TODO recoverable errors?
193 
194     return rc;
195 }
196 
197 } // namespace attn
198