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 minPowerSupplies; 15 int maxPowerSupplies; 16 }; 17 18 using namespace phosphor::power::psu; 19 using namespace phosphor::logging; 20 21 namespace phosphor 22 { 23 namespace power 24 { 25 namespace manager 26 { 27 28 /** 29 * @class PSUManager 30 * 31 * This class will create an object used to manage and monitor a list of power 32 * supply devices. 33 */ 34 class PSUManager 35 { 36 public: 37 PSUManager() = delete; 38 ~PSUManager() = default; 39 PSUManager(const PSUManager&) = delete; 40 PSUManager& operator=(const PSUManager&) = delete; 41 PSUManager(PSUManager&&) = delete; 42 PSUManager& operator=(PSUManager&&) = delete; 43 44 /** 45 * Constructor 46 * 47 * @param[in] bus - D-Bus bus object 48 * @param[in] e - event object 49 * @param[in] configfile - string path to the configuration file 50 */ 51 PSUManager(sdbusplus::bus::bus& bus, const sdeventplus::Event& e, 52 const std::string& configfile); 53 54 void getJSONProperties(const std::string& path, sdbusplus::bus::bus& bus, 55 sys_properties& p, 56 std::vector<std::unique_ptr<PowerSupply>>& psus); 57 58 /** 59 * Initializes the manager. 60 * 61 * Get current BMC state, ... 62 */ 63 void initialize() 64 { 65 // When state = 1, system is powered on 66 int32_t state = 0; 67 68 try 69 { 70 // Use getProperty utility function to get power state. 71 util::getProperty<int32_t>(POWER_IFACE, "state", POWER_OBJ_PATH, 72 powerService, bus, state); 73 74 if (state) 75 { 76 powerOn = true; 77 } 78 else 79 { 80 powerOn = false; 81 } 82 } 83 catch (std::exception& e) 84 { 85 log<level::INFO>("Failed to get power state. Assuming it is off."); 86 powerOn = false; 87 } 88 89 onOffConfig(phosphor::pmbus::ON_OFF_CONFIG_CONTROL_PIN_ONLY); 90 clearFaults(); 91 updateInventory(); 92 } 93 94 /** 95 * Starts the timer to start monitoring the list of devices. 96 */ 97 int run() 98 { 99 return timer->get_event().loop(); 100 } 101 102 /** 103 * Write PMBus ON_OFF_CONFIG 104 * 105 * This function will be called to cause the PMBus device driver to send the 106 * ON_OFF_CONFIG command. Takes one byte of data. 107 */ 108 void onOffConfig(const uint8_t data) 109 { 110 for (auto& psu : psus) 111 { 112 psu->onOffConfig(data); 113 } 114 } 115 116 /** 117 * This function will be called in various situations in order to clear 118 * any fault status bits that may have been set, in order to start over 119 * with a clean state. Presence changes and power state changes will want 120 * to clear any faults logged. 121 */ 122 void clearFaults() 123 { 124 for (auto& psu : psus) 125 { 126 psu->clearFaults(); 127 } 128 129 faultLogged = false; 130 } 131 132 private: 133 /** 134 * The D-Bus object 135 */ 136 sdbusplus::bus::bus& bus; 137 138 /** 139 * The timer that runs to periodically check the power supplies. 140 */ 141 std::unique_ptr< 142 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>> 143 timer; 144 145 /** 146 * Analyze the status of each of the power supplies. 147 */ 148 void analyze() 149 { 150 for (auto& psu : psus) 151 { 152 psu->analyze(); 153 } 154 155 for (auto& psu : psus) 156 { 157 // TODO: Fault priorities #918 158 if (!faultLogged && psu->isFaulted()) 159 { 160 if (psu->hasInputFault()) 161 { 162 // TODO: Create error log 163 } 164 165 if (psu->hasMFRFault()) 166 { 167 // TODO: Create error log 168 } 169 170 if (psu->hasVINUVFault()) 171 { 172 // TODO: Create error log 173 } 174 } 175 } 176 } 177 178 /** @brief True if the power is on. */ 179 bool powerOn = false; 180 181 /** @brief True if fault logged. Clear in clearFaults(). */ 182 bool faultLogged = false; 183 184 /** @brief Used as part of subscribing to power on state changes*/ 185 std::string powerService; 186 187 /** @brief Used to subscribe to D-Bus power on state changes */ 188 std::unique_ptr<sdbusplus::bus::match_t> powerOnMatch; 189 190 /** 191 * @brief Callback for power state property changes 192 * 193 * Process changes to the powered on state property for the system. 194 * 195 * @param[in] msg - Data associated with the power state signal 196 */ 197 void powerStateChanged(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 Minimum number of power supplies to operate. 218 */ 219 int minPSUs = 1; 220 221 /** 222 * @brief Maximum number of power supplies possible. 223 */ 224 int maxPSUs = 1; 225 226 /** 227 * @brief The vector for power supplies. 228 */ 229 std::vector<std::unique_ptr<PowerSupply>> psus; 230 }; 231 232 } // namespace manager 233 } // namespace power 234 } // namespace phosphor 235