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 <fmt/format.h> 22 23 #include <phosphor-logging/lg2.hpp> 24 #include <sdbusplus/bus.hpp> 25 #include <sdbusplus/exception.hpp> 26 27 #include <cstdint> 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 89 logError(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 * Reads all the GPIO values on the chip with the specified label. 106 * 107 * Throws an exception if an error occurs while obtaining the values. 108 * 109 * @param chipLabel label identifying the chip with the GPIOs 110 * @return GPIO values 111 */ 112 virtual std::vector<int> getGPIOValues(const std::string& chipLabel) = 0; 113 114 /** 115 * Creates object for communicating with a PMBus device by reading and 116 * writing sysfs files. 117 * 118 * Throws an exception if an error occurs. 119 * 120 * @param bus I2C bus 121 * @param address I2C address 122 * @param driverName Device driver name 123 * @param instance Chip instance number 124 * @return object for communicating with PMBus device 125 */ 126 virtual std::unique_ptr<PMBusBase> 127 createPMBus(uint8_t bus, uint16_t address, 128 const std::string& driverName = "", 129 size_t instance = 0) = 0; 130 }; 131 132 /** 133 * @class BMCServices 134 * 135 * Implementation of the Services interface using standard BMC system services. 136 */ 137 class BMCServices : public Services 138 { 139 public: 140 // Specify which compiler-generated methods we want 141 BMCServices() = delete; 142 BMCServices(const BMCServices&) = delete; 143 BMCServices(BMCServices&&) = delete; 144 BMCServices& operator=(const BMCServices&) = delete; 145 BMCServices& operator=(BMCServices&&) = delete; 146 virtual ~BMCServices() = default; 147 148 /** 149 * Constructor. 150 * 151 * @param bus D-Bus bus object 152 */ 153 explicit BMCServices(sdbusplus::bus_t& bus) : bus{bus} {} 154 155 /** @copydoc Services::getBus() */ 156 virtual sdbusplus::bus_t& getBus() override 157 { 158 return bus; 159 } 160 161 /** @copydoc Services::logErrorMsg() */ 162 virtual void logErrorMsg(const std::string& message) override 163 { 164 lg2::error(message.c_str()); 165 } 166 167 /** @copydoc Services::logInfoMsg() */ 168 virtual void logInfoMsg(const std::string& message) override 169 { 170 lg2::info(message.c_str()); 171 } 172 173 /** @copydoc Services::logError() */ 174 virtual void 175 logError(const std::string& message, Entry::Level severity, 176 std::map<std::string, std::string>& additionalData) override; 177 178 /** @copydoc Services::isPresent() */ 179 virtual bool isPresent(const std::string& inventoryPath) override; 180 181 /** @copydoc Services::getGPIOValues() */ 182 virtual std::vector<int> 183 getGPIOValues(const std::string& chipLabel) override; 184 185 /** @copydoc Services::createPMBus() */ 186 virtual std::unique_ptr<PMBusBase> 187 createPMBus(uint8_t bus, uint16_t address, 188 const std::string& driverName = "", 189 size_t instance = 0) override 190 { 191 std::string path = fmt::format("/sys/bus/i2c/devices/{}-{:04x}", bus, 192 address); 193 return std::make_unique<PMBus>(path, driverName, instance); 194 } 195 196 private: 197 /** 198 * Returns whether the specified D-Bus exception is one of the expected 199 * types that can be thrown if hardware is not present. 200 * 201 * @return true if exception type is expected, false otherwise 202 */ 203 bool isExpectedException(const sdbusplus::exception_t& e); 204 205 /** 206 * D-Bus bus object. 207 */ 208 sdbusplus::bus_t& bus; 209 }; 210 211 } // namespace phosphor::power::sequencer 212