blob: 25540bb12f5ddd80d5932681bc6e165ab8e9d2ec [file] [log] [blame]
Shawn McCarney906cc3f2024-02-01 13:33:06 -06001/**
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
Shawn McCarney175798c2025-11-20 13:50:03 -060018#include "gpio.hpp"
Shawn McCarney906cc3f2024-02-01 13:33:06 -060019#include "pmbus.hpp"
20#include "xyz/openbmc_project/Logging/Entry/server.hpp"
21
Shawn McCarney906cc3f2024-02-01 13:33:06 -060022#include <phosphor-logging/lg2.hpp>
23#include <sdbusplus/bus.hpp>
24#include <sdbusplus/exception.hpp>
25
26#include <cstdint>
Shawn McCarneye4fef0f2024-04-05 17:56:09 -050027#include <format>
Shawn McCarney906cc3f2024-02-01 13:33:06 -060028#include <map>
29#include <memory>
30#include <string>
31#include <vector>
32
33namespace phosphor::power::sequencer
34{
35
36using namespace sdbusplus::xyz::openbmc_project::Logging::server;
37using PMBusBase = phosphor::pmbus::PMBusBase;
38using 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 */
46class 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 */
Patrick Williams92261f82025-02-01 08:22:34 -050088 virtual void logError(
89 const std::string& message, Entry::Level severity,
90 std::map<std::string, std::string>& additionalData) = 0;
Shawn McCarney906cc3f2024-02-01 13:33:06 -060091
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 /**
Shawn McCarney175798c2025-11-20 13:50:03 -0600105 * 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 /**
Shawn McCarney906cc3f2024-02-01 13:33:06 -0600115 * 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 */
Patrick Williamsf5402192024-08-16 15:20:53 -0400136 virtual std::unique_ptr<PMBusBase> createPMBus(
137 uint8_t bus, uint16_t address, const std::string& driverName = "",
138 size_t instance = 0) = 0;
Shawn McCarneye4fef0f2024-04-05 17:56:09 -0500139
140 /**
Shawn McCarney3a11d632024-05-23 10:12:56 -0500141 * Creates a BMC dump.
142 */
143 virtual void createBMCDump() = 0;
144
145 /**
Shawn McCarneye4fef0f2024-04-05 17:56:09 -0500146 * 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;
Shawn McCarney906cc3f2024-02-01 13:33:06 -0600153};
154
155/**
156 * @class BMCServices
157 *
158 * Implementation of the Services interface using standard BMC system services.
159 */
160class 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 */
176 explicit BMCServices(sdbusplus::bus_t& bus) : bus{bus} {}
177
178 /** @copydoc Services::getBus() */
179 virtual sdbusplus::bus_t& getBus() override
180 {
181 return bus;
182 }
183
184 /** @copydoc Services::logErrorMsg() */
185 virtual void logErrorMsg(const std::string& message) override
186 {
187 lg2::error(message.c_str());
188 }
189
190 /** @copydoc Services::logInfoMsg() */
191 virtual void logInfoMsg(const std::string& message) override
192 {
193 lg2::info(message.c_str());
194 }
195
196 /** @copydoc Services::logError() */
Patrick Williams92261f82025-02-01 08:22:34 -0500197 virtual void logError(
198 const std::string& message, Entry::Level severity,
199 std::map<std::string, std::string>& additionalData) override;
Shawn McCarney906cc3f2024-02-01 13:33:06 -0600200
201 /** @copydoc Services::isPresent() */
202 virtual bool isPresent(const std::string& inventoryPath) override;
203
Shawn McCarney175798c2025-11-20 13:50:03 -0600204 /** @copydoc Services::createGPIO() */
205 virtual std::unique_ptr<GPIO> createGPIO(const std::string& name) override
206 {
207 return std::make_unique<BMCGPIO>(name);
208 }
209
Shawn McCarney906cc3f2024-02-01 13:33:06 -0600210 /** @copydoc Services::getGPIOValues() */
Patrick Williams92261f82025-02-01 08:22:34 -0500211 virtual std::vector<int> getGPIOValues(
212 const std::string& chipLabel) override;
Shawn McCarney906cc3f2024-02-01 13:33:06 -0600213
214 /** @copydoc Services::createPMBus() */
Patrick Williamsf5402192024-08-16 15:20:53 -0400215 virtual std::unique_ptr<PMBusBase> createPMBus(
216 uint8_t bus, uint16_t address, const std::string& driverName = "",
217 size_t instance = 0) override
Shawn McCarney906cc3f2024-02-01 13:33:06 -0600218 {
Patrick Williamsf5402192024-08-16 15:20:53 -0400219 std::string path =
220 std::format("/sys/bus/i2c/devices/{}-{:04x}", bus, address);
Shawn McCarney906cc3f2024-02-01 13:33:06 -0600221 return std::make_unique<PMBus>(path, driverName, instance);
222 }
223
Shawn McCarney3a11d632024-05-23 10:12:56 -0500224 /** @copydoc Services::createBMCDump() */
225 virtual void createBMCDump() override;
226
Shawn McCarneye4fef0f2024-04-05 17:56:09 -0500227 /** @copydoc Services::clearCache() */
228 virtual void clearCache() override
229 {
230 presenceCache.clear();
231 }
232
Shawn McCarney906cc3f2024-02-01 13:33:06 -0600233 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;
Shawn McCarneye4fef0f2024-04-05 17:56:09 -0500246
247 /**
248 * Cached presence data.
249 *
250 * Map from inventory paths to presence values.
251 */
252 std::map<std::string, bool> presenceCache{};
Shawn McCarney906cc3f2024-02-01 13:33:06 -0600253};
254
255} // namespace phosphor::power::sequencer