parse Unified SEL
Parsing Facebook Unified SEL
Change-Id: I7c6afe1d0ee559e34f8f0d9fa6db3c0e33af25d3
Signed-off-by: Cosmo Chou <cosmo.chou@quantatw.com>
diff --git a/include/storagecommands.hpp b/include/storagecommands.hpp
index 78a8393..dcff17a 100644
--- a/include/storagecommands.hpp
+++ b/include/storagecommands.hpp
@@ -130,6 +130,12 @@
static constexpr uint8_t unifiedPcieErr = 0;
static constexpr uint8_t unifiedMemErr = 1;
+static constexpr uint8_t unifiedIioErr = 3;
+static constexpr uint8_t unifiedPostEvt = 8;
+static constexpr uint8_t unifiedPcieEvt = 9;
+static constexpr uint8_t unifiedMemEvt = 10;
+static constexpr uint8_t unifiedBootGuard = 12;
+static constexpr uint8_t unifiedPprEvt = 13;
/* event sensor name in processing SEL */
static constexpr uint8_t memoryEccError = 0x63;
diff --git a/src/selcommands.cpp b/src/selcommands.cpp
index 420c797..0a46c53 100644
--- a/src/selcommands.cpp
+++ b/src/selcommands.cpp
@@ -28,6 +28,32 @@
#include <iostream>
#include <sstream>
+enum class MemErrType
+{
+ memTrainErr = 0,
+ memPmicErr = 7
+};
+
+enum class PostEvtType
+{
+ pxeBootFail = 0,
+ httpBootFail = 6,
+ getCertFail = 7,
+ amdAblFail = 10
+};
+
+enum class PcieEvtType
+{
+ dpc = 0
+};
+
+enum class MemEvtType
+{
+ ppr = 0,
+ adddc = 5,
+ noDimm = 7
+};
+
//----------------------------------------------------------------------
// Platform specific functions for storing app data
//----------------------------------------------------------------------
@@ -1093,54 +1119,233 @@
return;
}
+static std::string dimmLocationStr(uint8_t socket, uint8_t channel,
+ uint8_t slot)
+{
+ uint8_t sled = (socket >> 4) & 0x3;
+
+ socket &= 0xf;
+ if (channel == 0xFF && slot == 0xFF)
+ {
+ return std::format(
+ "DIMM Slot Location: Sled {:02}/Socket {:02}, Channel unknown"
+ ", Slot unknown, DIMM unknown",
+ sled, socket);
+ }
+ else
+ {
+ channel &= 0xf;
+ slot &= 0xf;
+ const char label[] = {'A', 'C', 'B', 'D'};
+ uint8_t idx = socket * 2 + slot;
+ return std::format("DIMM Slot Location: Sled {:02}/Socket {:02}"
+ ", Channel {:02}, Slot {:02} DIMM {}",
+ sled, socket, channel, slot,
+ (idx < sizeof(label))
+ ? label[idx] + std::to_string(channel)
+ : "NA");
+ }
+}
+
static void parseOemUnifiedSel(NtsOemSELEntry* data, std::string& errStr)
{
uint8_t* ptr = data->oemData;
+ uint8_t eventType = ptr[5] & 0xf;
int genInfo = ptr[0];
int errType = genInfo & 0x0f;
- std::vector<std::string> dimmEvent = {
- "Memory training failure", "Memory correctable error",
- "Memory uncorrectable error", "Reserved"};
+ std::vector<std::string> dimmErr = {
+ "Memory training failure",
+ "Memory correctable error",
+ "Memory uncorrectable error",
+ "Memory correctable error (Patrol scrub)",
+ "Memory uncorrectable error (Patrol scrub)",
+ "Memory Parity Error (PCC=0)",
+ "Memory Parity Error (PCC=1)",
+ "Memory PMIC Error",
+ "CXL Memory training error",
+ "Reserved"};
+ std::vector<std::string> postEvent = {
+ "System PXE boot fail",
+ "CMOS/NVRAM configuration cleared",
+ "TPM Self-Test Fail",
+ "Boot Drive failure",
+ "Data Drive failure",
+ "Received invalid boot order request from BMC",
+ "System HTTP boot fail",
+ "BIOS fails to get the certificate from BMC",
+ "Password cleared by jumper",
+ "DXE FV check failure",
+ "AMD ABL failure",
+ "Reserved"};
+ std::vector<std::string> certErr = {
+ "No certificate at BMC", "IPMI transaction fail",
+ "Certificate data corrupted", "Reserved"};
+ std::vector<std::string> pcieEvent = {"PCIe DPC Event",
+ "PCIe LER Event",
+ "PCIe Link Retraining and Recovery",
+ "PCIe Link CRC Error Check and Retry",
+ "PCIe Corrupt Data Containment",
+ "PCIe Express ECRC",
+ "Reserved"};
+ std::vector<std::string> memEvent = {
+ "Memory PPR event",
+ "Memory Correctable Error logging limit reached",
+ "Memory disable/map-out for FRB",
+ "Memory SDDC",
+ "Memory Address range/Partial mirroring",
+ "Memory ADDDC",
+ "Memory SMBus hang recovery",
+ "No DIMM in System",
+ "Reserved"};
+ std::vector<std::string> memPprTime = {"Boot time", "Autonomous",
+ "Run time", "Reserved"};
+ std::vector<std::string> memPpr = {"PPR success", "PPR fail", "PPR request",
+ "Reserved"};
+ std::vector<std::string> memAdddc = {"Bank VLS", "r-Bank VLS + re-buddy",
+ "r-Bank VLS + Rank VLS",
+ "r-Rank VLS + re-buddy", "Reserved"};
+ std::vector<std::string> pprEvent = {"PPR disable", "Soft PPR", "Hard PPR",
+ "Reserved"};
std::stringstream tmpStream;
- tmpStream << std::hex << std::uppercase << std::setfill('0');
switch (errType)
{
case unifiedPcieErr:
- if (((genInfo & 0x10) >> 4) == 0) // x86
- {
- tmpStream << "GeneralInfo: x86/PCIeErr(0x" << std::setw(2)
- << genInfo << "),";
- }
-
- tmpStream << " Bus " << std::setw(2) << (int)(ptr[8]) << "/Dev "
- << std::setw(2) << (int)(ptr[7] >> 3) << "/Fun "
- << std::setw(2) << (int)(ptr[7] & 0x7)
- << ", TotalErrID1Cnt: 0x" << std::setw(4)
- << (int)((ptr[10] << 8) | ptr[9]) << ", ErrID2: 0x"
- << std::setw(2) << (int)(ptr[11]) << ", ErrID1: 0x"
- << std::setw(2) << (int)(ptr[12]);
-
+ tmpStream << std::format(
+ "GeneralInfo: x86/PCIeErr(0x{:02X})"
+ ", Bus {:02X}/Dev {:02X}/Fun {:02X}, TotalErrID1Cnt: 0x{:04X}"
+ ", ErrID2: 0x{:02X}, ErrID1: 0x{:02X}",
+ genInfo, ptr[8], ptr[7] >> 3, ptr[7] & 0x7,
+ (ptr[10] << 8) | ptr[9], ptr[11], ptr[12]);
break;
case unifiedMemErr:
- tmpStream << "GeneralInfo: MemErr(0x" << std::setw(2) << genInfo
- << "), DIMM Slot Location: Sled " << std::setw(2)
- << (int)((ptr[5] >> 4) & 0x03) << "/Socket "
- << std::setw(2) << (int)(ptr[5] & 0x0f) << ", Channel "
- << std::setw(2) << (int)(ptr[6] & 0x0f) << ", Slot "
- << std::setw(2) << (int)(ptr[7] & 0x0f)
- << ", DIMM Failure Event: " << dimmEvent[(ptr[9] & 0x03)]
- << ", Major Code: 0x" << std::setw(2) << (int)(ptr[10])
- << ", Minor Code: 0x" << std::setw(2) << (int)(ptr[11]);
+ eventType = ptr[9] & 0xf;
+ tmpStream << std::format(
+ "GeneralInfo: MemErr(0x{:02X}), {}, DIMM Failure Event: {}",
+ genInfo, dimmLocationStr(ptr[5], ptr[6], ptr[7]),
+ dimmErr[std::min(eventType,
+ static_cast<uint8_t>(dimmErr.size() - 1))]);
+ if (static_cast<MemErrType>(eventType) == MemErrType::memTrainErr ||
+ static_cast<MemErrType>(eventType) == MemErrType::memPmicErr)
+ {
+ bool amd = ptr[9] & 0x80;
+ tmpStream << std::format(
+ ", Major Code: 0x{:02X}, Minor Code: 0x{:0{}X}", ptr[10],
+ amd ? (ptr[12] << 8 | ptr[11]) : ptr[11], amd ? 4 : 2);
+ }
+ break;
+ case unifiedIioErr:
+ tmpStream << std::format(
+ "GeneralInfo: IIOErr(0x{:02X})"
+ ", IIO Port Location: Sled {:02}/Socket {:02}, Stack 0x{:02X}"
+ ", Error Type: 0x{:02X}, Error Severity: 0x{:02X}"
+ ", Error ID: 0x{:02X}",
+ genInfo, (ptr[5] >> 4) & 0x3, ptr[5] & 0xf, ptr[6], ptr[10],
+ ptr[11] & 0xf, ptr[12]);
+ break;
+ case unifiedPostEvt:
+ tmpStream << std::format(
+ "GeneralInfo: POST(0x{:02X}), POST Failure Event: {}", genInfo,
+ postEvent[std::min(
+ eventType, static_cast<uint8_t>(postEvent.size() - 1))]);
+
+ switch (static_cast<PostEvtType>(eventType))
+ {
+ case PostEvtType::pxeBootFail:
+ case PostEvtType::httpBootFail:
+ {
+ uint8_t failType = ptr[10] & 0xf;
+ tmpStream
+ << std::format(", Fail Type: {}, Error Code: 0x{:02X}",
+ (failType == 4 || failType == 6)
+ ? std::format("IPv{} fail", failType)
+ : std::format("0x{:02X}", ptr[10]),
+ ptr[11]);
+ break;
+ }
+ case PostEvtType::getCertFail:
+ tmpStream << std::format(
+ ", Failure Detail: {}",
+ certErr[std::min(
+ ptr[9], static_cast<uint8_t>(certErr.size() - 1))]);
+ break;
+ case PostEvtType::amdAblFail:
+ tmpStream << std::format(", ABL Error Code: 0x{:04X}",
+ (ptr[12] << 8) | ptr[11]);
+ break;
+ }
+ break;
+ case unifiedPcieEvt:
+ tmpStream << std::format(
+ "GeneralInfo: PCIeEvent(0x{:02X}), PCIe Failure Event: {}",
+ genInfo,
+ pcieEvent[std::min(
+ eventType, static_cast<uint8_t>(pcieEvent.size() - 1))]);
+
+ if (static_cast<PcieEvtType>(eventType) == PcieEvtType::dpc)
+ {
+ tmpStream << std::format(
+ ", Status: 0x{:04X}, Source ID: 0x{:04X}",
+ (ptr[8] << 8) | ptr[7], (ptr[10] << 8) | ptr[9]);
+ }
+ break;
+ case unifiedMemEvt:
+ eventType = ptr[9] & 0xf;
+ tmpStream << std::format("GeneralInfo: MemEvent(0x{:02X})", genInfo)
+ << (static_cast<MemEvtType>(eventType) !=
+ MemEvtType::noDimm
+ ? std::format(", {}", dimmLocationStr(
+ ptr[5], ptr[6], ptr[7]))
+ : "")
+ << ", DIMM Failure Event: ";
+
+ switch (static_cast<MemEvtType>(eventType))
+ {
+ case MemEvtType::ppr:
+ tmpStream << std::format("{} {}",
+ memPprTime[(ptr[10] >> 2) & 0x3],
+ memPpr[ptr[10] & 0x3]);
+ break;
+ case MemEvtType::adddc:
+ tmpStream << std::format(
+ "{} {}",
+ memEvent[std::min(eventType, static_cast<uint8_t>(
+ memEvent.size() - 1))],
+ memAdddc[std::min(
+ static_cast<uint8_t>(ptr[11] & 0xf),
+ static_cast<uint8_t>(memAdddc.size() - 1))]);
+ break;
+ default:
+ tmpStream << std::format(
+ "{}", memEvent[std::min(
+ eventType,
+ static_cast<uint8_t>(memEvent.size() - 1))]);
+ break;
+ }
+ break;
+ case unifiedBootGuard:
+ tmpStream << std::format(
+ "GeneralInfo: Boot Guard ACM Failure Events(0x{:02X})"
+ ", Error Class: 0x{:02X}, Error Code: 0x{:02X}",
+ genInfo, ptr[9], ptr[10]);
+ break;
+ case unifiedPprEvt:
+ tmpStream << std::format(
+ "GeneralInfo: PPREvent(0x{:02X}), {}"
+ ", DIMM Info: {:02X}{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}",
+ genInfo,
+ pprEvent[std::min(eventType,
+ static_cast<uint8_t>(pprEvent.size() - 1))],
+ ptr[6], ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12]);
break;
default:
std::vector<uint8_t> oemData(ptr, ptr + 13);
std::string oemDataStr;
toHexStr(oemData, oemDataStr);
- tmpStream << "Undefined Error Type(0x" << std::setw(2) << errType
- << "), Raw: " << oemDataStr;
+ tmpStream << std::format("Undefined Error Type(0x{:02X}), Raw: {}",
+ errType, oemDataStr);
}
errStr = tmpStream.str();