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