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)