blob: 743c03439778f9649e321f060465fba0509e6e75 [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
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
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 */
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 */
137class 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