xref: /openbmc/phosphor-power/phosphor-power-supply/psu_manager.hpp (revision 4d9aaf9133899a4576ce90f704a5b5f0a20d2113)
12bac8609SBrandon Wyman #pragma once
22bac8609SBrandon Wyman 
3a0f33ce3SBrandon Wyman #include "power_supply.hpp"
4a0f33ce3SBrandon Wyman #include "types.hpp"
5a0f33ce3SBrandon Wyman #include "utility.hpp"
6a0f33ce3SBrandon Wyman 
7a0f33ce3SBrandon Wyman #include <phosphor-logging/log.hpp>
82bac8609SBrandon Wyman #include <sdbusplus/bus/match.hpp>
92bac8609SBrandon Wyman #include <sdeventplus/event.hpp>
102bac8609SBrandon Wyman #include <sdeventplus/utility/timer.hpp>
112bac8609SBrandon Wyman 
12aed1f75dSBrandon Wyman struct sys_properties
13aed1f75dSBrandon Wyman {
14d3a70d98SAdriana Kobylak     int powerSupplyCount;
15d3a70d98SAdriana Kobylak     std::vector<uint64_t> inputVoltage;
16aed1f75dSBrandon Wyman };
17aed1f75dSBrandon Wyman 
18a0f33ce3SBrandon Wyman using namespace phosphor::power::psu;
19a0f33ce3SBrandon Wyman using namespace phosphor::logging;
20a0f33ce3SBrandon Wyman 
2163ea78b9SBrandon Wyman namespace phosphor::power::manager
222bac8609SBrandon Wyman {
232bac8609SBrandon Wyman 
242bac8609SBrandon Wyman /**
252bac8609SBrandon Wyman  * @class PSUManager
262bac8609SBrandon Wyman  *
272bac8609SBrandon Wyman  * This class will create an object used to manage and monitor a list of power
282bac8609SBrandon Wyman  * supply devices.
292bac8609SBrandon Wyman  */
302bac8609SBrandon Wyman class PSUManager
312bac8609SBrandon Wyman {
322bac8609SBrandon Wyman   public:
332bac8609SBrandon Wyman     PSUManager() = delete;
342bac8609SBrandon Wyman     ~PSUManager() = default;
352bac8609SBrandon Wyman     PSUManager(const PSUManager&) = delete;
362bac8609SBrandon Wyman     PSUManager& operator=(const PSUManager&) = delete;
372bac8609SBrandon Wyman     PSUManager(PSUManager&&) = delete;
382bac8609SBrandon Wyman     PSUManager& operator=(PSUManager&&) = delete;
392bac8609SBrandon Wyman 
402bac8609SBrandon Wyman     /**
41510acaabSBrandon Wyman      * Constructor to read configuration from D-Bus.
42510acaabSBrandon Wyman      *
43510acaabSBrandon Wyman      * @param[in] bus - D-Bus bus object
44510acaabSBrandon Wyman      * @param[in] e - event object
45510acaabSBrandon Wyman      */
46510acaabSBrandon Wyman     PSUManager(sdbusplus::bus::bus& bus, const sdeventplus::Event& e);
47510acaabSBrandon Wyman 
48510acaabSBrandon Wyman     /**
49510acaabSBrandon Wyman      * Get PSU properties from D-Bus, use that to build a power supply
50510acaabSBrandon Wyman      * object.
51510acaabSBrandon Wyman      *
52510acaabSBrandon Wyman      * @param[in] properties - A map of property names and values
53510acaabSBrandon Wyman      *
54510acaabSBrandon Wyman      */
55510acaabSBrandon Wyman     void getPSUProperties(util::DbusPropertyMap& properties);
56510acaabSBrandon Wyman 
57510acaabSBrandon Wyman     /**
58510acaabSBrandon Wyman      * Get PSU configuration from D-Bus
59510acaabSBrandon Wyman      */
60510acaabSBrandon Wyman     void getPSUConfiguration();
61510acaabSBrandon Wyman 
62510acaabSBrandon Wyman     /**
639bab9e10SAdriana Kobylak      * @brief Initialize the system properties from the Supported Configuration
649bab9e10SAdriana Kobylak      *        D-Bus object provided by Entity Manager.
659bab9e10SAdriana Kobylak      */
669bab9e10SAdriana Kobylak     void getSystemProperties();
679bab9e10SAdriana Kobylak 
689bab9e10SAdriana Kobylak     /**
692bac8609SBrandon Wyman      * Initializes the manager.
702bac8609SBrandon Wyman      *
712bac8609SBrandon Wyman      * Get current BMC state, ...
722bac8609SBrandon Wyman      */
732bac8609SBrandon Wyman     void initialize()
742bac8609SBrandon Wyman     {
75a0f33ce3SBrandon Wyman         // When state = 1, system is powered on
76a0f33ce3SBrandon Wyman         int32_t state = 0;
77a0f33ce3SBrandon Wyman 
78a0f33ce3SBrandon Wyman         try
79a0f33ce3SBrandon Wyman         {
80a0f33ce3SBrandon Wyman             // Use getProperty utility function to get power state.
81a0f33ce3SBrandon Wyman             util::getProperty<int32_t>(POWER_IFACE, "state", POWER_OBJ_PATH,
82a0f33ce3SBrandon Wyman                                        powerService, bus, state);
83a0f33ce3SBrandon Wyman 
84a0f33ce3SBrandon Wyman             if (state)
85a0f33ce3SBrandon Wyman             {
86a0f33ce3SBrandon Wyman                 powerOn = true;
878f16fb5eSAdriana Kobylak                 validateConfig();
88a0f33ce3SBrandon Wyman             }
89a0f33ce3SBrandon Wyman             else
90a0f33ce3SBrandon Wyman             {
91a0f33ce3SBrandon Wyman                 powerOn = false;
928f16fb5eSAdriana Kobylak                 runValidateConfig = true;
93a0f33ce3SBrandon Wyman             }
94a0f33ce3SBrandon Wyman         }
95a0f33ce3SBrandon Wyman         catch (std::exception& e)
96a0f33ce3SBrandon Wyman         {
97a0f33ce3SBrandon Wyman             log<level::INFO>("Failed to get power state. Assuming it is off.");
98a0f33ce3SBrandon Wyman             powerOn = false;
998f16fb5eSAdriana Kobylak             runValidateConfig = true;
100a0f33ce3SBrandon Wyman         }
101a0f33ce3SBrandon Wyman 
10259a35793SBrandon Wyman         onOffConfig(phosphor::pmbus::ON_OFF_CONFIG_CONTROL_PIN_ONLY);
103a0f33ce3SBrandon Wyman         clearFaults();
104a0f33ce3SBrandon Wyman         updateInventory();
1052bac8609SBrandon Wyman     }
1062bac8609SBrandon Wyman 
1072bac8609SBrandon Wyman     /**
1082bac8609SBrandon Wyman      * Starts the timer to start monitoring the list of devices.
1092bac8609SBrandon Wyman      */
1102bac8609SBrandon Wyman     int run()
1112bac8609SBrandon Wyman     {
1122fe5186eSBrandon Wyman         return timer->get_event().loop();
1132bac8609SBrandon Wyman     }
1142bac8609SBrandon Wyman 
1152bac8609SBrandon Wyman     /**
11659a35793SBrandon Wyman      * Write PMBus ON_OFF_CONFIG
11759a35793SBrandon Wyman      *
11859a35793SBrandon Wyman      * This function will be called to cause the PMBus device driver to send the
11959a35793SBrandon Wyman      * ON_OFF_CONFIG command. Takes one byte of data.
12059a35793SBrandon Wyman      */
12159a35793SBrandon Wyman     void onOffConfig(const uint8_t data)
12259a35793SBrandon Wyman     {
12359a35793SBrandon Wyman         for (auto& psu : psus)
12459a35793SBrandon Wyman         {
12559a35793SBrandon Wyman             psu->onOffConfig(data);
12659a35793SBrandon Wyman         }
12759a35793SBrandon Wyman     }
12859a35793SBrandon Wyman 
12959a35793SBrandon Wyman     /**
1302bac8609SBrandon Wyman      * This function will be called in various situations in order to clear
1312bac8609SBrandon Wyman      * any fault status bits that may have been set, in order to start over
1322bac8609SBrandon Wyman      * with a clean state. Presence changes and power state changes will want
1332bac8609SBrandon Wyman      * to clear any faults logged.
1342bac8609SBrandon Wyman      */
1352bac8609SBrandon Wyman     void clearFaults()
1362bac8609SBrandon Wyman     {
137a0f33ce3SBrandon Wyman         for (auto& psu : psus)
138a0f33ce3SBrandon Wyman         {
139aed1f75dSBrandon Wyman             psu->clearFaults();
140a0f33ce3SBrandon Wyman         }
1412bac8609SBrandon Wyman     }
1422bac8609SBrandon Wyman 
1432bac8609SBrandon Wyman   private:
1442bac8609SBrandon Wyman     /**
1452bac8609SBrandon Wyman      * The D-Bus object
1462bac8609SBrandon Wyman      */
1472bac8609SBrandon Wyman     sdbusplus::bus::bus& bus;
1482bac8609SBrandon Wyman 
1492bac8609SBrandon Wyman     /**
1502bac8609SBrandon Wyman      * The timer that runs to periodically check the power supplies.
1512bac8609SBrandon Wyman      */
1522fe5186eSBrandon Wyman     std::unique_ptr<
1532fe5186eSBrandon Wyman         sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>
1542fe5186eSBrandon Wyman         timer;
1552bac8609SBrandon Wyman 
1562bac8609SBrandon Wyman     /**
157b76ab249SBrandon Wyman      * Create an error
158b76ab249SBrandon Wyman      *
159b76ab249SBrandon Wyman      * @param[in] faultName - 'name' message for the BMC error log entry
160b76ab249SBrandon Wyman      * @param[in] additionalData - The AdditionalData property for the error
161b76ab249SBrandon Wyman      */
162b76ab249SBrandon Wyman     void createError(const std::string& faultName,
163b76ab249SBrandon Wyman                      const std::map<std::string, std::string>& additionalData);
164b76ab249SBrandon Wyman 
165b76ab249SBrandon Wyman     /**
1662bac8609SBrandon Wyman      * Analyze the status of each of the power supplies.
167b76ab249SBrandon Wyman      *
168b76ab249SBrandon Wyman      * Log errors for faults, when and where appropriate.
1692bac8609SBrandon Wyman      */
17063ea78b9SBrandon Wyman     void analyze();
1712bac8609SBrandon Wyman 
1722bac8609SBrandon Wyman     /** @brief True if the power is on. */
1732bac8609SBrandon Wyman     bool powerOn = false;
1742bac8609SBrandon Wyman 
175a0f33ce3SBrandon Wyman     /** @brief Used as part of subscribing to power on state changes*/
176a0f33ce3SBrandon Wyman     std::string powerService;
177a0f33ce3SBrandon Wyman 
1782bac8609SBrandon Wyman     /** @brief Used to subscribe to D-Bus power on state changes */
1792bac8609SBrandon Wyman     std::unique_ptr<sdbusplus::bus::match_t> powerOnMatch;
1802bac8609SBrandon Wyman 
1819bab9e10SAdriana Kobylak     /** @brief Used to subscribe to Entity Manager interfaces added */
1829bab9e10SAdriana Kobylak     std::unique_ptr<sdbusplus::bus::match_t> entityManagerIfacesAddedMatch;
1839bab9e10SAdriana Kobylak 
1842bac8609SBrandon Wyman     /**
1852bac8609SBrandon Wyman      * @brief Callback for power state property changes
1862bac8609SBrandon Wyman      *
1872bac8609SBrandon Wyman      * Process changes to the powered on state property for the system.
1882bac8609SBrandon Wyman      *
1892bac8609SBrandon Wyman      * @param[in] msg - Data associated with the power state signal
1902bac8609SBrandon Wyman      */
1912bac8609SBrandon Wyman     void powerStateChanged(sdbusplus::message::message& msg);
1922bac8609SBrandon Wyman 
1932bac8609SBrandon Wyman     /**
1943e42913fSBrandon Wyman      * @brief Callback for entity-manager interface added
1959bab9e10SAdriana Kobylak      *
1963e42913fSBrandon Wyman      * Process the information from the supported configuration and or IBM CFFPS
1973e42913fSBrandon Wyman      * Connector interface being added.
1989bab9e10SAdriana Kobylak      *
1999bab9e10SAdriana Kobylak      * @param[in] msg - Data associated with the interfaces added signal
2009bab9e10SAdriana Kobylak      */
2013e42913fSBrandon Wyman     void entityManagerIfaceAdded(sdbusplus::message::message& msg);
2029bab9e10SAdriana Kobylak 
2039bab9e10SAdriana Kobylak     /**
2042bac8609SBrandon Wyman      * @brief Adds properties to the inventory.
2052bac8609SBrandon Wyman      *
2062bac8609SBrandon Wyman      * Reads the values from the devices and writes them to the associated
2072bac8609SBrandon Wyman      * power supply D-Bus inventory objects.
2082bac8609SBrandon Wyman      *
2092bac8609SBrandon Wyman      * This needs to be done on startup, and each time the presence state
2102bac8609SBrandon Wyman      * changes.
2112bac8609SBrandon Wyman      */
212a0f33ce3SBrandon Wyman     void updateInventory()
213a0f33ce3SBrandon Wyman     {
214a0f33ce3SBrandon Wyman         for (auto& psu : psus)
215a0f33ce3SBrandon Wyman         {
216aed1f75dSBrandon Wyman             psu->updateInventory();
217a0f33ce3SBrandon Wyman         }
218a0f33ce3SBrandon Wyman     }
219a0f33ce3SBrandon Wyman 
220a0f33ce3SBrandon Wyman     /**
221e1074d8eSAdriana Kobylak      * @brief Helper function to populate the system properties
222e1074d8eSAdriana Kobylak      *
223e1074d8eSAdriana Kobylak      * @param[in] properties - A map of property names and values
224e1074d8eSAdriana Kobylak      */
225e1074d8eSAdriana Kobylak     void populateSysProperties(const util::DbusPropertyMap& properties);
226e1074d8eSAdriana Kobylak 
227e1074d8eSAdriana Kobylak     /**
2288f16fb5eSAdriana Kobylak      * @brief Perform power supply configuration validation.
2298f16fb5eSAdriana Kobylak      * @details Validates if the existing power supply properties are a
2308f16fb5eSAdriana Kobylak      * supported configuration, and acts on its findings such as logging errors.
2318f16fb5eSAdriana Kobylak      */
2328f16fb5eSAdriana Kobylak     void validateConfig();
2338f16fb5eSAdriana Kobylak 
2348f16fb5eSAdriana Kobylak     /**
2358f16fb5eSAdriana Kobylak      * @brief Flag to indicate if the validateConfig() function should be run.
2368f16fb5eSAdriana Kobylak      * Set to false once the configuration has been validated to avoid running
2378f16fb5eSAdriana Kobylak      * multiple times due to interfaces added signal. Set to true during power
2388f16fb5eSAdriana Kobylak      * off to trigger the validation on power on.
2398f16fb5eSAdriana Kobylak      */
2408f16fb5eSAdriana Kobylak     bool runValidateConfig = true;
2418f16fb5eSAdriana Kobylak 
2428f16fb5eSAdriana Kobylak     /**
243*4d9aaf91SAdriana Kobylak      * @brief Check that all PSUs have the same model name and that the system
244*4d9aaf91SAdriana Kobylak      * has the required number of PSUs present as specified in the Supported
245*4d9aaf91SAdriana Kobylak      * Configuration interface.
246*4d9aaf91SAdriana Kobylak      *
247*4d9aaf91SAdriana Kobylak      * @param[out] additionalData - Contains debug information on why the check
248*4d9aaf91SAdriana Kobylak      *             might have failed. Can be used to fill in error logs.
249*4d9aaf91SAdriana Kobylak      * @return true if all the required PSUs are present, false otherwise.
250*4d9aaf91SAdriana Kobylak      */
251*4d9aaf91SAdriana Kobylak     bool hasRequiredPSUs(std::map<std::string, std::string>& additionalData);
252*4d9aaf91SAdriana Kobylak 
253*4d9aaf91SAdriana Kobylak     /**
2549ea66a67SAdriana Kobylak      * @brief Map of supported PSU configurations that include the model name
2559ea66a67SAdriana Kobylak      * and their properties.
256aed1f75dSBrandon Wyman      */
257d3a70d98SAdriana Kobylak     std::map<std::string, sys_properties> supportedConfigs;
258aed1f75dSBrandon Wyman 
259aed1f75dSBrandon Wyman     /**
260a0f33ce3SBrandon Wyman      * @brief The vector for power supplies.
261a0f33ce3SBrandon Wyman      */
262aed1f75dSBrandon Wyman     std::vector<std::unique_ptr<PowerSupply>> psus;
2632bac8609SBrandon Wyman };
2642bac8609SBrandon Wyman 
26563ea78b9SBrandon Wyman } // namespace phosphor::power::manager
266