blob: 3fa0f6fea1b5fccb7c8a4fbc515fab204dc0fbbf [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 */
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;
Shawn McCarneye4fef0f2024-04-05 17:56:09 -0500129
130 /**
Shawn McCarney3a11d632024-05-23 10:12:56 -0500131 * Creates a BMC dump.
132 */
133 virtual void createBMCDump() = 0;
134
135 /**
Shawn McCarneye4fef0f2024-04-05 17:56:09 -0500136 * 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;
Shawn McCarney906cc3f2024-02-01 13:33:06 -0600143};
144
145/**
146 * @class BMCServices
147 *
148 * Implementation of the Services interface using standard BMC system services.
149 */
150class 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 {
Shawn McCarneye4fef0f2024-04-05 17:56:09 -0500204 std::string path = std::format("/sys/bus/i2c/devices/{}-{:04x}", bus,
Shawn McCarney906cc3f2024-02-01 13:33:06 -0600205 address);
206 return std::make_unique<PMBus>(path, driverName, instance);
207 }
208
Shawn McCarney3a11d632024-05-23 10:12:56 -0500209 /** @copydoc Services::createBMCDump() */
210 virtual void createBMCDump() override;
211
Shawn McCarneye4fef0f2024-04-05 17:56:09 -0500212 /** @copydoc Services::clearCache() */
213 virtual void clearCache() override
214 {
215 presenceCache.clear();
216 }
217
Shawn McCarney906cc3f2024-02-01 13:33:06 -0600218 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;
Shawn McCarneye4fef0f2024-04-05 17:56:09 -0500231
232 /**
233 * Cached presence data.
234 *
235 * Map from inventory paths to presence values.
236 */
237 std::map<std::string, bool> presenceCache{};
Shawn McCarney906cc3f2024-02-01 13:33:06 -0600238};
239
240} // namespace phosphor::power::sequencer