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 witherspoon
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<witherspoon::power::Device>&& d,
52                    sdbusplus::bus::bus& 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     /**
62      * Clears faults and then runs DeviceMonitor::run to
63      * call Device::analyze() on an ongoing interval.
64      *
65      * @return the return value from sd_event_loop()
66      */
67     int run() override;
68 
69   private:
70     /**
71      * The PowerLost signal handler.
72      *
73      * After doing an analysis, will issue a power off
74      * as some device has a power fault and needs to be
75      * properly shut down.
76      *
77      * @param[in] msg - D-Bus message for callback
78      */
79     void onPowerLost(sdbusplus::message::message& msg);
80 
81     /**
82      * Returns the match string for the PowerLost signal
83      */
84     std::string getMatchString()
85     {
86         using namespace sdbusplus::bus::match::rules;
87 
88         std::string s = type::signal() + path("/org/openbmc/control/power0") +
89                         interface("org.openbmc.control.Power") +
90                         member("PowerLost");
91 
92         return s;
93     }
94 
95     /**
96      * The D-Bus object
97      */
98     sdbusplus::bus::bus& bus;
99 
100     /**
101      * Match object for PowerLost signals
102      */
103     sdbusplus::bus::match_t match;
104 };
105 
106 } // namespace power
107 } // namespace witherspoon
108