diff options
Diffstat (limited to 'roms/skiboot/hw/fsp/fsp-attn.c')
-rw-r--r-- | roms/skiboot/hw/fsp/fsp-attn.c | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/roms/skiboot/hw/fsp/fsp-attn.c b/roms/skiboot/hw/fsp/fsp-attn.c new file mode 100644 index 000000000..6e358e0d4 --- /dev/null +++ b/roms/skiboot/hw/fsp/fsp-attn.c @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +/* + * FSP ATTentioN support + * + * FSP can grab a bunch of things on host firmware dying, + * let's set that up. + * + * Copyright 2013-2019 IBM Corp. +*/ +#include <fsp.h> +#include <skiboot.h> +#include <fsp-elog.h> +#include <fsp-attn.h> +#include <hdata/spira.h> +#include <stack.h> +#include <processor.h> +#include <opal-dump.h> + +#define TI_CMD_VALID 0x1 /* Command valid */ +#define TI_CMD 0xA1 /* Terminate Immediate command */ +#define TI_DATA_LEN 0x0400 /* Data length */ +/* Controls dump actions + * - Non-destructive hardware dump (bit 0) + * - memory dump (bit 1) + * - Destructive hardware dump (bit 2) + */ +#define TI_DMP_CTL 0x6 +/* Dump type + * 0 - Abbreviated hardware dump + * 1 - Complete hardware dump + * 2 - No hardware dump + */ +#define TI_DUMP_TYPE 0x1 +#define TI_FORMAT 0x02 /* SRC format */ +#define TI_SRC_FLAGS 0x0 /* SRC flags */ +#define TI_ASCII_WORDS 0x0 /* Number of ASCII words */ + +/* HEX words: Number of hex words of data added, up to 8 total + * this value is one more. + */ +#define TI_HEX_WORDS 0x02 +/* SRC length : 8 byte header, 8 hex words of data and + * 32 byte ASCII SRC + */ +#define TI_SRC_LEN 0x48 + +static struct ti_attn *ti_attn; + +/* Initialises SP attention area with default values */ +static void init_sp_attn_area(void) +{ + /* Already done */ + if (ti_attn) + return; + + /* We are just enabling attention area 1 */ + ti_attn = (struct ti_attn *)&cpu_ctl_sp_attn_area1; + + /* Attention component checks Attn area 2 first, if its NULL + * it will check for Attn area 1. + */ + memset(&cpu_ctl_sp_attn_area1, 0, sizeof(struct sp_attn_area)); + memset(&cpu_ctl_sp_attn_area2, 0, sizeof(struct sp_attn_area)); + + ti_attn->cmd_valid = TI_CMD_VALID; + ti_attn->attn_cmd = TI_CMD; + ti_attn->data_len = CPU_TO_BE16(TI_DATA_LEN); + /* Dump control byte not used as of now */ + ti_attn->dump_ctrl =TI_DMP_CTL; + ti_attn->dump_type = CPU_TO_BE16(TI_DUMP_TYPE); + + /* SRC format */ + ti_attn->src_fmt = TI_FORMAT; + /* SRC flags */ + ti_attn->src_flags = TI_SRC_FLAGS; + /* #ASCII words */ + ti_attn->ascii_cnt = TI_ASCII_WORDS; + /* #HEX words */ + ti_attn->hex_cnt = TI_HEX_WORDS; + ti_attn->src_len = CPU_TO_BE16(TI_SRC_LEN); + snprintf(ti_attn->src, SRC_LEN, "%X", generate_src_from_comp(OPAL_RC_ATTN)); +} + +/* Updates src in sp attention area + */ +static void update_sp_attn_area(const char *msg) +{ +#define STACK_BUF_ENTRIES 20 + struct bt_entry bt_buf[STACK_BUF_ENTRIES]; + struct bt_metadata metadata; + unsigned int len; + + if (!fsp_present()) + return; + + /* This can be called early */ + if (!ti_attn) + init_sp_attn_area(); + + ti_attn->src_word[0] = + cpu_to_be32((uint32_t)((uint64_t)__builtin_return_address(0) & 0xffffffff)); + + snprintf(ti_attn->msg.version, VERSION_LEN, "%s", version); + backtrace_create(bt_buf, STACK_BUF_ENTRIES, &metadata); + metadata.token = OPAL_LAST + 1; + len = BT_FRAME_LEN; + backtrace_print(bt_buf, &metadata, ti_attn->msg.bt_buf, &len, false); + snprintf(ti_attn->msg.file_info, FILE_INFO_LEN, "%s", msg); + + ti_attn->msg_len = cpu_to_be32(VERSION_LEN + BT_FRAME_LEN + + strlen(ti_attn->msg.file_info)); +} + +void __attribute__((noreturn)) ibm_fsp_terminate(const char *msg) +{ + /* Update SP attention area */ + update_sp_attn_area(msg); + + /* Update op panel op_display */ + op_display(OP_FATAL, OP_MOD_CORE, 0x6666); + + /* Save crashing CPU details */ + opal_mpipl_save_crashing_pir(); + + /* XXX FIXME: We should fsp_poll for a while to ensure any pending + * console writes have made it out, but until we have decent PSI + * link handling we must not do it forever. Polling can prevent the + * FSP from bringing the PSI link up and it can get stuck in a + * reboot loop. + */ + + trigger_attn(); + for (;;) ; +} + +/* Intialises SP attention area */ +void fsp_attn_init(void) +{ + if (!fsp_present()) + return; + + init_sp_attn_area(); +} |