chassis-psu: Add Chassis class for PSU management
This commit introduces the `Chassis` class within the
`phosphor::power::chassis` namespace. This class is responsible for
managing and monitoring power supply units (PSUs) associated with a
chassis.
Key functionalities include:
- Discovering individual PSUs and retrieving their properties and
configuration from D-Bus.
- Monitoring PSU presence changes and system power state.
- Retrieving overall system power properties.
- Implementing a validation timer for PSU configurations.
- Use an `sdeventplus` timer to delay configuration validation
until all EM interfaces are available.
- Maintain internal state flags (`powerOn`, `powerFaultOccurring`,
`brownoutLogged`,`runValidateConfig`) and data structures:
- `supportedConfigs` map of model names to `sys_properties`.
- Vector of `PowerSupply` instances.
- Building and populating PSU driver names.
Tested:
Simulated a multi-chassis setup, with each chassis containing a
couple of PSUs. Executed a simulated application to invoke the Chassis
object.
- Verified each Chassis object listed only PSUs belong to the chassis,
by verifying the PSU path has the correct chassis ID.
Note: Removed implementation of getSupportedConfiguration until design
issue resolved.
Change-Id: Ic4bda5ab0bd6173a67284ed27a0bc883ed04f92f
Signed-off-by: Faisal Awada <faisal@us.ibm.com>
diff --git a/phosphor-power-supply/chassis.hpp b/phosphor-power-supply/chassis.hpp
new file mode 100644
index 0000000..527b0ff
--- /dev/null
+++ b/phosphor-power-supply/chassis.hpp
@@ -0,0 +1,189 @@
+#pragma once
+
+#include "power_supply.hpp"
+#include "types.hpp"
+#include "utility.hpp"
+
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/bus/match.hpp>
+#include <sdbusplus/server/manager.hpp>
+#include <sdbusplus/server/object.hpp>
+#include <sdeventplus/event.hpp>
+#include <sdeventplus/utility/timer.hpp>
+#include <xyz/openbmc_project/State/Decorator/PowerSystemInputs/server.hpp>
+
+#include <map>
+#include <string>
+#include <vector>
+
+struct SupportedPsuConfiguration
+{
+ int powerSupplyCount;
+ std::vector<uint64_t> inputVoltage;
+ bool powerConfigFullLoad;
+};
+
+using namespace phosphor::power::psu;
+
+namespace phosphor::power::chassis
+{
+
+constexpr uint32_t invalidObjectPathUniqueId = 9999;
+using PowerSystemInputsInterface = sdbusplus::xyz::openbmc_project::State::
+ Decorator::server::PowerSystemInputs;
+using PowerSystemInputsObject =
+ sdbusplus::server::object_t<PowerSystemInputsInterface>;
+
+// Validation timeout. Allow 30s to detect if new EM interfaces show up in D-Bus
+// before performing the validation.
+// Previously the timer was set to 10 seconds was too short, it results in
+// incorrect errors being logged, but no real consequence of longer timeout.
+constexpr auto validationTimeout = std::chrono::seconds(30);
+
+/**
+ * @class Chassis
+ *
+ * @brief This class will create an object used to manage and monitor a list of
+ * power supply devices attached to the chassis.
+ */
+class Chassis
+{
+ public:
+ Chassis() = delete;
+ ~Chassis() = default;
+ Chassis(const Chassis&) = delete;
+ Chassis& operator=(const Chassis&) = delete;
+ Chassis(Chassis&&) = delete;
+ Chassis& operator=(Chassis&&) = delete;
+
+ /**
+ * @brief Constructor to read configuration from D-Bus.
+ *
+ * @param[in] bus - D-Bus bus object
+ * @param[in] chassisPath - Chassis path
+ */
+ Chassis(sdbusplus::bus_t& bus, const std::string& chassisPath);
+
+ /**
+ * @brief Get the status of Power on.
+ */
+ bool isPowerOn()
+ {
+ return powerOn;
+ }
+
+ private:
+ /**
+ * @brief The D-Bus object
+ */
+ sdbusplus::bus_t& bus;
+
+ /**
+ * @brief The timer that performs power supply validation as the entity
+ * manager interfaces show up in d-bus.
+ */
+ std::unique_ptr<
+ sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>
+ validationTimer;
+
+ /** @brief True if the power is on. */
+ bool powerOn = false;
+
+ /** @brief Used to subscribe to D-Bus power supply presence changes */
+ std::vector<std::unique_ptr<sdbusplus::bus::match_t>> presenceMatches;
+
+ /**
+ * @brief Flag to indicate if the validateConfig() function should be run.
+ * Set to false once the configuration has been validated to avoid
+ * running multiple times due to interfaces added signal. Set to
+ * true during power off to trigger the validation on power on.
+ */
+ bool runValidateConfig = true;
+
+ /**
+ * @brief Map of supported PSU configurations that include the model name
+ * and their properties.
+ */
+ std::map<std::string, SupportedPsuConfiguration> supportedConfigs;
+
+ /**
+ * @brief The vector for power supplies.
+ */
+ std::vector<std::unique_ptr<PowerSupply>> psus;
+
+ /**
+ * @brief The device driver name for all power supplies.
+ */
+ std::string driverName;
+
+ /**
+ * @brief Chassis D-Bus object path
+ */
+ std::string chassisPath;
+
+ /**
+ * @brief The Chassis path unique ID
+ */
+ uint32_t chassisPathUniqueId = invalidObjectPathUniqueId;
+
+ /**
+ * @brief Get PSU properties from D-Bus, use that to build a power supply
+ * object.
+ *
+ * @param[in] properties - A map of property names and values
+ */
+ void getPSUProperties(util::DbusPropertyMap& properties);
+
+ /**
+ * @brief Get PSU configuration from D-Bus
+ */
+ void getPSUConfiguration();
+
+ /**
+ * @brief Initialize the chassis's supported configuration from the
+ * Supported Configuration D-Bus object provided by the Entity
+ * Manager.
+ */
+ void getSupportedConfiguration();
+
+ /**
+ * @brief Callback for inventory property changes
+ *
+ * Process change of the Power Supply presence.
+ *
+ * @param[in] msg - Data associated with the Present change signal
+ **/
+ void psuPresenceChanged(sdbusplus::message_t& msg);
+
+ /**
+ * @brief Helper function to populate the PSU supported configuration
+ *
+ * @param[in] properties - A map of property names and values
+ */
+ void populateSupportedConfiguration(
+ const util::DbusPropertyMap& properties);
+
+ /**
+ * @brief Build the device driver name for the power supply.
+ *
+ * @param[in] i2cbus - i2c bus
+ * @param[in] i2caddr - i2c bus address
+ */
+ void buildDriverName(uint64_t i2cbus, uint64_t i2caddr);
+
+ /**
+ * @brief Find PSU with device driver name, then populate the device
+ * driver name to all PSUs (including missing PSUs).
+ */
+ void populateDriverName();
+
+ /**
+ * @brief Get chassis path unique ID.
+ *
+ * @return uint32_t - Chassis path unique ID.
+ */
+ uint32_t getChassisPathUniqueId();
+};
+
+} // namespace phosphor::power::chassis