1 /** 2 * Copyright © 2020 IBM Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #pragma once 17 18 #include "services.hpp" 19 #include "system.hpp" 20 21 #include <interfaces/manager_interface.hpp> 22 #include <sdbusplus/bus.hpp> 23 #include <sdbusplus/bus/match.hpp> 24 #include <sdbusplus/server/object.hpp> 25 #include <sdeventplus/event.hpp> 26 #include <sdeventplus/source/signal.hpp> 27 #include <sdeventplus/utility/timer.hpp> 28 29 #include <filesystem> 30 #include <memory> 31 #include <string> 32 #include <vector> 33 34 namespace phosphor::power::regulators 35 { 36 37 using Timer = sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic>; 38 39 using ManagerObject = sdbusplus::server::object::object< 40 phosphor::power::regulators::interface::ManagerInterface>; 41 42 class Manager : public ManagerObject 43 { 44 public: 45 Manager() = delete; 46 Manager(const Manager&) = delete; 47 Manager(Manager&&) = delete; 48 Manager& operator=(const Manager&) = delete; 49 Manager& operator=(Manager&&) = delete; 50 ~Manager() = default; 51 52 /** 53 * Constructor 54 * Creates a manager over the regulators. 55 * 56 * @param bus the D-Bus bus 57 * @param event the sdevent event 58 */ 59 Manager(sdbusplus::bus::bus& bus, const sdeventplus::Event& event); 60 61 /** 62 * Implements the D-Bus "configure" method. 63 * 64 * Configures all the voltage regulators in the system. 65 * 66 * This method should be called when the system is being powered on. It 67 * needs to occur before the regulators have been enabled/turned on. 68 */ 69 void configure() override; 70 71 /** 72 * Callback function to handle interfacesAdded D-Bus signals 73 * 74 * @param msg Expanded sdbusplus message data 75 */ 76 void interfacesAddedHandler(sdbusplus::message::message& msg); 77 78 /** 79 * Implements the D-Bus "monitor" method. 80 * 81 * Sets whether regulator monitoring is enabled. 82 * 83 * When monitoring is enabled: 84 * - regulator sensors will be read and published on D-Bus 85 * - phase fault detection will be performed 86 * 87 * Regulator monitoring should be enabled when the system is being powered 88 * on. It needs to occur after the regulators have been configured and 89 * enabled/turned on. 90 * 91 * Regulator monitoring should be disabled when the system is being powered 92 * off. It needs to occur before the regulators have been disabled/turned 93 * off. 94 * 95 * Regulator monitoring can also be temporarily disabled and then re-enabled 96 * while the system is powered on. This allows other applications or tools 97 * to temporarily communicate with the regulators for testing or debug. 98 * Monitoring should be disabled for only short periods of time; other 99 * applications, such as fan control, may be dependent on regulator sensors. 100 * 101 * @param enable true if monitoring should be enabled, false if it should be 102 * disabled 103 */ 104 void monitor(bool enable) override; 105 106 /** 107 * Phase fault detection timer expired callback function. 108 */ 109 void phaseFaultTimerExpired(); 110 111 /** 112 * Sensor monitoring timer expired callback function. 113 */ 114 void sensorTimerExpired(); 115 116 /** 117 * Callback function to handle receiving a HUP signal 118 * to reload the configuration data. 119 * 120 * @param sigSrc sd_event_source signal wrapper 121 * @param sigInfo signal info on signal fd 122 */ 123 void sighupHandler(sdeventplus::source::Signal& sigSrc, 124 const struct signalfd_siginfo* sigInfo); 125 126 private: 127 /** 128 * Clear any cached data or error history related to hardware devices. 129 * 130 * This method should be called when the system is powering on (booting). 131 * While the system was powered off, hardware could have been added, 132 * removed, or replaced. 133 */ 134 void clearHardwareData(); 135 136 /** 137 * Finds the list of compatible system types using D-Bus methods. 138 * 139 * This list is used to find the correct JSON configuration file for the 140 * current system. 141 * 142 * Note that some systems do not support the D-Bus compatible interface. 143 * 144 * If a list of compatible system types is found, it is stored in the 145 * compatibleSystemTypes data member. 146 */ 147 void findCompatibleSystemTypes(); 148 149 /** 150 * Finds the JSON configuration file. 151 * 152 * Looks for a configuration file based on the list of compatible system 153 * types. If no file is found, looks for a file with the default name. 154 * 155 * Looks for the file in the test directory and standard directory. 156 * 157 * Throws an exception if an operating system error occurs while checking 158 * for the existence of a file. 159 * 160 * @return absolute path to config file, or an empty path if none found 161 */ 162 std::filesystem::path findConfigFile(); 163 164 /** 165 * Returns whether the JSON configuration file has been loaded. 166 * 167 * @return true if config file loaded, false otherwise 168 */ 169 bool isConfigFileLoaded() const 170 { 171 // If System object exists, the config file has been loaded 172 return (system != nullptr); 173 } 174 175 /** 176 * Returns whether the system is currently powered on. 177 * 178 * @return true if system is powered on, false otherwise 179 */ 180 bool isSystemPoweredOn(); 181 182 /** 183 * Loads the JSON configuration file. 184 * 185 * Looks for the config file using findConfigFile(). 186 * 187 * If the config file is found, it is parsed and the resulting information 188 * is stored in the system data member. If parsing fails, an error is 189 * logged. 190 */ 191 void loadConfigFile(); 192 193 /** 194 * Waits until the JSON configuration file has been loaded. 195 * 196 * If the config file has not yet been loaded, waits until one of the 197 * following occurs: 198 * - config file is loaded 199 * - maximum amount of time to wait has elapsed 200 */ 201 void waitUntilConfigFileLoaded(); 202 203 /** 204 * The D-Bus bus 205 */ 206 sdbusplus::bus::bus& bus; 207 208 /** 209 * Event to loop on 210 */ 211 const sdeventplus::Event& eventLoop; 212 213 /** 214 * System services like error logging and the journal. 215 */ 216 BMCServices services; 217 218 /** 219 * Event timer used to initiate phase fault detection. 220 */ 221 Timer phaseFaultTimer; 222 223 /** 224 * Event timer used to initiate sensor monitoring. 225 */ 226 Timer sensorTimer; 227 228 /** 229 * List of D-Bus signal matches 230 */ 231 std::vector<std::unique_ptr<sdbusplus::bus::match::match>> signals{}; 232 233 /** 234 * Indicates whether regulator monitoring is enabled. 235 */ 236 bool isMonitoringEnabled{false}; 237 238 /** 239 * List of compatible system types for the current system. 240 * 241 * Used to find the JSON configuration file. 242 */ 243 std::vector<std::string> compatibleSystemTypes{}; 244 245 /** 246 * Computer system being controlled and monitored by the BMC. 247 * 248 * Contains the information loaded from the JSON configuration file. 249 * Contains nullptr if the configuration file has not been loaded. 250 */ 251 std::unique_ptr<System> system{}; 252 }; 253 254 } // namespace phosphor::power::regulators 255