selcommands.cpp (020ff3e49f6420b99d6a0092922da9375ea9a024) selcommands.cpp (2405ae98b39a97e9d7753d8dc5c673a4a8885b85)
1/*
2 * Copyright (c) 2018 Intel Corporation.
3 * Copyright (c) 2018-present Facebook.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *

--- 246 unchanged lines hidden (view full) ---

255 else
256 {
257 errLog = "Unknown";
258 }
259}
260
261static void logCritIrq(uint8_t* data, std::string& errLog)
262{
1/*
2 * Copyright (c) 2018 Intel Corporation.
3 * Copyright (c) 2018-present Facebook.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *

--- 246 unchanged lines hidden (view full) ---

255 else
256 {
257 errLog = "Unknown";
258 }
259}
260
261static void logCritIrq(uint8_t* data, std::string& errLog)
262{
263
264 if (data[0] == 0x0)
265 {
266 errLog = "NMI / Diagnostic Interrupt";
267 }
268 else if (data[0] == 0x03)
269 {
270 errLog = "Software NMI";
271 }
272 else
273 {
274 errLog = "Unknown";
275 }
276
277 /* TODO: Call add_cri_sel for CRITICAL_IRQ */
278}
279
280static void logPostErr(uint8_t* data, std::string& errLog)
281{
263 if (data[0] == 0x0)
264 {
265 errLog = "NMI / Diagnostic Interrupt";
266 }
267 else if (data[0] == 0x03)
268 {
269 errLog = "Software NMI";
270 }
271 else
272 {
273 errLog = "Unknown";
274 }
275
276 /* TODO: Call add_cri_sel for CRITICAL_IRQ */
277}
278
279static void logPostErr(uint8_t* data, std::string& errLog)
280{
282
283 if ((data[0] & 0x0F) == 0x0)
284 {
285 errLog = "System Firmware Error";
286 }
287 else
288 {
289 errLog = "Unknown";
290 }
291
292 if (((data[0] >> 6) & 0x03) == 0x3)
293 {
294 // TODO: Need to implement IPMI spec based Post Code
295 errLog += ", IPMI Post Code";
296 }
297 else if (((data[0] >> 6) & 0x03) == 0x2)
298 {
281 if ((data[0] & 0x0F) == 0x0)
282 {
283 errLog = "System Firmware Error";
284 }
285 else
286 {
287 errLog = "Unknown";
288 }
289
290 if (((data[0] >> 6) & 0x03) == 0x3)
291 {
292 // TODO: Need to implement IPMI spec based Post Code
293 errLog += ", IPMI Post Code";
294 }
295 else if (((data[0] >> 6) & 0x03) == 0x2)
296 {
299 errLog +=
300 ", OEM Post Code 0x" + byteToStr(data[2]) + byteToStr(data[1]);
297 errLog += ", OEM Post Code 0x" + byteToStr(data[2]) +
298 byteToStr(data[1]);
301
302 switch ((data[2] << 8) | data[1])
303 {
304 case 0xA105:
305 errLog += ", BMC Failed (No Response)";
306 break;
307 case 0xA106:
308 errLog += ", BMC Failed (Self Test Fail)";

--- 170 unchanged lines hidden (view full) ---

479 std::string cpuStr = "CPU# " + std::to_string((data[2] & 0xE0) >> 5);
480 std::string chStr = "CHN# " + std::to_string((data[2] & 0x18) >> 3);
481 std::string dimmStr = "DIMM#" + std::to_string(data[2] & 0x7);
482
483 switch ((data[1] & 0xC) >> 2)
484 {
485 case 0x0:
486 {
299
300 switch ((data[2] << 8) | data[1])
301 {
302 case 0xA105:
303 errLog += ", BMC Failed (No Response)";
304 break;
305 case 0xA106:
306 errLog += ", BMC Failed (Self Test Fail)";

--- 170 unchanged lines hidden (view full) ---

477 std::string cpuStr = "CPU# " + std::to_string((data[2] & 0xE0) >> 5);
478 std::string chStr = "CHN# " + std::to_string((data[2] & 0x18) >> 3);
479 std::string dimmStr = "DIMM#" + std::to_string(data[2] & 0x7);
480
481 switch ((data[1] & 0xC) >> 2)
482 {
483 case 0x0:
484 {
487
488 /* All Info Valid */
489 [[maybe_unused]] uint8_t chnNum = (data[2] & 0x1C) >> 2;
490 [[maybe_unused]] uint8_t dimmNum = data[2] & 0x3;
491
492 /* TODO: If critical SEL logging is available, do it */
493 if (snrType == 0x0C)
494 {
495 if ((data[0] & 0x0F) == 0x0)

--- 30 unchanged lines hidden (view full) ---

526 /* CPU info not valid */
527 errLog += " (" + chStr + ", " + dimmStr + ")";
528 break;
529 }
530}
531
532static void logPwrErr(uint8_t* data, std::string& errLog)
533{
485 /* All Info Valid */
486 [[maybe_unused]] uint8_t chnNum = (data[2] & 0x1C) >> 2;
487 [[maybe_unused]] uint8_t dimmNum = data[2] & 0x3;
488
489 /* TODO: If critical SEL logging is available, do it */
490 if (snrType == 0x0C)
491 {
492 if ((data[0] & 0x0F) == 0x0)

--- 30 unchanged lines hidden (view full) ---

523 /* CPU info not valid */
524 errLog += " (" + chStr + ", " + dimmStr + ")";
525 break;
526 }
527}
528
529static void logPwrErr(uint8_t* data, std::string& errLog)
530{
534
535 if (data[0] == 0x1)
536 {
537 errLog = "SYS_PWROK failure";
538 /* Also try logging to Critial log file, if available */
539 /* "SYS_PWROK failure,FRU:1" */
540 }
541 else if (data[0] == 0x2)
542 {

--- 4 unchanged lines hidden (view full) ---

547 else
548 {
549 errLog = "Unknown";
550 }
551}
552
553static void logCatErr(uint8_t* data, std::string& errLog)
554{
531 if (data[0] == 0x1)
532 {
533 errLog = "SYS_PWROK failure";
534 /* Also try logging to Critial log file, if available */
535 /* "SYS_PWROK failure,FRU:1" */
536 }
537 else if (data[0] == 0x2)
538 {

--- 4 unchanged lines hidden (view full) ---

543 else
544 {
545 errLog = "Unknown";
546 }
547}
548
549static void logCatErr(uint8_t* data, std::string& errLog)
550{
555
556 if (data[0] == 0x0)
557 {
558 errLog = "IERR/CATERR";
559 /* Also try logging to Critial log file, if available */
560 /* "IERR,FRU:1 */
561 }
562 else if (data[0] == 0xB)
563 {

--- 188 unchanged lines hidden (view full) ---

752
753 errLog += ", Domain:" + nmDomName[domIdx] +
754 ", ErrType:" + nmErrType[errIdx] + ", Err:0x" +
755 byteToStr(data[2]);
756}
757
758static void logNmCap(uint8_t* data, std::string& errLog)
759{
551 if (data[0] == 0x0)
552 {
553 errLog = "IERR/CATERR";
554 /* Also try logging to Critial log file, if available */
555 /* "IERR,FRU:1 */
556 }
557 else if (data[0] == 0xB)
558 {

--- 188 unchanged lines hidden (view full) ---

747
748 errLog += ", Domain:" + nmDomName[domIdx] +
749 ", ErrType:" + nmErrType[errIdx] + ", Err:0x" +
750 byteToStr(data[2]);
751}
752
753static void logNmCap(uint8_t* data, std::string& errLog)
754{
760
761 const std::vector<std::string> nmCapStsStr = {"Not Available", "Available"};
762 if (data[0] & 0x7) // BIT1=policy, BIT2=monitoring, BIT3=pwr
763 // limit and the others are reserved
764 {
765 errLog = "PolicyInterface:" + nmCapStsStr[BIT(data[0], 0)] +
766 ",Monitoring:" + nmCapStsStr[BIT(data[0], 1)] +
767 ",PowerLimit:" + nmCapStsStr[BIT(data[0], 2)];
768 }

--- 30 unchanged lines hidden (view full) ---

799 else
800 {
801 errLog = "Unknown";
802 }
803}
804
805static void logMSMI(uint8_t* data, std::string& errLog)
806{
755 const std::vector<std::string> nmCapStsStr = {"Not Available", "Available"};
756 if (data[0] & 0x7) // BIT1=policy, BIT2=monitoring, BIT3=pwr
757 // limit and the others are reserved
758 {
759 errLog = "PolicyInterface:" + nmCapStsStr[BIT(data[0], 0)] +
760 ",Monitoring:" + nmCapStsStr[BIT(data[0], 1)] +
761 ",PowerLimit:" + nmCapStsStr[BIT(data[0], 2)];
762 }

--- 30 unchanged lines hidden (view full) ---

793 else
794 {
795 errLog = "Unknown";
796 }
797}
798
799static void logMSMI(uint8_t* data, std::string& errLog)
800{
807
808 if (data[0] == 0x0)
809 {
810 errLog = "IERR/MSMI";
811 }
812 else if (data[0] == 0x0B)
813 {
814 errLog = "MCERR/MSMI";
815 }

--- 52 unchanged lines hidden (view full) ---

868 {0x1A, {"NM_CAPABILITIES", logNmCap}},
869 {0x1B, {"NM_THRESHOLD", logNmThreshold}},
870 {0x3B, {"PWR_THRESH_EVT", logPwrThreshold}},
871 {0xE7, {"MSMI", logMSMI}},
872 {0xC5, {"HPR_WARNING", logHprWarn}}};
873
874static void parseSelHelper(StdSELEntry* data, std::string& errStr)
875{
801 if (data[0] == 0x0)
802 {
803 errLog = "IERR/MSMI";
804 }
805 else if (data[0] == 0x0B)
806 {
807 errLog = "MCERR/MSMI";
808 }

--- 52 unchanged lines hidden (view full) ---

861 {0x1A, {"NM_CAPABILITIES", logNmCap}},
862 {0x1B, {"NM_THRESHOLD", logNmThreshold}},
863 {0x3B, {"PWR_THRESH_EVT", logPwrThreshold}},
864 {0xE7, {"MSMI", logMSMI}},
865 {0xC5, {"HPR_WARNING", logHprWarn}}};
866
867static void parseSelHelper(StdSELEntry* data, std::string& errStr)
868{
876
877 /* Check if sensor type is OS_BOOT (0x1f) */
878 if (data->sensorType == 0x1F)
879 {
880 /* OS_BOOT used by OS */
881 switch (data->eventData1 & 0xF)
882 {
883 case 0x07:
884 errStr = "Base OS/Hypervisor Installation started";

--- 269 unchanged lines hidden (view full) ---

1154 errStr = tmpStream.str();
1155
1156 return;
1157}
1158
1159static void parseSelData(uint8_t fruId, std::vector<uint8_t>& reqData,
1160 std::string& msgLog)
1161{
869 /* Check if sensor type is OS_BOOT (0x1f) */
870 if (data->sensorType == 0x1F)
871 {
872 /* OS_BOOT used by OS */
873 switch (data->eventData1 & 0xF)
874 {
875 case 0x07:
876 errStr = "Base OS/Hypervisor Installation started";

--- 269 unchanged lines hidden (view full) ---

1146 errStr = tmpStream.str();
1147
1148 return;
1149}
1150
1151static void parseSelData(uint8_t fruId, std::vector<uint8_t>& reqData,
1152 std::string& msgLog)
1153{
1162
1163 /* Get record type */
1164 int recType = reqData[2];
1165 std::string errType, errLog;
1166
1167 uint8_t* ptr = NULL;
1168
1169 std::stringstream recTypeStream;
1170 recTypeStream << std::hex << std::uppercase << std::setfill('0')

--- 89 unchanged lines hidden (view full) ---

1260 parseOemSel((TsOemSELEntry*)data, errLog);
1261 msgLog += errType + " (0x" + recTypeStream.str() + "), OEM Data: (" +
1262 oemDataStr + ") " + errLog;
1263 }
1264 else
1265 {
1266 errType = unknownErr;
1267 toHexStr(reqData, errLog);
1154 /* Get record type */
1155 int recType = reqData[2];
1156 std::string errType, errLog;
1157
1158 uint8_t* ptr = NULL;
1159
1160 std::stringstream recTypeStream;
1161 recTypeStream << std::hex << std::uppercase << std::setfill('0')

--- 89 unchanged lines hidden (view full) ---

1251 parseOemSel((TsOemSELEntry*)data, errLog);
1252 msgLog += errType + " (0x" + recTypeStream.str() + "), OEM Data: (" +
1253 oemDataStr + ") " + errLog;
1254 }
1255 else
1256 {
1257 errType = unknownErr;
1258 toHexStr(reqData, errLog);
1268 msgLog +=
1269 errType + " (0x" + recTypeStream.str() + ") RawData: " + errLog;
1259 msgLog += errType + " (0x" + recTypeStream.str() +
1260 ") RawData: " + errLog;
1270 }
1271}
1272
1273} // namespace fb_oem::ipmi::sel
1274
1275namespace ipmi
1276{
1277

--- 6 unchanged lines hidden (view full) ---

1284ipmi::RspType<uint8_t, // SEL version
1285 uint16_t, // SEL entry count
1286 uint16_t, // free space
1287 uint32_t, // last add timestamp
1288 uint32_t, // last erase timestamp
1289 uint8_t> // operation support
1290 ipmiStorageGetSELInfo()
1291{
1261 }
1262}
1263
1264} // namespace fb_oem::ipmi::sel
1265
1266namespace ipmi
1267{
1268

--- 6 unchanged lines hidden (view full) ---

1275ipmi::RspType<uint8_t, // SEL version
1276 uint16_t, // SEL entry count
1277 uint16_t, // free space
1278 uint32_t, // last add timestamp
1279 uint32_t, // last erase timestamp
1280 uint8_t> // operation support
1281 ipmiStorageGetSELInfo()
1282{
1292
1293 fb_oem::ipmi::sel::GetSELInfoData info;
1294
1295 selObj.getInfo(info);
1296 return ipmi::responseSuccess(info.selVersion, info.entries, info.freeSpace,
1297 info.addTimeStamp, info.eraseTimeStamp,
1298 info.operationSupport);
1299}
1300
1301ipmi::RspType<uint16_t, std::vector<uint8_t>>
1302 ipmiStorageGetSELEntry(std::vector<uint8_t> data)
1303{
1283 fb_oem::ipmi::sel::GetSELInfoData info;
1284
1285 selObj.getInfo(info);
1286 return ipmi::responseSuccess(info.selVersion, info.entries, info.freeSpace,
1287 info.addTimeStamp, info.eraseTimeStamp,
1288 info.operationSupport);
1289}
1290
1291ipmi::RspType<uint16_t, std::vector<uint8_t>>
1292 ipmiStorageGetSELEntry(std::vector<uint8_t> data)
1293{
1304
1305 if (data.size() != sizeof(fb_oem::ipmi::sel::GetSELEntryRequest))
1306 {
1307 return ipmi::responseReqDataLenInvalid();
1308 }
1309
1310 fb_oem::ipmi::sel::GetSELEntryRequest* reqData =
1311 reinterpret_cast<fb_oem::ipmi::sel::GetSELEntryRequest*>(&data[0]);
1312

--- 89 unchanged lines hidden (view full) ---

1402
1403 std::string ipmiRaw, logErr;
1404 toHexStr(data, ipmiRaw);
1405
1406 /* Parse sel data and get an error log to be filed */
1407 fb_oem::ipmi::sel::parseSelData((ctx->hostIdx + 1), data, logErr);
1408
1409 static const std::string openBMCMessageRegistryVersion("0.1");
1294 if (data.size() != sizeof(fb_oem::ipmi::sel::GetSELEntryRequest))
1295 {
1296 return ipmi::responseReqDataLenInvalid();
1297 }
1298
1299 fb_oem::ipmi::sel::GetSELEntryRequest* reqData =
1300 reinterpret_cast<fb_oem::ipmi::sel::GetSELEntryRequest*>(&data[0]);
1301

--- 89 unchanged lines hidden (view full) ---

1391
1392 std::string ipmiRaw, logErr;
1393 toHexStr(data, ipmiRaw);
1394
1395 /* Parse sel data and get an error log to be filed */
1396 fb_oem::ipmi::sel::parseSelData((ctx->hostIdx + 1), data, logErr);
1397
1398 static const std::string openBMCMessageRegistryVersion("0.1");
1410 std::string messageID =
1411 "OpenBMC." + openBMCMessageRegistryVersion + ".SELEntryAdded";
1399 std::string messageID = "OpenBMC." + openBMCMessageRegistryVersion +
1400 ".SELEntryAdded";
1412
1413 /* Log the Raw SEL message to the journal */
1414 std::string journalMsg = "SEL Entry Added: " + ipmiRaw;
1415
1416 phosphor::logging::log<phosphor::logging::level::INFO>(
1417 journalMsg.c_str(),
1418 phosphor::logging::entry("IPMISEL_MESSAGE_ID=%s", messageID.c_str()),
1419 phosphor::logging::entry("IPMISEL_MESSAGE_ARGS=%s", logErr.c_str()));

--- 130 unchanged lines hidden ---
1401
1402 /* Log the Raw SEL message to the journal */
1403 std::string journalMsg = "SEL Entry Added: " + ipmiRaw;
1404
1405 phosphor::logging::log<phosphor::logging::level::INFO>(
1406 journalMsg.c_str(),
1407 phosphor::logging::entry("IPMISEL_MESSAGE_ID=%s", messageID.c_str()),
1408 phosphor::logging::entry("IPMISEL_MESSAGE_ARGS=%s", logErr.c_str()));

--- 130 unchanged lines hidden ---