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