summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0021-Implement-IPMI-Commmand-Get-Host-Restart-Cause.patch
blob: cba0cde32dd335f6362c21e254d15f807eb71bcc (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
141
142
143
From 6d5a372e0cf98de4d97a88d2cd42a00b7a8f034f Mon Sep 17 00:00:00 2001
From: Yong Li <yong.b.li@linux.intel.com>
Date: Sun, 16 Sep 2018 21:32:38 +0800
Subject: [PATCH] Implement IPMI Commmand - Get Host Restart Cause.

It supports to track the information about what
action last caused the system to restart.
Return value includes: restart_cause and channel_number.

According to IPMI Spec, it includes 12 types as following:
1. Unknown                  0x0
2. IpmiCommand              0x1
3. ResetButton              0x2
4. PowerButton              0x3
5. WatchdogTimer            0x4
6. OEM                      0x5
7. PowerPolicyAlwaysOn      0x6
8. PowerPolicyPreviousState 0x7
9. PEF-Reset                0x8
10. PEF-PowerCycle          0x9
11. SoftReset               0xA
12. RTC-Wakeup              0xB

Change-Id: Id3b32e271b85b5fc4c69d5ca40227f8f9c08ce48
Signed-off-by: Kuiying Wang <kuiying.wang@intel.com>
Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
---
 chassishandler.cpp        | 54 +++++++++++++++++++++++++++++++++++++++
 chassishandler.hpp        |  1 +
 host-ipmid-whitelist.conf |  1 +
 3 files changed, 56 insertions(+)

diff --git a/chassishandler.cpp b/chassishandler.cpp
index d20b220..8a8cb26 100644
--- a/chassishandler.cpp
+++ b/chassishandler.cpp
@@ -90,6 +90,11 @@ static constexpr auto chassisPOHStateIntf =
     "xyz.openbmc_project.State.PowerOnHours";
 static constexpr auto pOHCounterProperty = "POHCounter";
 static constexpr auto match = "chassis0";
+const static constexpr char* stateHostInterface =
+    "xyz.openbmc_project.State.Host";
+const static constexpr char* hostRestartCauseInterface =
+    "xyz.openbmc_project.State.Host.HostRestartCause";
+const static constexpr char* hostRestartCause = "HostRestartCause";
 const static constexpr char chassisCapIntf[] =
     "xyz.openbmc_project.Control.ChassisCapabilities";
 const static constexpr char chassisCapFlagsProp[] = "CapabilitiesFlags";
@@ -176,6 +181,13 @@ struct set_sys_boot_options_t
     uint8_t data[SIZE_BOOT_OPTION];
 } __attribute__((packed));
 
+struct GetSysRestartCauseResponse
+{
+    uint8_t restartCause;
+    uint8_t channelNum;
+
+} __attribute__((packed));
+
 int getHostNetworkData(get_sys_boot_options_response_t* respptr)
 {
     ipmi::PropertyMap properties;
@@ -1584,6 +1596,44 @@ ipmi_ret_t ipmi_chassis_set_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
     return rc;
 }
 
+ipmi_ret_t ipmi_chassis_get_sys_restart_cause(
+    ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request,
+    ipmi_response_t response, ipmi_data_len_t data_len, ipmi_context_t context)
+{
+    ipmi_ret_t rc = IPMI_CC_OK;
+
+    GetSysRestartCauseResponse* resp = (GetSysRestartCauseResponse*)response;
+    std::fill(reinterpret_cast<uint8_t*>(resp),
+              reinterpret_cast<uint8_t*>(resp) + sizeof(*resp), 0);
+    if (*data_len != 0)
+    {
+        rc = IPMI_CC_REQ_DATA_LEN_INVALID;
+        return rc;
+    }
+
+    try
+    {
+        sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
+        ipmi::DbusObjectInfo hostObject =
+            ipmi::getDbusObject(bus, stateHostInterface);
+        ipmi::Value variant =
+            ipmi::getDbusProperty(bus, hostObject.second, hostObject.first,
+                                  hostRestartCauseInterface, hostRestartCause);
+        resp->restartCause = variant.get<uint8_t>();
+    }
+
+    catch (std::exception& e)
+    {
+        log<level::ERR>(e.what());
+        rc = IPMI_CC_UNSPECIFIED_ERROR;
+        return rc;
+    }
+    resp->channelNum = 0; // Fix to primary channel.
+    *data_len = sizeof(GetSysRestartCauseResponse);
+
+    return rc;
+}
+
 /** @brief implements Get POH counter command
  *  @parameter
  *   -  none
@@ -1739,4 +1789,8 @@ void register_netfn_chassis_functions()
                           ipmi::chassis::cmdSetPowerRestorePolicy,
                           ipmi::Privilege::Operator,
                           ipmiChassisSetPowerRestorePolicy);
+
+    // <get Host Restart Cause>
+    ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_SYS_RESTART_CAUSE, NULL,
+                           ipmi_chassis_get_sys_restart_cause, PRIVILEGE_USER);
 }
diff --git a/chassishandler.hpp b/chassishandler.hpp
index 49b5ef8..2c42b11 100644
--- a/chassishandler.hpp
+++ b/chassishandler.hpp
@@ -17,6 +17,7 @@ enum ipmi_netfn_chassis_cmds
     // Set Power Restore Policy
     IPMI_CMD_SET_RESTORE_POLICY = 0x06,
     // Get capability bits
+    IPMI_CMD_GET_SYS_RESTART_CAUSE = 0x07,
     IPMI_CMD_SET_SYS_BOOT_OPTIONS = 0x08,
     IPMI_CMD_GET_SYS_BOOT_OPTIONS = 0x09,
     IPMI_CMD_GET_POH_COUNTER = 0x0F,
diff --git a/host-ipmid-whitelist.conf b/host-ipmid-whitelist.conf
index c1fca1d..94232de 100644
--- a/host-ipmid-whitelist.conf
+++ b/host-ipmid-whitelist.conf
@@ -4,6 +4,7 @@
 0x00:0x02    //<Chassis>:<Chassis Control>
 0x00:0x05    //<Chassis>:<Set Chassis Capabilities>
 0x00:0x06    //<Chassis>:<Set Power Restore Policy>
+0x00:0x07    //<Chassis>:<Get System Restart Cause>
 0x00:0x08    //<Chassis>:<Set System Boot Options>
 0x00:0x09    //<Chassis>:<Get System Boot Options>
 0x00:0x0F    //<Chassis>:<Get POH Counter Command>
-- 
2.17.1