xref: /openbmc/phosphor-power/phosphor-power-sequencer/src/power_control.hpp (revision d62367d6b4018179fb53c596860e511979447d2e)
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