diff options
-rw-r--r-- | hw/ipmi/Makefile.inc | 2 | ||||
-rw-r--r-- | hw/ipmi/ipmi-attn.c | 85 | ||||
-rw-r--r-- | include/ipmi.h | 3 | ||||
-rw-r--r-- | platforms/astbmc/firestone.c | 1 | ||||
-rw-r--r-- | platforms/astbmc/garrison.c | 1 | ||||
-rw-r--r-- | platforms/astbmc/habanero.c | 1 | ||||
-rw-r--r-- | platforms/astbmc/palmetto.c | 1 |
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, }; |