Add option to ignore soft resets before POST
In some cases it is expected that the host will
send a soft reset. This can overwrite previous power state
changes which we may want to keep.
Tested:
Set restore policy to always on. AC cycle system.
Check restart cause is always on, and not overwritten as soft reset
Once host has posted, do warm reset through host and
check that restart cause is soft reset.
Change-Id: I0bd861f25680a11fc2e7eb77088f3009bcf8b03b
Signed-off-by: Matt Simmering <matthew.simmering@intel.com>
diff --git a/meson.build b/meson.build
index 4271a39..23c92c2 100644
--- a/meson.build
+++ b/meson.build
@@ -32,6 +32,9 @@
if get_option('use-acboot').enabled()
cpp_args += '-DUSE_ACBOOT'
endif
+if get_option('ignore-soft-resets-during-post').enabled()
+ cpp_args += '-DIGNORE_SOFT_RESETS_DURING_POST'
+endif
deps = [
dependency('libgpiodcxx', default_options: ['bindings=cxx']),
diff --git a/meson_options.txt b/meson_options.txt
index 25639c5..c32fd30 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -4,3 +4,5 @@
description: 'Use the PLT_RST eSPI signal to detect warm reset instead of POST Complete')
option('use-acboot', type: 'feature', value : 'disabled',
description: 'Use hardware Reset Reason to control Power Restore. Note: this only works with Intel-BMC')
+option('ignore-soft-resets-during-post', type: 'feature', value : 'disabled',
+ description: 'Ignore soft resets from host during POST')
diff --git a/src/power_control.cpp b/src/power_control.cpp
index 9f5be28..6229251 100644
--- a/src/power_control.cpp
+++ b/src/power_control.cpp
@@ -127,6 +127,9 @@
static gpiod::line powerButtonMask;
static gpiod::line resetButtonMask;
static bool nmiButtonMasked = false;
+#if IGNORE_SOFT_RESETS_DURING_POST
+static bool ignoreNextSoftReset = false;
+#endif
// This map contains all timer values that are to be read from json config
boost::container::flat_map<std::string, int> TimerMap = {
@@ -213,6 +216,7 @@
Inactive,
Standby,
};
+static OperatingSystemStateStage operatingSystemState;
static constexpr std::string_view
getOperatingSystemStateStage(const OperatingSystemStateStage stage)
{
@@ -231,6 +235,15 @@
};
static void setOperatingSystemState(const OperatingSystemStateStage stage)
{
+ operatingSystemState = stage;
+#if IGNORE_SOFT_RESETS_DURING_POST
+ // If POST complete has asserted set ignoreNextSoftReset to false to avoid
+ // masking soft resets after POST
+ if (operatingSystemState == OperatingSystemStateStage::Standby)
+ {
+ ignoreNextSoftReset = false;
+ }
+#endif
osIface->set_property("OperatingSystemState",
std::string(getOperatingSystemStateStage(stage)));
@@ -707,6 +720,13 @@
}
else if (causeSet.contains(RestartCause::softReset))
{
+#if IGNORE_SOFT_RESETS_DURING_POST
+ if (ignoreNextSoftReset)
+ {
+ ignoreNextSoftReset = false;
+ return;
+ }
+#endif
restartCause = getRestartCause(RestartCause::softReset);
}
@@ -1671,6 +1691,13 @@
break;
case Event::sioS5Assert:
setPowerState(PowerState::transitionToOff);
+#if IGNORE_SOFT_RESETS_DURING_POST
+ // Only recognize soft resets once host gets past POST COMPLETE
+ if (operatingSystemState != OperatingSystemStateStage::Standby)
+ {
+ ignoreNextSoftReset = true;
+ }
+#endif
addRestartCause(RestartCause::softReset);
break;
#if USE_PLT_RST
@@ -1679,6 +1706,13 @@
case Event::postCompleteDeAssert:
#endif
setPowerState(PowerState::checkForWarmReset);
+#if IGNORE_SOFT_RESETS_DURING_POST
+ // Only recognize soft resets once host gets past POST COMPLETE
+ if (operatingSystemState != OperatingSystemStateStage::Standby)
+ {
+ ignoreNextSoftReset = true;
+ }
+#endif
addRestartCause(RestartCause::softReset);
warmResetCheckTimerStart();
break;
@@ -2754,8 +2788,9 @@
// Release line
line.reset();
- // Initialize the power state
+ // Initialize the power state and operating system state
powerState = PowerState::off;
+ operatingSystemState = OperatingSystemStateStage::Inactive;
// Check power good
if (powerOkConfig.type == ConfigType::GPIO)