blob: cac1f84c2cfc7cdb2bc0a61ab2f2d1afccad9c1a [file] [log] [blame]
Ben Tyneref320152020-01-09 10:31:23 -06001#include <libpdbg.h>
2
3#include <phosphor-logging/log.hpp>
4#include <sdbusplus/bus.hpp>
5
6#include <iomanip>
7
8using namespace phosphor::logging;
9
10namespace attn
11{
12
13/**
14 * @brief Handle SBE vital attention
15 *
16 * @return 0 = success
17 */
18int handleVital();
19
20/**
21 * @brief Handle checkstop attention
22 *
23 * @return 0 = success
24 */
25int handleCheckstop();
26
27/**
28 * @brief Handle special attention
29 *
30 * @return 0 = success
31 */
32int handleSpecial();
33
34/**
35 * @brief Notify Cronus over dbus interface
36 *
37 * @param i_proc Processor number with Special attention
38 * @param i_core Core number with special attention
39 * @param i_thread Thread number with special attention
40 */
41void notifyCronus(uint32_t i_proc, uint32_t i_core, uint32_t i_thread);
42
43/**
44 * @brief The main attention handler logic
45 */
46void attnHandler()
47{
48 uint32_t isr_val, isr_mask;
49 uint32_t proc;
50
51 // loop through processors looking for active attentions
52 pdbg_target* target;
53 pdbg_for_each_class_target("fsi", target)
54 {
55 if (PDBG_TARGET_ENABLED == pdbg_target_probe(target))
56 {
57 proc = pdbg_target_index(target); // get processor number
58
59 std::stringstream ss; // log message stream
60 ss << "[ATTN] checking processor " << proc << std::endl;
61 log<level::INFO>(ss.str().c_str());
62
63 // get active attentions on processor
64 if (0 != fsi_read(target, 0x1007, &isr_val))
65 {
66 std::stringstream ss; // log message stream
67 ss << "[ATTN] Error! cfam read 0x1007 FAILED" << std::endl;
68 log<level::INFO>(ss.str().c_str());
69 }
70 else
71 {
72 std::stringstream ss; // log message stream
73 ss << "[ATTN] cfam 0x1007 = 0x";
74 ss << std::hex << std::setw(8) << std::setfill('0');
75 ss << isr_val << std::endl;
76 log<level::INFO>(ss.str().c_str());
77
78 // get interrupt enabled special attentions mask
79 if (0 != fsi_read(target, 0x100d, &isr_mask))
80 {
81 std::stringstream ss; // log message stream
82 ss << "[ATTN] Error! cfam read 0x100d FAILED" << std::endl;
83 log<level::INFO>(ss.str().c_str());
84 }
85 else
86 {
87 std::stringstream ss; // log message stream
88 ss << "[ATTN] cfam 0x100d = 0x";
89 ss << std::hex << std::setw(8) << std::setfill('0');
90 ss << isr_mask << std::endl;
91 log<level::INFO>(ss.str().c_str());
92
93 // bit 0 on "left": bit 30 = SBE vital attention
94 if (isr_val & isr_mask & 0x00000002)
95 {
96 handleVital();
97 }
98
99 // bit 0 on "left": bit 1 = checkstop
100 if (isr_val & isr_mask & 0x40000000)
101 {
102 handleCheckstop();
103 }
104
105 // bit 0 on "left": bit 2 = special attention
106 if (isr_val & isr_mask & 0x20000000)
107 {
108 handleSpecial();
109 }
110 } // cfam 0x100d valid
111 } // cfam 0x1007 valid
112 } // fsi target enabled
113 } // next processor
114
115 return; // checked all processors
116}
117
118/**
119 * @brief Handle SBE vital attention
120 */
121int handleVital()
122{
123 int rc = 1; // vital attention handling not yet supported
124
125 std::stringstream ss; // log message stream
126 ss << "[ATTN] vital" << std::endl;
127 log<level::INFO>(ss.str().c_str());
128
129 if (0 != rc)
130 {
131 std::stringstream ss; // log message stream
132 ss << "[ATTN] vital NOT handled" << std::endl;
133 log<level::INFO>(ss.str().c_str());
134 }
135
136 return rc;
137}
138
139/**
140 * @brief Handle checkstop attention
141 */
142int handleCheckstop()
143{
144 int rc = 1; // checkstop handling not yet supported
145
146 std::stringstream ss; // log message stream
147 ss << "[ATTN] checkstop" << std::endl;
148 log<level::INFO>(ss.str().c_str());
149
150 if (0 != rc)
151 {
152 std::stringstream ss; // log message stream
153 ss << "[ATTN] checkstop NOT handled" << std::endl;
154 log<level::INFO>(ss.str().c_str());
155 }
156
157 // TODO recoverable errors?
158
159 return rc;
160}
161
162/**
163 * @brief Handle special attention
164 */
165int handleSpecial()
166{
167 int rc = 0; // special attention handling supported
168
169 std::stringstream ss; // log message stream
170
171 ss << "[ATTN] special" << std::endl;
172
173 // Currently we are only handling Cronus breakpoints
174 ss << "[ATTN] breakpoint" << std::endl;
175 log<level::INFO>(ss.str().c_str());
176
177 // Cronus will determine proc, core and thread so just notify
178 notifyCronus(0, 0, 0); // proc-0, core-0, thread-0
179
180 // TODO recoverable errors?
181
182 return rc;
183}
184
185/**
186 * @brief Notify Cronus over dbus interface
187 */
188void notifyCronus(uint32_t i_proc, uint32_t i_core, uint32_t i_thread)
189{
190 std::stringstream ss; // log message stream
191
192 // log status info
193 ss << "[ATTN] notify ";
194 ss << i_proc << ", " << i_core << ", " << i_thread << std::endl;
195 log<level::INFO>(ss.str().c_str());
196
197 // notify Cronus over dbus
198 auto bus = sdbusplus::bus::new_system();
199 auto msg = bus.new_signal("/", "org.openbmc.cronus", "Brkpt");
200
201 std::array<uint32_t, 3> params{i_proc, i_core, i_thread};
202 msg.append(params);
203
204 msg.signal_send();
205}
206
207} // namespace attn