blob: 2754eab4db44fa831d3544756d419d4410dd1735 [file] [log] [blame]
Brandon Wyman2bac8602019-09-12 18:12:21 -05001#pragma once
2
Brandon Wymana0f33ce2019-10-17 18:32:29 -05003#include "power_supply.hpp"
4#include "types.hpp"
5#include "utility.hpp"
6
7#include <phosphor-logging/log.hpp>
Brandon Wyman2bac8602019-09-12 18:12:21 -05008#include <sdbusplus/bus/match.hpp>
9#include <sdeventplus/event.hpp>
10#include <sdeventplus/utility/timer.hpp>
11
Brandon Wymanaed1f752019-11-25 18:10:52 -060012struct sys_properties
13{
Adriana Kobylakd3a70d92021-06-04 16:24:45 +000014 int powerSupplyCount;
15 std::vector<uint64_t> inputVoltage;
Adriana Kobylak886574c2021-11-01 18:22:28 +000016 bool powerConfigFullLoad;
Brandon Wymanaed1f752019-11-25 18:10:52 -060017};
18
Brandon Wymana0f33ce2019-10-17 18:32:29 -050019using namespace phosphor::power::psu;
20using namespace phosphor::logging;
21
Brandon Wyman63ea78b2020-09-24 16:49:09 -050022namespace phosphor::power::manager
Brandon Wyman2bac8602019-09-12 18:12:21 -050023{
24
Adriana Kobylak2aba2b22021-10-11 16:00:05 +000025// Validation timeout. Allow 10s to detect if new EM interfaces show up in D-Bus
26// before performing the validation.
27constexpr auto validationTimeout = std::chrono::seconds(10);
Adriana Kobylaka4d38fa2021-10-05 19:57:47 +000028
Brandon Wyman2bac8602019-09-12 18:12:21 -050029/**
30 * @class PSUManager
31 *
32 * This class will create an object used to manage and monitor a list of power
33 * supply devices.
34 */
35class PSUManager
36{
37 public:
38 PSUManager() = delete;
39 ~PSUManager() = default;
40 PSUManager(const PSUManager&) = delete;
41 PSUManager& operator=(const PSUManager&) = delete;
42 PSUManager(PSUManager&&) = delete;
43 PSUManager& operator=(PSUManager&&) = delete;
44
45 /**
Brandon Wyman510acaa2020-11-05 18:32:04 -060046 * Constructor to read configuration from D-Bus.
47 *
48 * @param[in] bus - D-Bus bus object
49 * @param[in] e - event object
50 */
51 PSUManager(sdbusplus::bus::bus& bus, const sdeventplus::Event& e);
52
53 /**
Brandon Wyman510acaa2020-11-05 18:32:04 -060054 * Get PSU properties from D-Bus, use that to build a power supply
55 * object.
56 *
57 * @param[in] properties - A map of property names and values
58 *
59 */
60 void getPSUProperties(util::DbusPropertyMap& properties);
61
62 /**
63 * Get PSU configuration from D-Bus
64 */
65 void getPSUConfiguration();
66
67 /**
Adriana Kobylak9bab9e12021-02-24 15:32:03 -060068 * @brief Initialize the system properties from the Supported Configuration
69 * D-Bus object provided by Entity Manager.
70 */
71 void getSystemProperties();
72
73 /**
Brandon Wyman2bac8602019-09-12 18:12:21 -050074 * Initializes the manager.
75 *
76 * Get current BMC state, ...
77 */
78 void initialize()
79 {
Brandon Wymana0f33ce2019-10-17 18:32:29 -050080 // When state = 1, system is powered on
81 int32_t state = 0;
82
83 try
84 {
85 // Use getProperty utility function to get power state.
86 util::getProperty<int32_t>(POWER_IFACE, "state", POWER_OBJ_PATH,
87 powerService, bus, state);
88
89 if (state)
90 {
91 powerOn = true;
Adriana Kobylaka4d38fa2021-10-05 19:57:47 +000092 validationTimer->restartOnce(validationTimeout);
Brandon Wymana0f33ce2019-10-17 18:32:29 -050093 }
94 else
95 {
96 powerOn = false;
Adriana Kobylak8f16fb52021-03-31 15:50:15 +000097 runValidateConfig = true;
Brandon Wymana0f33ce2019-10-17 18:32:29 -050098 }
99 }
Patrick Williamsc1d4de52021-10-06 12:45:57 -0500100 catch (const std::exception& e)
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500101 {
102 log<level::INFO>("Failed to get power state. Assuming it is off.");
103 powerOn = false;
Adriana Kobylak8f16fb52021-03-31 15:50:15 +0000104 runValidateConfig = true;
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500105 }
106
Brandon Wyman59a35792020-06-04 12:37:40 -0500107 onOffConfig(phosphor::pmbus::ON_OFF_CONFIG_CONTROL_PIN_ONLY);
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500108 clearFaults();
109 updateInventory();
Adriana Kobylakc0a07582021-10-13 15:52:25 +0000110 setPowerConfigGPIO();
Brandon Wyman2bac8602019-09-12 18:12:21 -0500111 }
112
113 /**
114 * Starts the timer to start monitoring the list of devices.
115 */
116 int run()
117 {
Brandon Wyman2fe51862019-11-25 16:43:21 -0600118 return timer->get_event().loop();
Brandon Wyman2bac8602019-09-12 18:12:21 -0500119 }
120
121 /**
Brandon Wyman59a35792020-06-04 12:37:40 -0500122 * Write PMBus ON_OFF_CONFIG
123 *
124 * This function will be called to cause the PMBus device driver to send the
125 * ON_OFF_CONFIG command. Takes one byte of data.
126 */
127 void onOffConfig(const uint8_t data)
128 {
129 for (auto& psu : psus)
130 {
131 psu->onOffConfig(data);
132 }
133 }
134
135 /**
Brandon Wyman2bac8602019-09-12 18:12:21 -0500136 * This function will be called in various situations in order to clear
137 * any fault status bits that may have been set, in order to start over
138 * with a clean state. Presence changes and power state changes will want
139 * to clear any faults logged.
140 */
141 void clearFaults()
142 {
Brandon Wyman10fc6e82022-02-08 20:51:22 +0000143 setPowerSupplyError("");
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500144 for (auto& psu : psus)
145 {
Brandon Wymanaed1f752019-11-25 18:10:52 -0600146 psu->clearFaults();
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500147 }
Brandon Wyman2bac8602019-09-12 18:12:21 -0500148 }
149
150 private:
151 /**
152 * The D-Bus object
153 */
154 sdbusplus::bus::bus& bus;
155
156 /**
157 * The timer that runs to periodically check the power supplies.
158 */
Brandon Wyman2fe51862019-11-25 16:43:21 -0600159 std::unique_ptr<
160 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>
161 timer;
Brandon Wyman2bac8602019-09-12 18:12:21 -0500162
163 /**
Adriana Kobylaka4d38fa2021-10-05 19:57:47 +0000164 * The timer that performs power supply validation as the entity manager
165 * interfaces show up in d-bus.
166 */
167 std::unique_ptr<
168 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>
169 validationTimer;
170
171 /**
Brandon Wyman10fc6e82022-02-08 20:51:22 +0000172 * Let power control/sequencer application know of PSU error(s).
173 *
174 * @param[in] psuErrorString - string for power supply error
175 */
176 void setPowerSupplyError(const std::string& psuErrorString);
177
178 /**
Brandon Wymanb76ab242020-09-16 18:06:06 -0500179 * Create an error
180 *
181 * @param[in] faultName - 'name' message for the BMC error log entry
Brandon Wyman8b662882021-10-08 17:31:51 +0000182 * @param[in,out] additionalData - The AdditionalData property for the error
Brandon Wymanb76ab242020-09-16 18:06:06 -0500183 */
184 void createError(const std::string& faultName,
Brandon Wyman8b662882021-10-08 17:31:51 +0000185 std::map<std::string, std::string>& additionalData);
Brandon Wymanb76ab242020-09-16 18:06:06 -0500186
187 /**
Brandon Wyman2bac8602019-09-12 18:12:21 -0500188 * Analyze the status of each of the power supplies.
Brandon Wymanb76ab242020-09-16 18:06:06 -0500189 *
190 * Log errors for faults, when and where appropriate.
Brandon Wyman2bac8602019-09-12 18:12:21 -0500191 */
Brandon Wyman63ea78b2020-09-24 16:49:09 -0500192 void analyze();
Brandon Wyman2bac8602019-09-12 18:12:21 -0500193
194 /** @brief True if the power is on. */
195 bool powerOn = false;
196
Adriana Kobylak2549d792022-01-26 20:51:30 +0000197 /** @brief True if an error for a brownout has already been logged. */
198 bool brownoutLogged = false;
199
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500200 /** @brief Used as part of subscribing to power on state changes*/
201 std::string powerService;
202
Brandon Wyman2bac8602019-09-12 18:12:21 -0500203 /** @brief Used to subscribe to D-Bus power on state changes */
204 std::unique_ptr<sdbusplus::bus::match_t> powerOnMatch;
205
Adriana Kobylak9ba38232021-11-16 20:27:45 +0000206 /** @brief Used to subscribe to D-Bus power supply presence changes */
207 std::vector<std::unique_ptr<sdbusplus::bus::match_t>> presenceMatches;
208
Adriana Kobylak9bab9e12021-02-24 15:32:03 -0600209 /** @brief Used to subscribe to Entity Manager interfaces added */
210 std::unique_ptr<sdbusplus::bus::match_t> entityManagerIfacesAddedMatch;
211
Brandon Wyman2bac8602019-09-12 18:12:21 -0500212 /**
Brandon Wyman2bac8602019-09-12 18:12:21 -0500213 * @brief Callback for power state property changes
214 *
215 * Process changes to the powered on state property for the system.
216 *
217 * @param[in] msg - Data associated with the power state signal
218 */
219 void powerStateChanged(sdbusplus::message::message& msg);
220
221 /**
Adriana Kobylak9ba38232021-11-16 20:27:45 +0000222 * @brief Callback for inventory property changes
223 *
224 * Process change of the Present property for power supply.
225 *
226 * @param[in] msg - Data associated with the Present change signal
227 **/
228 void presenceChanged(sdbusplus::message::message& msg);
229
230 /**
Brandon Wyman3e429132021-03-18 18:03:14 -0500231 * @brief Callback for entity-manager interface added
Adriana Kobylak9bab9e12021-02-24 15:32:03 -0600232 *
Brandon Wyman3e429132021-03-18 18:03:14 -0500233 * Process the information from the supported configuration and or IBM CFFPS
234 * Connector interface being added.
Adriana Kobylak9bab9e12021-02-24 15:32:03 -0600235 *
236 * @param[in] msg - Data associated with the interfaces added signal
237 */
Brandon Wyman3e429132021-03-18 18:03:14 -0500238 void entityManagerIfaceAdded(sdbusplus::message::message& msg);
Adriana Kobylak9bab9e12021-02-24 15:32:03 -0600239
240 /**
Brandon Wyman2bac8602019-09-12 18:12:21 -0500241 * @brief Adds properties to the inventory.
242 *
243 * Reads the values from the devices and writes them to the associated
244 * power supply D-Bus inventory objects.
245 *
246 * This needs to be done on startup, and each time the presence state
247 * changes.
248 */
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500249 void updateInventory()
250 {
251 for (auto& psu : psus)
252 {
Brandon Wymanaed1f752019-11-25 18:10:52 -0600253 psu->updateInventory();
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500254 }
255 }
256
257 /**
Adriana Kobylake1074d82021-03-16 20:46:44 +0000258 * @brief Helper function to populate the system properties
259 *
260 * @param[in] properties - A map of property names and values
261 */
262 void populateSysProperties(const util::DbusPropertyMap& properties);
263
264 /**
Adriana Kobylak8f16fb52021-03-31 15:50:15 +0000265 * @brief Perform power supply configuration validation.
266 * @details Validates if the existing power supply properties are a
267 * supported configuration, and acts on its findings such as logging errors.
268 */
269 void validateConfig();
270
271 /**
272 * @brief Flag to indicate if the validateConfig() function should be run.
273 * Set to false once the configuration has been validated to avoid running
274 * multiple times due to interfaces added signal. Set to true during power
275 * off to trigger the validation on power on.
276 */
277 bool runValidateConfig = true;
278
279 /**
Adriana Kobylak4d9aaf92021-06-30 15:27:42 +0000280 * @brief Check that all PSUs have the same model name and that the system
281 * has the required number of PSUs present as specified in the Supported
282 * Configuration interface.
283 *
284 * @param[out] additionalData - Contains debug information on why the check
285 * might have failed. Can be used to fill in error logs.
286 * @return true if all the required PSUs are present, false otherwise.
287 */
288 bool hasRequiredPSUs(std::map<std::string, std::string>& additionalData);
289
290 /**
Adriana Kobylak523704d2021-09-21 15:55:41 +0000291 * @brief Helper function to validate that all PSUs have the same model name
292 *
293 * @param[out] model - The model name. Empty if there is a mismatch.
294 * @param[out] additionalData - If there is a mismatch, it contains debug
295 * information such as the mismatched model name.
296 * @return true if all the PSUs have the same model name, false otherwise.
297 */
298 bool validateModelName(std::string& model,
299 std::map<std::string, std::string>& additionalData);
300
301 /**
Adriana Kobylakc0a07582021-10-13 15:52:25 +0000302 * @brief Set the power-config-full-load GPIO depending on the EM full load
303 * property value.
304 */
305 void setPowerConfigGPIO();
306
307 /**
Adriana Kobylak9ea66a62021-03-24 17:54:14 +0000308 * @brief Map of supported PSU configurations that include the model name
309 * and their properties.
Brandon Wymanaed1f752019-11-25 18:10:52 -0600310 */
Adriana Kobylakd3a70d92021-06-04 16:24:45 +0000311 std::map<std::string, sys_properties> supportedConfigs;
Brandon Wymanaed1f752019-11-25 18:10:52 -0600312
313 /**
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500314 * @brief The vector for power supplies.
315 */
Brandon Wymanaed1f752019-11-25 18:10:52 -0600316 std::vector<std::unique_ptr<PowerSupply>> psus;
Adriana Kobylakc0a07582021-10-13 15:52:25 +0000317
318 /**
319 * @brief The libgpiod object for setting the power supply config
320 */
321 std::unique_ptr<GPIOInterfaceBase> powerConfigGPIO = nullptr;
Brandon Wyman2bac8602019-09-12 18:12:21 -0500322};
323
Brandon Wyman63ea78b2020-09-24 16:49:09 -0500324} // namespace phosphor::power::manager