1 /** 2 * Copyright © 2024 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 "gpio.hpp" 19 #include "pmbus.hpp" 20 #include "xyz/openbmc_project/Logging/Entry/server.hpp" 21 22 #include <phosphor-logging/lg2.hpp> 23 #include <sdbusplus/bus.hpp> 24 #include <sdbusplus/exception.hpp> 25 26 #include <cstdint> 27 #include <format> 28 #include <map> 29 #include <memory> 30 #include <string> 31 #include <vector> 32 33 namespace phosphor::power::sequencer 34 { 35 36 using namespace sdbusplus::xyz::openbmc_project::Logging::server; 37 using PMBusBase = phosphor::pmbus::PMBusBase; 38 using PMBus = phosphor::pmbus::PMBus; 39 40 /** 41 * @class Services 42 * 43 * Abstract base class that provides an interface to system services like error 44 * logging and the journal. 45 */ 46 class Services 47 { 48 public: 49 // Specify which compiler-generated methods we want 50 Services() = default; 51 Services(const Services&) = delete; 52 Services(Services&&) = delete; 53 Services& operator=(const Services&) = delete; 54 Services& operator=(Services&&) = delete; 55 virtual ~Services() = default; 56 57 /** 58 * Returns the D-Bus bus object. 59 * 60 * @return D-Bus bus 61 */ 62 virtual sdbusplus::bus_t& getBus() = 0; 63 64 /** 65 * Logs an error message in the system journal. 66 * 67 * @param message message to log 68 */ 69 virtual void logErrorMsg(const std::string& message) = 0; 70 71 /** 72 * Logs an informational message in the system journal. 73 * 74 * @param message message to log 75 */ 76 virtual void logInfoMsg(const std::string& message) = 0; 77 78 /** 79 * Logs an error. 80 * 81 * If logging fails, a message is written to the system journal but an 82 * exception is not thrown. 83 * 84 * @param message Message property of the error log entry 85 * @param severity Severity property of the error log entry 86 * @param additionalData AdditionalData property of the error log entry 87 */ 88 virtual void logError( 89 const std::string& message, Entry::Level severity, 90 std::map<std::string, std::string>& additionalData) = 0; 91 92 /** 93 * Returns whether the hardware with the specified inventory path is 94 * present. 95 * 96 * Throws an exception if an error occurs while obtaining the presence 97 * value. 98 * 99 * @param inventoryPath D-Bus inventory path of the hardware 100 * @return true if hardware is present, false otherwise 101 */ 102 virtual bool isPresent(const std::string& inventoryPath) = 0; 103 104 /** 105 * Creates a GPIO object for getting/setting the value of a GPIO. 106 * 107 * Throws an exception if a GPIO with the specified name cannot be found. 108 * 109 * @param name GPIO name 110 * @return GPIO object 111 */ 112 virtual std::unique_ptr<GPIO> createGPIO(const std::string& name) = 0; 113 114 /** 115 * Reads all the GPIO values on the chip with the specified label. 116 * 117 * Throws an exception if an error occurs while obtaining the values. 118 * 119 * @param chipLabel label identifying the chip with the GPIOs 120 * @return GPIO values 121 */ 122 virtual std::vector<int> getGPIOValues(const std::string& chipLabel) = 0; 123 124 /** 125 * Creates object for communicating with a PMBus device by reading and 126 * writing sysfs files. 127 * 128 * Throws an exception if an error occurs. 129 * 130 * @param bus I2C bus 131 * @param address I2C address 132 * @param driverName Device driver name 133 * @param instance Chip instance number 134 * @return object for communicating with PMBus device 135 */ 136 virtual std::unique_ptr<PMBusBase> createPMBus( 137 uint8_t bus, uint16_t address, const std::string& driverName = "", 138 size_t instance = 0) = 0; 139 140 /** 141 * Creates a BMC dump. 142 */ 143 virtual void createBMCDump() = 0; 144 145 /** 146 * Clear any cached data. 147 * 148 * Some data may be cached for performance reasons, such as hardware 149 * presence. Clearing the cache results in the latest data being obtained 150 * by a subsequent method calls. 151 */ 152 virtual void clearCache() = 0; 153 }; 154 155 /** 156 * @class BMCServices 157 * 158 * Implementation of the Services interface using standard BMC system services. 159 */ 160 class BMCServices : public Services 161 { 162 public: 163 // Specify which compiler-generated methods we want 164 BMCServices() = delete; 165 BMCServices(const BMCServices&) = delete; 166 BMCServices(BMCServices&&) = delete; 167 BMCServices& operator=(const BMCServices&) = delete; 168 BMCServices& operator=(BMCServices&&) = delete; 169 virtual ~BMCServices() = default; 170 171 /** 172 * Constructor. 173 * 174 * @param bus D-Bus bus object 175 */ BMCServices(sdbusplus::bus_t & bus)176 explicit BMCServices(sdbusplus::bus_t& bus) : bus{bus} {} 177 178 /** @copydoc Services::getBus() */ getBus()179 virtual sdbusplus::bus_t& getBus() override 180 { 181 return bus; 182 } 183 184 /** @copydoc Services::logErrorMsg() */ logErrorMsg(const std::string & message)185 virtual void logErrorMsg(const std::string& message) override 186 { 187 lg2::error(message.c_str()); 188 } 189 190 /** @copydoc Services::logInfoMsg() */ logInfoMsg(const std::string & message)191 virtual void logInfoMsg(const std::string& message) override 192 { 193 lg2::info(message.c_str()); 194 } 195 196 /** @copydoc Services::logError() */ 197 virtual void logError( 198 const std::string& message, Entry::Level severity, 199 std::map<std::string, std::string>& additionalData) override; 200 201 /** @copydoc Services::isPresent() */ 202 virtual bool isPresent(const std::string& inventoryPath) override; 203 204 /** @copydoc Services::createGPIO() */ createGPIO(const std::string & name)205 virtual std::unique_ptr<GPIO> createGPIO(const std::string& name) override 206 { 207 return std::make_unique<BMCGPIO>(name); 208 } 209 210 /** @copydoc Services::getGPIOValues() */ 211 virtual std::vector<int> getGPIOValues( 212 const std::string& chipLabel) override; 213 214 /** @copydoc Services::createPMBus() */ createPMBus(uint8_t bus,uint16_t address,const std::string & driverName="",size_t instance=0)215 virtual std::unique_ptr<PMBusBase> createPMBus( 216 uint8_t bus, uint16_t address, const std::string& driverName = "", 217 size_t instance = 0) override 218 { 219 std::string path = 220 std::format("/sys/bus/i2c/devices/{}-{:04x}", bus, address); 221 return std::make_unique<PMBus>(path, driverName, instance); 222 } 223 224 /** @copydoc Services::createBMCDump() */ 225 virtual void createBMCDump() override; 226 227 /** @copydoc Services::clearCache() */ clearCache()228 virtual void clearCache() override 229 { 230 presenceCache.clear(); 231 } 232 233 private: 234 /** 235 * Returns whether the specified D-Bus exception is one of the expected 236 * types that can be thrown if hardware is not present. 237 * 238 * @return true if exception type is expected, false otherwise 239 */ 240 bool isExpectedException(const sdbusplus::exception_t& e); 241 242 /** 243 * D-Bus bus object. 244 */ 245 sdbusplus::bus_t& bus; 246 247 /** 248 * Cached presence data. 249 * 250 * Map from inventory paths to presence values. 251 */ 252 std::map<std::string, bool> presenceCache{}; 253 }; 254 255 } // namespace phosphor::power::sequencer 256