aboutsummaryrefslogtreecommitdiffstats
path: root/roms/skiboot/hw/fsp/fsp-attn.c
diff options
context:
space:
mode:
Diffstat (limited to 'roms/skiboot/hw/fsp/fsp-attn.c')
-rw-r--r--roms/skiboot/hw/fsp/fsp-attn.c143
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();
+}