Check OperatingSystemStatus to determine POST done.
updateBiosDone property in service xyz.openbmc_project.Host.Misc.Manager
is used to determine the POST done. But this service has Intel specific
dependencies. So if this service is not available, we can use property
OperatingSystemState in xyz.openbmc_project.State.OperatingSystem
service. According to x86-power-control repo, OperatingSystemState
should return one of "CBoot", "PXEBoot", "DiagBoot", "CDROMBoot",
"ROMBoot", "BootComplete" or "Standby" once the POST is asserted. Only
"Inactive" indicates that POST is not done.
Tested:
Tested this on the BMC and verified that the host state changes to
postComplete
Signed-off-by: kasunath <kasunath@google.com>
Change-Id: Ia9c6edf2305ef83587e187d1cd508e0024c052a5
diff --git a/src/cpuinfo_utils.cpp b/src/cpuinfo_utils.cpp
index 96e8e6f..e30a275 100644
--- a/src/cpuinfo_utils.cpp
+++ b/src/cpuinfo_utils.cpp
@@ -18,6 +18,7 @@
#include <boost/algorithm/string/predicate.hpp>
#include <sdbusplus/asio/property.hpp>
#include <xyz/openbmc_project/State/Host/server.hpp>
+#include <xyz/openbmc_project/State/OperatingSystem/Status/server.hpp>
#include <iostream>
#include <type_traits>
@@ -29,9 +30,11 @@
using namespace sdbusplus::xyz::openbmc_project;
using PowerState = State::server::Host::HostState;
+using OsState = State::OperatingSystem::server::Status::OSStatus;
HostState hostState = HostState::off;
static PowerState powerState = PowerState::Off;
+static OsState osState = OsState::Inactive;
static bool biosDone = false;
static std::shared_ptr<sdbusplus::asio::connection> dbusConn;
@@ -46,8 +49,16 @@
// since the two signals come from different services and there is no
// tight guarantee about their relationship.
biosDone = false;
+ // Setting osState to inactive for the same reason as above.
+ osState = OsState::Inactive;
}
- else if (!biosDone)
+ // Both biosDone and OsState tell us about the POST done status. At least
+ // one of them should indicate that the POST is done.
+ // According to openbmc_project/State/OperatingSystem/Status.interface.yaml
+ // Only "Inactive" indicates that the POST is not done. All the other
+ // statuses (CBoot, PXEBoot, DiagBoot, CDROMBoot, ROMBoot, BootComplete,
+ // Standby) indicate that the POST is done.
+ else if ((!biosDone) && (osState == OsState::Inactive))
{
hostState = HostState::postInProgress;
}
@@ -70,6 +81,37 @@
updateHostState();
}
+void updateOsState(const std::string& newState)
+{
+ // newState might not contain the full path. It might just contain the enum
+ // string (By the time I am writing this, its not returning the full path).
+ // Full string:
+ // "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus.Standby". Just
+ // the string for enum: "Standby". If the newState doesn't contain the full
+ // string, convertOSStatusFromString will fail. Prepend the full path if
+ // needed.
+ std::string full_path = newState;
+ if (newState.find("xyz.") == std::string::npos)
+ {
+ full_path =
+ "xyz.openbmc_project.State.OperatingSystem.Status.OSStatus." +
+ newState;
+ }
+
+ try
+ {
+ osState =
+ State::OperatingSystem::server::Status::convertOSStatusFromString(
+ full_path);
+ }
+ catch (const sdbusplus::exception::InvalidEnumString& ex)
+ {
+ std::cerr << "Invalid OperatingSystem Status: " << full_path << "\n";
+ osState = OsState::Inactive;
+ }
+ updateHostState();
+}
+
/**
* Register a handler to be called whenever the given property is changed. Also
* call the handler once immediately (asynchronously) with the current property
@@ -233,6 +275,15 @@
"/xyz/openbmc_project/misc/platform_state",
"xyz.openbmc_project.State.Host.Misc", "CoreBiosDone",
updateBiosDone);
+ // xyz.openbmc_project.Host.Misc.Manager has Intel specific dependencies.
+ // If it is not available, then we can use the OperatingSystemState in
+ // xyz.openbmc_project.State.OperatingSystem. According to x86-power-control
+ // repo, OperatingSystemState should return "standby" once the POST is
+ // asserted.
+ subscribeToProperty("xyz.openbmc_project.State.OperatingSystem",
+ "/xyz/openbmc_project/state/os",
+ "xyz.openbmc_project.State.OperatingSystem.Status",
+ "OperatingSystemState", updateOsState);
initialized = true;
}