blob: 5e9f7a4251c7e0ff9969aa902e41be176627a193 [file] [log] [blame]
Ben Tynerbcf65a82020-12-01 08:46:36 -06001#include <attn/attn_common.hpp>
Ben Tyner5c5db652021-02-22 18:22:35 -06002#include <attn/attn_dbus.hpp>
Ben Tyner0f481a42021-10-19 11:23:43 -05003#include <attn/attn_dump.hpp>
Ben Tynerb797b3e2020-06-29 10:12:05 -05004#include <attn/attn_logging.hpp>
Ben Tynerf5210bb2021-01-05 12:58:10 -06005#include <attn/pel/pel_common.hpp>
Ben Tynerb797b3e2020-06-29 10:12:05 -05006#include <attn/ti_handler.hpp>
Ben Tyner9ae5ca42020-02-28 13:13:50 -06007#include <sdbusplus/bus.hpp>
Ben Tynerff17f962020-09-23 08:21:19 -05008#include <sdbusplus/exception.hpp>
Ben Tyner93067162021-07-23 10:39:30 -05009#include <util/dbus.hpp>
Ben Tyner9ae5ca42020-02-28 13:13:50 -060010
Ben Tyner40717722020-09-23 09:43:20 -050011#include <iomanip>
12#include <iostream>
13
Ben Tyner9ae5ca42020-02-28 13:13:50 -060014namespace attn
15{
16
Ben Tyner8c5e4f42020-10-28 11:11:55 -050017/**
18 * @brief Determine if this is a HB or PHYP TI event
19 *
20 * Use the TI info data area to determine if this is either a HB or a PHYP
21 * TI event then handle the event.
22 *
Ben Tynerf5210bb2021-01-05 12:58:10 -060023 * @param i_tiDataArea pointer to the TI info data
Ben Tyner8c5e4f42020-10-28 11:11:55 -050024 */
Ben Tyner792f32f2020-06-02 08:50:47 -050025int tiHandler(TiDataArea* i_tiDataArea)
Ben Tyner9ae5ca42020-02-28 13:13:50 -060026{
Ben Tynere4f5dbe2020-10-19 07:19:33 -050027 int rc = RC_SUCCESS;
Ben Tyner9ae5ca42020-02-28 13:13:50 -060028
Ben Tynerb8335562021-07-16 12:43:52 -050029 // capture some additional data for logs/traces
30 addHbStatusRegs();
31
Ben Tyner8c5e4f42020-10-28 11:11:55 -050032 // check TI data area if it is available
Ben Tynere4f5dbe2020-10-19 07:19:33 -050033 if (nullptr != i_tiDataArea)
Ben Tyner792f32f2020-06-02 08:50:47 -050034 {
Ben Tyner8c5e4f42020-10-28 11:11:55 -050035 // HB v. PHYP TI logic: Only hosboot will fill in hbTerminateType
Ben Tyner8882c322021-02-05 12:13:21 -060036 // and it will be non-zero. Only hostboot will fill out source and
37 // it it will be non-zero. Only PHYP will fill in srcFormat and it
38 // will be non-zero.
Ben Tyner8c5e4f42020-10-28 11:11:55 -050039 if ((0 == i_tiDataArea->hbTerminateType) &&
40 (0 == i_tiDataArea->source) && (0 != i_tiDataArea->srcFormat))
Ben Tynere4f5dbe2020-10-19 07:19:33 -050041 {
Ben Tyner8c5e4f42020-10-28 11:11:55 -050042 handlePhypTi(i_tiDataArea);
Ben Tynere4f5dbe2020-10-19 07:19:33 -050043 }
44 else
45 {
Ben Tyner8c5e4f42020-10-28 11:11:55 -050046 handleHbTi(i_tiDataArea);
Ben Tynere4f5dbe2020-10-19 07:19:33 -050047 }
Ben Tyner8c5e4f42020-10-28 11:11:55 -050048 }
49 else
50 {
Ben Tyner29651ef2021-02-08 10:51:03 -060051 // TI data was not available This should not happen since we provide
52 // a default TI info in the case where get TI info was not successful.
Ben Tyner7a0dd542021-02-12 09:33:44 -060053 eventAttentionFail((int)AttnSection::tiHandler | ATTN_INFO_NULL);
Ben Tyner29651ef2021-02-08 10:51:03 -060054 rc = RC_NOT_HANDLED;
Ben Tynere4f5dbe2020-10-19 07:19:33 -050055 }
Ben Tyner40717722020-09-23 09:43:20 -050056
Ben Tyner8c5e4f42020-10-28 11:11:55 -050057 return rc;
58}
Ben Tynere4f5dbe2020-10-19 07:19:33 -050059
Ben Tyner8c5e4f42020-10-28 11:11:55 -050060/**
Ben Tyner8c5e4f42020-10-28 11:11:55 -050061 * @brief Handle a PHYP terminate immediate special attention
62 *
63 * The TI info data area will contain information pertaining to the TI
64 * condition. We will wither quiesce the host or initiate a MPIPL depending
65 * depending on the auto reboot configuration. We will also create a PEL which
66 * will contain the TI info data and FFDC data captured in the system journal.
67 *
68 * @param i_tiDataArea pointer to TI information filled in by hostboot
69 */
70void handlePhypTi(TiDataArea* i_tiDataArea)
71{
72 trace<level::INFO>("PHYP TI");
73
Ben Tyner8c5e4f42020-10-28 11:11:55 -050074 // gather additional data for PEL
75 std::map<std::string, std::string> tiAdditionalData;
Ben Tynere4f5dbe2020-10-19 07:19:33 -050076
Ben Tyner8c5e4f42020-10-28 11:11:55 -050077 if (nullptr != i_tiDataArea)
78 {
79 parsePhypOpalTiInfo(tiAdditionalData, i_tiDataArea);
Ben Tyner29651ef2021-02-08 10:51:03 -060080
81 tiAdditionalData["Subsystem"] =
82 std::to_string(static_cast<uint8_t>(pel::SubsystemID::hypervisor));
83
Ben Tyner9d4f91c2021-02-09 08:27:58 -060084 // Copy all ascii src chars to additional data
85 char srcChar[33]; // 32 ascii chars + null term
86 memcpy(srcChar, &(i_tiDataArea->asciiData0), 32);
87 srcChar[32] = 0;
Ben Tyner29651ef2021-02-08 10:51:03 -060088 tiAdditionalData["SrcAscii"] = std::string{srcChar};
89
90 // TI event
91 eventTerminate(tiAdditionalData, (char*)i_tiDataArea);
Ben Tyner8c5e4f42020-10-28 11:11:55 -050092 }
Ben Tyner29651ef2021-02-08 10:51:03 -060093 else
94 {
95 // TI data was not available This should not happen since we provide
96 // a default TI info in the case where get TI info was not successful.
Ben Tyner7a0dd542021-02-12 09:33:44 -060097 eventAttentionFail((int)AttnSection::handlePhypTi | ATTN_INFO_NULL);
Ben Tyner29651ef2021-02-08 10:51:03 -060098 }
Ben Tyner063f6bd2021-03-26 07:45:56 -050099
100 // We are finished creating the event log entries so transition host to
101 // the required state.
Ben Tyner39fcf652021-10-19 20:38:29 -0500102 if (true == util::dbus::dumpPolicyEnabled())
Ben Tyner063f6bd2021-03-26 07:45:56 -0500103 {
Ben Tyner39fcf652021-10-19 20:38:29 -0500104 // MPIPL is considered a "dump" so we will qualify this transition with
105 // the dumpPolicyEnabled property. MPIPL is triggered by by starting
106 // the host "crash" target.
Ben Tyner93067162021-07-23 10:39:30 -0500107 util::dbus::transitionHost(util::dbus::HostState::Crash);
Ben Tyner063f6bd2021-03-26 07:45:56 -0500108 }
109 else
110 {
Ben Tyner39fcf652021-10-19 20:38:29 -0500111 // If dumpPolicyEnabled property is disabled we will quiesce the host
Ben Tyner93067162021-07-23 10:39:30 -0500112 util::dbus::transitionHost(util::dbus::HostState::Quiesce);
Ben Tyner063f6bd2021-03-26 07:45:56 -0500113 }
Ben Tyner8c5e4f42020-10-28 11:11:55 -0500114}
115
116/**
Ben Tyner0f481a42021-10-19 11:23:43 -0500117 * @brief Handle a hostboot terminate immediate with SRC provided
Ben Tyner8c5e4f42020-10-28 11:11:55 -0500118 *
Ben Tyner0f481a42021-10-19 11:23:43 -0500119 * The TI info will contain the log ID of the event log that has already been
120 * submitted by hostboot. In this case the attention handler does not need to
121 * create a PEL. A hostboot dump may be requested and the host will be
122 * transitioned.
Ben Tyner8c5e4f42020-10-28 11:11:55 -0500123 *
124 * @param i_tiDataArea pointer to TI information filled in by hostboot
125 */
Ben Tyner0f481a42021-10-19 11:23:43 -0500126void handleHbTiWithEid(TiDataArea* i_tiDataArea)
Ben Tyner8c5e4f42020-10-28 11:11:55 -0500127{
Ben Tyner0f481a42021-10-19 11:23:43 -0500128 trace<level::INFO>("HB TI with PLID/EID");
Ben Tyner8c5e4f42020-10-28 11:11:55 -0500129
Ben Tyner0f481a42021-10-19 11:23:43 -0500130 if (nullptr != i_tiDataArea)
131 {
132 // see if HB dump is requested
133 if (0 != i_tiDataArea->hbDumpFlag)
134 {
135 // retrieve log ID from TI info data
136 uint32_t logId = be32toh(i_tiDataArea->asciiData1);
137 requestDump(DumpParameters{logId, 0, DumpType::Hostboot});
138 }
139 }
140
141 util::dbus::transitionHost(util::dbus::HostState::Quiesce);
142}
143
144/**
145 * @brief Handle a hostboot terminate immediate with SRC provided
146 *
147 * The TI info will contain the reason code and additional data necessary
148 * to create a PEL on behalf of hostboot. A hostboot dump may be created
149 * (after generating the PEL) and the host may be transitioned depending
150 * on the reason code.
151 *
152 * @param i_tiDataArea pointer to TI information filled in by hostboot
153 */
154void handleHbTiWithSrc(TiDataArea* i_tiDataArea)
155{
156 trace<level::INFO>("HB TI with SRC");
Ben Tyner8c5e4f42020-10-28 11:11:55 -0500157
158 // handle specific hostboot reason codes
159 if (nullptr != i_tiDataArea)
160 {
Ben Tyner0f481a42021-10-19 11:23:43 -0500161 // Reason code is byte 2 and 3 of 4 byte srcWord12HbWord0
162 uint16_t reasonCode = be32toh(i_tiDataArea->srcWord12HbWord0);
Ben Tyner8c5e4f42020-10-28 11:11:55 -0500163
Ben Tyner0f481a42021-10-19 11:23:43 -0500164 if (reasonCode != HB_SRC_SHUTDOWN_REQUEST)
Ben Tyner29651ef2021-02-08 10:51:03 -0600165 {
Ben Tyner5c5db652021-02-22 18:22:35 -0600166 // gather additional data for PEL
167 std::map<std::string, std::string> tiAdditionalData;
168
169 parseHbTiInfo(tiAdditionalData, i_tiDataArea);
170
Ben Tyner29651ef2021-02-08 10:51:03 -0600171 tiAdditionalData["Subsystem"] = std::to_string(
172 static_cast<uint8_t>(pel::SubsystemID::hostboot));
173
Ben Tyner5c5db652021-02-22 18:22:35 -0600174 // Translate hex src value to ascii. This results in an 8
175 // character SRC (hostboot SRC is 32 bits)
Ben Tyner9d4f91c2021-02-09 08:27:58 -0600176 std::stringstream src;
Ben Tyner4bbcb382021-02-22 09:29:00 -0600177 src << std::setw(8) << std::setfill('0') << std::uppercase
178 << std::hex << be32toh(i_tiDataArea->srcWord12HbWord0);
Ben Tyner9d4f91c2021-02-09 08:27:58 -0600179 tiAdditionalData["SrcAscii"] = src.str();
Ben Tyner29651ef2021-02-08 10:51:03 -0600180
Ben Tyner5c5db652021-02-22 18:22:35 -0600181 // Request dump after generating event log?
182 tiAdditionalData["Dump"] =
Ben Tyner0f481a42021-10-19 11:23:43 -0500183 (0 != i_tiDataArea->hbDumpFlag) ? "true" : "false";
Ben Tyner5c5db652021-02-22 18:22:35 -0600184
185 // Generate event log
Ben Tyner29651ef2021-02-08 10:51:03 -0600186 eventTerminate(tiAdditionalData, (char*)i_tiDataArea);
187 }
Ben Tyner0f481a42021-10-19 11:23:43 -0500188
189 if (HB_SRC_KEY_TRANSITION != reasonCode)
Ben Tyner5c5db652021-02-22 18:22:35 -0600190 {
Ben Tyner0f481a42021-10-19 11:23:43 -0500191 util::dbus::transitionHost(util::dbus::HostState::Quiesce);
Ben Tyner5c5db652021-02-22 18:22:35 -0600192 }
Ben Tyner40717722020-09-23 09:43:20 -0500193 }
Ben Tyner0f481a42021-10-19 11:23:43 -0500194 else
Ben Tyner063f6bd2021-03-26 07:45:56 -0500195 {
Ben Tyner0f481a42021-10-19 11:23:43 -0500196 // TI data was not available, this should not happen
197 eventAttentionFail((int)AttnSection::handleHbTi | ATTN_INFO_NULL);
198 }
199}
200
201/**
202 * @brief Handle a hostboot terminate immediate special attention
203 *
204 * The TI info data area will contain information pertaining to the TI
205 * condition. The course of action to take regarding the host state will
206 * depend on the contents of the TI info data area. We will also create a
207 * PEL containing the TI info data and FFDC data captured in the system
208 * journal.
209 *
210 * @param i_tiDataArea pointer to TI information filled in by hostboot
211 */
212void handleHbTi(TiDataArea* i_tiDataArea)
213{
214 trace<level::INFO>("HB TI");
215
216 // handle specific hostboot reason codes
217 if (nullptr != i_tiDataArea)
218 {
219 uint8_t terminateType = i_tiDataArea->hbTerminateType;
220
221 if (TI_WITH_SRC == terminateType)
222 {
223 handleHbTiWithSrc(i_tiDataArea);
224 }
225 else
226 {
227 handleHbTiWithEid(i_tiDataArea);
228 }
229 }
230 else
231 {
232 // TI data was not available, this should not happen
233 eventAttentionFail((int)AttnSection::handleHbTi | ATTN_INFO_NULL);
Ben Tyner063f6bd2021-03-26 07:45:56 -0500234 }
Ben Tyner40717722020-09-23 09:43:20 -0500235}
236
237/** @brief Parse the TI info data area into map as PHYP/OPAL data */
238void parsePhypOpalTiInfo(std::map<std::string, std::string>& i_map,
239 TiDataArea* i_tiDataArea)
240{
Ben Tyner1c4b02e2020-11-09 14:00:29 -0600241 if (nullptr == i_tiDataArea)
242 {
243 return;
244 }
245
Ben Tyner40717722020-09-23 09:43:20 -0500246 std::stringstream ss;
247
Ben Tynerfeeea832021-04-06 10:08:11 -0500248 ss << "0x00 TI Area Valid:" << std::setw(2) << std::setfill('0') << std::hex
249 << (int)i_tiDataArea->tiAreaValid << ":";
250 ss << "0x01 Command:" << std::setw(2) << std::setfill('0') << std::hex
251 << (int)i_tiDataArea->command << ":";
252 ss << "0x02 Num. Data Bytes:" << std::setw(4) << std::setfill('0')
253 << std::hex << be16toh(i_tiDataArea->numDataBytes) << ":";
254 ss << "0x04 Reserved:" << std::setw(2) << std::setfill('0') << std::hex
255 << (int)i_tiDataArea->reserved1 << ":";
256 ss << "0x06 HWDump Type:" << std::setw(4) << std::setfill('0') << std::hex
257 << be16toh(i_tiDataArea->hardwareDumpType) << ":";
258 ss << "0x08 SRC Format:" << std::setw(2) << std::setfill('0') << std::hex
259 << (int)i_tiDataArea->srcFormat << ":";
260 ss << "0x09 SRC Flags:" << std::setw(2) << std::setfill('0') << std::hex
261 << (int)i_tiDataArea->srcFlags << ":";
262 ss << "0x0a Num. ASCII Words:" << std::setw(2) << std::setfill('0')
263 << std::hex << (int)i_tiDataArea->numAsciiWords << ":";
264 ss << "0x0b Num. Hex Words:" << std::setw(2) << std::setfill('0')
265 << std::hex << (int)i_tiDataArea->numHexWords << ":";
266 ss << "0x0e Length of SRC:" << std::setw(4) << std::setfill('0') << std::hex
267 << be16toh(i_tiDataArea->lenSrc) << ":";
268 ss << "0x10 SRC Word 12:" << std::setw(8) << std::setfill('0') << std::hex
269 << be32toh(i_tiDataArea->srcWord12HbWord0) << ":";
270 ss << "0x14 SRC Word 13:" << std::setw(8) << std::setfill('0') << std::hex
271 << be32toh(i_tiDataArea->srcWord13HbWord2) << ":";
272 ss << "0x18 SRC Word 14:" << std::setw(8) << std::setfill('0') << std::hex
273 << be32toh(i_tiDataArea->srcWord14HbWord3) << ":";
274 ss << "0x1c SRC Word 15:" << std::setw(8) << std::setfill('0') << std::hex
275 << be32toh(i_tiDataArea->srcWord15HbWord4) << ":";
276 ss << "0x20 SRC Word 16:" << std::setw(8) << std::setfill('0') << std::hex
277 << be32toh(i_tiDataArea->srcWord16HbWord5) << ":";
278 ss << "0x24 SRC Word 17:" << std::setw(8) << std::setfill('0') << std::hex
279 << be32toh(i_tiDataArea->srcWord17HbWord6) << ":";
280 ss << "0x28 SRC Word 18:" << std::setw(8) << std::setfill('0') << std::hex
281 << be32toh(i_tiDataArea->srcWord18HbWord7) << ":";
282 ss << "0x2c SRC Word 19:" << std::setw(8) << std::setfill('0') << std::hex
283 << be32toh(i_tiDataArea->srcWord19HbWord8) << ":";
284 ss << "0x30 ASCII Data:" << std::setw(8) << std::setfill('0') << std::hex
285 << be32toh(i_tiDataArea->asciiData0) << ":";
286 ss << "0x34 ASCII Data:" << std::setw(8) << std::setfill('0') << std::hex
287 << be32toh(i_tiDataArea->asciiData1) << ":";
288 ss << "0x38 ASCII Data:" << std::setw(8) << std::setfill('0') << std::hex
289 << be32toh(i_tiDataArea->asciiData2) << ":";
290 ss << "0x3c ASCII Data:" << std::setw(8) << std::setfill('0') << std::hex
291 << be32toh(i_tiDataArea->asciiData3) << ":";
292 ss << "0x40 ASCII Data:" << std::setw(8) << std::setfill('0') << std::hex
293 << be32toh(i_tiDataArea->asciiData4) << ":";
294 ss << "0x44 ASCII Data:" << std::setw(8) << std::setfill('0') << std::hex
295 << be32toh(i_tiDataArea->asciiData5) << ":";
296 ss << "0x48 ASCII Data:" << std::setw(8) << std::setfill('0') << std::hex
297 << be32toh(i_tiDataArea->asciiData6) << ":";
298 ss << "0x4c ASCII Data:" << std::setw(8) << std::setfill('0') << std::hex
299 << be32toh(i_tiDataArea->asciiData7) << ":";
300 ss << "0x50 Location:" << std::setw(2) << std::setfill('0') << std::hex
301 << (int)i_tiDataArea->location << ":";
302 ss << "0x51 Code Sections:" << std::setw(2) << std::setfill('0') << std::hex
303 << (int)i_tiDataArea->codeSection << ":";
304 ss << "0x52 Additional Size:" << std::setw(2) << std::setfill('0')
305 << std::hex << (int)i_tiDataArea->additionalSize << ":";
306 ss << "0x53 Additional Data:" << std::setw(2) << std::setfill('0')
307 << std::hex << (int)i_tiDataArea->andData;
Ben Tyner40717722020-09-23 09:43:20 -0500308
309 std::string key, value;
310 char delim = ':';
311
312 while (std::getline(ss, key, delim))
313 {
314 std::getline(ss, value, delim);
315 i_map[key] = value;
316 }
317}
318
319/** @brief Parse the TI info data area into map as hostboot data */
320void parseHbTiInfo(std::map<std::string, std::string>& i_map,
321 TiDataArea* i_tiDataArea)
322{
Ben Tyner1c4b02e2020-11-09 14:00:29 -0600323 if (nullptr == i_tiDataArea)
324 {
325 return;
326 }
327
Ben Tyner40717722020-09-23 09:43:20 -0500328 std::stringstream ss;
329
Ben Tynerfeeea832021-04-06 10:08:11 -0500330 ss << "0x00 TI Area Valid:" << std::setw(2) << std::setfill('0') << std::hex
331 << (int)i_tiDataArea->tiAreaValid << ":";
332 ss << "0x04 Reserved:" << std::setw(2) << std::setfill('0') << std::hex
333 << (int)i_tiDataArea->reserved1 << ":";
334 ss << "0x05 HB_Term. Type:" << std::setw(2) << std::setfill('0') << std::hex
335 << (int)i_tiDataArea->hbTerminateType << ":";
336 ss << "0x0c HB Dump Flag:" << std::setw(2) << std::setfill('0') << std::hex
337 << (int)i_tiDataArea->hbDumpFlag << ":";
338 ss << "0x0d Source:" << std::setw(2) << std::setfill('0') << std::hex
339 << (int)i_tiDataArea->source << ":";
340 ss << "0x10 HB Word 0:" << std::setw(8) << std::setfill('0') << std::hex
341 << be32toh(i_tiDataArea->srcWord12HbWord0) << ":";
342 ss << "0x14 HB Word 2:" << std::setw(8) << std::setfill('0') << std::hex
343 << be32toh(i_tiDataArea->srcWord13HbWord2) << ":";
344 ss << "0x18 HB Word 3:" << std::setw(8) << std::setfill('0') << std::hex
345 << be32toh(i_tiDataArea->srcWord14HbWord3) << ":";
346 ss << "0x1c HB Word 4:" << std::setw(8) << std::setfill('0') << std::hex
347 << be32toh(i_tiDataArea->srcWord15HbWord4) << ":";
348 ss << "0x20 HB Word 5:" << std::setw(8) << std::setfill('0') << std::hex
349 << be32toh(i_tiDataArea->srcWord16HbWord5) << ":";
350 ss << "0x24 HB Word 6:" << std::setw(8) << std::setfill('0') << std::hex
351 << be32toh(i_tiDataArea->srcWord17HbWord6) << ":";
352 ss << "0x28 HB Word 7:" << std::setw(8) << std::setfill('0') << std::hex
353 << be32toh(i_tiDataArea->srcWord18HbWord7) << ":";
354 ss << "0x2c HB Word 8:" << std::setw(8) << std::setfill('0') << std::hex
355 << be32toh(i_tiDataArea->srcWord19HbWord8) << ":";
356 ss << "0x30 error_data:" << std::setw(8) << std::setfill('0') << std::hex
357 << be32toh(i_tiDataArea->asciiData0) << ":";
358 ss << "0x34 EID:" << std::setw(8) << std::setfill('0') << std::hex
359 << be32toh(i_tiDataArea->asciiData1);
Ben Tyner40717722020-09-23 09:43:20 -0500360
361 std::string key, value;
362 char delim = ':';
363
364 while (std::getline(ss, key, delim))
365 {
366 std::getline(ss, value, delim);
367 i_map[key] = value;
368 }
369}
370
Ben Tyner9ae5ca42020-02-28 13:13:50 -0600371} // namespace attn