1 #pragma once 2 3 #include "config.h" 4 5 #include "compatible_system_types_finder.hpp" 6 #include "power_interface.hpp" 7 #include "services.hpp" 8 #include "system.hpp" 9 10 #include <gpiod.hpp> 11 #include <sdbusplus/bus.hpp> 12 #include <sdbusplus/server/object.hpp> 13 #include <sdeventplus/clock.hpp> 14 #include <sdeventplus/event.hpp> 15 #include <sdeventplus/utility/timer.hpp> 16 17 #include <chrono> 18 #include <filesystem> 19 #include <map> 20 #include <memory> 21 #include <string> 22 #include <vector> 23 24 namespace phosphor::power::sequencer 25 { 26 27 using PowerObject = sdbusplus::server::object_t<PowerInterface>; 28 29 /** 30 * @class PowerControl 31 * This class implements GPIO control of power on / off, and monitoring of the 32 * chassis power good. 33 */ 34 class PowerControl : public PowerObject 35 { 36 public: 37 PowerControl() = delete; 38 PowerControl(const PowerControl&) = delete; 39 PowerControl& operator=(const PowerControl&) = delete; 40 PowerControl(PowerControl&&) = delete; 41 PowerControl& operator=(PowerControl&&) = delete; 42 ~PowerControl() = default; 43 44 /** 45 * Creates a controller object for power on and off. 46 * @param bus D-Bus bus object 47 * @param event event object 48 */ 49 PowerControl(sdbusplus::bus_t& bus, const sdeventplus::Event& event); 50 51 /** @copydoc PowerInterface::getPgood() */ 52 int getPgood() const override; 53 54 /** @copydoc PowerInterface::getPgoodTimeout() */ 55 int getPgoodTimeout() const override; 56 57 /** @copydoc PowerInterface::getState() */ 58 int getState() const override; 59 60 /** @copydoc PowerInterface::setPgoodTimeout() */ 61 void setPgoodTimeout(int timeout) override; 62 63 /** @copydoc PowerInterface::setState() */ 64 void setState(int state) override; 65 66 /** @copydoc PowerInterface::setPowerSupplyError() */ 67 void setPowerSupplyError(const std::string& error) override; 68 69 /** 70 * Callback that is called when a list of compatible system types is found. 71 * 72 * @param types Compatible system types for the current system ordered from 73 * most to least specific 74 */ 75 void compatibleSystemTypesFound(const std::vector<std::string>& types); 76 77 private: 78 /** 79 * The D-Bus bus object 80 */ 81 sdbusplus::bus_t& bus; 82 83 /** 84 * System services like hardware presence and the journal. 85 */ 86 BMCServices services; 87 88 /** 89 * Object that finds the compatible system types for the current system. 90 */ 91 std::unique_ptr<util::CompatibleSystemTypesFinder> compatSysTypesFinder; 92 93 /** 94 * Compatible system types for the current system ordered from most to least 95 * specific. 96 */ 97 std::vector<std::string> compatibleSystemTypes; 98 99 /** 100 * Computer system being controlled and monitored by the BMC. 101 * 102 * Contains the information loaded from the JSON configuration file. 103 * Contains nullptr if the configuration file has not been loaded. 104 */ 105 std::unique_ptr<System> system; 106 107 /** 108 * Indicates if a failure has already been found. Cleared at power on. 109 */ 110 bool failureFound{false}; 111 112 /** 113 * Indicates if a state transition is taking place 114 */ 115 bool inStateTransition{false}; 116 117 /** 118 * Minimum time from cold start to power on constant 119 */ 120 static constexpr std::chrono::seconds minimumColdStartTime{15}; 121 122 /** 123 * Minimum time from power off to power on constant 124 */ 125 static constexpr std::chrono::seconds minimumPowerOffTime{25}; 126 127 /** 128 * Power good 129 */ 130 int pgood{0}; 131 132 /** 133 * GPIO line object for chassis power good 134 */ 135 gpiod::line pgoodLine; 136 137 /** 138 * Power good timeout constant 139 */ 140 static constexpr std::chrono::seconds pgoodTimeout{PGOOD_TIMEOUT}; 141 142 /** 143 * Point in time at which power good timeout will take place 144 */ 145 std::chrono::time_point<std::chrono::steady_clock> pgoodTimeoutTime; 146 147 /** 148 * Timer to wait after pgood failure. This is to allow the power supplies 149 * and other hardware time to complete failure processing. 150 */ 151 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> pgoodWaitTimer; 152 153 /** 154 * Poll interval constant 155 */ 156 static constexpr std::chrono::milliseconds pollInterval{3000}; 157 158 /** 159 * GPIO line object for power on / power off control 160 */ 161 gpiod::line powerControlLine; 162 163 /** 164 * Point in time at which minumum power off time will have passed 165 */ 166 std::chrono::time_point<std::chrono::steady_clock> powerOnAllowedTime; 167 168 /** 169 * Power supply error. Cleared at power on. 170 */ 171 std::string powerSupplyError; 172 173 /** 174 * Power state 175 */ 176 int state{0}; 177 178 /** 179 * Power good timeout 180 */ 181 std::chrono::seconds timeout{pgoodTimeout}; 182 183 /** 184 * Timer to poll the pgood 185 */ 186 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> timer; 187 188 /** 189 * Callback to begin failure processing after observing pgood failure wait 190 */ 191 void onFailureCallback(); 192 193 /** 194 * Begin pgood failure processing 195 * 196 * @param wasTimeOut Indicates whether failure state was determined by 197 * timing out 198 */ 199 void onFailure(bool wasTimeOut); 200 201 /** 202 * Checks whether a pgood fault has occurred on one of the rails being 203 * monitored. 204 * 205 * If a pgood fault was found, this method returns a string containing the 206 * error that should be logged. If no fault was found, an empty string is 207 * returned. 208 * 209 * @param additionalData Additional data to include in the error log if 210 * a pgood fault was found 211 * @return error that should be logged if a pgood fault was found, or an 212 * empty string if no pgood fault was found 213 */ 214 std::string findPgoodFault( 215 std::map<std::string, std::string>& additionalData); 216 217 /** 218 * Polling method for monitoring the system power good 219 */ 220 void pollPgood(); 221 222 /** 223 * Set up GPIOs 224 */ 225 void setUpGpio(); 226 227 /** 228 * Loads the JSON configuration file. 229 * 230 * Looks for the config file using findConfigFile(). 231 * 232 * If the config file is found, it is parsed and the resulting information 233 * is stored in the system data member. 234 */ 235 void loadConfigFile(); 236 237 /** 238 * Finds the JSON configuration file for the current system based on the 239 * compatible system types. 240 * 241 * Does nothing if the compatible system types have not been found yet. 242 * 243 * @return absolute path to the config file, or empty path if file not found 244 */ 245 std::filesystem::path findConfigFile(); 246 }; 247 248 } // namespace phosphor::power::sequencer 249