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