1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 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();
}
|