blob: 54345a64fd036278320e78ea8d76c03bbd98a94d [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 Tynerb797b3e2020-06-29 10:12:05 -05003#include <attn/attn_logging.hpp>
Ben Tynerf5210bb2021-01-05 12:58:10 -06004#include <attn/pel/pel_common.hpp>
Ben Tynerb797b3e2020-06-29 10:12:05 -05005#include <attn/ti_handler.hpp>
Ben Tyner9ae5ca42020-02-28 13:13:50 -06006#include <sdbusplus/bus.hpp>
Ben Tynerff17f962020-09-23 08:21:19 -05007#include <sdbusplus/exception.hpp>
Ben Tyner93067162021-07-23 10:39:30 -05008#include <util/dbus.hpp>
Ben Tyner9ae5ca42020-02-28 13:13:50 -06009
Ben Tyner40717722020-09-23 09:43:20 -050010#include <iomanip>
11#include <iostream>
12
Ben Tyner9ae5ca42020-02-28 13:13:50 -060013namespace attn
14{
15
Ben Tyner8c5e4f42020-10-28 11:11:55 -050016/**
17 * @brief Determine if this is a HB or PHYP TI event
18 *
19 * Use the TI info data area to determine if this is either a HB or a PHYP
20 * TI event then handle the event.
21 *
Ben Tynerf5210bb2021-01-05 12:58:10 -060022 * @param i_tiDataArea pointer to the TI info data
Ben Tyner8c5e4f42020-10-28 11:11:55 -050023 */
Ben Tyner792f32f2020-06-02 08:50:47 -050024int tiHandler(TiDataArea* i_tiDataArea)
Ben Tyner9ae5ca42020-02-28 13:13:50 -060025{
Ben Tynere4f5dbe2020-10-19 07:19:33 -050026 int rc = RC_SUCCESS;
Ben Tyner9ae5ca42020-02-28 13:13:50 -060027
Ben Tynerb8335562021-07-16 12:43:52 -050028 // capture some additional data for logs/traces
29 addHbStatusRegs();
30
Ben Tyner8c5e4f42020-10-28 11:11:55 -050031 // check TI data area if it is available
Ben Tynere4f5dbe2020-10-19 07:19:33 -050032 if (nullptr != i_tiDataArea)
Ben Tyner792f32f2020-06-02 08:50:47 -050033 {
Ben Tyner8c5e4f42020-10-28 11:11:55 -050034 // HB v. PHYP TI logic: Only hosboot will fill in hbTerminateType
Ben Tyner8882c322021-02-05 12:13:21 -060035 // and it will be non-zero. Only hostboot will fill out source and
36 // it it will be non-zero. Only PHYP will fill in srcFormat and it
37 // will be non-zero.
Ben Tyner8c5e4f42020-10-28 11:11:55 -050038 if ((0 == i_tiDataArea->hbTerminateType) &&
39 (0 == i_tiDataArea->source) && (0 != i_tiDataArea->srcFormat))
Ben Tynere4f5dbe2020-10-19 07:19:33 -050040 {
Ben Tyner8c5e4f42020-10-28 11:11:55 -050041 handlePhypTi(i_tiDataArea);
Ben Tynere4f5dbe2020-10-19 07:19:33 -050042 }
43 else
44 {
Ben Tyner8c5e4f42020-10-28 11:11:55 -050045 handleHbTi(i_tiDataArea);
Ben Tynere4f5dbe2020-10-19 07:19:33 -050046 }
Ben Tyner8c5e4f42020-10-28 11:11:55 -050047 }
48 else
49 {
Ben Tyner29651ef2021-02-08 10:51:03 -060050 // TI data was not available This should not happen since we provide
51 // a default TI info in the case where get TI info was not successful.
Ben Tyner7a0dd542021-02-12 09:33:44 -060052 eventAttentionFail((int)AttnSection::tiHandler | ATTN_INFO_NULL);
Ben Tyner29651ef2021-02-08 10:51:03 -060053 rc = RC_NOT_HANDLED;
Ben Tynere4f5dbe2020-10-19 07:19:33 -050054 }
Ben Tyner40717722020-09-23 09:43:20 -050055
Ben Tyner8c5e4f42020-10-28 11:11:55 -050056 return rc;
57}
Ben Tynere4f5dbe2020-10-19 07:19:33 -050058
Ben Tyner8c5e4f42020-10-28 11:11:55 -050059/**
Ben Tyner8c5e4f42020-10-28 11:11:55 -050060 * @brief Handle a PHYP terminate immediate special attention
61 *
62 * The TI info data area will contain information pertaining to the TI
63 * condition. We will wither quiesce the host or initiate a MPIPL depending
64 * depending on the auto reboot configuration. We will also create a PEL which
65 * will contain the TI info data and FFDC data captured in the system journal.
66 *
67 * @param i_tiDataArea pointer to TI information filled in by hostboot
68 */
69void handlePhypTi(TiDataArea* i_tiDataArea)
70{
71 trace<level::INFO>("PHYP TI");
72
Ben Tyner8c5e4f42020-10-28 11:11:55 -050073 // gather additional data for PEL
74 std::map<std::string, std::string> tiAdditionalData;
Ben Tynere4f5dbe2020-10-19 07:19:33 -050075
Ben Tyner8c5e4f42020-10-28 11:11:55 -050076 if (nullptr != i_tiDataArea)
77 {
78 parsePhypOpalTiInfo(tiAdditionalData, i_tiDataArea);
Ben Tyner29651ef2021-02-08 10:51:03 -060079
80 tiAdditionalData["Subsystem"] =
81 std::to_string(static_cast<uint8_t>(pel::SubsystemID::hypervisor));
82
Ben Tyner9d4f91c2021-02-09 08:27:58 -060083 // Copy all ascii src chars to additional data
84 char srcChar[33]; // 32 ascii chars + null term
85 memcpy(srcChar, &(i_tiDataArea->asciiData0), 32);
86 srcChar[32] = 0;
Ben Tyner29651ef2021-02-08 10:51:03 -060087 tiAdditionalData["SrcAscii"] = std::string{srcChar};
88
89 // TI event
90 eventTerminate(tiAdditionalData, (char*)i_tiDataArea);
Ben Tyner8c5e4f42020-10-28 11:11:55 -050091 }
Ben Tyner29651ef2021-02-08 10:51:03 -060092 else
93 {
94 // TI data was not available This should not happen since we provide
95 // a default TI info in the case where get TI info was not successful.
Ben Tyner7a0dd542021-02-12 09:33:44 -060096 eventAttentionFail((int)AttnSection::handlePhypTi | ATTN_INFO_NULL);
Ben Tyner29651ef2021-02-08 10:51:03 -060097 }
Ben Tyner063f6bd2021-03-26 07:45:56 -050098
99 // We are finished creating the event log entries so transition host to
100 // the required state.
Ben Tynerffb48672021-07-23 12:29:03 -0500101 if (true == util::dbus::autoRebootEnabled())
Ben Tyner063f6bd2021-03-26 07:45:56 -0500102 {
103 // If autoreboot is enabled we will start crash (mpipl) mode target
Ben Tyner93067162021-07-23 10:39:30 -0500104 util::dbus::transitionHost(util::dbus::HostState::Crash);
Ben Tyner063f6bd2021-03-26 07:45:56 -0500105 }
106 else
107 {
108 // If autoreboot is disabled we will quiesce the host
Ben Tyner93067162021-07-23 10:39:30 -0500109 util::dbus::transitionHost(util::dbus::HostState::Quiesce);
Ben Tyner063f6bd2021-03-26 07:45:56 -0500110 }
Ben Tyner8c5e4f42020-10-28 11:11:55 -0500111}
112
113/**
114 * @brief Handle a hostboot terminate immediate special attention
115 *
116 * The TI info data area will contain information pertaining to the TI
117 * condition. The course of action to take regarding the host state will
118 * depend on the contents of the TI info data area. We will also create a
119 * PEL containing the TI info data and FFDC data captured in the system
120 * journal.
121 *
122 * @param i_tiDataArea pointer to TI information filled in by hostboot
123 */
124void handleHbTi(TiDataArea* i_tiDataArea)
125{
126 trace<level::INFO>("HB TI");
127
128 bool hbDumpRequested = true; // HB dump is common case
129 bool generatePel = true; // assume PEL will be created
130 bool terminateHost = true; // transition host state
131
132 // handle specific hostboot reason codes
133 if (nullptr != i_tiDataArea)
134 {
Ben Tyner8882c322021-02-05 12:13:21 -0600135 std::stringstream ss; // stream object for tracing
136 std::string strobj; // string object for tracing
Ben Tyner8c5e4f42020-10-28 11:11:55 -0500137
138 switch (i_tiDataArea->hbTerminateType)
139 {
140 case TI_WITH_PLID:
141 case TI_WITH_EID:
Ben Tyner8882c322021-02-05 12:13:21 -0600142
143 // trace this value
144 ss.str(std::string()); // empty the stream
145 ss.clear(); // clear the stream
146 ss << "TI with PLID/EID: " << std::hex << std::showbase
147 << std::setw(8) << std::setfill('0')
148 << be32toh(i_tiDataArea->asciiData1);
149 strobj = ss.str();
150 trace<level::INFO>(strobj.c_str());
151
152 // see if HB dump is requested
Ben Tyner8c5e4f42020-10-28 11:11:55 -0500153 if (0 == i_tiDataArea->hbDumpFlag)
154 {
155 hbDumpRequested = false; // no HB dump requested
156 }
157 break;
158 case TI_WITH_SRC:
Ben Tyner8882c322021-02-05 12:13:21 -0600159 // Reason code is byte 2 and 3 of 4 byte srcWord12HbWord0
160 uint16_t reasonCode = be32toh(i_tiDataArea->srcWord12HbWord0);
Ben Tyner8c5e4f42020-10-28 11:11:55 -0500161
Ben Tyner8882c322021-02-05 12:13:21 -0600162 // trace this value
163 ss.str(std::string()); // empty the stream
164 ss.clear(); // clear the stream
165 ss << "TI with SRC: " << std::hex << std::showbase
166 << std::setw(4) << std::setfill('0') << (int)reasonCode;
167 strobj = ss.str();
168 trace<level::INFO>(strobj.c_str());
Ben Tyner8c5e4f42020-10-28 11:11:55 -0500169
Ben Tyner8882c322021-02-05 12:13:21 -0600170 switch (reasonCode)
Ben Tyner8c5e4f42020-10-28 11:11:55 -0500171 {
172 case HB_SRC_SHUTDOWN_REQUEST:
173 trace<level::INFO>("shutdown request");
Ben Tyner8882c322021-02-05 12:13:21 -0600174 generatePel = false;
175 hbDumpRequested = false;
Ben Tyner8c5e4f42020-10-28 11:11:55 -0500176 break;
177 case HB_SRC_KEY_TRANSITION:
Ben Tyner8882c322021-02-05 12:13:21 -0600178 // Note: Should never see this so lets leave
179 // hbDumpRequested == true so we can figure out why
180 // we are here.
Ben Tyner8c5e4f42020-10-28 11:11:55 -0500181 trace<level::INFO>("key transition");
182 terminateHost = false;
183 break;
184 case HB_SRC_INSUFFICIENT_HW:
185 trace<level::INFO>("insufficient hardware");
186 break;
187 case HB_SRC_TPM_FAIL:
188 trace<level::INFO>("TPM fail");
189 break;
190 case HB_SRC_ROM_VERIFY:
191 trace<level::INFO>("ROM verify");
192 break;
193 case HB_SRC_EXT_MISMATCH:
194 trace<level::INFO>("EXT mismatch");
195 break;
196 case HB_SRC_ECC_UE:
197 trace<level::INFO>("ECC UE");
198 break;
199 case HB_SRC_UNSUPPORTED_MODE:
200 trace<level::INFO>("unsupported mode");
201 break;
202 case HB_SRC_UNSUPPORTED_SFCRANGE:
203 trace<level::INFO>("unsupported SFC range");
204 break;
205 case HB_SRC_PARTITION_TABLE:
206 trace<level::INFO>("partition table invalid");
207 break;
208 case HB_SRC_UNSUPPORTED_HARDWARE:
209 trace<level::INFO>("unsupported hardware");
210 break;
211 case HB_SRC_PNOR_CORRUPTION:
212 trace<level::INFO>("PNOR corruption");
213 break;
214 default:
215 trace<level::INFO>("reason: other");
216 }
217
Ben Tyner5c5db652021-02-22 18:22:35 -0600218 break; // case TI_WITH_SRC
Ben Tyner8c5e4f42020-10-28 11:11:55 -0500219 }
220 }
221
Ben Tyner5c5db652021-02-22 18:22:35 -0600222 if (true == generatePel)
Ben Tyner8c5e4f42020-10-28 11:11:55 -0500223 {
Ben Tyner5c5db652021-02-22 18:22:35 -0600224 if (nullptr != i_tiDataArea)
Ben Tyner29651ef2021-02-08 10:51:03 -0600225 {
Ben Tyner5c5db652021-02-22 18:22:35 -0600226 // gather additional data for PEL
227 std::map<std::string, std::string> tiAdditionalData;
228
229 parseHbTiInfo(tiAdditionalData, i_tiDataArea);
230
Ben Tyner29651ef2021-02-08 10:51:03 -0600231 tiAdditionalData["Subsystem"] = std::to_string(
232 static_cast<uint8_t>(pel::SubsystemID::hostboot));
233
Ben Tyner5c5db652021-02-22 18:22:35 -0600234 // Translate hex src value to ascii. This results in an 8
235 // character SRC (hostboot SRC is 32 bits)
Ben Tyner9d4f91c2021-02-09 08:27:58 -0600236 std::stringstream src;
Ben Tyner4bbcb382021-02-22 09:29:00 -0600237 src << std::setw(8) << std::setfill('0') << std::uppercase
238 << std::hex << be32toh(i_tiDataArea->srcWord12HbWord0);
Ben Tyner9d4f91c2021-02-09 08:27:58 -0600239 tiAdditionalData["SrcAscii"] = src.str();
Ben Tyner29651ef2021-02-08 10:51:03 -0600240
Ben Tyner5c5db652021-02-22 18:22:35 -0600241 // Request dump after generating event log?
242 tiAdditionalData["Dump"] =
243 (true == hbDumpRequested) ? "true" : "false";
244
245 // Generate event log
Ben Tyner29651ef2021-02-08 10:51:03 -0600246 eventTerminate(tiAdditionalData, (char*)i_tiDataArea);
247 }
Ben Tyner5c5db652021-02-22 18:22:35 -0600248 else
249 {
250 // TI data was not available This should not happen.
251 eventAttentionFail((int)AttnSection::handleHbTi | ATTN_INFO_NULL);
252 }
Ben Tyner40717722020-09-23 09:43:20 -0500253 }
Ben Tyner063f6bd2021-03-26 07:45:56 -0500254
255 if (true == terminateHost)
256 {
Ben Tyner93067162021-07-23 10:39:30 -0500257 util::dbus::transitionHost(util::dbus::HostState::Quiesce);
Ben Tyner063f6bd2021-03-26 07:45:56 -0500258 }
Ben Tyner40717722020-09-23 09:43:20 -0500259}
260
261/** @brief Parse the TI info data area into map as PHYP/OPAL data */
262void parsePhypOpalTiInfo(std::map<std::string, std::string>& i_map,
263 TiDataArea* i_tiDataArea)
264{
Ben Tyner1c4b02e2020-11-09 14:00:29 -0600265 if (nullptr == i_tiDataArea)
266 {
267 return;
268 }
269
Ben Tyner40717722020-09-23 09:43:20 -0500270 std::stringstream ss;
271
Ben Tynerfeeea832021-04-06 10:08:11 -0500272 ss << "0x00 TI Area Valid:" << std::setw(2) << std::setfill('0') << std::hex
273 << (int)i_tiDataArea->tiAreaValid << ":";
274 ss << "0x01 Command:" << std::setw(2) << std::setfill('0') << std::hex
275 << (int)i_tiDataArea->command << ":";
276 ss << "0x02 Num. Data Bytes:" << std::setw(4) << std::setfill('0')
277 << std::hex << be16toh(i_tiDataArea->numDataBytes) << ":";
278 ss << "0x04 Reserved:" << std::setw(2) << std::setfill('0') << std::hex
279 << (int)i_tiDataArea->reserved1 << ":";
280 ss << "0x06 HWDump Type:" << std::setw(4) << std::setfill('0') << std::hex
281 << be16toh(i_tiDataArea->hardwareDumpType) << ":";
282 ss << "0x08 SRC Format:" << std::setw(2) << std::setfill('0') << std::hex
283 << (int)i_tiDataArea->srcFormat << ":";
284 ss << "0x09 SRC Flags:" << std::setw(2) << std::setfill('0') << std::hex
285 << (int)i_tiDataArea->srcFlags << ":";
286 ss << "0x0a Num. ASCII Words:" << std::setw(2) << std::setfill('0')
287 << std::hex << (int)i_tiDataArea->numAsciiWords << ":";
288 ss << "0x0b Num. Hex Words:" << std::setw(2) << std::setfill('0')
289 << std::hex << (int)i_tiDataArea->numHexWords << ":";
290 ss << "0x0e Length of SRC:" << std::setw(4) << std::setfill('0') << std::hex
291 << be16toh(i_tiDataArea->lenSrc) << ":";
292 ss << "0x10 SRC Word 12:" << std::setw(8) << std::setfill('0') << std::hex
293 << be32toh(i_tiDataArea->srcWord12HbWord0) << ":";
294 ss << "0x14 SRC Word 13:" << std::setw(8) << std::setfill('0') << std::hex
295 << be32toh(i_tiDataArea->srcWord13HbWord2) << ":";
296 ss << "0x18 SRC Word 14:" << std::setw(8) << std::setfill('0') << std::hex
297 << be32toh(i_tiDataArea->srcWord14HbWord3) << ":";
298 ss << "0x1c SRC Word 15:" << std::setw(8) << std::setfill('0') << std::hex
299 << be32toh(i_tiDataArea->srcWord15HbWord4) << ":";
300 ss << "0x20 SRC Word 16:" << std::setw(8) << std::setfill('0') << std::hex
301 << be32toh(i_tiDataArea->srcWord16HbWord5) << ":";
302 ss << "0x24 SRC Word 17:" << std::setw(8) << std::setfill('0') << std::hex
303 << be32toh(i_tiDataArea->srcWord17HbWord6) << ":";
304 ss << "0x28 SRC Word 18:" << std::setw(8) << std::setfill('0') << std::hex
305 << be32toh(i_tiDataArea->srcWord18HbWord7) << ":";
306 ss << "0x2c SRC Word 19:" << std::setw(8) << std::setfill('0') << std::hex
307 << be32toh(i_tiDataArea->srcWord19HbWord8) << ":";
308 ss << "0x30 ASCII Data:" << std::setw(8) << std::setfill('0') << std::hex
309 << be32toh(i_tiDataArea->asciiData0) << ":";
310 ss << "0x34 ASCII Data:" << std::setw(8) << std::setfill('0') << std::hex
311 << be32toh(i_tiDataArea->asciiData1) << ":";
312 ss << "0x38 ASCII Data:" << std::setw(8) << std::setfill('0') << std::hex
313 << be32toh(i_tiDataArea->asciiData2) << ":";
314 ss << "0x3c ASCII Data:" << std::setw(8) << std::setfill('0') << std::hex
315 << be32toh(i_tiDataArea->asciiData3) << ":";
316 ss << "0x40 ASCII Data:" << std::setw(8) << std::setfill('0') << std::hex
317 << be32toh(i_tiDataArea->asciiData4) << ":";
318 ss << "0x44 ASCII Data:" << std::setw(8) << std::setfill('0') << std::hex
319 << be32toh(i_tiDataArea->asciiData5) << ":";
320 ss << "0x48 ASCII Data:" << std::setw(8) << std::setfill('0') << std::hex
321 << be32toh(i_tiDataArea->asciiData6) << ":";
322 ss << "0x4c ASCII Data:" << std::setw(8) << std::setfill('0') << std::hex
323 << be32toh(i_tiDataArea->asciiData7) << ":";
324 ss << "0x50 Location:" << std::setw(2) << std::setfill('0') << std::hex
325 << (int)i_tiDataArea->location << ":";
326 ss << "0x51 Code Sections:" << std::setw(2) << std::setfill('0') << std::hex
327 << (int)i_tiDataArea->codeSection << ":";
328 ss << "0x52 Additional Size:" << std::setw(2) << std::setfill('0')
329 << std::hex << (int)i_tiDataArea->additionalSize << ":";
330 ss << "0x53 Additional Data:" << std::setw(2) << std::setfill('0')
331 << std::hex << (int)i_tiDataArea->andData;
Ben Tyner40717722020-09-23 09:43:20 -0500332
333 std::string key, value;
334 char delim = ':';
335
336 while (std::getline(ss, key, delim))
337 {
338 std::getline(ss, value, delim);
339 i_map[key] = value;
340 }
341}
342
343/** @brief Parse the TI info data area into map as hostboot data */
344void parseHbTiInfo(std::map<std::string, std::string>& i_map,
345 TiDataArea* i_tiDataArea)
346{
Ben Tyner1c4b02e2020-11-09 14:00:29 -0600347 if (nullptr == i_tiDataArea)
348 {
349 return;
350 }
351
Ben Tyner40717722020-09-23 09:43:20 -0500352 std::stringstream ss;
353
Ben Tynerfeeea832021-04-06 10:08:11 -0500354 ss << "0x00 TI Area Valid:" << std::setw(2) << std::setfill('0') << std::hex
355 << (int)i_tiDataArea->tiAreaValid << ":";
356 ss << "0x04 Reserved:" << std::setw(2) << std::setfill('0') << std::hex
357 << (int)i_tiDataArea->reserved1 << ":";
358 ss << "0x05 HB_Term. Type:" << std::setw(2) << std::setfill('0') << std::hex
359 << (int)i_tiDataArea->hbTerminateType << ":";
360 ss << "0x0c HB Dump Flag:" << std::setw(2) << std::setfill('0') << std::hex
361 << (int)i_tiDataArea->hbDumpFlag << ":";
362 ss << "0x0d Source:" << std::setw(2) << std::setfill('0') << std::hex
363 << (int)i_tiDataArea->source << ":";
364 ss << "0x10 HB Word 0:" << std::setw(8) << std::setfill('0') << std::hex
365 << be32toh(i_tiDataArea->srcWord12HbWord0) << ":";
366 ss << "0x14 HB Word 2:" << std::setw(8) << std::setfill('0') << std::hex
367 << be32toh(i_tiDataArea->srcWord13HbWord2) << ":";
368 ss << "0x18 HB Word 3:" << std::setw(8) << std::setfill('0') << std::hex
369 << be32toh(i_tiDataArea->srcWord14HbWord3) << ":";
370 ss << "0x1c HB Word 4:" << std::setw(8) << std::setfill('0') << std::hex
371 << be32toh(i_tiDataArea->srcWord15HbWord4) << ":";
372 ss << "0x20 HB Word 5:" << std::setw(8) << std::setfill('0') << std::hex
373 << be32toh(i_tiDataArea->srcWord16HbWord5) << ":";
374 ss << "0x24 HB Word 6:" << std::setw(8) << std::setfill('0') << std::hex
375 << be32toh(i_tiDataArea->srcWord17HbWord6) << ":";
376 ss << "0x28 HB Word 7:" << std::setw(8) << std::setfill('0') << std::hex
377 << be32toh(i_tiDataArea->srcWord18HbWord7) << ":";
378 ss << "0x2c HB Word 8:" << std::setw(8) << std::setfill('0') << std::hex
379 << be32toh(i_tiDataArea->srcWord19HbWord8) << ":";
380 ss << "0x30 error_data:" << std::setw(8) << std::setfill('0') << std::hex
381 << be32toh(i_tiDataArea->asciiData0) << ":";
382 ss << "0x34 EID:" << std::setw(8) << std::setfill('0') << std::hex
383 << be32toh(i_tiDataArea->asciiData1);
Ben Tyner40717722020-09-23 09:43:20 -0500384
385 std::string key, value;
386 char delim = ':';
387
388 while (std::getline(ss, key, delim))
389 {
390 std::getline(ss, value, delim);
391 i_map[key] = value;
392 }
393}
394
Ben Tyner9ae5ca42020-02-28 13:13:50 -0600395} // namespace attn