yosemitev2:add host physical location info of DIMM
The current implementation for host dimm doesn't
provide much detail about the dimm physical
location as below,
Log:
SEL Entry: FRU:1, Record:Standard (0x02),
Time: Thu Jan 1 00:00:00 1970,
Sensor: MEMORY_ECC_ERR (0x63), Event Data: (00A0F0)
Correctable (DIMM 240)
Logical Rank 0 Assertion
This feature helps to print the host physical
location of info of DIMM to help
the data center techs to quickly locate
physical HW. (e.g. A0/A1 or B0/B1 etc.)
Tested:
Verified dimm physical location in Yosemitev2
as below,
Log:
SEL Entry: FRU:1, Record:Standard (0x02),
Time: Thu Jan 1 00:00:00 1970,
Sensor: MEMORY_ECC_ERR (0x63),
Event Data: (00A0F0) Correctable (DIMM 240)
Logical Rank 0 Node: 7, Card: 2,
Module: 0, Rank Number: 0,
Location: DIMM B0 Assertion
Signed-off-by: Manikandan Elumalai <manikandan.hcl.ers.epl@gmail.com>
Change-Id: I58dcb2eb1f8842607609494194fcbd5648fb443b
diff --git a/src/selcommands.cpp b/src/selcommands.cpp
index 127a593..ac68ace 100644
--- a/src/selcommands.cpp
+++ b/src/selcommands.cpp
@@ -477,7 +477,7 @@
/* TODO: Verify these bits */
std::string cpuStr = "CPU# " + std::to_string((data[2] & 0xE0) >> 5);
std::string chStr = "CHN# " + std::to_string((data[2] & 0x18) >> 3);
- std::string dimmStr = "DIMM# " + std::to_string(data[2] & 0x7);
+ std::string dimmStr = "DIMM#" + std::to_string(data[2] & 0x7);
switch ((data[1] & 0xC) >> 2)
{
@@ -928,6 +928,56 @@
}
}
+static void parseDimmPhyloc(StdSELEntry* data, std::string& errStr)
+{
+ // Log when " All info available"
+ uint8_t chNum = (data->eventData3 & 0x18) >> 3;
+ uint8_t dimmNum = data->eventData3 & 0x7;
+ uint8_t rankNum = data->eventData2 & 0x03;
+ uint8_t nodeNum = (data->eventData3 & 0xE0) >> 5;
+
+ if (chNum == 3 && dimmNum == 0)
+ {
+ errStr += " Node: " + std::to_string(nodeNum) + "," +
+ " Card: " + std::to_string(chNum) + "," +
+ " Module: " + std::to_string(dimmNum) + "," +
+ " Rank Number: " + std::to_string(rankNum) + "," +
+ " Location: DIMM A0";
+ }
+ else if (chNum == 2 && dimmNum == 0)
+ {
+ errStr += " Node: " + std::to_string(nodeNum) + "," +
+ " Card: " + std::to_string(chNum) + "," +
+ " Module: " + std::to_string(dimmNum) + "," +
+ " Rank Number: " + std::to_string(rankNum) + "," +
+ " Location: DIMM B0";
+ }
+ else if (chNum == 4 && dimmNum == 0)
+ {
+ errStr += " Node: " + std::to_string(nodeNum) + "," +
+ " Card: " + std::to_string(chNum) + "," +
+ " Module: " + std::to_string(dimmNum) + "," +
+ " Rank Number: " + std::to_string(rankNum) + "," +
+ " Location: DIMM C0 ";
+ }
+ else if (chNum == 5 && dimmNum == 0)
+ {
+ errStr += " Node: " + std::to_string(nodeNum) + "," +
+ " Card: " + std::to_string(chNum) + "," +
+ " Module: " + std::to_string(dimmNum) + "," +
+ " Rank Number: " + std::to_string(rankNum) + "," +
+ " Location: DIMM D0";
+ }
+ else
+ {
+ errStr += " Node: " + std::to_string(nodeNum) + "," +
+ " Card: " + std::to_string(chNum) + "," +
+ " Module: " + std::to_string(dimmNum) + "," +
+ " Rank Number: " + std::to_string(rankNum) + "," +
+ " Location: DIMM Unknow";
+ }
+}
+
static void parseStdSel(StdSELEntry* data, std::string& errStr)
{
std::stringstream tmpStream;
@@ -943,11 +993,13 @@
errStr = "Correctable";
tmpStream << "DIMM" << std::setw(2) << std::setfill('0')
<< data->eventData3 << " ECC err";
+ parseDimmPhyloc(data, errStr);
break;
case 0x01:
errStr = "Uncorrectable";
tmpStream << "DIMM" << std::setw(2) << std::setfill('0')
<< data->eventData3 << " UECC err";
+ parseDimmPhyloc(data, errStr);
break;
case 0x02:
errStr = "Parity";
@@ -1103,7 +1155,8 @@
return;
}
-static void parseSelData(std::vector<uint8_t>& reqData, std::string& msgLog)
+static void parseSelData(uint8_t fruId, std::vector<uint8_t>& reqData,
+ std::string& msgLog)
{
/* Get record type */
@@ -1116,7 +1169,7 @@
recTypeStream << std::hex << std::uppercase << std::setfill('0')
<< std::setw(2) << recType;
- msgLog = "SEL Entry: FRU: 1, Record: ";
+ msgLog = "SEL Entry: FRU: " + std::to_string(fruId) + ", Record: ";
if (recType == stdErrType)
{
@@ -1331,7 +1384,8 @@
}
}
-ipmi::RspType<uint16_t> ipmiStorageAddSELEntry(std::vector<uint8_t> data)
+ipmi::RspType<uint16_t> ipmiStorageAddSELEntry(ipmi::Context::ptr ctx,
+ std::vector<uint8_t> data)
{
/* Per the IPMI spec, need to cancel any reservation when a
* SEL entry is added
@@ -1347,7 +1401,7 @@
toHexStr(data, ipmiRaw);
/* Parse sel data and get an error log to be filed */
- fb_oem::ipmi::sel::parseSelData(data, logErr);
+ fb_oem::ipmi::sel::parseSelData((ctx->hostIdx + 1), data, logErr);
static const std::string openBMCMessageRegistryVersion("0.1");
std::string messageID =