aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/ipmi/Makefile.inc2
-rw-r--r--hw/ipmi/ipmi-attn.c85
-rw-r--r--include/ipmi.h3
-rw-r--r--platforms/astbmc/firestone.c1
-rw-r--r--platforms/astbmc/garrison.c1
-rw-r--r--platforms/astbmc/habanero.c1
-rw-r--r--platforms/astbmc/palmetto.c1
7 files changed, 93 insertions, 1 deletions
diff --git a/hw/ipmi/Makefile.inc b/hw/ipmi/Makefile.inc
index 06cdc96..6325369 100644
--- a/hw/ipmi/Makefile.inc
+++ b/hw/ipmi/Makefile.inc
@@ -1,7 +1,7 @@
SUBDIRS += hw/ipmi
IPMI_OBJS = ipmi-rtc.o ipmi-power.o ipmi-opal.o ipmi-fru.o ipmi-sel.o
-IPMI_OBJS += ipmi-watchdog.o ipmi-sensor.o
+IPMI_OBJS += ipmi-watchdog.o ipmi-sensor.o ipmi-attn.o
IPMI = hw/ipmi/built-in.o
$(IPMI): $(IPMI_OBJS:%=hw/ipmi/%)
diff --git a/hw/ipmi/ipmi-attn.c b/hw/ipmi/ipmi-attn.c
new file mode 100644
index 0000000..a3e4878
--- /dev/null
+++ b/hw/ipmi/ipmi-attn.c
@@ -0,0 +1,85 @@
+/* Copyright 2015 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <errorlog.h>
+#include <ipmi.h>
+#include <pel.h>
+#include <platform.h>
+#include <processor.h>
+#include <skiboot.h>
+#include <stack.h>
+#include <timebase.h>
+
+/* Use same attention SRC for BMC based machine */
+DEFINE_LOG_ENTRY(OPAL_RC_ATTN, OPAL_PLATFORM_ERR_EVT,
+ OPAL_ATTN, OPAL_PLATFORM_FIRMWARE,
+ OPAL_ERROR_PANIC, OPAL_ABNORMAL_POWER_OFF);
+
+/* Maximum buffer size to capture backtrace and other useful information */
+#define IPMI_TI_BUFFER_SIZE (IPMI_MAX_PEL_SIZE - PEL_MIN_SIZE)
+static char ti_buffer[IPMI_TI_BUFFER_SIZE];
+
+#define STACK_BUF_ENTRIES 20
+struct bt_entry bt_buf[STACK_BUF_ENTRIES];
+
+/* Log eSEL event with OPAL backtrace */
+static void ipmi_log_terminate_event(const char *msg)
+{
+ unsigned int bt_entry_cnt = STACK_BUF_ENTRIES;
+ unsigned int ti_len;
+ unsigned int ti_size;
+ struct errorlog *elog_buf;
+
+ /* Fill OPAL version */
+ ti_len = snprintf(ti_buffer, IPMI_TI_BUFFER_SIZE,
+ "OPAL version : %s\n", version);
+
+ /* File information */
+ ti_len += snprintf(ti_buffer + ti_len, IPMI_TI_BUFFER_SIZE - ti_len,
+ "File info : %s\n", msg);
+ ti_size = IPMI_TI_BUFFER_SIZE - ti_len;
+
+ /* Backtrace */
+ __backtrace(bt_buf, &bt_entry_cnt);
+ __print_backtrace(mfspr(SPR_PIR), bt_buf, bt_entry_cnt,
+ ti_buffer + ti_len, &ti_size, true);
+
+ /* Create eSEL event and commit */
+ elog_buf = opal_elog_create(&e_info(OPAL_RC_ATTN), 0);
+ log_append_data(elog_buf, (char *)&ti_buffer, ti_len + ti_size);
+ log_commit(elog_buf);
+}
+
+void __attribute__((noreturn)) ipmi_terminate(const char *msg)
+{
+ /* Terminate called before initializing IPMI (early abort) */
+ if (!ipmi_present()) {
+ if (platform.cec_reboot())
+ platform.cec_reboot();
+ goto out;
+ }
+
+ /* Log eSEL event */
+ ipmi_log_terminate_event(msg);
+
+ /* Reboot call */
+ if (platform.cec_reboot())
+ platform.cec_reboot();
+
+out:
+ while (1)
+ time_wait_ms(100);
+}
diff --git a/include/ipmi.h b/include/ipmi.h
index b33041b..99a9094 100644
--- a/include/ipmi.h
+++ b/include/ipmi.h
@@ -276,4 +276,7 @@ uint8_t ipmi_get_sensor_number(uint8_t sensor_type);
/* Set the boot count once the OS is up and running */
int ipmi_set_boot_count(void);
+/* Terminate immediate */
+void __attribute__((noreturn)) ipmi_terminate(const char *msg);
+
#endif
diff --git a/platforms/astbmc/firestone.c b/platforms/astbmc/firestone.c
index cda9d06..445a28b 100644
--- a/platforms/astbmc/firestone.c
+++ b/platforms/astbmc/firestone.c
@@ -47,4 +47,5 @@ DECLARE_PLATFORM(firestone) = {
.start_preload_resource = flash_start_preload_resource,
.resource_loaded = flash_resource_loaded,
.exit = ipmi_wdt_final_reset,
+ .terminate = ipmi_terminate,
};
diff --git a/platforms/astbmc/garrison.c b/platforms/astbmc/garrison.c
index 5cd8e2e..edc3522 100644
--- a/platforms/astbmc/garrison.c
+++ b/platforms/astbmc/garrison.c
@@ -56,4 +56,5 @@ DECLARE_PLATFORM(garrison) = {
.start_preload_resource = flash_start_preload_resource,
.resource_loaded = flash_resource_loaded,
.exit = ipmi_wdt_final_reset,
+ .terminate = ipmi_terminate,
};
diff --git a/platforms/astbmc/habanero.c b/platforms/astbmc/habanero.c
index 41e84f7..4ab2cdc 100644
--- a/platforms/astbmc/habanero.c
+++ b/platforms/astbmc/habanero.c
@@ -153,4 +153,5 @@ DECLARE_PLATFORM(habanero) = {
.start_preload_resource = flash_start_preload_resource,
.resource_loaded = flash_resource_loaded,
.exit = ipmi_wdt_final_reset,
+ .terminate = ipmi_terminate,
};
diff --git a/platforms/astbmc/palmetto.c b/platforms/astbmc/palmetto.c
index 7c2a157..ca91908 100644
--- a/platforms/astbmc/palmetto.c
+++ b/platforms/astbmc/palmetto.c
@@ -56,4 +56,5 @@ DECLARE_PLATFORM(palmetto) = {
.start_preload_resource = flash_start_preload_resource,
.resource_loaded = flash_resource_loaded,
.exit = ipmi_wdt_final_reset,
+ .terminate = ipmi_terminate,
};