xref: /openbmc/pldm/oem/meta/event/oem_event_manager.cpp (revision c86cd0427d889484440912722a7e5ec861673378)
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