Add command to control BMC system reset on SMI timeout
This adds a get and set command to enable or disable the BMC
system reset to recover a system after an SMI timeout error.
Tested:
Get SMI Reset Disable Status:
ipmitool raw 0x30 0x43
01
Injected SMI Timeout error and system did not reset.
Clear SMI Reset Disable:
ipmitool raw 0x30 0x42 0
ipmitool raw 0x30 0x43
00
Injected SMI Timeout error and system was reset.
Change-Id: If0321c5abd17fbdb97579516bf4864f8ffeec3a5
Signed-off-by: Jason M. Bills <jason.m.bills@linux.intel.com>
diff --git a/include/oemcommands.hpp b/include/oemcommands.hpp
index d20e53d..7486576 100644
--- a/include/oemcommands.hpp
+++ b/include/oemcommands.hpp
@@ -25,6 +25,8 @@
cmdGetColdRedundancyConfig = 0x2e,
cmdGetAICSlotFRUIDSlotPosRecords = 0x31,
cmdSetSystemGUID = 0x41,
+ cmdDisableBMCSystemReset = 0x42,
+ cmdGetBMCResetDisables = 0x43,
cmdSendEmbeddedFWUpdStatus = 0x44,
cmdSetPowerRestoreDelay = 0x54,
cmdGetPowerRestoreDelay = 0x55,
@@ -118,6 +120,10 @@
"/xyz/openbmc_project/control/processor_error_config";
static constexpr const char* processorErrConfigIntf =
"xyz.openbmc_project.Control.Processor.ErrConfig";
+static constexpr const char* bmcResetDisablesPath =
+ "/xyz/openbmc_project/control/bmc_reset_disables";
+static constexpr const char* bmcResetDisablesIntf =
+ "xyz.openbmc_project.Control.ResetDisables";
static constexpr const char* postCodesObjPath =
"/xyz/openbmc_project/State/Boot/PostCode";
diff --git a/src/oemcommands.cpp b/src/oemcommands.cpp
index a11d3b5..aa8330e 100644
--- a/src/oemcommands.cpp
+++ b/src/oemcommands.cpp
@@ -202,6 +202,58 @@
return IPMI_CC_OK;
}
+ipmi::RspType<> ipmiOEMDisableBMCSystemReset(bool disableResetOnSMI,
+ uint7_t reserved1)
+{
+ std::shared_ptr<sdbusplus::asio::connection> busp = getSdBus();
+
+ try
+ {
+ auto service =
+ ipmi::getService(*busp, bmcResetDisablesIntf, bmcResetDisablesPath);
+ ipmi::setDbusProperty(*busp, service, bmcResetDisablesPath,
+ bmcResetDisablesIntf, "ResetOnSMI",
+ !disableResetOnSMI);
+ }
+ catch (std::exception& e)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "Failed to set BMC reset disables",
+ phosphor::logging::entry("EXCEPTION=%s", e.what()));
+ return ipmi::responseUnspecifiedError();
+ }
+
+ return ipmi::responseSuccess();
+}
+
+ipmi::RspType<bool, // disableResetOnSMI
+ uint7_t // reserved
+ >
+ ipmiOEMGetBMCResetDisables()
+{
+ bool disableResetOnSMI = true;
+
+ std::shared_ptr<sdbusplus::asio::connection> busp = getSdBus();
+ try
+ {
+ auto service =
+ ipmi::getService(*busp, bmcResetDisablesIntf, bmcResetDisablesPath);
+ Value variant =
+ ipmi::getDbusProperty(*busp, service, bmcResetDisablesPath,
+ bmcResetDisablesIntf, "ResetOnSMI");
+ disableResetOnSMI = !std::get<bool>(variant);
+ }
+ catch (std::exception& e)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "Failed to get BMC reset disables",
+ phosphor::logging::entry("EXCEPTION=%s", e.what()));
+ return ipmi::responseUnspecifiedError();
+ }
+
+ return ipmi::responseSuccess(disableResetOnSMI, 0);
+}
+
ipmi_ret_t ipmiOEMSetBIOSID(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
ipmi_request_t request, ipmi_response_t response,
ipmi_data_len_t dataLen, ipmi_context_t context)
@@ -2731,6 +2783,20 @@
static_cast<ipmi_cmd_t>(IPMINetfnIntelOEMGeneralCmd::cmdSetSystemGUID),
NULL, ipmiOEMSetSystemGUID,
PRIVILEGE_ADMIN); // set system guid
+
+ // <Disable BMC System Reset Action>
+ ipmi::registerHandler(
+ ipmi::prioOemBase, netfnIntcOEMGeneral,
+ static_cast<ipmi::Cmd>(
+ IPMINetfnIntelOEMGeneralCmd::cmdDisableBMCSystemReset),
+ ipmi::Privilege::Admin, ipmiOEMDisableBMCSystemReset);
+ // <Get BMC Reset Disables>
+ ipmi::registerHandler(
+ ipmi::prioOemBase, netfnIntcOEMGeneral,
+ static_cast<ipmi::Cmd>(
+ IPMINetfnIntelOEMGeneralCmd::cmdGetBMCResetDisables),
+ ipmi::Privilege::Admin, ipmiOEMGetBMCResetDisables);
+
ipmiPrintAndRegister(
netfnIntcOEMGeneral,
static_cast<ipmi_cmd_t>(IPMINetfnIntelOEMGeneralCmd::cmdSetBIOSID),