1 #pragma once 2 3 #include "power_supply.hpp" 4 #include "types.hpp" 5 #include "utility.hpp" 6 7 #include <phosphor-logging/log.hpp> 8 #include <sdbusplus/bus/match.hpp> 9 #include <sdeventplus/event.hpp> 10 #include <sdeventplus/utility/timer.hpp> 11 12 struct sys_properties 13 { 14 int powerSupplyCount; 15 std::vector<uint64_t> inputVoltage; 16 }; 17 18 using namespace phosphor::power::psu; 19 using namespace phosphor::logging; 20 21 namespace phosphor::power::manager 22 { 23 24 /** 25 * @class PSUManager 26 * 27 * This class will create an object used to manage and monitor a list of power 28 * supply devices. 29 */ 30 class PSUManager 31 { 32 public: 33 PSUManager() = delete; 34 ~PSUManager() = default; 35 PSUManager(const PSUManager&) = delete; 36 PSUManager& operator=(const PSUManager&) = delete; 37 PSUManager(PSUManager&&) = delete; 38 PSUManager& operator=(PSUManager&&) = delete; 39 40 /** 41 * Constructor to read configuration from D-Bus. 42 * 43 * @param[in] bus - D-Bus bus object 44 * @param[in] e - event object 45 */ 46 PSUManager(sdbusplus::bus::bus& bus, const sdeventplus::Event& e); 47 48 /** 49 * Get PSU properties from D-Bus, use that to build a power supply 50 * object. 51 * 52 * @param[in] properties - A map of property names and values 53 * 54 */ 55 void getPSUProperties(util::DbusPropertyMap& properties); 56 57 /** 58 * Get PSU configuration from D-Bus 59 */ 60 void getPSUConfiguration(); 61 62 /** 63 * @brief Initialize the system properties from the Supported Configuration 64 * D-Bus object provided by Entity Manager. 65 */ 66 void getSystemProperties(); 67 68 /** 69 * Initializes the manager. 70 * 71 * Get current BMC state, ... 72 */ 73 void initialize() 74 { 75 // When state = 1, system is powered on 76 int32_t state = 0; 77 78 try 79 { 80 // Use getProperty utility function to get power state. 81 util::getProperty<int32_t>(POWER_IFACE, "state", POWER_OBJ_PATH, 82 powerService, bus, state); 83 84 if (state) 85 { 86 powerOn = true; 87 validateConfig(); 88 } 89 else 90 { 91 powerOn = false; 92 runValidateConfig = true; 93 } 94 } 95 catch (std::exception& e) 96 { 97 log<level::INFO>("Failed to get power state. Assuming it is off."); 98 powerOn = false; 99 runValidateConfig = true; 100 } 101 102 onOffConfig(phosphor::pmbus::ON_OFF_CONFIG_CONTROL_PIN_ONLY); 103 clearFaults(); 104 updateInventory(); 105 } 106 107 /** 108 * Starts the timer to start monitoring the list of devices. 109 */ 110 int run() 111 { 112 return timer->get_event().loop(); 113 } 114 115 /** 116 * Write PMBus ON_OFF_CONFIG 117 * 118 * This function will be called to cause the PMBus device driver to send the 119 * ON_OFF_CONFIG command. Takes one byte of data. 120 */ 121 void onOffConfig(const uint8_t data) 122 { 123 for (auto& psu : psus) 124 { 125 psu->onOffConfig(data); 126 } 127 } 128 129 /** 130 * This function will be called in various situations in order to clear 131 * any fault status bits that may have been set, in order to start over 132 * with a clean state. Presence changes and power state changes will want 133 * to clear any faults logged. 134 */ 135 void clearFaults() 136 { 137 for (auto& psu : psus) 138 { 139 psu->clearFaults(); 140 } 141 } 142 143 private: 144 /** 145 * The D-Bus object 146 */ 147 sdbusplus::bus::bus& bus; 148 149 /** 150 * The timer that runs to periodically check the power supplies. 151 */ 152 std::unique_ptr< 153 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>> 154 timer; 155 156 /** 157 * Create an error 158 * 159 * @param[in] faultName - 'name' message for the BMC error log entry 160 * @param[in] additionalData - The AdditionalData property for the error 161 */ 162 void createError(const std::string& faultName, 163 const std::map<std::string, std::string>& additionalData); 164 165 /** 166 * Analyze the status of each of the power supplies. 167 * 168 * Log errors for faults, when and where appropriate. 169 */ 170 void analyze(); 171 172 /** @brief True if the power is on. */ 173 bool powerOn = false; 174 175 /** @brief Used as part of subscribing to power on state changes*/ 176 std::string powerService; 177 178 /** @brief Used to subscribe to D-Bus power on state changes */ 179 std::unique_ptr<sdbusplus::bus::match_t> powerOnMatch; 180 181 /** @brief Used to subscribe to Entity Manager interfaces added */ 182 std::unique_ptr<sdbusplus::bus::match_t> entityManagerIfacesAddedMatch; 183 184 /** 185 * @brief Callback for power state property changes 186 * 187 * Process changes to the powered on state property for the system. 188 * 189 * @param[in] msg - Data associated with the power state signal 190 */ 191 void powerStateChanged(sdbusplus::message::message& msg); 192 193 /** 194 * @brief Callback for entity-manager interface added 195 * 196 * Process the information from the supported configuration and or IBM CFFPS 197 * Connector interface being added. 198 * 199 * @param[in] msg - Data associated with the interfaces added signal 200 */ 201 void entityManagerIfaceAdded(sdbusplus::message::message& msg); 202 203 /** 204 * @brief Adds properties to the inventory. 205 * 206 * Reads the values from the devices and writes them to the associated 207 * power supply D-Bus inventory objects. 208 * 209 * This needs to be done on startup, and each time the presence state 210 * changes. 211 */ 212 void updateInventory() 213 { 214 for (auto& psu : psus) 215 { 216 psu->updateInventory(); 217 } 218 } 219 220 /** 221 * @brief Helper function to populate the system properties 222 * 223 * @param[in] properties - A map of property names and values 224 */ 225 void populateSysProperties(const util::DbusPropertyMap& properties); 226 227 /** 228 * @brief Perform power supply configuration validation. 229 * @details Validates if the existing power supply properties are a 230 * supported configuration, and acts on its findings such as logging errors. 231 */ 232 void validateConfig(); 233 234 /** 235 * @brief Flag to indicate if the validateConfig() function should be run. 236 * Set to false once the configuration has been validated to avoid running 237 * multiple times due to interfaces added signal. Set to true during power 238 * off to trigger the validation on power on. 239 */ 240 bool runValidateConfig = true; 241 242 /** 243 * @brief Check that all PSUs have the same model name and that the system 244 * has the required number of PSUs present as specified in the Supported 245 * Configuration interface. 246 * 247 * @param[out] additionalData - Contains debug information on why the check 248 * might have failed. Can be used to fill in error logs. 249 * @return true if all the required PSUs are present, false otherwise. 250 */ 251 bool hasRequiredPSUs(std::map<std::string, std::string>& additionalData); 252 253 /** 254 * @brief Map of supported PSU configurations that include the model name 255 * and their properties. 256 */ 257 std::map<std::string, sys_properties> supportedConfigs; 258 259 /** 260 * @brief The vector for power supplies. 261 */ 262 std::vector<std::unique_ptr<PowerSupply>> psus; 263 }; 264 265 } // namespace phosphor::power::manager 266