19284c307SShawn McCarney /**
29284c307SShawn McCarney  * Copyright © 2021 IBM Corporation
39284c307SShawn McCarney  *
49284c307SShawn McCarney  * Licensed under the Apache License, Version 2.0 (the "License");
59284c307SShawn McCarney  * you may not use this file except in compliance with the License.
69284c307SShawn McCarney  * You may obtain a copy of the License at
79284c307SShawn McCarney  *
89284c307SShawn McCarney  *     http://www.apache.org/licenses/LICENSE-2.0
99284c307SShawn McCarney  *
109284c307SShawn McCarney  * Unless required by applicable law or agreed to in writing, software
119284c307SShawn McCarney  * distributed under the License is distributed on an "AS IS" BASIS,
129284c307SShawn McCarney  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139284c307SShawn McCarney  * See the License for the specific language governing permissions and
149284c307SShawn McCarney  * limitations under the License.
159284c307SShawn McCarney  */
169284c307SShawn McCarney #pragma once
179284c307SShawn McCarney 
189284c307SShawn McCarney #include "action.hpp"
199284c307SShawn McCarney #include "action_environment.hpp"
209284c307SShawn McCarney #include "error_history.hpp"
219284c307SShawn McCarney #include "phase_fault.hpp"
229284c307SShawn McCarney #include "services.hpp"
239284c307SShawn McCarney 
249284c307SShawn McCarney #include <memory>
259284c307SShawn McCarney #include <string>
269284c307SShawn McCarney #include <utility>
279284c307SShawn McCarney #include <vector>
289284c307SShawn McCarney 
299284c307SShawn McCarney namespace phosphor::power::regulators
309284c307SShawn McCarney {
319284c307SShawn McCarney 
329284c307SShawn McCarney // Forward declarations to avoid circular dependencies
339284c307SShawn McCarney class Chassis;
349284c307SShawn McCarney class Device;
359284c307SShawn McCarney class System;
369284c307SShawn McCarney 
379284c307SShawn McCarney /**
389284c307SShawn McCarney  * @class PhaseFaultDetection
399284c307SShawn McCarney  *
409284c307SShawn McCarney  * Detects and logs redundant phase faults in a voltage regulator.
419284c307SShawn McCarney  *
429284c307SShawn McCarney  * A voltage regulator is sometimes called a "phase controller" because it
439284c307SShawn McCarney  * controls one or more phases that perform the actual voltage regulation.
449284c307SShawn McCarney  *
459284c307SShawn McCarney  * A regulator may have redundant phases.  If a redundant phase fails, the
469284c307SShawn McCarney  * regulator will continue to provide the desired output voltage.  However, a
479284c307SShawn McCarney  * phase fault error should be logged warning the user that the regulator has
489284c307SShawn McCarney  * lost redundancy.
499284c307SShawn McCarney  *
509284c307SShawn McCarney  * The technique used to detect a phase fault varies depending on the regulator
519284c307SShawn McCarney  * hardware.  Often a bit is checked in a status register.  The status register
529284c307SShawn McCarney  * could exist in the regulator or in a related I/O expander.
539284c307SShawn McCarney  *
54*54b3ab9bSShawn McCarney  * Phase fault detection is executed repeatedly based on a timer.  A phase fault
55*54b3ab9bSShawn McCarney  * must be detected two consecutive times before an error is logged.  This
56*54b3ab9bSShawn McCarney  * provides "de-glitching" to ignore transient hardware problems.
579284c307SShawn McCarney  *
589284c307SShawn McCarney  * Phase faults are detected by executing actions.
599284c307SShawn McCarney  */
609284c307SShawn McCarney class PhaseFaultDetection
619284c307SShawn McCarney {
629284c307SShawn McCarney   public:
639284c307SShawn McCarney     // Specify which compiler-generated methods we want
649284c307SShawn McCarney     PhaseFaultDetection() = delete;
659284c307SShawn McCarney     PhaseFaultDetection(const PhaseFaultDetection&) = delete;
669284c307SShawn McCarney     PhaseFaultDetection(PhaseFaultDetection&&) = delete;
679284c307SShawn McCarney     PhaseFaultDetection& operator=(const PhaseFaultDetection&) = delete;
689284c307SShawn McCarney     PhaseFaultDetection& operator=(PhaseFaultDetection&&) = delete;
699284c307SShawn McCarney     ~PhaseFaultDetection() = default;
709284c307SShawn McCarney 
719284c307SShawn McCarney     /**
729284c307SShawn McCarney      * Constructor.
739284c307SShawn McCarney      *
749284c307SShawn McCarney      * @param actions Actions that detect phase faults in the regulator.
759284c307SShawn McCarney      * @param deviceID Unique ID of the device to use when detecting phase
769284c307SShawn McCarney      *                 faults.  If not specified, the regulator will be used.
779284c307SShawn McCarney      */
PhaseFaultDetection(std::vector<std::unique_ptr<Action>> actions,const std::string & deviceID="")789284c307SShawn McCarney     explicit PhaseFaultDetection(std::vector<std::unique_ptr<Action>> actions,
799284c307SShawn McCarney                                  const std::string& deviceID = "") :
809284c307SShawn McCarney         actions{std::move(actions)},
819284c307SShawn McCarney         deviceID{deviceID}
820c9a33d6SAdriana Kobylak     {}
839284c307SShawn McCarney 
849284c307SShawn McCarney     /**
859284c307SShawn McCarney      * Clears all error history.
869284c307SShawn McCarney      *
879284c307SShawn McCarney      * All data on previously logged errors will be deleted.  If errors occur
889284c307SShawn McCarney      * again in the future they will be logged again.
899284c307SShawn McCarney      *
909284c307SShawn McCarney      * This method is normally called when the system is being powered on.
919284c307SShawn McCarney      */
clearErrorHistory()929284c307SShawn McCarney     void clearErrorHistory()
939284c307SShawn McCarney     {
949284c307SShawn McCarney         errorHistory.clear();
959284c307SShawn McCarney         actionErrorCount = 0;
969284c307SShawn McCarney         nFaultCount = 0;
979284c307SShawn McCarney         nPlus1FaultCount = 0;
989284c307SShawn McCarney     }
999284c307SShawn McCarney 
1009284c307SShawn McCarney     /**
1019284c307SShawn McCarney      * Executes the actions that detect phase faults in the regulator.
1029284c307SShawn McCarney      *
1039284c307SShawn McCarney      * If the required number of consecutive phase faults are detected, an error
1049284c307SShawn McCarney      * is logged.
1059284c307SShawn McCarney      *
1069284c307SShawn McCarney      * @param services system services like error logging and the journal
1079284c307SShawn McCarney      * @param system system that contains the chassis
1089284c307SShawn McCarney      * @param chassis chassis that contains the regulator device
1099284c307SShawn McCarney      * @param regulator voltage regulator device
1109284c307SShawn McCarney      */
1119284c307SShawn McCarney     void execute(Services& services, System& system, Chassis& chassis,
1129284c307SShawn McCarney                  Device& regulator);
1139284c307SShawn McCarney 
1149284c307SShawn McCarney     /**
1159284c307SShawn McCarney      * Returns the actions that detect phase faults in the regulator.
1169284c307SShawn McCarney      *
1179284c307SShawn McCarney      * @return actions
1189284c307SShawn McCarney      */
getActions() const1199284c307SShawn McCarney     const std::vector<std::unique_ptr<Action>>& getActions() const
1209284c307SShawn McCarney     {
1219284c307SShawn McCarney         return actions;
1229284c307SShawn McCarney     }
1239284c307SShawn McCarney 
1249284c307SShawn McCarney     /**
1259284c307SShawn McCarney      * Returns the unique ID of the device to use when detecting phase
1269284c307SShawn McCarney      * faults.
1279284c307SShawn McCarney      *
1289284c307SShawn McCarney      * If the value is "", the regulator will be used.
1299284c307SShawn McCarney      *
1309284c307SShawn McCarney      * @return device ID
1319284c307SShawn McCarney      */
getDeviceID() const1329284c307SShawn McCarney     const std::string& getDeviceID() const
1339284c307SShawn McCarney     {
1349284c307SShawn McCarney         return deviceID;
1359284c307SShawn McCarney     }
1369284c307SShawn McCarney 
1379284c307SShawn McCarney   private:
1389284c307SShawn McCarney     /**
1399284c307SShawn McCarney      * Checks if the specified phase fault type was detected.
1409284c307SShawn McCarney      *
1419284c307SShawn McCarney      * If the fault type was detected, increments the counter tracking
1429284c307SShawn McCarney      * consecutive faults.  If the required number of consecutive faults have
1439284c307SShawn McCarney      * been detected, logs a phase fault error.
1449284c307SShawn McCarney      *
1459284c307SShawn McCarney      * The ActionEnvironment contains the set of phase fault types that were
1469284c307SShawn McCarney      * detected (if any).
1479284c307SShawn McCarney      *
1489284c307SShawn McCarney      * @param faultType phase fault type to check
1499284c307SShawn McCarney      * @param services system services like error logging and the journal
1509284c307SShawn McCarney      * @param regulator voltage regulator device
1519284c307SShawn McCarney      * @param environment action execution environment
1529284c307SShawn McCarney      */
1539284c307SShawn McCarney     void checkForPhaseFault(PhaseFaultType faultType, Services& services,
1549284c307SShawn McCarney                             Device& regulator, ActionEnvironment& environment);
1559284c307SShawn McCarney 
1569284c307SShawn McCarney     /**
1579284c307SShawn McCarney      * Logs an error for the specified phase fault type.
1589284c307SShawn McCarney      *
1599284c307SShawn McCarney      * @param faultType phase fault type that occurred
1609284c307SShawn McCarney      * @param services system services like error logging and the journal
1619284c307SShawn McCarney      * @param regulator voltage regulator device
1629284c307SShawn McCarney      * @param environment action execution environment
1639284c307SShawn McCarney      */
1649284c307SShawn McCarney     void logPhaseFault(PhaseFaultType faultType, Services& services,
1659284c307SShawn McCarney                        Device& regulator, ActionEnvironment& environment);
1669284c307SShawn McCarney 
1679284c307SShawn McCarney     /**
1689284c307SShawn McCarney      * Actions that detect phase faults in the regulator.
1699284c307SShawn McCarney      */
1709284c307SShawn McCarney     std::vector<std::unique_ptr<Action>> actions{};
1719284c307SShawn McCarney 
1729284c307SShawn McCarney     /**
1739284c307SShawn McCarney      * Unique ID of the device to use when detecting phase faults.
1749284c307SShawn McCarney      *
1759284c307SShawn McCarney      * Sometimes a separate device, such as an I/O expander, is accessed to
1769284c307SShawn McCarney      * obtain the phase fault status for a regulator.
1779284c307SShawn McCarney      *
1789284c307SShawn McCarney      * If the value is "", the regulator will be used.
1799284c307SShawn McCarney      */
1809284c307SShawn McCarney     const std::string deviceID{};
1819284c307SShawn McCarney 
1829284c307SShawn McCarney     /**
1839284c307SShawn McCarney      * History of which error types have been logged.
1849284c307SShawn McCarney      *
1859284c307SShawn McCarney      * Since phase fault detection runs repeatedly based on a timer, each error
1869284c307SShawn McCarney      * type is only logged once.
1879284c307SShawn McCarney      */
1889284c307SShawn McCarney     ErrorHistory errorHistory{};
1899284c307SShawn McCarney 
1909284c307SShawn McCarney     /**
1919284c307SShawn McCarney      * Number of errors that have occurred while executing actions, resulting in
1929284c307SShawn McCarney      * an exception.
1939284c307SShawn McCarney      */
1949284c307SShawn McCarney     unsigned short actionErrorCount{0};
1959284c307SShawn McCarney 
1969284c307SShawn McCarney     /**
1979284c307SShawn McCarney      * Number of consecutive N phase faults that have been detected.
1989284c307SShawn McCarney      */
1999284c307SShawn McCarney     unsigned short nFaultCount{0};
2009284c307SShawn McCarney 
2019284c307SShawn McCarney     /**
2029284c307SShawn McCarney      * Number of consecutive N+1 phase faults that have been detected.
2039284c307SShawn McCarney      */
2049284c307SShawn McCarney     unsigned short nPlus1FaultCount{0};
2059284c307SShawn McCarney };
2069284c307SShawn McCarney 
2079284c307SShawn McCarney } // namespace phosphor::power::regulators
208