xref: /openbmc/phosphor-power/power-sequencer/runtime_monitor.hpp (revision f54021972b91be5058b50e9046bb0dd5a3b22a80)
17084927eSMatt Spinler #pragma once
27084927eSMatt Spinler 
3f0f02b9aSMatt Spinler #include "device.hpp"
4f0f02b9aSMatt Spinler #include "device_monitor.hpp"
5f0f02b9aSMatt Spinler 
67084927eSMatt Spinler #include <sdbusplus/bus.hpp>
77084927eSMatt Spinler #include <sdbusplus/server.hpp>
8e5a8b473SWilliam A. Kennington III #include <sdeventplus/event.hpp>
97084927eSMatt Spinler 
10ab093328SLei YU namespace phosphor
117084927eSMatt Spinler {
127084927eSMatt Spinler namespace power
137084927eSMatt Spinler {
147084927eSMatt Spinler 
157084927eSMatt Spinler /**
167084927eSMatt Spinler  * @class RuntimeMonitor
177084927eSMatt Spinler  *
187084927eSMatt Spinler  * Monitors the power sequencer for faults at runtime
197084927eSMatt Spinler  *
207084927eSMatt Spinler  * Triggers the power sequencer fault check 2 different ways:
217084927eSMatt Spinler  *
227084927eSMatt Spinler  * 1) Listens for the PowerLost signal that indicates master
237084927eSMatt Spinler  *    PGOOD was dropped due to a fatal fault.  After the analysis,
247084927eSMatt Spinler  *    a power off will be issued so the sequencer will stop
257084927eSMatt Spinler  *    driving power to a faulted component.
267084927eSMatt Spinler  *
277084927eSMatt Spinler  * 2) Polls for faults, as some won't always drop PGOOD.
287084927eSMatt Spinler  *
297084927eSMatt Spinler  * The application this runs in will only run while PGOOD is
307084927eSMatt Spinler  * expected to be asserted, so any loss of PGOOD is considered
317084927eSMatt Spinler  * an error.
327084927eSMatt Spinler  */
337084927eSMatt Spinler class RuntimeMonitor : public DeviceMonitor
347084927eSMatt Spinler {
357084927eSMatt Spinler   public:
367084927eSMatt Spinler     RuntimeMonitor() = delete;
377084927eSMatt Spinler     ~RuntimeMonitor() = default;
387084927eSMatt Spinler     RuntimeMonitor(const RuntimeMonitor&) = delete;
397084927eSMatt Spinler     RuntimeMonitor& operator=(const RuntimeMonitor&) = delete;
407084927eSMatt Spinler     RuntimeMonitor(RuntimeMonitor&&) = delete;
417084927eSMatt Spinler     RuntimeMonitor& operator=(RuntimeMonitor&&) = delete;
427084927eSMatt Spinler 
437084927eSMatt Spinler     /**
447084927eSMatt Spinler      * Constructor
457084927eSMatt Spinler      *
467084927eSMatt Spinler      * @param[in] d - the device to monitor
477084927eSMatt Spinler      * @param[in] b - D-Bus bus object
487084927eSMatt Spinler      * @param[in] e - event object
497084927eSMatt Spinler      * @param[in] i - poll interval
507084927eSMatt Spinler      */
RuntimeMonitor(std::unique_ptr<phosphor::power::Device> && d,sdbusplus::bus_t & b,const sdeventplus::Event & e,std::chrono::milliseconds & i)51ab093328SLei YU     RuntimeMonitor(std::unique_ptr<phosphor::power::Device>&& d,
527354ce62SPatrick Williams                    sdbusplus::bus_t& b, const sdeventplus::Event& e,
5378c5c2b0SMatt Spinler                    std::chrono::milliseconds& i) :
54*f5402197SPatrick Williams         DeviceMonitor(std::move(d), e, i), bus(b),
55*f5402197SPatrick Williams         match(bus, getMatchString(),
56f0f02b9aSMatt Spinler               std::bind(std::mem_fn(&RuntimeMonitor::onPowerLost), this,
57f0f02b9aSMatt Spinler                         std::placeholders::_1))
580c9a33d6SAdriana Kobylak     {}
597084927eSMatt Spinler 
607084927eSMatt Spinler     /**
617084927eSMatt Spinler      * Clears faults and then runs DeviceMonitor::run to
627084927eSMatt Spinler      * call Device::analyze() on an ongoing interval.
637084927eSMatt Spinler      *
647084927eSMatt Spinler      * @return the return value from sd_event_loop()
657084927eSMatt Spinler      */
667084927eSMatt Spinler     int run() override;
677084927eSMatt Spinler 
687084927eSMatt Spinler   private:
697084927eSMatt Spinler     /**
707084927eSMatt Spinler      * The PowerLost signal handler.
717084927eSMatt Spinler      *
727084927eSMatt Spinler      * After doing an analysis, will issue a power off
737084927eSMatt Spinler      * as some device has a power fault and needs to be
747084927eSMatt Spinler      * properly shut down.
757084927eSMatt Spinler      *
767084927eSMatt Spinler      * @param[in] msg - D-Bus message for callback
777084927eSMatt Spinler      */
787354ce62SPatrick Williams     void onPowerLost(sdbusplus::message_t& msg);
797084927eSMatt Spinler 
807084927eSMatt Spinler     /**
817084927eSMatt Spinler      * Returns the match string for the PowerLost signal
827084927eSMatt Spinler      */
getMatchString()837084927eSMatt Spinler     std::string getMatchString()
847084927eSMatt Spinler     {
857084927eSMatt Spinler         using namespace sdbusplus::bus::match::rules;
867084927eSMatt Spinler 
87f0f02b9aSMatt Spinler         std::string s = type::signal() + path("/org/openbmc/control/power0") +
887084927eSMatt Spinler                         interface("org.openbmc.control.Power") +
897084927eSMatt Spinler                         member("PowerLost");
907084927eSMatt Spinler 
917084927eSMatt Spinler         return s;
927084927eSMatt Spinler     }
937084927eSMatt Spinler 
947084927eSMatt Spinler     /**
957084927eSMatt Spinler      * The D-Bus object
967084927eSMatt Spinler      */
977354ce62SPatrick Williams     sdbusplus::bus_t& bus;
987084927eSMatt Spinler 
997084927eSMatt Spinler     /**
1007084927eSMatt Spinler      * Match object for PowerLost signals
1017084927eSMatt Spinler      */
1027084927eSMatt Spinler     sdbusplus::bus::match_t match;
1037084927eSMatt Spinler };
1047084927eSMatt Spinler 
105f0f02b9aSMatt Spinler } // namespace power
106ab093328SLei YU } // namespace phosphor
107