blob: d95caa34cf9a906a532a949f61f18b82803dec5e [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;
Brandon Wymanaed1f752019-11-25 18:10:52 -060016};
17
Brandon Wymana0f33ce2019-10-17 18:32:29 -050018using namespace phosphor::power::psu;
19using namespace phosphor::logging;
20
Brandon Wyman63ea78b2020-09-24 16:49:09 -050021namespace phosphor::power::manager
Brandon Wyman2bac8602019-09-12 18:12:21 -050022{
23
24/**
25 * @class PSUManager
26 *
27 * This class will create an object used to manage and monitor a list of power
28 * supply devices.
29 */
30class PSUManager
31{
32 public:
33 PSUManager() = delete;
34 ~PSUManager() = default;
35 PSUManager(const PSUManager&) = delete;
36 PSUManager& operator=(const PSUManager&) = delete;
37 PSUManager(PSUManager&&) = delete;
38 PSUManager& operator=(PSUManager&&) = delete;
39
40 /**
Brandon Wyman510acaa2020-11-05 18:32:04 -060041 * Constructor to read configuration from D-Bus.
42 *
43 * @param[in] bus - D-Bus bus object
44 * @param[in] e - event object
45 */
46 PSUManager(sdbusplus::bus::bus& bus, const sdeventplus::Event& e);
47
48 /**
Brandon Wyman510acaa2020-11-05 18:32:04 -060049 * Get PSU properties from D-Bus, use that to build a power supply
50 * object.
51 *
52 * @param[in] properties - A map of property names and values
53 *
54 */
55 void getPSUProperties(util::DbusPropertyMap& properties);
56
57 /**
58 * Get PSU configuration from D-Bus
59 */
60 void getPSUConfiguration();
61
62 /**
Adriana Kobylak9bab9e12021-02-24 15:32:03 -060063 * @brief Initialize the system properties from the Supported Configuration
64 * D-Bus object provided by Entity Manager.
65 */
66 void getSystemProperties();
67
68 /**
Brandon Wyman2bac8602019-09-12 18:12:21 -050069 * Initializes the manager.
70 *
71 * Get current BMC state, ...
72 */
73 void initialize()
74 {
Brandon Wymana0f33ce2019-10-17 18:32:29 -050075 // When state = 1, system is powered on
76 int32_t state = 0;
77
78 try
79 {
80 // Use getProperty utility function to get power state.
81 util::getProperty<int32_t>(POWER_IFACE, "state", POWER_OBJ_PATH,
82 powerService, bus, state);
83
84 if (state)
85 {
86 powerOn = true;
Adriana Kobylak8f16fb52021-03-31 15:50:15 +000087 validateConfig();
Brandon Wymana0f33ce2019-10-17 18:32:29 -050088 }
89 else
90 {
91 powerOn = false;
Adriana Kobylak8f16fb52021-03-31 15:50:15 +000092 runValidateConfig = true;
Brandon Wymana0f33ce2019-10-17 18:32:29 -050093 }
94 }
Patrick Williamsc1d4de52021-10-06 12:45:57 -050095 catch (const std::exception& e)
Brandon Wymana0f33ce2019-10-17 18:32:29 -050096 {
97 log<level::INFO>("Failed to get power state. Assuming it is off.");
98 powerOn = false;
Adriana Kobylak8f16fb52021-03-31 15:50:15 +000099 runValidateConfig = true;
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500100 }
101
Brandon Wyman59a35792020-06-04 12:37:40 -0500102 onOffConfig(phosphor::pmbus::ON_OFF_CONFIG_CONTROL_PIN_ONLY);
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500103 clearFaults();
104 updateInventory();
Brandon Wyman2bac8602019-09-12 18:12:21 -0500105 }
106
107 /**
108 * Starts the timer to start monitoring the list of devices.
109 */
110 int run()
111 {
Brandon Wyman2fe51862019-11-25 16:43:21 -0600112 return timer->get_event().loop();
Brandon Wyman2bac8602019-09-12 18:12:21 -0500113 }
114
115 /**
Brandon Wyman59a35792020-06-04 12:37:40 -0500116 * Write PMBus ON_OFF_CONFIG
117 *
118 * This function will be called to cause the PMBus device driver to send the
119 * ON_OFF_CONFIG command. Takes one byte of data.
120 */
121 void onOffConfig(const uint8_t data)
122 {
123 for (auto& psu : psus)
124 {
125 psu->onOffConfig(data);
126 }
127 }
128
129 /**
Brandon Wyman2bac8602019-09-12 18:12:21 -0500130 * This function will be called in various situations in order to clear
131 * any fault status bits that may have been set, in order to start over
132 * with a clean state. Presence changes and power state changes will want
133 * to clear any faults logged.
134 */
135 void clearFaults()
136 {
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500137 for (auto& psu : psus)
138 {
Brandon Wymanaed1f752019-11-25 18:10:52 -0600139 psu->clearFaults();
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500140 }
Brandon Wyman2bac8602019-09-12 18:12:21 -0500141 }
142
143 private:
144 /**
145 * The D-Bus object
146 */
147 sdbusplus::bus::bus& bus;
148
149 /**
150 * The timer that runs to periodically check the power supplies.
151 */
Brandon Wyman2fe51862019-11-25 16:43:21 -0600152 std::unique_ptr<
153 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>>
154 timer;
Brandon Wyman2bac8602019-09-12 18:12:21 -0500155
156 /**
Brandon Wymanb76ab242020-09-16 18:06:06 -0500157 * Create an error
158 *
159 * @param[in] faultName - 'name' message for the BMC error log entry
160 * @param[in] additionalData - The AdditionalData property for the error
161 */
162 void createError(const std::string& faultName,
163 const std::map<std::string, std::string>& additionalData);
164
165 /**
Brandon Wyman2bac8602019-09-12 18:12:21 -0500166 * Analyze the status of each of the power supplies.
Brandon Wymanb76ab242020-09-16 18:06:06 -0500167 *
168 * Log errors for faults, when and where appropriate.
Brandon Wyman2bac8602019-09-12 18:12:21 -0500169 */
Brandon Wyman63ea78b2020-09-24 16:49:09 -0500170 void analyze();
Brandon Wyman2bac8602019-09-12 18:12:21 -0500171
172 /** @brief True if the power is on. */
173 bool powerOn = false;
174
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500175 /** @brief Used as part of subscribing to power on state changes*/
176 std::string powerService;
177
Brandon Wyman2bac8602019-09-12 18:12:21 -0500178 /** @brief Used to subscribe to D-Bus power on state changes */
179 std::unique_ptr<sdbusplus::bus::match_t> powerOnMatch;
180
Adriana Kobylak9bab9e12021-02-24 15:32:03 -0600181 /** @brief Used to subscribe to Entity Manager interfaces added */
182 std::unique_ptr<sdbusplus::bus::match_t> entityManagerIfacesAddedMatch;
183
Brandon Wyman2bac8602019-09-12 18:12:21 -0500184 /**
Brandon Wyman2bac8602019-09-12 18:12:21 -0500185 * @brief Callback for power state property changes
186 *
187 * Process changes to the powered on state property for the system.
188 *
189 * @param[in] msg - Data associated with the power state signal
190 */
191 void powerStateChanged(sdbusplus::message::message& msg);
192
193 /**
Brandon Wyman3e429132021-03-18 18:03:14 -0500194 * @brief Callback for entity-manager interface added
Adriana Kobylak9bab9e12021-02-24 15:32:03 -0600195 *
Brandon Wyman3e429132021-03-18 18:03:14 -0500196 * Process the information from the supported configuration and or IBM CFFPS
197 * Connector interface being added.
Adriana Kobylak9bab9e12021-02-24 15:32:03 -0600198 *
199 * @param[in] msg - Data associated with the interfaces added signal
200 */
Brandon Wyman3e429132021-03-18 18:03:14 -0500201 void entityManagerIfaceAdded(sdbusplus::message::message& msg);
Adriana Kobylak9bab9e12021-02-24 15:32:03 -0600202
203 /**
Brandon Wyman2bac8602019-09-12 18:12:21 -0500204 * @brief Adds properties to the inventory.
205 *
206 * Reads the values from the devices and writes them to the associated
207 * power supply D-Bus inventory objects.
208 *
209 * This needs to be done on startup, and each time the presence state
210 * changes.
211 */
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500212 void updateInventory()
213 {
214 for (auto& psu : psus)
215 {
Brandon Wymanaed1f752019-11-25 18:10:52 -0600216 psu->updateInventory();
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500217 }
218 }
219
220 /**
Adriana Kobylake1074d82021-03-16 20:46:44 +0000221 * @brief Helper function to populate the system properties
222 *
223 * @param[in] properties - A map of property names and values
224 */
225 void populateSysProperties(const util::DbusPropertyMap& properties);
226
227 /**
Adriana Kobylak8f16fb52021-03-31 15:50:15 +0000228 * @brief Perform power supply configuration validation.
229 * @details Validates if the existing power supply properties are a
230 * supported configuration, and acts on its findings such as logging errors.
231 */
232 void validateConfig();
233
234 /**
235 * @brief Flag to indicate if the validateConfig() function should be run.
236 * Set to false once the configuration has been validated to avoid running
237 * multiple times due to interfaces added signal. Set to true during power
238 * off to trigger the validation on power on.
239 */
240 bool runValidateConfig = true;
241
242 /**
Adriana Kobylak4d9aaf92021-06-30 15:27:42 +0000243 * @brief Check that all PSUs have the same model name and that the system
244 * has the required number of PSUs present as specified in the Supported
245 * Configuration interface.
246 *
247 * @param[out] additionalData - Contains debug information on why the check
248 * might have failed. Can be used to fill in error logs.
249 * @return true if all the required PSUs are present, false otherwise.
250 */
251 bool hasRequiredPSUs(std::map<std::string, std::string>& additionalData);
252
253 /**
Adriana Kobylak9ea66a62021-03-24 17:54:14 +0000254 * @brief Map of supported PSU configurations that include the model name
255 * and their properties.
Brandon Wymanaed1f752019-11-25 18:10:52 -0600256 */
Adriana Kobylakd3a70d92021-06-04 16:24:45 +0000257 std::map<std::string, sys_properties> supportedConfigs;
Brandon Wymanaed1f752019-11-25 18:10:52 -0600258
259 /**
Brandon Wymana0f33ce2019-10-17 18:32:29 -0500260 * @brief The vector for power supplies.
261 */
Brandon Wymanaed1f752019-11-25 18:10:52 -0600262 std::vector<std::unique_ptr<PowerSupply>> psus;
Brandon Wyman2bac8602019-09-12 18:12:21 -0500263};
264
Brandon Wyman63ea78b2020-09-24 16:49:09 -0500265} // namespace phosphor::power::manager