1 #include "oem_event_manager.hpp"
2
3 #include <com/meta/IPMI/UnifiedSEL/event.hpp>
4 #include <oem/meta/utils.hpp>
5 #include <phosphor-logging/commit.hpp>
6 #include <phosphor-logging/lg2.hpp>
7 #include <xyz/openbmc_project/Inventory/Decorator/Slot/client.hpp>
8
9 #include <cstdint>
10 #include <iostream>
11 #include <sstream>
12
13 namespace pldm
14 {
15 namespace oem_meta
16 {
17
processOemMetaEvent(pldm_tid_t tid,const uint8_t * eventData,size_t eventDataSize) const18 int OemEventManager::processOemMetaEvent(
19 pldm_tid_t tid, const uint8_t* eventData, size_t eventDataSize) const
20 {
21 RecordType recordType = static_cast<RecordType>(eventData[0]);
22 std::string errorLog;
23 switch (recordType)
24 {
25 case RecordType::SYSTEM_EVENT_RECORD:
26 {
27 handleSystemEvent(eventData, errorLog);
28 break;
29 }
30 case RecordType::UNIFIED_BIOS_SEL:
31 {
32 handleUnifiedBIOSEvent(eventData, errorLog);
33 break;
34 }
35 default:
36 {
37 return PLDM_ERROR;
38 }
39 }
40
41 std::string slotNumber = getSlotNumberStringByTID(tid);
42 std::string message =
43 "SEL Entry: Host: " + slotNumber + ", Record: " + errorLog;
44 lg2::error("{ERROR}", "ERROR", message); // Create log in journal
45
46 std::string rawLog = [eventData, eventDataSize]() {
47 std::stringstream stream;
48 stream << std::hex << std::uppercase << std::setfill('0');
49 for (int i = 0; i < static_cast<int>(eventDataSize); ++i)
50 {
51 stream << std::setw(2) << static_cast<int>(eventData[i]);
52 }
53 return stream.str();
54 }();
55
56 std::string source = "/xyz/openbmc_project/state/host" + slotNumber;
57 {
58 namespace Errors = sdbusplus::error::com::meta::ipmi::UnifiedSEL;
59 lg2::commit(Errors::UnifiedSELEvent("SOURCE", source, "EVENT", errorLog,
60 "RAW_EVENT", rawLog));
61 }
62
63 return 0;
64 }
65
handleOemEvent(const pldm_msg * request,size_t payloadLength,uint8_t,pldm_tid_t tid,size_t eventDataOffset) const66 int OemEventManager::handleOemEvent(
67 const pldm_msg* request, size_t payloadLength, uint8_t /* formatVersion */,
68 pldm_tid_t tid, size_t eventDataOffset) const
69 {
70 auto eventData =
71 reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset;
72 auto eventDataSize = payloadLength - eventDataOffset;
73 if (!pldm::oem_meta::checkMetaIana(tid))
74 {
75 lg2::error("Recieve OEM Meta event from not Meta specific device");
76 return PLDM_ERROR;
77 }
78 if (!processOemMetaEvent(tid, eventData, eventDataSize))
79 {
80 return PLDM_ERROR;
81 }
82
83 return PLDM_SUCCESS;
84 }
85
handleSystemEvent(const uint8_t * eventData,std::string & errorLog) const86 void OemEventManager::handleSystemEvent(const uint8_t* eventData,
87 std::string& errorLog) const
88 {
89 errorLog = "Standard (0x02), ";
90 switch (auto se = static_cast<SystemError>(eventData[8]); se)
91 {
92 case SystemError::SYSTEM_PROCESSOR_ERR:
93 {
94 switch (auto pe = static_cast<ProcessorError>(eventData[9]); pe)
95 {
96 case ProcessorError::MACHINE_CHK_ERR:
97 {
98 errorLog += "MACHINE_CHK_ERR (" +
99 to_hex_string(eventData[9]) + "), ";
100 errorLog += "Event Data: (" + to_hex_string(eventData[11]) +
101 to_hex_string(eventData[12]) +
102 to_hex_string(eventData[13]) + ") ";
103
104 switch (auto ps = static_cast<ProcessorSeverity>(
105 eventData[11] & 0x0F);
106 ps)
107 {
108 case ProcessorSeverity::UNCORRECT_SYSTEM_FATAL_ERR:
109 errorLog += "Uncorrected System Fatal Error, ";
110 break;
111 case ProcessorSeverity::CORRECTABLE_SYSTEM_ERR:
112 errorLog += "Correctable System Error, ";
113 break;
114 default:
115 errorLog += "Unknown Error, ";
116 break;
117 }
118
119 if (eventData[12] == 0x1D)
120 {
121 errorLog += "Bank Number " +
122 std::to_string(eventData[12]) +
123 " (SMU/MPDMA), ";
124 }
125
126 errorLog += "CPU " + std::to_string(eventData[13] >> 5) +
127 ", CCD " + std::to_string(eventData[13] & 0x1F);
128 break;
129 }
130 }
131 break;
132 }
133 case SystemError::SYSTEM_POST_ERR:
134 {
135 errorLog += "POST_ERROR:";
136 if ((eventData[11] & 0x0F) == 0x0)
137 errorLog += ", System Firmware Error";
138
139 if (((eventData[11] >> 6) & 0x03) == 0x2)
140 {
141 errorLog += ", OEM Post Code 0x" +
142 to_hex_string(eventData[13]) +
143 to_hex_string(eventData[12]);
144 }
145
146 if (((eventData[13] << 8) | eventData[12]) == 0xD9)
147 {
148 errorLog +=
149 ", Error loading Boot Option (Load image returned error)";
150 }
151 break;
152 }
153 case SystemError::SYSTEM_CXL_ERR:
154 {
155 errorLog += "CXL 1.1 Error, ";
156 switch (auto ce = static_cast<CxlError>(eventData[9]); ce)
157 {
158 case CxlError::PROTOCOL_ERR:
159 {
160 errorLog += ", Protocol Error(0x1), ";
161 break;
162 }
163 case CxlError::COMPONENT_ERR:
164 {
165 errorLog += ", Component Error(0x2), ";
166 break;
167 }
168 }
169
170 errorLog += "Severity: ";
171 errorLog +=
172 (eventData[11] & 0x01) ? "Uncorrectable" : "Correctable";
173 errorLog += ", Detected By: ";
174 errorLog += (eventData[11] & 0x02) ? "CXL 1.1 Host Downstream Port"
175 : "CXL 1.1 Device";
176
177 uint8_t errorType = (eventData[11] >> 2) & 0x03;
178
179 errorLog += ", Error Type: " + std::string(cxlError[errorType]) +
180 ", Bus " + to_hex_string(eventData[12]) + "/Dev " +
181 to_hex_string(eventData[13] >> 3) + "/Fun " +
182 to_hex_string(eventData[13] & 0x7);
183 break;
184 }
185 case SystemError::SYSTEM_CXL_ERR_2_0:
186 {
187 errorLog += "CXL 2.0 Error, ";
188 switch (auto ce = static_cast<CxlError2>(eventData[9]); ce)
189 {
190 case CxlError2::PROTOCOL_ERR:
191 {
192 errorLog += ", Protocol Error(0x1), ";
193 break;
194 }
195 case CxlError2::COMPONENT_ERR:
196 {
197 errorLog += ", Component Error(0x2), ";
198 break;
199 }
200 }
201
202 errorLog += "Severity: ";
203 errorLog +=
204 (eventData[11] & 0x01) ? "Uncorrectable" : "Correctable";
205 // root port only
206 errorLog += ", Detected By: CXL Root Port";
207
208 uint8_t errorType = (eventData[11] >> 2) & 0x03;
209
210 errorLog += ", Error Type: " + std::string(cxlError[errorType]) +
211 ", Bus " + to_hex_string(eventData[12]) + "/Dev " +
212 to_hex_string(eventData[13] >> 3) + "/Fun " +
213 to_hex_string(eventData[13] & 0x7);
214 break;
215 }
216 default:
217 { // Not supported
218 errorLog +=
219 "Raw: " + to_hex_string(eventData[1]) +
220 to_hex_string(eventData[2]) + to_hex_string(eventData[3]) +
221 to_hex_string(eventData[4]) + to_hex_string(eventData[5]) +
222 to_hex_string(eventData[6]) + to_hex_string(eventData[7]) +
223 to_hex_string(eventData[8]) + to_hex_string(eventData[9]) +
224 to_hex_string(eventData[10]) + to_hex_string(eventData[11]) +
225 to_hex_string(eventData[12]) + to_hex_string(eventData[13]);
226 }
227 }
228 }
229
handleUnifiedBIOSEvent(const uint8_t * eventData,std::string & errorLog) const230 void OemEventManager::handleUnifiedBIOSEvent(const uint8_t* eventData,
231 std::string& errorLog) const
232 {
233 errorLog = "Meta Unified SEL (0xFB), ";
234
235 DimmInfo dimmInfo = {
236 static_cast<uint8_t>((eventData[6] >> 4) & 0x03), // Sled
237 static_cast<uint8_t>(eventData[6] & 0x0F), // Socket
238 static_cast<uint8_t>(eventData[7]), // Channel
239 static_cast<uint8_t>(eventData[8]) // Slot
240 };
241
242 uint8_t generalInfo = eventData[1];
243 UnifiedError errorType = static_cast<UnifiedError>(generalInfo & 0xF);
244 switch (errorType)
245 {
246 case UnifiedError::UNIFIED_PCIE_ERR:
247 {
248 uint8_t plat = (generalInfo & 0x10) >> 4;
249 if (plat == 0)
250 { // x86
251 errorLog +=
252 "GeneralInfo: x86/PCIeErr(0x" + to_hex_string(generalInfo) +
253 "), Bus " + to_hex_string(eventData[9]) + "/Dev " +
254 to_hex_string(eventData[8] >> 3) + "/Fun " +
255 to_hex_string(eventData[8] & 0x7) + ", ErrID2: 0x" +
256 to_hex_string(eventData[12]) + ", ErrID1: 0x" +
257 to_hex_string(eventData[13]);
258 }
259 else
260 {
261 errorLog +=
262 "GeneralInfo: ARM/PCIeErr(0x" + to_hex_string(generalInfo) +
263 "), Aux. Info: 0x" +
264 to_hex_string((eventData[7] << 8) | eventData[6], 4) +
265 ", Bus " + to_hex_string(eventData[9]) + "/Dev " +
266 to_hex_string(eventData[8] >> 3) + "/Fun " +
267 to_hex_string(eventData[8] & 0x7) + ", ErrID2: 0x" +
268 to_hex_string(eventData[12]) + ", ErrID1: 0x" +
269 to_hex_string(eventData[13]);
270 }
271 break;
272 }
273 case UnifiedError::UNIFIED_MEM_ERR:
274 {
275 handleMemoryError(eventData, errorLog, dimmInfo, generalInfo);
276 break;
277 }
278 case UnifiedError::UNIFIED_UPI_ERR:
279 {
280 UpiError eventType = static_cast<UpiError>(eventData[10] & 0xF);
281 uint8_t estrIdx =
282 (static_cast<uint8_t>(eventType) < upiError.size())
283 ? static_cast<uint8_t>(eventType)
284 : (upiError.size() - 1);
285
286 switch (eventType)
287 {
288 case UpiError::UPI_INIT_ERR:
289 {
290 errorLog +=
291 "GeneralInfo: UPIErr(0x" + to_hex_string(generalInfo) +
292 "), UPI Port Location: Sled " +
293 std::to_string(dimmInfo.sled) + "/Socket " +
294 std::to_string(dimmInfo.socket) + ", Port " +
295 std::to_string(eventData[4] & 0xF) +
296 ", UPI Failure Event: " + upiError[estrIdx] +
297 ", Major Code: 0x" + to_hex_string(eventData[8]) +
298 ", Minor Code: 0x" + to_hex_string(eventData[9]);
299 break;
300 }
301 default:
302 {
303 errorLog +=
304 "GeneralInfo: UPIErr(0x" + to_hex_string(generalInfo) +
305 "), UPI Port Location: Sled " +
306 std::to_string(dimmInfo.sled) + "/Socket " +
307 std::to_string(dimmInfo.socket) + ", Port " +
308 std::to_string(eventData[4] & 0xF) +
309 ", UPI Failure Event: " + upiError[estrIdx];
310 break;
311 }
312 }
313 break;
314 }
315 case UnifiedError::UNIFIED_IIO_ERR:
316 {
317 uint8_t stack = eventData[7];
318 uint8_t selErrorType = eventData[11];
319 uint8_t selErrorSeverity = eventData[12];
320 uint8_t selErrorId = eventData[13];
321
322 errorLog +=
323 "GeneralInfo: IIOErr(0x" + to_hex_string(generalInfo) +
324 "), IIO Port Location: Sled " + std::to_string(dimmInfo.sled) +
325 "/Socket " + std::to_string(dimmInfo.socket) + ", Stack 0x" +
326 to_hex_string(stack) + ", Error Type: 0x" +
327 to_hex_string(selErrorType) + ", Error Severity: 0x" +
328 to_hex_string(selErrorSeverity) + ", Error ID: 0x" +
329 to_hex_string(selErrorId);
330 break;
331 }
332 case UnifiedError::UNIFIED_MCA_ERR:
333 {
334 uint8_t mcaSeverity = ((eventData[6] >> 4) & 0x07);
335 uint8_t cpuNumber = (eventData[7] >> 5) & 0x07;
336 uint8_t coreNumber = eventData[7] & 0x1F;
337 uint8_t machineCheckBankNumber = eventData[8];
338 uint32_t errorInfo = (static_cast<uint32_t>(eventData[9]) << 16) |
339 (static_cast<uint32_t>(eventData[10]) << 8) |
340 static_cast<uint32_t>(eventData[11]);
341 uint8_t errorCode = eventData[12];
342 uint8_t errorStatus = eventData[13];
343
344 errorLog +=
345 "GeneralInfo: MCAErr(0x" + to_hex_string(generalInfo) +
346 "), MCA Severity: " + errorSeverityDetail[mcaSeverity] +
347 ", CPU Number: " + std::to_string(cpuNumber) +
348 ", Core Number: " + std::to_string(coreNumber) +
349 ", Machine Check Bank: " +
350 machineCheckBank[machineCheckBankNumber] + ", Error Info: 0x" +
351 to_hex_string(errorInfo, 6) + ", Error Code: 0x" +
352 to_hex_string(errorCode) + ", Error Status: 0x" +
353 to_hex_string(errorStatus);
354 break;
355 }
356 case UnifiedError::UNIFIED_MCA_ERR_EXT:
357 {
358 uint8_t mcaSeverity = ((eventData[6] >> 4) & 0x07);
359 uint8_t cpuNumber = (eventData[7] >> 5) & 0x07;
360 uint8_t coreNumber = eventData[7] & 0x1F;
361 uint8_t machineCheckBankNumber = eventData[8];
362 uint16_t errorCode = (eventData[9] << 8) | eventData[10];
363
364 errorLog +=
365 "GeneralInfo: MCAErrExt(0x" + to_hex_string(generalInfo) +
366 "), MCA Severity: " + errorSeverityDetail[mcaSeverity] +
367 ", CPU Number: " + std::to_string(cpuNumber) +
368 ", Core Number: " + std::to_string(coreNumber) +
369 ", Machine Check Bank: " +
370 machineCheckBank[machineCheckBankNumber] + ", Error Code: 0x" +
371 to_hex_string(errorCode, 4);
372 break;
373 }
374 case UnifiedError::UNIFIED_RP_PIO_1st:
375 case UnifiedError::UNIFIED_RP_PIO_2nd:
376 {
377 auto offset =
378 static_cast<uint8_t>(errorType) -
379 static_cast<uint8_t>(UnifiedError::UNIFIED_RP_PIO_1st);
380 errorLog +=
381 "GeneralInfo: RP_PIOEvent(0x" + to_hex_string(generalInfo) +
382 "), RP_PIO Header Log" + std::to_string(1 + offset * 2) +
383 ": 0x" + to_hex_string(eventData[9]) +
384 to_hex_string(eventData[8]) + to_hex_string(eventData[7]) +
385 to_hex_string(eventData[6]) + ", RP_PIO Header Log" +
386 std::to_string(2 + offset * 2) + ": 0x" +
387 to_hex_string(eventData[13]) + to_hex_string(eventData[12]) +
388 to_hex_string(eventData[11]) + to_hex_string(eventData[10]);
389 break;
390 }
391 case UnifiedError::UNIFIED_POST_EVENT:
392 {
393 handleSystemPostEvent(eventData, errorLog, generalInfo);
394 break;
395 }
396 case UnifiedError::UNIFIED_PCIE_EVENT:
397 {
398 PcieEvent eventType = static_cast<PcieEvent>(eventData[6] & 0xF);
399 uint8_t estrIdx =
400 (static_cast<uint8_t>(eventType) < pcieEvent.size())
401 ? static_cast<uint8_t>(eventType)
402 : (pcieEvent.size() - 1);
403 switch (eventType)
404 {
405 case PcieEvent::PCIE_DPC:
406 {
407 errorLog +=
408 "GeneralInfo: PCIeEvent(0x" +
409 to_hex_string(generalInfo) +
410 "), PCIe Failure Event: " + pcieEvent[estrIdx] +
411 ", Status: 0x" +
412 to_hex_string((eventData[9] << 8) | eventData[8], 4) +
413 ", Source ID: 0x" +
414 to_hex_string((eventData[11] << 8) | eventData[10], 4);
415 break;
416 }
417 default:
418 {
419 errorLog += "GeneralInfo: PCIeEvent(0x" +
420 to_hex_string(generalInfo) +
421 "), PCIe Failure Event: " + pcieEvent[estrIdx];
422 break;
423 }
424 }
425 break;
426 }
427 case UnifiedError::UNIFIED_MEM_EVENT:
428 {
429 // get dimm location data string.
430 std::string dimmLocation, dimm;
431 getCommonDimmLocation(dimmInfo, dimmLocation, dimm);
432
433 // Event-Type Bit[3:0]
434 MemoryEvent eventType =
435 static_cast<MemoryEvent>(eventData[10] & 0x0F);
436 switch (eventType)
437 {
438 case MemoryEvent::MEM_PPR:
439 {
440 errorLog += "GeneralInfo: MemEvent(0x" +
441 to_hex_string(generalInfo) + "), " +
442 dimmLocation + ", DIMM Failure Event: " +
443 memoryPprRepairTime[eventData[11] >> 2 & 0x03] +
444 ", " + memoryPprEvent[eventData[11] & 0x03];
445 break;
446 }
447 case MemoryEvent::MEM_ADDDC:
448 {
449 uint8_t estrIdx = eventData[12] & 0x03;
450 if (estrIdx >= memoryAdddcEvent.size())
451 estrIdx = memoryAdddcEvent.size() - 1;
452 errorLog += "GeneralInfo: MemEvent(0x" +
453 to_hex_string(generalInfo) + "), " +
454 dimmLocation + ", DIMM Failure Event: " +
455 memoryEvent[static_cast<uint8_t>(eventType)] +
456 " " + memoryAdddcEvent[estrIdx];
457 break;
458 }
459 case MemoryEvent::MEM_NO_DIMM:
460 {
461 errorLog += "GeneralInfo: MemEvent(0x" +
462 to_hex_string(generalInfo) +
463 "), DIMM Failure Event: " +
464 memoryEvent[static_cast<uint8_t>(eventType)];
465 break;
466 }
467 case MemoryEvent::MEM_CXL_POST_PPR:
468 {
469 errorLog +=
470 "GeneralInfo: MemEvent(0x" +
471 to_hex_string(generalInfo) + "), Bus " +
472 to_hex_string(eventData[12]) + "/Dev " +
473 to_hex_string(eventData[13] >> 3) + "/Fun " +
474 to_hex_string(eventData[13] & 0x7) +
475 ", DIMM Failure Event: " +
476 memoryEvent[static_cast<uint8_t>(eventType)] + ", " +
477 memoryCXLPostPprEvent[eventData[11] >> 7 & 0x1] + ", " +
478 getDimmDeviceName(eventData, 12) +
479 memoryCxlEvent[eventData[11] & 0x3];
480 break;
481 }
482 default:
483 {
484 uint8_t estrIdx =
485 (static_cast<uint8_t>(eventType) < memoryEvent.size())
486 ? static_cast<uint8_t>(eventType)
487 : (memoryEvent.size() - 1);
488 errorLog += "GeneralInfo: MemEvent(0x" +
489 to_hex_string(generalInfo) + "), " +
490 dimmLocation +
491 ", DIMM Failure Event: " + memoryEvent[estrIdx];
492 break;
493 }
494 }
495 break;
496 }
497 case UnifiedError::UNIFIED_UPI_EVENT:
498 {
499 uint8_t eventType = eventData[10] & 0x0F;
500 uint8_t estrIdx = (eventType < upiEvent.size())
501 ? eventType
502 : (upiEvent.size() - 1);
503 errorLog +=
504 "GeneralInfo: UPIEvent(0x" + to_hex_string(generalInfo) +
505 "), UPI Port Location: Sled " + std::to_string(dimmInfo.sled) +
506 "/Socket " + std::to_string(dimmInfo.socket) + ", Port " +
507 std::to_string(eventData[7] & 0xF) +
508 ", UPI Failure Event: " + upiEvent[estrIdx];
509 break;
510 }
511 case UnifiedError::UNIFIED_BOOT_GUARD:
512 {
513 errorLog +=
514 "GeneralInfo: Boot Guard ACM Failure Events(0x" +
515 to_hex_string(generalInfo) + "), Error Class(0x" +
516 to_hex_string(eventData[10]) + "), Major Error Code(0x" +
517 to_hex_string(eventData[11]) + "), Minor Error Code(0x" +
518 to_hex_string(eventData[12]) + ")";
519 break;
520 }
521 case UnifiedError::UNIFIED_PPR_EVENT:
522 {
523 uint8_t eventType = eventData[6] & 0x0F;
524 errorLog +=
525 "GeneralInfo: PPR Events(0x" + to_hex_string(generalInfo) +
526 "), " + pprEvent[eventType] + ". DIMM Info: (" +
527 to_hex_string(eventData[7]) + to_hex_string(eventData[8]) +
528 to_hex_string(eventData[9]) + to_hex_string(eventData[10]) +
529 to_hex_string(eventData[11]) + to_hex_string(eventData[12]) +
530 to_hex_string(eventData[13]) + ")";
531 break;
532 }
533 case UnifiedError::UNIFIED_CXL_MEM_ERR:
534 {
535 uint8_t eventType = eventData[10] & 0xF;
536
537 errorLog += "GeneralInfo: CXL Memory Error(0x" +
538 to_hex_string(generalInfo) + "), Bus " +
539 to_hex_string(eventData[7]) + "/Dev " +
540 to_hex_string(eventData[8] >> 3) + "/Fun " +
541 to_hex_string(eventData[8] & 0x7) +
542 ", DIMM Failure Event: " + memoryError[eventType] +
543 ", " + getDimmDeviceName(eventData, 7) +
544 memoryCxlEvent[eventData[11] & 0x7];
545 break;
546 }
547 default:
548 {
549 errorLog +=
550 "Undefined Error Type(0x" +
551 to_hex_string(static_cast<uint8_t>(errorType)) +
552 "), Raw: " + to_hex_string(eventData[1]) +
553 to_hex_string(eventData[2]) + to_hex_string(eventData[3]) +
554 to_hex_string(eventData[4]) + to_hex_string(eventData[5]) +
555 to_hex_string(eventData[6]) + to_hex_string(eventData[7]) +
556 to_hex_string(eventData[8]) + to_hex_string(eventData[9]) +
557 to_hex_string(eventData[10]) + to_hex_string(eventData[11]) +
558 to_hex_string(eventData[12]) + to_hex_string(eventData[13]);
559 break;
560 }
561 }
562 }
563
handleMemoryError(const uint8_t * eventData,std::string & errorLog,const DimmInfo & dimmInfo,uint8_t generalInfo) const564 void OemEventManager::handleMemoryError(
565 const uint8_t* eventData, std::string& errorLog, const DimmInfo& dimmInfo,
566 uint8_t generalInfo) const
567 {
568 std::string dimmLocation, dimm;
569 getCommonDimmLocation(dimmInfo, dimmLocation, dimm);
570 uint8_t plat = (eventData[10] & 0x80) >> 7;
571 MemoryError eventType = static_cast<MemoryError>(eventData[10] & 0xF);
572 switch (eventType)
573 {
574 case MemoryError::MEMORY_TRAINING_ERR:
575 case MemoryError::MEMORY_PMIC_ERR:
576 {
577 if (plat == 0)
578 { // Intel
579 errorLog += "GeneralInfo: MEMORY_ECC_ERR(0x" +
580 to_hex_string(generalInfo) + "), " + dimmLocation +
581 ", DIMM Failure Event: " +
582 memoryError[static_cast<uint8_t>(eventType)] +
583 ", Major Code: 0x" + to_hex_string(eventData[11]) +
584 ", Minor Code: 0x" + to_hex_string(eventData[12]);
585 }
586 else
587 { // AMD
588 errorLog +=
589 "GeneralInfo: MEMORY_ECC_ERR(0x" +
590 to_hex_string(generalInfo) + "), " + dimmLocation +
591 ", DIMM Failure Event: " +
592 memoryError[static_cast<uint8_t>(eventType)] +
593 ", Major Code: 0x" + to_hex_string(eventData[11]) +
594 ", Minor Code: 0x" +
595 to_hex_string((eventData[13] << 8) | eventData[12], 4);
596 }
597 break;
598 }
599 default:
600 convertToDimmString(dimmInfo.socket, dimmInfo.channel,
601 dimmInfo.slot, dimm);
602 uint8_t estrIdx =
603 (static_cast<uint8_t>(eventType) < memoryError.size())
604 ? static_cast<uint8_t>(eventType)
605 : (memoryError.size() - 1);
606 errorLog += "GeneralInfo: MEMORY_ECC_ERR(0x" +
607 to_hex_string(generalInfo) + "), " + dimmLocation +
608 ", DIMM Failure Event: " + memoryError[estrIdx];
609 break;
610 }
611 }
612
handleSystemPostEvent(const uint8_t * eventData,std::string & errorLog,uint8_t generalInfo) const613 void OemEventManager::handleSystemPostEvent(
614 const uint8_t* eventData, std::string& errorLog, uint8_t generalInfo) const
615 {
616 uint8_t certEventIdx = (eventData[10] < certEvent.size())
617 ? eventData[10]
618 : (certEvent.size() - 1);
619 uint8_t failType = eventData[11] & 0xF;
620 uint8_t errCode = eventData[12];
621 PostError eventType = static_cast<PostError>(eventData[6] & 0xF);
622 uint8_t estrIdx = (static_cast<uint8_t>(eventType) < postError.size())
623 ? static_cast<uint8_t>(eventType)
624 : (postError.size() - 1);
625
626 switch (eventType)
627 {
628 case PostError::POST_PXE_BOOT_FAIL:
629 case PostError::POST_HTTP_BOOT_FAIL:
630 {
631 std::string tempLog;
632 if (failType == 4 || failType == 6)
633 {
634 tempLog = "IPv" + std::to_string(failType) + " fail";
635 }
636 else
637 {
638 tempLog = "0x" + to_hex_string(eventData[11]);
639 }
640 errorLog += "GeneralInfo: POST(0x" + to_hex_string(generalInfo) +
641 "), POST Failure Event: " + postError[estrIdx] +
642 ", Fail Type: " + tempLog + ", Error Code: 0x" +
643 to_hex_string(errCode);
644 break;
645 }
646 case PostError::POST_GET_CERT_FAIL:
647 {
648 errorLog += "GeneralInfo: POST(0x" + to_hex_string(generalInfo) +
649 "), POST Failure Event: " + postError[estrIdx] +
650 ", Failure Detail: " + certEvent[certEventIdx];
651 break;
652 }
653 case PostError::POST_AMD_ABL_FAIL:
654 {
655 uint16_t ablErrCode = (eventData[13] << 8) | eventData[12];
656 errorLog += "GeneralInfo: POST(0x" + to_hex_string(generalInfo) +
657 "), POST Failure Event: " + postError[estrIdx] +
658 ", ABL Error Code: 0x" + to_hex_string(ablErrCode, 4);
659 break;
660 }
661 case PostError::POST_BOOT_DRIVE_FAIL:
662 case PostError::POST_DATA_DRIVE_FAIL:
663 case PostError::POST_CXL_NOT_READY:
664 case PostError::POST_CXL_ERR_RECORD_CLEARED_BY_BIOS:
665 {
666 errorLog += "GeneralInfo: POST(0x" + to_hex_string(generalInfo) +
667 "), Bus " + to_hex_string(eventData[7]) + "/Dev " +
668 to_hex_string(eventData[8] >> 3) + "/Fun " +
669 to_hex_string(eventData[8] & 0x7) +
670 ", POST Failure Event: " + postError[estrIdx];
671 break;
672 }
673 default:
674 {
675 errorLog += "GeneralInfo: POST(0x" + to_hex_string(generalInfo) +
676 "), POST Failure Event: " + postError[estrIdx];
677 break;
678 }
679 }
680 }
681
682 } // namespace oem_meta
683 } // namespace pldm
684