1 #pragma once
2 
3 #include "device.hpp"
4 #include "device_monitor.hpp"
5 
6 #include <sdbusplus/bus.hpp>
7 #include <sdbusplus/server.hpp>
8 #include <sdeventplus/event.hpp>
9 
10 namespace phosphor
11 {
12 namespace power
13 {
14 
15 /**
16  * @class RuntimeMonitor
17  *
18  * Monitors the power sequencer for faults at runtime
19  *
20  * Triggers the power sequencer fault check 2 different ways:
21  *
22  * 1) Listens for the PowerLost signal that indicates master
23  *    PGOOD was dropped due to a fatal fault.  After the analysis,
24  *    a power off will be issued so the sequencer will stop
25  *    driving power to a faulted component.
26  *
27  * 2) Polls for faults, as some won't always drop PGOOD.
28  *
29  * The application this runs in will only run while PGOOD is
30  * expected to be asserted, so any loss of PGOOD is considered
31  * an error.
32  */
33 class RuntimeMonitor : public DeviceMonitor
34 {
35   public:
36     RuntimeMonitor() = delete;
37     ~RuntimeMonitor() = default;
38     RuntimeMonitor(const RuntimeMonitor&) = delete;
39     RuntimeMonitor& operator=(const RuntimeMonitor&) = delete;
40     RuntimeMonitor(RuntimeMonitor&&) = delete;
41     RuntimeMonitor& operator=(RuntimeMonitor&&) = delete;
42 
43     /**
44      * Constructor
45      *
46      * @param[in] d - the device to monitor
47      * @param[in] b - D-Bus bus object
48      * @param[in] e - event object
49      * @param[in] i - poll interval
50      */
51     RuntimeMonitor(std::unique_ptr<phosphor::power::Device>&& d,
52                    sdbusplus::bus_t& b, const sdeventplus::Event& e,
53                    std::chrono::milliseconds& i) :
54         DeviceMonitor(std::move(d), e, i),
55         bus(b), match(bus, getMatchString(),
56                       std::bind(std::mem_fn(&RuntimeMonitor::onPowerLost), this,
57                                 std::placeholders::_1))
58     {}
59 
60     /**
61      * Clears faults and then runs DeviceMonitor::run to
62      * call Device::analyze() on an ongoing interval.
63      *
64      * @return the return value from sd_event_loop()
65      */
66     int run() override;
67 
68   private:
69     /**
70      * The PowerLost signal handler.
71      *
72      * After doing an analysis, will issue a power off
73      * as some device has a power fault and needs to be
74      * properly shut down.
75      *
76      * @param[in] msg - D-Bus message for callback
77      */
78     void onPowerLost(sdbusplus::message_t& msg);
79 
80     /**
81      * Returns the match string for the PowerLost signal
82      */
83     std::string getMatchString()
84     {
85         using namespace sdbusplus::bus::match::rules;
86 
87         std::string s = type::signal() + path("/org/openbmc/control/power0") +
88                         interface("org.openbmc.control.Power") +
89                         member("PowerLost");
90 
91         return s;
92     }
93 
94     /**
95      * The D-Bus object
96      */
97     sdbusplus::bus_t& bus;
98 
99     /**
100      * Match object for PowerLost signals
101      */
102     sdbusplus::bus::match_t match;
103 };
104 
105 } // namespace power
106 } // namespace phosphor
107