summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAruna Balakrishnaiah <aruna@linux.vnet.ibm.com>2014-07-31 14:46:06 +0530
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-08-01 16:02:27 +1000
commite810dcbc09c375a39ce36f461eb0cc2f7e9a1aed (patch)
tree18590f39e6e997c4826a998a12c03c7f86239139
parent025184d5cb8626cd50ac28982d001f92f66a38e2 (diff)
downloadtalos-skiboot-e810dcbc09c375a39ce36f461eb0cc2f7e9a1aed.tar.gz
talos-skiboot-e810dcbc09c375a39ce36f461eb0cc2f7e9a1aed.zip
ATTN: Set up attention area to handle attention
At present CPU control area ntuple in SPIRA structure is NULL. ATTN component in Service Processor side checks for this field and if its empty, it logs hardcoded SRC (0xBB821410) and generates SYSDUMP. So we have 1 SRC for all failure (assert call) from OPAL side. This makes difficult to debug the issue. Service processor provides attention area interface (FIPS PHyp Attentions spec), so that we can pass SRC and user data (error message) to service processor. This will helps us identify different failures in OPAL. This patch enables attention area and provides interface (update_sp_attn_area()) to add src and user data (error message) through assert macro. Attention SRC format: 1st byte - Opal src type 2-4 bytes - Holds the address of the assert function call Signed-off-by: Aruna Balakrishnaiah <aruna@linux.vnet.ibm.com> Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--hdata/spira.c36
-rw-r--r--hdata/spira.h32
-rw-r--r--hw/fsp/Makefile.inc1
-rw-r--r--hw/fsp/fsp-attn.c109
-rw-r--r--include/fsp-attn.h142
-rw-r--r--include/fsp.h3
-rw-r--r--include/mem-map.h5
-rw-r--r--libc/include/assert.h8
-rw-r--r--platforms/ibm-fsp/common.c3
-rw-r--r--skiboot.lds.S5
10 files changed, 342 insertions, 2 deletions
diff --git a/hdata/spira.c b/hdata/spira.c
index 45c282ca..3923bb5b 100644
--- a/hdata/spira.c
+++ b/hdata/spira.c
@@ -23,6 +23,7 @@
#include <ccan/str/str.h>
#include <chip.h>
#include <fsp-mdst-table.h>
+#include <fsp-attn.h>
#include "hdata.h"
#include "hostservices.h"
@@ -46,6 +47,34 @@ __section(".procin.data") struct proc_init_data proc_init_data = {
},
};
+__section(".cpuctrl.data") struct sp_addr_table cpu_ctl_spat_area;
+__section(".cpuctrl.data") struct sp_attn_area cpu_ctl_sp_attn_area1;
+__section(".cpuctrl.data") struct sp_attn_area cpu_ctl_sp_attn_area2;
+__section(".cpuctrl.data") struct hsr_data_area cpu_ctl_hsr_area;
+
+__section(".cpuctrl.data") struct cpu_ctl_init_data cpu_ctl_init_data = {
+ .hdr = HDIF_SIMPLE_HDR(CPU_CTL_HDIF_SIG, 2, struct cpu_ctl_init_data),
+ .cpu_ctl = HDIF_IDATA_PTR(offsetof(struct cpu_ctl_init_data, cpu_ctl_lt), sizeof(struct cpu_ctl_legacy_table)),
+ .cpu_ctl_lt = {
+ .spat = {
+ .addr = CPU_TO_BE64((unsigned long)&(cpu_ctl_spat_area) + SKIBOOT_BASE),
+ .size = CPU_TO_BE64(sizeof(struct sp_addr_table)),
+ },
+ .sp_attn_area1 = {
+ .addr = CPU_TO_BE64((unsigned long)&(cpu_ctl_sp_attn_area1) + SKIBOOT_BASE),
+ .size = CPU_TO_BE64(sizeof(struct sp_attn_area)),
+ },
+ .sp_attn_area2 = {
+ .addr = CPU_TO_BE64((unsigned long)&(cpu_ctl_sp_attn_area2) + SKIBOOT_BASE),
+ .size = CPU_TO_BE64(sizeof(struct sp_attn_area)),
+ },
+ .hsr_area = {
+ .addr = CPU_TO_BE64((unsigned long)&(cpu_ctl_hsr_area) + SKIBOOT_BASE),
+ .size = CPU_TO_BE64(sizeof(struct hsr_data_area)),
+ },
+ },
+};
+
/* Populate MDST table
*
* Note that we only pass sapphire console buffer here so that we can
@@ -104,6 +133,13 @@ __section(".spira.data") struct spira spira = {
.alloc_len =
CPU_TO_BE32(sizeof(init_mdst_table)),
},
+ .cpu_ctrl = {
+ .addr = CPU_TO_BE64((unsigned long)&cpu_ctl_init_data),
+ .alloc_cnt = CPU_TO_BE16(1),
+ .act_cnt = CPU_TO_BE16(1),
+ .alloc_len =
+ CPU_TO_BE32(sizeof(cpu_ctl_init_data)),
+ },
},
};
diff --git a/hdata/spira.h b/hdata/spira.h
index 93239d0f..fa734521 100644
--- a/hdata/spira.h
+++ b/hdata/spira.h
@@ -537,6 +537,38 @@ struct cechub_io_hub {
#define IOKID_KW_VPD 1
/*
+ * CPU Controls Legacy Structure
+ */
+struct cpu_ctl_legacy {
+ __be64 addr;
+ __be64 size;
+} __packed;
+
+/*
+ * CPU Control Legacy table
+ *
+ * Format of this table is defined in FIPS PHYP Attn spec.
+ */
+struct cpu_ctl_legacy_table {
+ struct cpu_ctl_legacy spat;
+ struct cpu_ctl_legacy sp_attn_area1;
+ struct cpu_ctl_legacy sp_attn_area2;
+ struct cpu_ctl_legacy hsr_area;
+ struct cpu_ctl_legacy reserved[12];
+} __packed;
+
+/*
+ * CPU Controls Header Structure
+ */
+#define CPU_CTL_HDIF_SIG "CPUCTL"
+struct cpu_ctl_init_data {
+ struct HDIF_common_hdr hdr;
+ struct HDIF_idata_ptr cpu_ctl;
+ uint8_t reserved[8];
+ struct cpu_ctl_legacy_table cpu_ctl_lt;
+} __packed __align(0x10);
+
+/*
* Slot Location Code Array (aka SLCA)
*
* This is a pile of location codes referenced by various other
diff --git a/hw/fsp/Makefile.inc b/hw/fsp/Makefile.inc
index 126ebad8..95f1f04d 100644
--- a/hw/fsp/Makefile.inc
+++ b/hw/fsp/Makefile.inc
@@ -5,5 +5,6 @@ FSP_OBJS += fsp-surveillance.o fsp-codeupdate.o fsp-sensor.o
FSP_OBJS += fsp-diag.o fsp-leds.o fsp-mem-err.o fsp-op-panel.o
FSP_OBJS += fsp-elog-read.o fsp-elog-write.o fsp-epow.o
FSP_OBJS += fsp-dump.o fsp-mdst-table.o
+FSP_OBJS += fsp-attn.o
FSP = hw/fsp/built-in.o
$(FSP): $(FSP_OBJS:%=hw/fsp/%)
diff --git a/hw/fsp/fsp-attn.c b/hw/fsp/fsp-attn.c
new file mode 100644
index 00000000..32e3f029
--- /dev/null
+++ b/hw/fsp/fsp-attn.c
@@ -0,0 +1,109 @@
+/* Copyright 2013-2014 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 <fsp.h>
+#include <skiboot.h>
+#include <fsp-elog.h>
+#include <fsp-attn.h>
+#include <hdata/spira.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
+
+/* Generate src from assert function's address
+ * First byte in the SRC used for source opal src_type
+ * Next 3 bytes used for assert function call address
+ */
+#define generate_attn_src(addr) (OPAL_SRC_TYPE_ERROR << 24 | (addr & 0xffffff))
+
+static struct ti_attn *ti_attn;
+
+/* Initialises SP attention area with default values */
+static void init_sp_attn_area(void)
+{
+ /* 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);
+}
+
+/* Updates src in sp attention area
+ */
+void update_sp_attn_area(const char *msg)
+{
+ if (!fsp_present())
+ return;
+
+ sprintf(ti_attn->src, "%X",
+ (uint32_t)generate_attn_src((uint64_t)__builtin_return_address(0)));
+
+ ti_attn->msg_len = strlen(msg);
+ sprintf(ti_attn->msg, "%s", msg);
+}
+
+/* Intialises SP attention area */
+void fsp_attn_init(void)
+{
+ if (!fsp_present())
+ return;
+
+ init_sp_attn_area();
+}
diff --git a/include/fsp-attn.h b/include/fsp-attn.h
new file mode 100644
index 00000000..0149b7c7
--- /dev/null
+++ b/include/fsp-attn.h
@@ -0,0 +1,142 @@
+/* Copyright 2013-2014 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.
+*/
+
+#ifndef __FSP_ATTN_H
+#define __FSP_ATTN_H
+
+/* Per spec attn area can go up to 0x400 bytes */
+#define ATTN_AREA_SZ 0x400
+
+extern struct sp_attn_area cpu_ctl_sp_attn_area1;
+extern struct sp_attn_area cpu_ctl_sp_attn_area2;
+
+struct spat_entry {
+ /* Virtual address */
+ __be64 vaddr;
+ /* Partition id */
+ __be16 id;
+ uint8_t reserved[6];
+} __packed;
+
+/* SP Address Table: Structure is not used as of today, defined to
+ * keep in sync with the spec */
+struct sp_addr_table {
+ /* Index of last valid spat entry */
+ __be32 idx;
+ /* Number of SPAT entries allocated = 31 for SP */
+ __be32 count;
+ uint8_t reserved1[8];
+ /* SPAT entries */
+ struct spat_entry spat_entry[31];
+} __packed;
+
+/* SP Attention Areas */
+struct sp_attn_area {
+ /* Processor Number */
+ uint8_t processor;
+ /* Attention command */
+ uint8_t attn_cmd;
+ __be16 data_len;
+ uint8_t data[];
+} __packed __align(ATTN_AREA_SZ);
+
+#define SRC_WORD_COUNT 8
+#define SRC_LEN 32
+/* Max limit of user data size is 940 (due to attention area size) */
+#define TI_MSG_LEN 940
+/* Terminate Immediate Attention */
+struct ti_attn {
+ /* Command valid */
+ uint8_t cmd_valid;
+ /* Attention command */
+ uint8_t attn_cmd;
+ __be16 data_len;
+ /* Controls dump actions */
+ uint8_t dump_ctrl;
+ uint8_t reserved1;
+ /* Hardware dump type */
+ __be16 dump_type;
+ /* SRC format */
+ uint8_t src_fmt;
+ /* SRC flags */
+ uint8_t src_flags;
+ /* Number of ASCII words */
+ uint8_t ascii_cnt;
+ /* Number of HEX words */
+ uint8_t hex_cnt;
+ __be16 reserved2;
+ /* SRC length */
+ __be16 src_len;
+ __be32 src_word[SRC_WORD_COUNT];
+ /* ASCII data */
+ char src[SRC_LEN];
+ uint32_t msg_len;
+ /* User data: Simple error message */
+ char msg[TI_MSG_LEN];
+} __packed __align(ATTN_AREA_SZ);
+
+/* Hypervisor Service Routine Data area: Structure is not used as of today,
+ * defined to keep in sync with the spec */
+struct hsr_data_area {
+ /* MS Address Compare Address */
+ __be64 ms_cmp_addr;
+ /* MS Address Compare Op (set/reset) */
+ __be16 ms_cmp_op;
+ /* MS Address Compare Length */
+ __be16 ms_cmp_len;
+ /* MS Address Compare Data */
+ __be32 ms_cmp_data;
+ /* MS Address Compare Service Routine */
+ __be64 ms_cmp_sr;
+ /* Pointer to MS Display / Alter HSR */
+ __be64 ms_display;
+ __be64 reserved1;
+ /* MS Dump HSR */
+ __be64 ms_dump_hsr;
+ /* Pointer to Real Address Validation HSR */
+ __be64 hsr_raddr;
+ /* Effective Address Field */
+ __be64 eaddr;
+ /* Pointer to CPU Spin HSR */
+ __be64 hsr_cpu_spin;
+ /* Pointer to SP Glue HSR */
+ __be64 hsr_sp_glue;
+ uint8_t reserved2[19];
+ /* Time Base Flags
+ * bit 7 (0x01) = 0b1: hardware time base disabled
+ * other bits reserved
+ */
+ uint8_t time_flags;
+ uint8_t reserved3[12];
+ /* TDE Addr Parm */
+ __be64 tde_addr;
+ /* SDR1 Shared Processor HSR */
+ __be64 hsr_sdr1_proc;
+ __be64 partition_id;
+ uint8_t reserved4[12];
+ /* Address Type for Compare
+ * 1 = real address
+ * 2 = effective address
+ * 3 = virtual address
+ */
+ __be16 ms_addr_type;
+ uint8_t reserved5[10];
+ /* Cache Flush Service Routine Pointer */
+ __be64 cfsr;
+ uint8_t reserved6[88];
+} __packed;
+
+#endif /* __FSP_ATTN_H */
diff --git a/include/fsp.h b/include/fsp.h
index 9541a8b0..8e02adec 100644
--- a/include/fsp.h
+++ b/include/fsp.h
@@ -719,6 +719,9 @@ extern void fsp_code_update_wait_vpd(bool is_boot);
extern void fsp_dump_init(void);
extern void fsp_fips_dump_notify(uint32_t dump_id, uint32_t dump_len);
+/* Attention Handler */
+extern void fsp_attn_init(void);
+
/* MDST table */
extern void fsp_mdst_table_init(void);
diff --git a/include/mem-map.h b/include/mem-map.h
index effd6892..2d01ab69 100644
--- a/include/mem-map.h
+++ b/include/mem-map.h
@@ -46,6 +46,11 @@
*/
#define MDST_TABLE_OFF (SPIRA_OFF + 0x1000)
+/* Like MDST, we need fixed address for CPU control header.
+ * We leave a 2k gap for MDST. CPU_CTL table is of size ~4k
+ */
+#define CPU_CTL_OFF (SPIRA_OFF + 0x1800)
+
/* We keep a gap of 2M for skiboot text & bss for now. We will
* then we have our heap which goes up to base + 14M (so 12M for
* now, though we can certainly reduce that a lot).
diff --git a/libc/include/assert.h b/libc/include/assert.h
index 755fc71b..fbfb2cce 100644
--- a/libc/include/assert.h
+++ b/libc/include/assert.h
@@ -13,11 +13,15 @@
#ifndef _ASSERT_H
#define _ASSERT_H
+extern void update_sp_attn_area(const char *msg);
+
#define assert(cond) \
- do { if (!(cond)) \
+ do { if (!(cond)) { \
+ update_sp_attn_area(__FILE__ \
+ ":" stringify(__LINE__)); \
assert_fail(__FILE__ \
":" stringify(__LINE__) \
- ":" stringify(cond)); \
+ ":" stringify(cond)); } \
} while(0)
void __attribute__((noreturn)) assert_fail(const char *msg);
diff --git a/platforms/ibm-fsp/common.c b/platforms/ibm-fsp/common.c
index 2c268eb9..91eaeead 100644
--- a/platforms/ibm-fsp/common.c
+++ b/platforms/ibm-fsp/common.c
@@ -103,6 +103,9 @@ void ibm_fsp_init(void)
/* Start FSP/HV state controller & perform OPL */
fsp_opl();
+ /* Initialize SP attention area */
+ fsp_attn_init();
+
/* Send MDST table notification to FSP */
op_display(OP_LOG, OP_MOD_INIT, 0x0000);
fsp_mdst_table_init();
diff --git a/skiboot.lds.S b/skiboot.lds.S
index cbc8b85b..82cbdb28 100644
--- a/skiboot.lds.S
+++ b/skiboot.lds.S
@@ -41,6 +41,11 @@ SECTIONS
KEEP(*(.mdst.data))
}
+ . = CPU_CTL_OFF;
+ .cpuctrl : {
+ KEEP(*(.cpuctrl.data))
+ }
+
. = ALIGN(0x10);
.text : {
*(.text*)
OpenPOWER on IntegriCloud