Add option to use PLT_RST for warm reset detection
To support platforms that provide a PLT_RST eSPI signal,
this change adds an option to detect warm resets from the
eSPI PLT_RST signal instead of POST Complete.
The eSPI PLT_RST signal is provided by the
xyz.openbmc_project.Host.Misc.Manager service.
Tested:
Confirmed that warm reset can be detected based on PLT_RST
changes.
Change-Id: I8ac2c260280cf4edec8800e8e2ee12159748f24e
Signed-off-by: Jason M. Bills <jason.m.bills@linux.intel.com>
diff --git a/README.md b/README.md
index b1c74b2..243cf77 100644
--- a/README.md
+++ b/README.md
@@ -27,13 +27,13 @@
POWER_BUTTON
POWER_OUT
-On an aspeed, these are generally connected to E0, E1, E2, and E3 respecitvely.
+On an aspeed, these are generally connected to E0, E1, E2, and E3 respectively.
An example of this is available in the s2600WF config.
This patch allows the passthrough to be reenabled to the default condition when
the appropriate pin is released. This allows power control to take control
when needed by a user power action, but leave the hardware in control a majority
-of the time, reducing the possibilty of bricking a system due to a failed BMC.
+of the time, reducing the possibility of bricking a system due to a failed BMC.
https://github.com/Intel-BMC/openbmc/blob/intel/meta-openbmc-mods/meta-ast2500/recipes-kernel/linux/linux-aspeed/0002-Enable-pass-through-on-GPIOE1-and-GPIOE3-free.patch
https://github.com/Intel-BMC/openbmc/blob/intel/meta-openbmc-mods/meta-ast2500/recipes-kernel/linux/linux-aspeed/0003-Enable-GPIOE0-and-GPIOE2-pass-through-by-default.patch
@@ -44,3 +44,14 @@
This implementation does not currently implement the common targets that other
implementations do. There were several attempts to, but all ended in timing
issues and boot inconsistencies during stress operations.
+
+## Build Options
+
+#### USE_PLT_RST
+The POST Complete GPIO is usually held asserted by BIOS after POST complete
+and de-asserts on reset. This de-assert behavior is currently used to detect
+warm resets.
+
+Some systems are adding support for a PLT_RST eSPI signal that can be used to
+more accurately detect warm resets. When this option is enabled, x86-power-control
+will use PLT_RST to detect warm resets instead of POST Complete.
\ No newline at end of file
diff --git a/power-control-x86/CMakeLists.txt b/power-control-x86/CMakeLists.txt
index 2a94f78..ba06ed4 100644
--- a/power-control-x86/CMakeLists.txt
+++ b/power-control-x86/CMakeLists.txt
@@ -9,6 +9,12 @@
power and restoring back"
OFF
)
+option (
+ USE_PLT_RST
+ "Use the PLT_RST eSPI signal to detect warm reset
+ instead of POST Complete"
+ OFF
+)
add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY)
add_definitions(-DBOOST_SYSTEM_NO_DEPRECATED)
@@ -30,6 +36,8 @@
target_compile_definitions (
${PROJECT_NAME} PRIVATE $<$<BOOL:${CHASSIS_SYSTEM_RESET}>:
-DCHASSIS_SYSTEM_RESET>
+ ${PROJECT_NAME} PRIVATE $<$<BOOL:${USE_PLT_RST}>:
+ -DUSE_PLT_RST>
)
install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/power-control-x86/src/power_control.cpp b/power-control-x86/src/power_control.cpp
index 987a76f..0379c4c 100644
--- a/power-control-x86/src/power_control.cpp
+++ b/power-control-x86/src/power_control.cpp
@@ -219,6 +219,8 @@
sioPowerGoodDeAssert,
sioS5Assert,
sioS5DeAssert,
+ pltRstAssert,
+ pltRstDeAssert,
postCompleteAssert,
postCompleteDeAssert,
powerButtonPressed,
@@ -257,6 +259,12 @@
case Event::sioS5DeAssert:
return "SIO S5 de-assert";
break;
+ case Event::pltRstAssert:
+ return "PLT_RST assert";
+ break;
+ case Event::pltRstDeAssert:
+ return "PLT_RST de-assert";
+ break;
case Event::postCompleteAssert:
return "POST Complete assert";
break;
@@ -1416,7 +1424,11 @@
setPowerState(PowerState::transitionToOff);
addRestartCause(RestartCause::softReset);
break;
+#if USE_PLT_RST
+ case Event::pltRstAssert:
+#else
case Event::postCompleteDeAssert:
+#endif
setPowerState(PowerState::checkForWarmReset);
addRestartCause(RestartCause::softReset);
warmResetCheckTimerStart();
@@ -2032,6 +2044,55 @@
});
}
+static void pltRstHandler(bool pltRst)
+{
+ if (pltRst)
+ {
+ sendPowerControlEvent(Event::pltRstDeAssert);
+ }
+ else
+ {
+ sendPowerControlEvent(Event::pltRstAssert);
+ }
+}
+
+static void hostMiscHandler(sdbusplus::message::message& msg)
+{
+ std::string interfaceName;
+ boost::container::flat_map<std::string, std::variant<bool>>
+ propertiesChanged;
+ bool pltRst;
+ try
+ {
+ msg.read(interfaceName, propertiesChanged);
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "Unable to read Host Misc status\n";
+ return;
+ }
+ if (propertiesChanged.empty())
+ {
+ std::cerr
+ << "ERROR: Empty Host.Misc PropertiesChanged signal received\n";
+ return;
+ }
+
+ for (auto& [property, value] : propertiesChanged)
+ {
+ if (property == "ESpiPlatformReset")
+ {
+ bool* pltRst = std::get_if<bool>(&value);
+ if (pltRst == nullptr)
+ {
+ std::cerr << property << " property invalid\n";
+ return;
+ }
+ pltRstHandler(*pltRst);
+ }
+ }
+}
+
static void postCompleteHandler()
{
gpiod::line_event gpioLineEvent = postCompleteLine.event_read();
@@ -2274,6 +2335,14 @@
power_control::idButtonLine, power_control::idButtonEvent);
}
+#ifdef USE_PLT_RST
+ sdbusplus::bus::match::match pltRstMatch(
+ *power_control::conn,
+ "type='signal',interface='org.freedesktop.DBus.Properties',member='"
+ "PropertiesChanged',arg0='xyz.openbmc_project.State.Host.Misc'",
+ power_control::hostMiscHandler);
+#endif
+
// Request POST_COMPLETE GPIO events
if (!power_control::postCompleteName.empty())
{