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 maxPowerSupplies; 15 int 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 } 88 else 89 { 90 powerOn = false; 91 } 92 } 93 catch (std::exception& e) 94 { 95 log<level::INFO>("Failed to get power state. Assuming it is off."); 96 powerOn = false; 97 } 98 99 onOffConfig(phosphor::pmbus::ON_OFF_CONFIG_CONTROL_PIN_ONLY); 100 clearFaults(); 101 updateInventory(); 102 } 103 104 /** 105 * Starts the timer to start monitoring the list of devices. 106 */ 107 int run() 108 { 109 return timer->get_event().loop(); 110 } 111 112 /** 113 * Write PMBus ON_OFF_CONFIG 114 * 115 * This function will be called to cause the PMBus device driver to send the 116 * ON_OFF_CONFIG command. Takes one byte of data. 117 */ 118 void onOffConfig(const uint8_t data) 119 { 120 for (auto& psu : psus) 121 { 122 psu->onOffConfig(data); 123 } 124 } 125 126 /** 127 * This function will be called in various situations in order to clear 128 * any fault status bits that may have been set, in order to start over 129 * with a clean state. Presence changes and power state changes will want 130 * to clear any faults logged. 131 */ 132 void clearFaults() 133 { 134 for (auto& psu : psus) 135 { 136 psu->clearFaults(); 137 } 138 } 139 140 private: 141 /** 142 * The D-Bus object 143 */ 144 sdbusplus::bus::bus& bus; 145 146 /** 147 * The timer that runs to periodically check the power supplies. 148 */ 149 std::unique_ptr< 150 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>> 151 timer; 152 153 /** 154 * Create an error 155 * 156 * @param[in] faultName - 'name' message for the BMC error log entry 157 * @param[in] additionalData - The AdditionalData property for the error 158 */ 159 void createError(const std::string& faultName, 160 const std::map<std::string, std::string>& additionalData); 161 162 /** 163 * Analyze the status of each of the power supplies. 164 * 165 * Log errors for faults, when and where appropriate. 166 */ 167 void analyze(); 168 169 /** @brief True if the power is on. */ 170 bool powerOn = false; 171 172 /** @brief Used as part of subscribing to power on state changes*/ 173 std::string powerService; 174 175 /** @brief Used to subscribe to D-Bus power on state changes */ 176 std::unique_ptr<sdbusplus::bus::match_t> powerOnMatch; 177 178 /** @brief Used to subscribe to Entity Manager interfaces added */ 179 std::unique_ptr<sdbusplus::bus::match_t> entityManagerIfacesAddedMatch; 180 181 /** 182 * @brief Callback for power state property changes 183 * 184 * Process changes to the powered on state property for the system. 185 * 186 * @param[in] msg - Data associated with the power state signal 187 */ 188 void powerStateChanged(sdbusplus::message::message& msg); 189 190 /** 191 * @brief Callback for entity-manager interface added 192 * 193 * Process the information from the supported configuration and or IBM CFFPS 194 * Connector interface being added. 195 * 196 * @param[in] msg - Data associated with the interfaces added signal 197 */ 198 void entityManagerIfaceAdded(sdbusplus::message::message& msg); 199 200 /** 201 * @brief Adds properties to the inventory. 202 * 203 * Reads the values from the devices and writes them to the associated 204 * power supply D-Bus inventory objects. 205 * 206 * This needs to be done on startup, and each time the presence state 207 * changes. 208 */ 209 void updateInventory() 210 { 211 for (auto& psu : psus) 212 { 213 psu->updateInventory(); 214 } 215 } 216 217 /** 218 * @brief Helper function to populate the system properties 219 * 220 * @param[in] properties - A map of property names and values 221 */ 222 void populateSysProperties(const util::DbusPropertyMap& properties); 223 224 /** 225 * @brief Map of supported PSU configurations that include the model name 226 * and their properties. 227 */ 228 std::multimap<std::string, sys_properties> supportedConfigs; 229 230 /** 231 * @brief The vector for power supplies. 232 */ 233 std::vector<std::unique_ptr<PowerSupply>> psus; 234 }; 235 236 } // namespace phosphor::power::manager 237