/** * Copyright © 2024 IBM Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include "power_sequencer_device.hpp" #include "rail.hpp" #include "services.hpp" #include <map> #include <memory> #include <string> #include <utility> #include <vector> namespace phosphor::power::sequencer { /** * @class StandardDevice * * PowerSequencerDevice sub-class that implements the standard pgood fault * detection algorithm. * * When adding support for a new power sequencer device type, create a sub-class * of StandardDevice if possible. This will ensure that pgood fault detection * works consistently across device types. */ class StandardDevice : public PowerSequencerDevice { public: // Specify which compiler-generated methods we want StandardDevice() = delete; StandardDevice(const StandardDevice&) = delete; StandardDevice(StandardDevice&&) = delete; StandardDevice& operator=(const StandardDevice&) = delete; StandardDevice& operator=(StandardDevice&&) = delete; virtual ~StandardDevice() = default; /** * Constructor. * * @param name device name * @param rails voltage rails that are enabled and monitored by this device */ explicit StandardDevice(const std::string& name, std::vector<std::unique_ptr<Rail>> rails) : name{name}, rails{std::move(rails)} {} /** @copydoc PowerSequencerDevice::getName() */ virtual const std::string& getName() const override { return name; } /** @copydoc PowerSequencerDevice::getRails() */ virtual const std::vector<std::unique_ptr<Rail>>& getRails() const override { return rails; } /** @copydoc PowerSequencerDevice::findPgoodFault() * * Calls prepareForPgoodFaultDetection() before starting detection. If a * pgood fault is detected, calls storePgoodFaultDebugData(). */ virtual std::string findPgoodFault( Services& services, const std::string& powerSupplyError, std::map<std::string, std::string>& additionalData) override; protected: /** * Prepare for pgood fault detection. * * Perform any actions that are necessary to prepare for fault detection. * For example, cache information that is slow to obtain and is used * multiple times during detection. * * Default implementation does nothing. Override in sub-classes if needed. * * @param services System services like hardware presence and the journal */ virtual void prepareForPgoodFaultDetection([[maybe_unused]] Services& services) {} /** * Returns the GPIO values that can be read from the device, if possible. * * If the device does not support reading GPIO values or an error occurs, an * empty vector is returned. * * @param services System services like hardware presence and the journal * @return GPIO values, or empty vector if values could not be read */ virtual std::vector<int> getGPIOValuesIfPossible(Services& services); /** * Checks whether a pgood fault has occurred on one of the rails being * monitored by this device. * * If a pgood fault was found in a rail, a pointer to the Rail object is * returned. * * Throws an exception if an error occurs while trying to obtain the status * of the rails. * * @param services System services like hardware presence and the journal * @param gpioValues GPIO values obtained from the device (if any) * @param additionalData Additional data to include in the error log if * a pgood fault was found * @return pointer to Rail object where fault was found, or nullptr if no * Rail found */ virtual Rail* findRailWithPgoodFault( Services& services, const std::vector<int>& gpioValues, std::map<std::string, std::string>& additionalData); /** * Store pgood fault debug data in the specified additional data map. * * The default implementation stores the device name and then calls * storeGPIOValues(). * * Sub-classes should override if needed to store device-specific data. * * This method should NOT throw exceptions. If debug data cannot be * obtained, the error should be caught and ignored so that pgood error * handling can continue. * * @param services System services like hardware presence and the journal * @param gpioValues GPIO values obtained from the device (if any) * @param additionalData Additional data to include in an error log */ virtual void storePgoodFaultDebugData( Services& services, const std::vector<int>& gpioValues, std::map<std::string, std::string>& additionalData); /** * Store GPIO values in the specified additional data map. * * The default implementation stores the values as a simple list of * integers. * * Sub-classes should override if more advanced formatting is needed. For * example, GPIOs could be stored individually with a name and value, or * related GPIOs could be formatted as a group. * * @param services System services like hardware presence and the journal * @param values GPIO values obtained from the device (if any) * @param additionalData Additional data to include in an error log */ virtual void storeGPIOValues(Services& services, const std::vector<int>& values, std::map<std::string, std::string>& additionalData); /** * Device name. */ std::string name{}; /** * Voltage rails that are enabled and monitored by this device. */ std::vector<std::unique_ptr<Rail>> rails{}; }; } // namespace phosphor::power::sequencer