aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorJoel Stanley <joel@jms.id.au>2015-02-05 13:40:05 +1030
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-02-09 14:19:44 +1100
commite8ffc3caadf6e5ddbcd0910ae239eb1be0fdb381 (patch)
treeaf051f0c47e70b3eae331618f4b96bde07875349 /hw
parent77e4b445025b05d4da12862e34a47519d0a64868 (diff)
downloadskiboot-e8ffc3caadf6e5ddbcd0910ae239eb1be0fdb381.zip
skiboot-e8ffc3caadf6e5ddbcd0910ae239eb1be0fdb381.tar.gz
skiboot-e8ffc3caadf6e5ddbcd0910ae239eb1be0fdb381.tar.bz2
ipmi: Message Linux to perform graceful shutdown
This sends the previously unused OPAL_MSG_SHUTDOWN using opal_queue_msg to initiate a graceful shutdown. The message provides a single parameter indicating weather the shutdown is will result in a power-off, or a reboot. Signed-off-by: Joel Stanley <joel@jms.id.au> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/ipmi/ipmi-sel.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/hw/ipmi/ipmi-sel.c b/hw/ipmi/ipmi-sel.c
index 4c66bd1..2fbb45d 100644
--- a/hw/ipmi/ipmi-sel.c
+++ b/hw/ipmi/ipmi-sel.c
@@ -23,6 +23,7 @@
#include <lock.h>
#include <errorlog.h>
#include <pel.h>
+#include <opal-msg.h>
/* OEM SEL fields */
#define SEL_OEM_ID_0 0x55
@@ -36,6 +37,9 @@
#define CMD_AMI_POWER 0x04
#define CMD_AMI_PNOR_ACCESS 0x07
+#define SOFT_OFF 0x00
+#define SOFT_REBOOT 0x01
+
struct oem_sel {
/* SEL header */
uint8_t id[2];
@@ -175,6 +179,23 @@ int ipmi_elog_commit(struct errorlog *elog_buf)
return 0;
}
+static void sel_power(uint8_t power)
+{
+ switch (power) {
+ case SOFT_OFF:
+ prlog(PR_NOTICE, "IPMI: soft shutdown requested\n");
+ opal_queue_msg(OPAL_MSG_SHUTDOWN, NULL, NULL, SOFT_OFF);
+ break;
+ case SOFT_REBOOT:
+ prlog(PR_NOTICE, "IPMI: soft reboot rqeuested\n");
+ opal_queue_msg(OPAL_MSG_SHUTDOWN, NULL, NULL, SOFT_REBOOT);
+ break;
+ default:
+ prlog(PR_WARNING, "IPMI: requested bad power state: %02x\n",
+ power);
+ }
+}
+
static void dump_sel(struct oem_sel *sel)
{
const int level = PR_DEBUG;
@@ -220,6 +241,7 @@ void ipmi_parse_sel(struct ipmi_msg *msg)
switch (sel.cmd) {
case CMD_AMI_POWER:
+ sel_power(sel.data[0]);
break;
case CMD_AMI_PNOR_ACCESS:
break;