summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0063-Save-the-pre-timeout-interrupt-in-dbus-property.patch
blob: d0f9331d2f6af5ea2af5621536bb7e7bd921b841 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
From cfb5e13388531e1317eeb3ccf0f8eef0c6eeca60 Mon Sep 17 00:00:00 2001
From: Ren Yu <yux.ren@intel.com>
Date: Tue, 28 May 2019 17:11:17 +0800
Subject: [PATCH] Save the pre-timeout interrupt in dbus property

Get the watchdog pre-timeout interrupt value from ipmi watchdog set command,
and store it into dbus property.

Tested:
Config IPMI watchdog: BIOS FRB2 Power Cycle after 1 seconds:
ipmitool raw 0x06 0x24 0x01 0x13 0x0 0x2 0xa 0x00
Start watchdog:
Ipmitool mc watchdog reset
Check the watchdog pre-timeout interrupt in below:
https://BMCIP/redfish/v1/Systems/system/LogServices/EventLog/Entries

Signed-off-by: Ren Yu <yux.ren@intel.com>
---
 app/watchdog.cpp         | 47 ++++++++++++++++++++++++++++++++++++++++
 app/watchdog_service.cpp |  6 +++++
 app/watchdog_service.hpp |  9 ++++++++
 3 files changed, 62 insertions(+)

diff --git a/app/watchdog.cpp b/app/watchdog.cpp
index 03c373e..cb0b1fd 100644
--- a/app/watchdog.cpp
+++ b/app/watchdog.cpp
@@ -80,6 +80,7 @@ ipmi::RspType<> ipmiAppResetWatchdogTimer()
 
 static constexpr uint8_t wd_dont_stop = 0x1 << 6;
 static constexpr uint8_t wd_timeout_action_mask = 0x3;
+static constexpr uint8_t wdPreTimeoutInterruptMask = 0x3;
 
 static constexpr uint8_t wdTimerUseResTimer1 = 0x0;
 static constexpr uint8_t wdTimerUseResTimer2 = 0x6;
@@ -127,6 +128,45 @@ WatchdogService::Action ipmiActionToWdAction(IpmiAction ipmi_action)
     }
 }
 
+enum class IpmiPreTimeoutInterrupt : uint8_t
+{
+    None = 0x0,
+    SMI = 0x1,
+    NMI = 0x2,
+    MI = 0x3,
+};
+/** @brief Converts an IPMI Watchdog PreTimeoutInterrupt to DBUS defined action
+ *  @param[in] ipmi_action The IPMI Watchdog PreTimeoutInterrupt
+ *  @return The Watchdog PreTimeoutInterrupt that the ipmi_action maps to
+ */
+WatchdogService::PreTimeoutInterruptAction ipmiPreTimeoutInterruptToWdAction(
+    IpmiPreTimeoutInterrupt ipmiPreTimeOutInterrupt)
+{
+    switch (ipmiPreTimeOutInterrupt)
+    {
+        case IpmiPreTimeoutInterrupt::None:
+        {
+            return WatchdogService::PreTimeoutInterruptAction::None;
+        }
+        case IpmiPreTimeoutInterrupt::SMI:
+        {
+            return WatchdogService::PreTimeoutInterruptAction::SMI;
+        }
+        case IpmiPreTimeoutInterrupt::NMI:
+        {
+            return WatchdogService::PreTimeoutInterruptAction::NMI;
+        }
+        case IpmiPreTimeoutInterrupt::MI:
+        {
+            return WatchdogService::PreTimeoutInterruptAction::MI;
+        }
+        default:
+        {
+            throw std::domain_error("IPMI PreTimeoutInterrupt is invalid");
+        }
+    }
+}
+
 enum class IpmiTimerUse : uint8_t
 {
     Reserved = 0x0,
@@ -250,6 +290,13 @@ ipmi::RspType<>
         // Mark as initialized so that future resets behave correctly
         wd_service.setInitialized(true);
 
+        // pretimeOutAction
+        const auto ipmiPreTimeoutInterrupt =
+            static_cast<IpmiPreTimeoutInterrupt>(wdPreTimeoutInterruptMask &
+                (static_cast<uint8_t>(preTimeoutInterrupt)));
+        wd_service.setPreTimeoutInterrupt(
+            ipmiPreTimeoutInterruptToWdAction(ipmiPreTimeoutInterrupt));
+
         lastCallSuccessful = true;
         return ipmi::responseSuccess();
     }
diff --git a/app/watchdog_service.cpp b/app/watchdog_service.cpp
index 3534e89..4df1ab6 100644
--- a/app/watchdog_service.cpp
+++ b/app/watchdog_service.cpp
@@ -198,3 +198,9 @@ void WatchdogService::setInterval(uint64_t interval)
 {
     setProperty("Interval", interval);
 }
+
+void WatchdogService::setPreTimeoutInterrupt(
+    PreTimeoutInterruptAction preTimeoutInterrupt)
+{
+    setProperty("PreTimeoutInterrupt", convertForMessage(preTimeoutInterrupt));
+}
\ No newline at end of file
diff --git a/app/watchdog_service.hpp b/app/watchdog_service.hpp
index 141bdb7..32b7461 100644
--- a/app/watchdog_service.hpp
+++ b/app/watchdog_service.hpp
@@ -15,6 +15,8 @@ class WatchdogService
 
     using Action =
         sdbusplus::xyz::openbmc_project::State::server::Watchdog::Action;
+    using PreTimeoutInterruptAction = sdbusplus::xyz::openbmc_project::State::
+        server::Watchdog::PreTimeoutInterruptAction;
     using TimerUse =
         sdbusplus::xyz::openbmc_project::State::server::Watchdog::TimerUse;
 
@@ -92,6 +94,13 @@ class WatchdogService
      */
     void setInterval(uint64_t interval);
 
+    /** @brief Sets the value of the PreTimeoutInterrupt property on the host
+     * watchdog
+     *
+     *  @param[in] PreTimeoutInterrupt - The new PreTimeoutInterrupt value
+     */
+    void setPreTimeoutInterrupt(PreTimeoutInterruptAction preTimeoutInterrupt);
+
   private:
     /** @brief sdbusplus handle */
     sdbusplus::bus::bus bus;
-- 
2.17.1