blob: d573743febb098d58c3b8e3ecb1e25021c66d8b8 [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
18#include "pmbus.hpp"
19#include "xyz/openbmc_project/Logging/Entry/server.hpp"
20
Shawn McCarney906cc3f2024-02-01 13:33:06 -060021#include <phosphor-logging/lg2.hpp>
22#include <sdbusplus/bus.hpp>
23#include <sdbusplus/exception.hpp>
24
25#include <cstdint>
Shawn McCarneye4fef0f2024-04-05 17:56:09 -050026#include <format>
Shawn McCarney906cc3f2024-02-01 13:33:06 -060027#include <map>
28#include <memory>
29#include <string>
30#include <vector>
31
32namespace phosphor::power::sequencer
33{
34
35using namespace sdbusplus::xyz::openbmc_project::Logging::server;
36using PMBusBase = phosphor::pmbus::PMBusBase;
37using 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 */
45class 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 */
Patrick Williamsf5402192024-08-16 15:20:53 -0400125 virtual std::unique_ptr<PMBusBase> createPMBus(
126 uint8_t bus, uint16_t address, const std::string& driverName = "",
127 size_t instance = 0) = 0;
Shawn McCarneye4fef0f2024-04-05 17:56:09 -0500128
129 /**
Shawn McCarney3a11d632024-05-23 10:12:56 -0500130 * Creates a BMC dump.
131 */
132 virtual void createBMCDump() = 0;
133
134 /**
Shawn McCarneye4fef0f2024-04-05 17:56:09 -0500135 * Clear any cached data.
136 *
137 * Some data may be cached for performance reasons, such as hardware
138 * presence. Clearing the cache results in the latest data being obtained
139 * by a subsequent method calls.
140 */
141 virtual void clearCache() = 0;
Shawn McCarney906cc3f2024-02-01 13:33:06 -0600142};
143
144/**
145 * @class BMCServices
146 *
147 * Implementation of the Services interface using standard BMC system services.
148 */
149class BMCServices : public Services
150{
151 public:
152 // Specify which compiler-generated methods we want
153 BMCServices() = delete;
154 BMCServices(const BMCServices&) = delete;
155 BMCServices(BMCServices&&) = delete;
156 BMCServices& operator=(const BMCServices&) = delete;
157 BMCServices& operator=(BMCServices&&) = delete;
158 virtual ~BMCServices() = default;
159
160 /**
161 * Constructor.
162 *
163 * @param bus D-Bus bus object
164 */
165 explicit BMCServices(sdbusplus::bus_t& bus) : bus{bus} {}
166
167 /** @copydoc Services::getBus() */
168 virtual sdbusplus::bus_t& getBus() override
169 {
170 return bus;
171 }
172
173 /** @copydoc Services::logErrorMsg() */
174 virtual void logErrorMsg(const std::string& message) override
175 {
176 lg2::error(message.c_str());
177 }
178
179 /** @copydoc Services::logInfoMsg() */
180 virtual void logInfoMsg(const std::string& message) override
181 {
182 lg2::info(message.c_str());
183 }
184
185 /** @copydoc Services::logError() */
186 virtual void
187 logError(const std::string& message, Entry::Level severity,
188 std::map<std::string, std::string>& additionalData) override;
189
190 /** @copydoc Services::isPresent() */
191 virtual bool isPresent(const std::string& inventoryPath) override;
192
193 /** @copydoc Services::getGPIOValues() */
194 virtual std::vector<int>
195 getGPIOValues(const std::string& chipLabel) override;
196
197 /** @copydoc Services::createPMBus() */
Patrick Williamsf5402192024-08-16 15:20:53 -0400198 virtual std::unique_ptr<PMBusBase> createPMBus(
199 uint8_t bus, uint16_t address, const std::string& driverName = "",
200 size_t instance = 0) override
Shawn McCarney906cc3f2024-02-01 13:33:06 -0600201 {
Patrick Williamsf5402192024-08-16 15:20:53 -0400202 std::string path =
203 std::format("/sys/bus/i2c/devices/{}-{:04x}", bus, address);
Shawn McCarney906cc3f2024-02-01 13:33:06 -0600204 return std::make_unique<PMBus>(path, driverName, instance);
205 }
206
Shawn McCarney3a11d632024-05-23 10:12:56 -0500207 /** @copydoc Services::createBMCDump() */
208 virtual void createBMCDump() override;
209
Shawn McCarneye4fef0f2024-04-05 17:56:09 -0500210 /** @copydoc Services::clearCache() */
211 virtual void clearCache() override
212 {
213 presenceCache.clear();
214 }
215
Shawn McCarney906cc3f2024-02-01 13:33:06 -0600216 private:
217 /**
218 * Returns whether the specified D-Bus exception is one of the expected
219 * types that can be thrown if hardware is not present.
220 *
221 * @return true if exception type is expected, false otherwise
222 */
223 bool isExpectedException(const sdbusplus::exception_t& e);
224
225 /**
226 * D-Bus bus object.
227 */
228 sdbusplus::bus_t& bus;
Shawn McCarneye4fef0f2024-04-05 17:56:09 -0500229
230 /**
231 * Cached presence data.
232 *
233 * Map from inventory paths to presence values.
234 */
235 std::map<std::string, bool> presenceCache{};
Shawn McCarney906cc3f2024-02-01 13:33:06 -0600236};
237
238} // namespace phosphor::power::sequencer