1 #pragma once
2 
3 #include <sdbusplus/bus.hpp>
4 #include <sdbusplus/server.hpp>
5 #include "device.hpp"
6 #include "event.hpp"
7 #include "device_monitor.hpp"
8 #include "timer.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 
37         RuntimeMonitor() = delete;
38         ~RuntimeMonitor() = default;
39         RuntimeMonitor(const RuntimeMonitor&) = delete;
40         RuntimeMonitor& operator=(const RuntimeMonitor&) = delete;
41         RuntimeMonitor(RuntimeMonitor&&) = delete;
42         RuntimeMonitor& operator=(RuntimeMonitor&&) = delete;
43 
44         /**
45          * Constructor
46          *
47          * @param[in] d - the device to monitor
48          * @param[in] b - D-Bus bus object
49          * @param[in] e - event object
50          * @param[in] i - poll interval
51          */
52         RuntimeMonitor(std::unique_ptr<witherspoon::power::Device>&& d,
53                 sdbusplus::bus::bus& b,
54                 witherspoon::power::event::Event& e,
55                 std::chrono::milliseconds& i) :
56             DeviceMonitor(std::move(d), e, i),
57             bus(b),
58             match(bus,
59                   getMatchString(),
60                   std::bind(std::mem_fn(&RuntimeMonitor::onPowerLost),
61                             this, std::placeholders::_1))
62         {
63         }
64 
65         /**
66          * Clears faults and then runs DeviceMonitor::run to
67          * call Device::analyze() on an ongoing interval.
68          *
69          * @return the return value from sd_event_loop()
70          */
71         int run() override;
72 
73     private:
74 
75         /**
76          * The PowerLost signal handler.
77          *
78          * After doing an analysis, will issue a power off
79          * as some device has a power fault and needs to be
80          * properly shut down.
81          *
82          * @param[in] msg - D-Bus message for callback
83          */
84         void onPowerLost(sdbusplus::message::message& msg);
85 
86         /**
87          * Returns the match string for the PowerLost signal
88          */
89         std::string getMatchString()
90         {
91             using namespace sdbusplus::bus::match::rules;
92 
93             std::string s =
94                 type::signal() +
95                 path("/org/openbmc/control/power0") +
96                 interface("org.openbmc.control.Power") +
97                 member("PowerLost");
98 
99             return s;
100         }
101 
102         /**
103          * The D-Bus object
104          */
105         sdbusplus::bus::bus& bus;
106 
107         /**
108          * Match object for PowerLost signals
109          */
110         sdbusplus::bus::match_t match;
111 };
112 
113 }
114 }
115