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