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: 685e7c39ddce127501128d09f511d17b1696cfc4 (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 d9c89943d7b0aa00ee99b7c11278ac272a47a790 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 2ffaae3..e9b7a9c 100644
--- a/app/watchdog.cpp
+++ b/app/watchdog.cpp
@@ -81,6 +81,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 wdTimerUseMask = 0x7;
 static constexpr uint8_t wdTimerUseResTimer1 = 0x0;
@@ -130,6 +131,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,
@@ -257,6 +297,13 @@ ipmi_ret_t ipmi_app_watchdog_set(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
         // Mark as initialized so that future resets behave correctly
         wd_service.setInitialized(true);
 
+        // pretimeOutAction
+        const auto ipmiPreTimeoutInterrupt =
+            static_cast<IpmiPreTimeoutInterrupt>((req.timer_action >> 4) &
+                                                 wdPreTimeoutInterruptMask);
+        wd_service.setPreTimeoutInterrupt(
+            ipmiPreTimeoutInterruptToWdAction(ipmiPreTimeoutInterrupt));
+
         lastCallSuccessful = true;
         return IPMI_CC_OK;
     }
diff --git a/app/watchdog_service.cpp b/app/watchdog_service.cpp
index 77663b4..0c4ea28 100644
--- a/app/watchdog_service.cpp
+++ b/app/watchdog_service.cpp
@@ -203,3 +203,9 @@ void WatchdogService::setTimeRemaining(uint64_t timeRemaining)
 {
     setProperty("TimeRemaining", timeRemaining);
 }
+
+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 ed64a3c..b550f37 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;
 
@@ -99,6 +101,13 @@ class WatchdogService
      */
     void setTimeRemaining(uint64_t timeRemaining);
 
+    /** @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.7.4